On Fri, Oct 28, 2011 at 1:50 PM, Eric Anholt <e...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev