Mesa (master): swrast: MapRenderbuffer in separate depth/ stencil readpixels fastpath

Eric Anholt anholt at kemper.freedesktop.org
Fri Nov 4 06:48:36 UTC 2011


Module: Mesa
Branch: master
Commit: f53680857aeb2ac1fb71a0bac958769d4f83952d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f53680857aeb2ac1fb71a0bac958769d4f83952d

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Oct 12 12:40:18 2011 -0700

swrast: MapRenderbuffer in separate depth/stencil readpixels fastpath

This introduces two new span helper functions we'll want to use in
several places as we move to MapRenderbuffer, which pull out integer
depth and stencil values from a renderbuffer mapping based on the
renderbuffer format.

v2: Use format_unpack helper for stencil read.
v3: Clean up comment after conversion to format_unpack.

Reviewed-by: Brian Paul <brianp at vmware.com>

---

 src/mesa/swrast/s_depth.h   |    1 -
 src/mesa/swrast/s_readpix.c |   79 ++++++++++++++++++++++++++++++++-----------
 2 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/src/mesa/swrast/s_depth.h b/src/mesa/swrast/s_depth.h
index 44820ac..8d5cdfa 100644
--- a/src/mesa/swrast/s_depth.h
+++ b/src/mesa/swrast/s_depth.h
@@ -53,7 +53,6 @@ extern void
 _swrast_read_depth_span_uint( struct gl_context *ctx, struct gl_renderbuffer *rb,
                               GLint n, GLint x, GLint y, GLuint depth[] );
 
-
 extern void
 _swrast_clear_depth_buffer( struct gl_context *ctx, struct gl_renderbuffer *rb );
 
diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c
index f6c3674..6de310b 100644
--- a/src/mesa/swrast/s_readpix.c
+++ b/src/mesa/swrast/s_readpix.c
@@ -366,14 +366,14 @@ read_rgba_pixels( struct gl_context *ctx,
 }
 
 /**
- * For a packed depth/stencil buffer being read as depth/stencil, memcpy the
+ * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
  * data (possibly swapping 8/24 vs 24/8 as we go).
  */
 static GLboolean
 fast_read_depth_stencil_pixels(struct gl_context *ctx,
 			       GLint x, GLint y,
 			       GLsizei width, GLsizei height,
-			       GLenum type, GLvoid *dst, int dstStride)
+			       GLvoid *dst, int dstStride)
 {
    struct gl_framebuffer *fb = ctx->ReadBuffer;
    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
@@ -384,9 +384,6 @@ fast_read_depth_stencil_pixels(struct gl_context *ctx,
    if (rb != stencilRb)
       return GL_FALSE;
 
-   if (type != GL_UNSIGNED_INT_24_8)
-      return GL_FALSE;
-
    if (rb->Format != MESA_FORMAT_Z24_S8 &&
        rb->Format != MESA_FORMAT_S8_Z24)
       return GL_FALSE;
@@ -408,6 +405,54 @@ fast_read_depth_stencil_pixels(struct gl_context *ctx,
 
 
 /**
+ * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
+ * copy the integer data directly instead of converting depth to float and
+ * re-packing.
+ */
+static GLboolean
+fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
+					GLint x, GLint y,
+					GLsizei width, GLsizei height,
+					uint32_t *dst, int dstStride)
+{
+   struct gl_framebuffer *fb = ctx->ReadBuffer;
+   struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+   struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
+   GLubyte *depthMap, *stencilMap;
+   int depthStride, stencilStride, i, j;
+
+   if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_INT)
+      return GL_FALSE;
+
+   ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
+			       GL_MAP_READ_BIT, &depthMap, &depthStride);
+   ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
+			       GL_MAP_READ_BIT, &stencilMap, &stencilStride);
+
+   for (j = 0; j < height; j++) {
+      GLstencil stencilVals[MAX_WIDTH];
+
+      _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
+      _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
+				     stencilMap, stencilVals);
+
+      for (i = 0; i < width; i++) {
+	 dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
+      }
+
+      depthMap += depthStride;
+      stencilMap += stencilStride;
+      dst += dstStride / 4;
+   }
+
+   ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
+   ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
+
+   return GL_TRUE;
+}
+
+
+/**
  * Read combined depth/stencil values.
  * We'll have already done error checking to be sure the expected
  * depth and stencil buffers really exist.
@@ -440,10 +485,16 @@ read_depth_stencil_pixels(struct gl_context *ctx,
    dstStride = _mesa_image_row_stride(packing, width,
 				      GL_DEPTH_STENCIL_EXT, type);
 
-   if (!scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
-      if (fast_read_depth_stencil_pixels(ctx, x, y, width, height, type,
+   /* Fast 24/8 reads. */
+   if (type == GL_UNSIGNED_INT_24_8 &&
+       !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
+      if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
 					 dst, dstStride))
 	 return;
+
+      if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
+						  (uint32_t *)dst, dstStride))
+	 return;
    }
 
       /* Reading GL_DEPTH_STENCIL pixels from separate depth/stencil buffers,
@@ -459,19 +510,7 @@ read_depth_stencil_pixels(struct gl_context *ctx,
          _swrast_read_stencil_span(ctx, stencilRb, width,
                                    x, y + i, stencilVals);
 
-         if (!scaleOrBias && !stencilTransfer
-             && ctx->ReadBuffer->Visual.depthBits == 24) {
-            /* ideal case */
-            GLuint zVals[MAX_WIDTH]; /* 24-bit values! */
-            GLint j;
-            ASSERT(depthRb->DataType == GL_UNSIGNED_INT);
-            /* note, we've already been clipped */
-            depthRb->GetRow(ctx, depthRb, width, x, y + i, zVals);
-            for (j = 0; j < width; j++) {
-               depthStencilDst[j] = (zVals[j] << 8) | (stencilVals[j] & 0xff);
-            }
-         }
-         else {
+	 {
             /* general case */
             GLfloat depthVals[MAX_WIDTH];
             _swrast_read_depth_span_float(ctx, depthRb, width, x, y + i,




More information about the mesa-commit mailing list