[Mesa-dev] [PATCH 12/24] swrast: MapRenderbuffer in separate depth/stencil readpixels fastpath

Brian Paul brian.e.paul at gmail.com
Sat Oct 29 10:04:12 PDT 2011


On Fri, Oct 28, 2011 at 1:50 PM, Eric Anholt <eric at anholt.net> wrote:
> This introduces two new span helper functions we'll want to use in
> several palces as we move to MapRenderbuffer, which pull out integer
> depth and stencil values from a renderbuffer mapping based on the
> renderbuffer format.
> ---
>  src/mesa/swrast/s_depth.h   |    1 -
>  src/mesa/swrast/s_readpix.c |   76 ++++++++++++++++++++++++++++++++-----------
>  src/mesa/swrast/s_stencil.c |   39 ++++++++++++++++++++++
>  src/mesa/swrast/s_stencil.h |    4 ++
>  4 files changed, 100 insertions(+), 20 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 7b74ed3..b4db25d 100644
> --- a/src/mesa/swrast/s_readpix.c
> +++ b/src/mesa/swrast/s_readpix.c
> @@ -400,7 +400,7 @@ 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;
> @@ -411,9 +411,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;
> @@ -445,6 +442,53 @@ fast_read_depth_stencil_pixels(struct gl_context *ctx,
>
>
>  /**
> + * For separate depth/stencil buffers being read as 24/8 depth/stencil, memcpy
> + * the data (possibly swapping 8/24 vs 24/8 as we go).
> + */
> +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);
> +      _swrast_read_stencil_span_mapped(ctx, stencilRb, stencilMap, width,
> +                                      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.
> @@ -477,10 +521,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,
> @@ -496,19 +546,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,
> diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c
> index e713e23..e812550 100644
> --- a/src/mesa/swrast/s_stencil.c
> +++ b/src/mesa/swrast/s_stencil.c
> @@ -1070,6 +1070,45 @@ _swrast_read_stencil_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
>  }
>
>
> +/**
> + * Return a span of stencil values from a stencil buffer mapped by
> + * MapRenderbuffer().
> + *
> + * Used for glRead/CopyPixels
> + */
> +void
> +_swrast_read_stencil_span_mapped(struct gl_context *ctx,
> +                                struct gl_renderbuffer *rb,
> +                                void *map, GLint n, GLstencil *stencil)
> +{
> +   uint8_t *map_u8 = map;
> +   uint32_t *map_u32 = map;
> +   int i;
> +
> +   switch (rb->Format) {
> +   case MESA_FORMAT_S8:
> +      for (i = 0; i < n; i++)
> +        stencil[i] = map_u8[i];
> +      break;
> +   case MESA_FORMAT_S8_Z24:
> +      for (i = 0; i < n; i++)
> +        stencil[i] = map_u32[i] >> 24;
> +      break;
> +   case MESA_FORMAT_Z24_S8:
> +      for (i = 0; i < n; i++)
> +        stencil[i] = map_u32[i] & 0xff;
> +      break;
> +   case MESA_FORMAT_Z32_FLOAT_X24S8:
> +      for (i = 0; i < n; i++)
> +        stencil[i] = map_u32[i * 2 + 1] & 0xff;
> +      break;
> +   default:
> +      _mesa_problem(ctx, "Unknown stencil format %s\n",
> +                   _mesa_get_format_name(rb->Format));
> +   }
> +}

Per my previous comment, I think this code could be moved into
format_unpack.c so it's reused/shared.

-Brian


More information about the mesa-dev mailing list