swrast: Directly map the stencil buffer in read_stencil_pixels.
authorEric Anholt <eric@anholt.net>
Wed, 12 Oct 2011 00:07:37 +0000 (17:07 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 4 Nov 2011 06:29:52 +0000 (23:29 -0700)
This avoids going through the wrapper that has to rewrite the data for
packed depth/stencil.  This isn't done in _swrast_read_stencil_span
because we don't want to map/unmap for each span.

v2: Move the unpack code to format_unpack.c.
v3: Fix signed/unsigned comparison.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/main/format_unpack.c
src/mesa/main/format_unpack.h
src/mesa/swrast/s_readpix.c

index fbda03135e9d4852766bd19e51fe1006bf82bdce..3d044af0d4dcc429f73ea6ff98023cf888bfa0e5 100644 (file)
@@ -1480,4 +1480,62 @@ _mesa_unpack_uint_z_row(gl_format format, GLuint n,
    }
 }
 
+static void
+unpack_ubyte_s_S8(const void *src, GLubyte *dst, GLuint n)
+{
+   memcpy(dst, src, n);
+}
+
+static void
+unpack_ubyte_s_Z24_S8(const void *src, GLubyte *dst, GLuint n)
+{
+   GLuint i;
+   const GLuint *src32 = src;
+
+   for (i = 0; i < n; i++)
+      dst[i] = src32[i] & 0xff;
+}
+
+static void
+unpack_ubyte_s_S8_Z24(const void *src, GLubyte *dst, GLuint n)
+{
+   GLuint i;
+   const GLuint *src32 = src;
+
+   for (i = 0; i < n; i++)
+      dst[i] = src32[i] >> 24;
+}
+
+static void
+unpack_ubyte_s_Z32_FLOAT_X24S8(const void *src, GLubyte *dst, GLuint n)
+{
+   GLuint i;
+   const GLuint *src32 = src;
+
+   for (i = 0; i < n; i++)
+      dst[i] = src32[i * 2 + 1] & 0xff;
+}
 
+void
+_mesa_unpack_ubyte_stencil_row(gl_format format, GLuint n,
+                              const void *src, GLubyte *dst)
+{
+   switch (format) {
+   case MESA_FORMAT_S8:
+      unpack_ubyte_s_S8(src, dst, n);
+      break;
+   case MESA_FORMAT_Z24_S8:
+      unpack_ubyte_s_Z24_S8(src, dst, n);
+      break;
+   case MESA_FORMAT_S8_Z24:
+      unpack_ubyte_s_S8_Z24(src, dst, n);
+      break;
+   case MESA_FORMAT_Z32_FLOAT_X24S8:
+      unpack_ubyte_s_Z32_FLOAT_X24S8(src, dst, n);
+      break;
+   default:
+      _mesa_problem(NULL, "bad format %s in _mesa_unpack_ubyte_s_row",
+                    _mesa_get_format_name(format));
+      return;
+   }
+}
index c37727d91a0a8d4abf9d5905658486191f1c24bb..2e00047c2018cc1f9d87443c264bd7e77acddb0d 100644 (file)
@@ -45,5 +45,9 @@ void
 _mesa_unpack_uint_z_row(gl_format format, GLuint n,
                         const void *src, GLuint *dst);
 
+void
+_mesa_unpack_ubyte_stencil_row(gl_format format, GLuint n,
+                              const void *src, GLubyte *dst);
+
 
 #endif /* FORMAT_UNPACK_H */
index 187c27e4ece7d3fbb9428d1b8fe0bca473be3440..6351ec123ea09647012d1b7af9c9c17087b96efc 100644 (file)
@@ -142,8 +142,10 @@ read_stencil_pixels( struct gl_context *ctx,
                      const struct gl_pixelstore_attrib *packing )
 {
    struct gl_framebuffer *fb = ctx->ReadBuffer;
-   struct gl_renderbuffer *rb = fb->_StencilBuffer;
+   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
    GLint j;
+   GLubyte *map;
+   GLint stride;
 
    if (!rb)
       return;
@@ -151,18 +153,24 @@ read_stencil_pixels( struct gl_context *ctx,
    /* width should never be > MAX_WIDTH since we did clipping earlier */
    ASSERT(width <= MAX_WIDTH);
 
+   ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
+                              &map, &stride);
+
    /* process image row by row */
-   for (j=0;j<height;j++,y++) {
+   for (j = 0; j < height; j++) {
       GLvoid *dest;
       GLstencil stencil[MAX_WIDTH];
 
-      _swrast_read_stencil_span(ctx, rb, width, x, y, stencil);
-
+      _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
       dest = _mesa_image_address2d(packing, pixels, width, height,
                                    GL_STENCIL_INDEX, type, j, 0);
 
       _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
+
+      map += stride;
    }
+
+   ctx->Driver.UnmapRenderbuffer(ctx, rb);
 }