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).
This commit is contained in:
Roland Scheidegger 2010-08-23 17:55:16 +02:00
parent c907b94713
commit c2f074d8a4
4 changed files with 47 additions and 61 deletions

View File

@ -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];
};
/**

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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);