summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2010-08-23 17:55:16 +0200
committerRoland Scheidegger <[email protected]>2010-08-23 17:55:16 +0200
commitc2f074d8a4b93f3f3a81311f9a114b11bc5f80d8 (patch)
treed389c7e693eac270d3bca424642c17df629d7ec5
parentc907b947130c884de09e48e1ecbeecc9afc9f75b (diff)
util: fix util_fill_rect to take util_color instead of u32 param
util_fill_rect could not handle formats with more than 32 bits, since the fill color was a uint32_t value. Fix this by using a util_color union instead, and also expand the union so it works with formats which have up to 256 bits (the max of any format currently defined).
-rw-r--r--src/gallium/auxiliary/util/u_pack_color.h8
-rw-r--r--src/gallium/auxiliary/util/u_rect.c51
-rw-r--r--src/gallium/auxiliary/util/u_rect.h3
-rw-r--r--src/gallium/auxiliary/util/u_surface.c46
4 files changed, 47 insertions, 61 deletions
diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h
index 5f113f742b1..aae8b8bdf18 100644
--- a/src/gallium/auxiliary/util/u_pack_color.h
+++ b/src/gallium/auxiliary/util/u_pack_color.h
@@ -42,12 +42,18 @@
#include "util/u_math.h"
-
+/**
+ * Helper union for packing pixel values.
+ * Will often contain values in formats which are too complex to be described
+ * in simple terms, hence might just effectively contain a number of bytes.
+ * Must be big enough to hold data for all formats (currently 256 bits).
+ */
union util_color {
ubyte ub;
ushort us;
uint ui;
float f[4];
+ double d[4];
};
/**
diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c
index 9bbcf1c8c49..56fcfac0693 100644
--- a/src/gallium/auxiliary/util/u_rect.c
+++ b/src/gallium/auxiliary/util/u_rect.c
@@ -32,6 +32,7 @@
#include "util/u_format.h"
#include "util/u_rect.h"
+#include "util/u_pack_color.h"
/**
@@ -94,7 +95,7 @@ util_fill_rect(ubyte * dst,
unsigned dst_y,
unsigned width,
unsigned height,
- uint32_t value)
+ union util_color *uc)
{
unsigned i, j;
unsigned width_size;
@@ -110,40 +111,54 @@ util_fill_rect(ubyte * dst,
dst_y /= blockheight;
width = (width + blockwidth - 1)/blockwidth;
height = (height + blockheight - 1)/blockheight;
-
+
dst += dst_x * blocksize;
dst += dst_y * dst_stride;
width_size = width * blocksize;
-
+
switch (blocksize) {
case 1:
if(dst_stride == width_size)
- memset(dst, (ubyte) value, height * width_size);
+ memset(dst, uc->ub, height * width_size);
else {
- for (i = 0; i < height; i++) {
- memset(dst, (ubyte) value, width_size);
- dst += dst_stride;
- }
+ for (i = 0; i < height; i++) {
+ memset(dst, uc->ub, width_size);
+ dst += dst_stride;
+ }
}
break;
case 2:
for (i = 0; i < height; i++) {
- uint16_t *row = (uint16_t *)dst;
- for (j = 0; j < width; j++)
- *row++ = (uint16_t) value;
- dst += dst_stride;
+ uint16_t *row = (uint16_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = uc->us;
+ dst += dst_stride;
}
break;
case 4:
for (i = 0; i < height; i++) {
- uint32_t *row = (uint32_t *)dst;
- for (j = 0; j < width; j++)
- *row++ = value;
- dst += dst_stride;
+ uint32_t *row = (uint32_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = uc->ui;
+ dst += dst_stride;
+ }
+ break;
+ case 8:
+ case 12:
+ case 16:
+ case 24:
+ case 32:
+ for (i = 0; i < height; i++) {
+ ubyte *row = dst;
+ for (j = 0; j < width; j++) {
+ memcpy(row, uc, blocksize);
+ row += blocksize;
+ }
+ dst += dst_stride;
}
break;
default:
- assert(0);
- break;
+ assert(0);
+ break;
}
}
diff --git a/src/gallium/auxiliary/util/u_rect.h b/src/gallium/auxiliary/util/u_rect.h
index 40d57e662d7..deb00cc80cd 100644
--- a/src/gallium/auxiliary/util/u_rect.h
+++ b/src/gallium/auxiliary/util/u_rect.h
@@ -36,6 +36,7 @@
#include "pipe/p_format.h"
+#include "util/u_pack_color.h"
extern void
@@ -47,7 +48,7 @@ util_copy_rect(ubyte * dst, enum pipe_format format,
extern void
util_fill_rect(ubyte * dst, enum pipe_format format,
unsigned dst_stride, unsigned dst_x, unsigned dst_y,
- unsigned width, unsigned height, uint32_t value);
+ unsigned width, unsigned height, union util_color *uc);
#endif /* U_RECT_H */
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index cab7691c705..af99163b2ed 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -216,7 +216,7 @@ util_clear_render_target(struct pipe_context *pipe,
assert(dst->texture);
if (!dst->texture)
return;
- util_pack_color(rgba, dst->texture->format, &uc);
+
dst_trans = pipe_get_transfer(pipe,
dst->texture,
dst->face,
@@ -232,46 +232,10 @@ util_clear_render_target(struct pipe_context *pipe,
if (dst_map) {
assert(dst_trans->stride > 0);
- switch (util_format_get_blocksize(dst->texture->format)) {
- case 1:
- case 2:
- case 4:
- util_pack_color(rgba, dst->texture->format, &uc);
- util_fill_rect(dst_map, dst->texture->format,
- dst_trans->stride,
- 0, 0, width, height, uc.ui);
- break;
- case 8:
- {
- /* expand the 4-byte clear value to an 8-byte value */
- /* should probably not convert back from ubyte but not
- sure what this code really achieved since it doesn't even
- check for format type... */
- ushort *row = (ushort *) dst_map;
- ushort val0 = UBYTE_TO_USHORT((uc.ui >> 0) & 0xff);
- ushort val1 = UBYTE_TO_USHORT((uc.ui >> 8) & 0xff);
- ushort val2 = UBYTE_TO_USHORT((uc.ui >> 16) & 0xff);
- ushort val3 = UBYTE_TO_USHORT((uc.ui >> 24) & 0xff);
- unsigned i, j;
- val0 = (val0 << 8) | val0;
- val1 = (val1 << 8) | val1;
- val2 = (val2 << 8) | val2;
- val3 = (val3 << 8) | val3;
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- row[j*4+0] = val0;
- row[j*4+1] = val1;
- row[j*4+2] = val2;
- row[j*4+3] = val3;
- }
- row += dst_trans->stride/2;
- }
- }
- break;
- default:
- assert(0);
- break;
- }
+ util_pack_color(rgba, dst->texture->format, &uc);
+ util_fill_rect(dst_map, dst->texture->format,
+ dst_trans->stride,
+ 0, 0, width, height, &uc);
}
pipe->transfer_unmap(pipe, dst_trans);