More work on glClear.
authorBrian <brian@i915.localnet.net>
Wed, 1 Aug 2007 20:46:07 +0000 (14:46 -0600)
committerBrian <brian@i915.localnet.net>
Wed, 1 Aug 2007 20:46:07 +0000 (14:46 -0600)
Add a 'mask' param to region_fill() to help with clearing combined Z/stencil buffers, glColorMask, etc.

src/mesa/drivers/dri/i915pipe/intel_blit.c
src/mesa/drivers/dri/i915pipe/intel_blit.h
src/mesa/drivers/dri/i915pipe/intel_regions.c
src/mesa/pipe/p_context.h
src/mesa/pipe/softpipe/sp_clear.c
src/mesa/pipe/softpipe/sp_region.c

index 8e7f294..109d4fa 100644 (file)
@@ -209,9 +209,11 @@ intelEmitFillBlit(struct intel_context *intel,
                   GLshort dst_pitch,
                   struct _DriBufferObject *dst_buffer,
                   GLuint dst_offset,
-                  GLshort x, GLshort y, GLshort w, GLshort h, GLuint color)
+                  GLshort x, GLshort y, GLshort w, GLshort h,
+                  GLuint value, GLuint mask)
 {
    GLuint BR13, CMD;
+   GLboolean badMask = GL_FALSE;
    BATCH_LOCALS;
 
    dst_pitch *= cpp;
@@ -222,16 +224,32 @@ intelEmitFillBlit(struct intel_context *intel,
    case 3:
       BR13 = dst_pitch | (0xF0 << 16) | (1 << 24);
       CMD = XY_COLOR_BLT_CMD;
+      if ((mask & 0xffff) != 0xffff)
+         badMask = GL_TRUE;
       break;
    case 4:
       BR13 = dst_pitch | (0xF0 << 16) | (1 << 24) | (1 << 25);
+#if 0
       CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
              XY_COLOR_BLT_WRITE_RGB);
+#else
+      CMD = XY_COLOR_BLT_CMD;
+      if ((mask & 0xff000000) == 0xff000000)
+         CMD |= XY_COLOR_BLT_WRITE_ALPHA;
+      else if (mask & 0xff000000)
+         badMask = GL_TRUE;
+      if ((mask & 0x00ffffff) == 0x00ffffff)
+         CMD |= XY_COLOR_BLT_WRITE_RGB;
+      else if (mask & 0x00ffffff)
+         badMask = GL_TRUE;
+#endif
       break;
    default:
       return;
    }
 
+   assert(!badMask);
+
    DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
        __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h);
 
@@ -243,7 +261,7 @@ intelEmitFillBlit(struct intel_context *intel,
    OUT_BATCH(((y + h) << 16) | (x + w));
    OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
              DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset);
-   OUT_BATCH(color);
+   OUT_BATCH(value);
    ADVANCE_BATCH();
 }
 
index 7768644..46c2594 100644 (file)
@@ -56,7 +56,7 @@ extern void intelEmitFillBlit(struct intel_context *intel,
                               struct _DriBufferObject *dst_buffer,
                               GLuint dst_offset,
                               GLshort x, GLshort y,
-                              GLshort w, GLshort h, GLuint color);
+                              GLshort w, GLshort h, GLuint value, GLuint mask);
 
 
 #endif
index e95e745..bdbc59e 100644 (file)
@@ -343,7 +343,8 @@ intel_region_fill(struct pipe_context *pipe,
                   struct pipe_region *dst,
                   GLuint dst_offset,
                   GLuint dstx, GLuint dsty,
-                  GLuint width, GLuint height, GLuint color)
+                  GLuint width, GLuint height,
+                  GLuint value, GLuint mask)
 {
    intelScreenPrivate *intelScreen = pipe_screen(pipe);
    struct intel_context *intel = intelScreenContext(intelScreen);
@@ -364,7 +365,7 @@ intel_region_fill(struct pipe_context *pipe,
    intelEmitFillBlit(intel,
                      dst->cpp,
                      dst->pitch, dst->buffer, dst_offset,
-                     dstx, dsty, width, height, color);
+                     dstx, dsty, width, height, value, mask);
 }
 
 /* Attach to a pbo, discarding our data.  Effectively zero-copy upload
index 8517d7a..8e51daa 100644 (file)
@@ -172,7 +172,8 @@ struct pipe_context {
                        struct pipe_region *dst,
                        GLuint dst_offset,
                        GLuint dstx, GLuint dsty,
-                       GLuint width, GLuint height, GLuint color);
+                       GLuint width, GLuint height,
+                       GLuint value, GLuint mask);
 
    void (*region_cow)(struct pipe_context *pipe, struct pipe_region *region);
 
index 6266d12..aa7601a 100644 (file)
@@ -59,7 +59,39 @@ color_value(GLuint format, const GLfloat color[4])
    }
 }
  
+static GLuint
+color_mask(GLuint format, GLuint pipeMask)
+{
+   GLuint mask = 0x0;
+   switch (format) {
+   case PIPE_FORMAT_U_R8_G8_B8_A8:
+      if (pipeMask & PIPE_MASK_R)  mask |= 0xff000000;
+      if (pipeMask & PIPE_MASK_G)  mask |= 0x00ff0000;
+      if (pipeMask & PIPE_MASK_B)  mask |= 0x0000ff00;
+      if (pipeMask & PIPE_MASK_A)  mask |= 0x000000ff;
+      break;
+   case PIPE_FORMAT_U_A8_R8_G8_B8:
+      if (pipeMask & PIPE_MASK_R)  mask |= 0x00ff0000;
+      if (pipeMask & PIPE_MASK_G)  mask |= 0x0000ff00;
+      if (pipeMask & PIPE_MASK_B)  mask |= 0x000000ff;
+      if (pipeMask & PIPE_MASK_A)  mask |= 0xff000000;
+      break;
+   case PIPE_FORMAT_U_R5_G6_B5:
+      if (pipeMask & PIPE_MASK_R)  mask |= 0xf800;
+      if (pipeMask & PIPE_MASK_G)  mask |= 0x07e0;
+      if (pipeMask & PIPE_MASK_B)  mask |= 0x001f;
+      if (pipeMask & PIPE_MASK_A)  mask |= 0;
+      break;
+   default:
+      return 0;
+   }
+   return mask;
+}
 
+
+/**
+ * XXX maybe this belongs in the GL state tracker...
+ */
 void
 softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
                GLboolean stencil, GLboolean accum)
@@ -74,58 +106,67 @@ softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth,
       GLuint i;
       for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
          struct pipe_surface *ps = softpipe->framebuffer.cbufs[i];
-
-         if (softpipe->blend.colormask == (PIPE_MASK_R | PIPE_MASK_G |
-                                           PIPE_MASK_B | PIPE_MASK_A)) {
-            /* no masking */
-            GLuint clearVal = color_value(ps->format,
-                                          softpipe->clear_color.color);
-            pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal);
-         }
-         else {
-            /* masking */
-
-            /*
-            for (j = 0; j < h; j++) {
-               sps->write_mono_row_ub(sps, w, x, y + j, clr);
-            }
-            */
-         }
+         GLuint clearVal = color_value(ps->format,
+                                       softpipe->clear_color.color);
+         GLuint mask = color_mask(ps->format, softpipe->blend.colormask);
+         pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask);
       }
    }
 
-   if (depth) {
+   if (depth && stencil &&
+       softpipe->framebuffer.zbuf == softpipe->framebuffer.sbuf) {
+      /* clear Z and stencil together */
       struct pipe_surface *ps = softpipe->framebuffer.zbuf;
-      GLuint clearVal;
-
-      switch (ps->format) {
-      case PIPE_FORMAT_U_Z16:
-         clearVal = (GLuint) (softpipe->depth_test.clear * 65535.0);
-         break;
-      case PIPE_FORMAT_U_Z32:
-         clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffffff);
-         break;
-      case PIPE_FORMAT_S8_Z24:
-         clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff);
-         break;
-      default:
+      if (ps->format == PIPE_FORMAT_S8_Z24) {
+         GLuint mask = (softpipe->stencil.write_mask[0] << 8) | 0xffffff;
+         GLuint clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff);
+         clearVal |= (softpipe->stencil.clear_value << 24);
+         pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask);
+      }
+      else {
+         /* XXX Z24_S8 format? */
          assert(0);
       }
-
-      pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal);
    }
+   else {
+      /* separate Z and stencil */
+      if (depth) {
+         struct pipe_surface *ps = softpipe->framebuffer.zbuf;
+         GLuint mask, clearVal;
+
+         switch (ps->format) {
+         case PIPE_FORMAT_U_Z16:
+            clearVal = (GLuint) (softpipe->depth_test.clear * 65535.0);
+            mask = 0xffff;
+            break;
+         case PIPE_FORMAT_U_Z32:
+            clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffffff);
+            mask = 0xffffffff;
+            break;
+         case PIPE_FORMAT_S8_Z24:
+            clearVal = (GLuint) (softpipe->depth_test.clear * 0xffffff);
+            mask = 0xffffff;
+            break;
+         default:
+            assert(0);
+         }
 
-   if (stencil) {
-      struct pipe_surface *ps = softpipe->framebuffer.sbuf;
-      GLuint clearVal = softpipe->stencil.clear_value;
-      if (softpipe->stencil.write_mask[0] /*== 0xff*/) {
-         /* no masking */
-         pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal);
+         pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask);
       }
-      else if (softpipe->stencil.write_mask[0] != 0x0) {
-         /* masking */
-         /* fill with quad funcs */
-         assert(0);
+
+      if (stencil) {
+         struct pipe_surface *ps = softpipe->framebuffer.sbuf;
+         GLuint clearVal = softpipe->stencil.clear_value;
+         GLuint mask = 0xff;
+         if (softpipe->stencil.write_mask[0] /*== 0xff*/) {
+            /* no masking */
+            pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearVal, mask);
+         }
+         else if (softpipe->stencil.write_mask[0] != 0x0) {
+            /* masking */
+            /* fill with quad funcs */
+            assert(0);
+         }
       }
    }
 }
index 4d8b35d..34fbcce 100644 (file)
@@ -105,7 +105,7 @@ sp_region_fill(struct pipe_context *pipe,
                struct pipe_region *dst,
                GLuint dst_offset,
                GLuint dstx, GLuint dsty,
-               GLuint width, GLuint height, GLuint value)
+               GLuint width, GLuint height, GLuint value, GLuint mask)
 {
    GLuint i, j;
    switch (dst->cpp) {