[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