util: fix issues with util_clear_render_target.
authorRoland Scheidegger <sroland@vmware.com>
Wed, 27 Feb 2013 18:25:48 +0000 (19:25 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Thu, 28 Feb 2013 02:39:53 +0000 (03:39 +0100)
For PIPE_BUFFER we need coord adjustments for the transfer.
And for pure integer formats util_pack_color just crashes,
need to handle that differently due to clear colors being ints/uints.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/util/u_surface.c

index b948b46d25f96a6a4a1f582ce4c0274088808aef..5c3a655d6285855bc923090a49bd8ff813ea9b9a 100644 (file)
@@ -322,21 +322,58 @@ util_clear_render_target(struct pipe_context *pipe,
    assert(dst->texture);
    if (!dst->texture)
       return;
-   /* XXX: should handle multiple layers */
-   dst_map = pipe_transfer_map(pipe,
-                               dst->texture,
-                               dst->u.tex.level,
-                               dst->u.tex.first_layer,
-                               PIPE_TRANSFER_WRITE,
-                               dstx, dsty, width, height, &dst_trans);
+
+   if (dst->texture->target == PIPE_BUFFER) {
+      /*
+       * The fill naturally works on the surface format, however
+       * the transfer uses resource format which is just bytes for buffers.
+       */
+      unsigned dx, w;
+      unsigned pixstride = util_format_get_blocksize(dst->format);
+      dx = (dst->u.buf.first_element + dstx) * pixstride;
+      w = width * pixstride;
+      dst_map = pipe_transfer_map(pipe,
+                                  dst->texture,
+                                  0, 0,
+                                  PIPE_TRANSFER_WRITE,
+                                  dx, 0, w, 1,
+                                  &dst_trans);
+   }
+   else {
+      /* XXX: should handle multiple layers */
+      dst_map = pipe_transfer_map(pipe,
+                                  dst->texture,
+                                  dst->u.tex.level,
+                                  dst->u.tex.first_layer,
+                                  PIPE_TRANSFER_WRITE,
+                                  dstx, dsty, width, height, &dst_trans);
+
+   }
 
    assert(dst_map);
 
    if (dst_map) {
+      enum pipe_format format = dst->format;
       assert(dst_trans->stride > 0);
 
-      util_pack_color(color->f, dst->texture->format, &uc);
-      util_fill_rect(dst_map, dst->texture->format,
+      if (util_format_is_pure_integer(format)) {
+         /*
+          * We expect int/uint clear values here, though some APIs
+          * might disagree (but in any case util_pack_color()
+          * couldn't handle it)...
+          */
+         if (util_format_is_pure_sint(format)) {
+            util_format_write_4i(format, color->i, 0, &uc, 0, 0, 0, 1, 1);
+         }
+         else {
+            assert(util_format_is_pure_uint(format));
+            util_format_write_4ui(format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
+         }
+      }
+      else {
+         util_pack_color(color->f, dst->format, &uc);
+      }
+      util_fill_rect(dst_map, dst->format,
                      dst_trans->stride,
                      0, 0, width, height, &uc);