util: fix util_fill_rect to take util_color instead of u32 param
authorRoland Scheidegger <sroland@vmware.com>
Mon, 23 Aug 2010 15:55:16 +0000 (17:55 +0200)
committerRoland Scheidegger <sroland@vmware.com>
Mon, 23 Aug 2010 15:55:16 +0000 (17:55 +0200)
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).

src/gallium/auxiliary/util/u_pack_color.h
src/gallium/auxiliary/util/u_rect.c
src/gallium/auxiliary/util/u_rect.h
src/gallium/auxiliary/util/u_surface.c

index 5f113f742b113060701f150074a86a94b1a79c87..aae8b8bdf189d4af35851cf67c6520bf207e2313 100644 (file)
 #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];
 };
 
 /**
index 9bbcf1c8c49ae1d636b46facb9534ff6993f67c3..56fcfac069368fc5d487068b46ec077c5b856ad4 100644 (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;
    }
 }
index 40d57e662d7e3ec1a7ebe96e2e1981ec7e31b899..deb00cc80cd3bc067272e7945476a539a08cad86 100644 (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 */
index cab7691c705a77d5a4da1a86aacaa3e6bfd6afac..af99163b2ed2b780cddb0d698a1ab60e21545eb4 100644 (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);