[Mesa-dev] [PATCH 04/17] swrast: MapRenderbuffer in separate depth/stencil readpixels fastpath
Eric Anholt
eric at anholt.net
Tue Nov 1 16:17:29 PDT 2011
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.
v2: Use format_unpack helper for stencil read.
---
src/mesa/swrast/s_depth.h | 1 -
src/mesa/swrast/s_readpix.c | 76 ++++++++++++++++++++++++++++++++-----------
2 files changed, 57 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 f6c3674..8559ab7 100644
--- a/src/mesa/swrast/s_readpix.c
+++ b/src/mesa/swrast/s_readpix.c
@@ -373,7 +373,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;
@@ -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,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);
+ _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 +484,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 +509,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,
--
1.7.7
More information about the mesa-dev
mailing list