diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2005-09-28 02:29:50 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2005-09-28 02:29:50 +0000 |
commit | 1ad7b99925e044f82e635f746c1ef2df77f69ac9 (patch) | |
tree | 7fa22cf8b21a35350191399dcab96db8c0d1e363 /src/mesa/swrast | |
parent | b955474093445d6e5b8c5d3cfa69e2752a01bcf8 (diff) |
Initial work for GL_EXT_packed_depth_stencil extension.
glReadPixels done, glDrawPixels mostly done.
Diffstat (limited to 'src/mesa/swrast')
-rw-r--r-- | src/mesa/swrast/s_copypix.c | 13 | ||||
-rw-r--r-- | src/mesa/swrast/s_drawpix.c | 113 | ||||
-rw-r--r-- | src/mesa/swrast/s_readpix.c | 107 | ||||
-rw-r--r-- | src/mesa/swrast/s_zoom.c | 35 |
4 files changed, 243 insertions, 25 deletions
diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index ed6a02ee13..4b8c7c4fa2 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -699,6 +699,16 @@ copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, } +static void +copy_depth_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, + GLint width, GLint height, GLint destx, GLint desty) +{ + + + +} + + /** * Do software-based glCopyPixels. * By time we get here, all parameters will have been error-checked. @@ -729,6 +739,9 @@ _swrast_CopyPixels( GLcontext *ctx, case GL_STENCIL: copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty ); break; + case GL_DEPTH_STENCIL_EXT: + copy_depth_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty); + break; default: _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels"); } diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index d908ca4db4..c1f33a2fa3 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -641,7 +641,6 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, ? MAX_WIDTH : (width - skipPixels); ASSERT(span.end <= MAX_WIDTH); for (row = 0; row < height; row++, spanY++) { - GLfloat floatSpan[MAX_WIDTH]; const GLvoid *zSrc = _mesa_image_address2d(unpack, pixels, width, height, GL_DEPTH_COMPONENT, type, @@ -654,15 +653,9 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, span.y = spanY; span.end = spanEnd; - _mesa_unpack_depth_span(ctx, span.end, floatSpan, type, - zSrc, unpack); - /* clamp depth values to [0,1] and convert from floats to ints */ - { - GLuint i; - for (i = 0; i < span.end; i++) { - span.array->z[i] = (GLuint) (floatSpan[i] * depthMax); - } - } + _mesa_unpack_depth_span(ctx, span.end, + GL_UNSIGNED_INT, span.array->z, depthMax, + type, zSrc, unpack); if (zoom) { _swrast_write_zoomed_depth_span(ctx, &span, desty, skipPixels); } @@ -840,6 +833,102 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, } + +static void +draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels) +{ + const GLfloat depthScale = ctx->DrawBuffer->_DepthMaxF; + const GLuint stencilMask = ctx->Stencil.WriteMask[0]; + const GLuint stencilType = (STENCIL_BITS == 8) ? + GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; + const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; + struct gl_renderbuffer *depthRb, *stencilRb; + struct gl_pixelstore_attrib clippedUnpack = *unpack; + GLint i; + + depthRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; + stencilRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; + + ASSERT(depthRb); + ASSERT(stencilRb); + + if (!zoom) { + if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, + &clippedUnpack)) { + /* totally clipped */ + return; + } + } + + /* XXX need to do pixelzoom! */ + + for (i = 0; i < height; i++) { + const GLuint *depthStencilSrc = (const GLuint *) + _mesa_image_address2d(&clippedUnpack, pixels, width, height, + GL_DEPTH_STENCIL_EXT, type, i, 0); + + if (ctx->Depth.Mask) { + if (ctx->Pixel.DepthScale == 1.0F && ctx->Pixel.DepthBias == 0.0F + && depthRb->DepthBits == 24) { + /* fast path 24-bit zbuffer */ + GLuint zValues[MAX_WIDTH]; + GLint j; + ASSERT(depthRb->DataType == GL_UNSIGNED_INT); + for (j = 0; j < width; j++) { + zValues[j] = depthStencilSrc[j] >> 8; + } + if (zoom) + ; + else + depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL); + } + else if (ctx->Pixel.DepthScale == 1.0F && ctx->Pixel.DepthBias == 0.0F + && depthRb->DepthBits == 16) { + /* fast path 16-bit zbuffer */ + GLushort zValues[MAX_WIDTH]; + GLint j; + ASSERT(depthRb->DataType == GL_UNSIGNED_SHORT); + for (j = 0; j < width; j++) { + zValues[j] = depthStencilSrc[j] >> 16; + } + if (zoom) + ; + else + depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL); + } + else { + /* general case */ + GLuint zValues[MAX_WIDTH]; + _mesa_unpack_depth_span(ctx, width, + depthRb->DataType, zValues, depthScale, + type, depthStencilSrc, &clippedUnpack); + if (zoom) + ; + else + depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues, NULL); + } + } + + if (stencilMask != 0x0) { + GLstencil stencilValues[MAX_WIDTH]; + /* get stencil values, with shift/offset/mapping */ + _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues, + type, depthStencilSrc, &clippedUnpack, + ctx->_ImageTransferState); + if (zoom) + ; + else + _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues); + } + + } +} + + + /** * Execute software-based glDrawPixels. * By time we get here, all error checking will have been done. @@ -905,6 +994,10 @@ _swrast_DrawPixels( GLcontext *ctx, case GL_ABGR_EXT: draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels); break; + case GL_DEPTH_STENCIL_EXT: + draw_depth_stencil_pixels(ctx, x, y, width, height, + type, unpack, pixels); + break; default: _mesa_problem(ctx, "unexpected format in _swrast_DrawPixels"); /* don't return yet, clean-up */ diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 423661a872..984205d44d 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -105,7 +105,7 @@ read_depth_pixels( GLcontext *ctx, bias_or_scale = ctx->Pixel.DepthBias != 0.0 || ctx->Pixel.DepthScale != 1.0; - if (type == GL_UNSIGNED_SHORT && fb->Visual.depthBits == 16 + if (type == GL_UNSIGNED_SHORT && rb->DepthBits == 16 && !bias_or_scale && !packing->SwapBytes) { /* Special case: directly read 16-bit unsigned depth values. */ GLint j; @@ -117,7 +117,25 @@ read_depth_pixels( GLcontext *ctx, rb->GetRow(ctx, rb, width, x, y, dest); } } - else if (type == GL_UNSIGNED_INT && fb->Visual.depthBits == 32 + else if (type == GL_UNSIGNED_INT && rb->DepthBits == 24 + && !bias_or_scale && !packing->SwapBytes) { + /* Special case: directly read 24-bit unsigned depth values. */ + GLint j; + ASSERT(rb->InternalFormat == GL_DEPTH_COMPONENT32); + ASSERT(rb->DataType == GL_UNSIGNED_INT); + for (j = 0; j < height; j++, y++) { + GLuint *dest = (GLuint *) + _mesa_image_address2d(packing, pixels, width, height, + GL_DEPTH_COMPONENT, type, j, 0); + GLint k; + rb->GetRow(ctx, rb, width, x, y, dest); + /* convert range from 24-bit to 32-bit */ + for (k = 0; k < width; k++) { + dest[k] = (dest[k] << 8) | (dest[k] >> 24); + } + } + } + else if (type == GL_UNSIGNED_INT && rb->DepthBits == 32 && !bias_or_scale && !packing->SwapBytes) { /* Special case: directly read 32-bit unsigned depth values. */ GLint j; @@ -396,6 +414,77 @@ read_rgba_pixels( GLcontext *ctx, /** + * Read combined depth/stencil values. + * We'll have already done error checking to be sure the expected + * depth and stencil buffers really exist. + */ +static void +read_depth_stencil_pixels(GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type, GLvoid *pixels, + const struct gl_pixelstore_attrib *packing ) +{ + struct gl_renderbuffer *depthRb, *stencilRb; + GLint i; + + depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; + stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; + + ASSERT(depthRb); + ASSERT(stencilRb); + + for (i = 0; i < height; i++) { + GLuint zVals[MAX_WIDTH]; /* 24-bit values! */ + GLstencil stencilVals[MAX_WIDTH]; + GLint j; + + GLuint *depthStencilDst = (GLuint *) + _mesa_image_address2d(packing, pixels, width, height, + GL_DEPTH_STENCIL_EXT, type, i, 0); + + /* get depth values */ + if (ctx->Pixel.DepthScale == 1.0 + && ctx->Pixel.DepthBias == 0.0 + && depthRb->DepthBits == 24) { + /* ideal case */ + ASSERT(depthRb->DataType == GL_UNSIGNED_INT); + /* note, we've already been clipped */ + depthRb->GetRow(ctx, depthRb, width, x, y + i, zVals); + } + else { + /* general case */ + GLfloat depthVals[MAX_WIDTH]; + _swrast_read_depth_span_float(ctx, depthRb, width, x, y + i, + depthVals); + if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) { + _mesa_scale_and_bias_depth(ctx, width, depthVals); + } + /* convert to 24-bit GLuints */ + for (j = 0; j < width; j++) { + zVals[j] = FLOAT_TO_UINT(depthVals[j]) >> 8; + } + } + + /* get stencil values */ + _swrast_read_stencil_span(ctx, stencilRb, width, x, y + i, stencilVals); + if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) { + _mesa_shift_and_offset_stencil(ctx, width, stencilVals); + } + if (ctx->Pixel.MapStencilFlag) { + _mesa_map_stencil(ctx, width, stencilVals); + } + + for (j = 0; j < width; j++) { + /* build combined Z/stencil values */ + depthStencilDst[j] = (zVals[j] << 8) | (stencilVals[j] & 0xff); + } + } +} + + + +/** * Software fallback routine for ctx->Driver.ReadPixels(). * By time we get here, all error checking will have been done. */ @@ -407,19 +496,13 @@ _swrast_ReadPixels( GLcontext *ctx, GLvoid *pixels ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - struct gl_pixelstore_attrib clippedPacking; + struct gl_pixelstore_attrib clippedPacking = *packing; if (swrast->NewState) _swrast_validate_derived( ctx ); /* Do all needed clipping here, so that we can forget about it later */ - clippedPacking = *packing; - if (clippedPacking.RowLength == 0) { - clippedPacking.RowLength = width; - } - if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, - &clippedPacking.SkipPixels, - &clippedPacking.SkipRows)) { + if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) { /* The ReadPixels region is totally outside the window bounds */ return; } @@ -473,6 +556,10 @@ _swrast_ReadPixels( GLcontext *ctx, read_rgba_pixels(ctx, x, y, width, height, format, type, pixels, &clippedPacking); break; + case GL_DEPTH_STENCIL_EXT: + read_depth_stencil_pixels(ctx, x, y, width, height, + type, pixels, &clippedPacking); + break; default: _mesa_problem(ctx, "unexpected format in _swrast_ReadPixels"); /* don't return yet, clean-up */ diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c index 580e25e945..dfbc691dc1 100644 --- a/src/mesa/swrast/s_zoom.c +++ b/src/mesa/swrast/s_zoom.c @@ -75,8 +75,7 @@ zoom_span( GLcontext *ctx, const struct sw_span *span, zoomed.interpMask = span->interpMask & ~SPAN_INDEX; zoomed.arrayMask |= SPAN_INDEX; } - else { - assert(format == GL_DEPTH_COMPONENT); + else if (format == GL_DEPTH_COMPONENT) { /* Copy color info */ zoomed.red = span->red; zoomed.green = span->green; @@ -90,6 +89,14 @@ zoom_span( GLcontext *ctx, const struct sw_span *span, zoomed.interpMask = span->interpMask & ~SPAN_Z; zoomed.arrayMask |= SPAN_Z; } + else if (format == GL_DEPTH_COMPONENT16 || + format == GL_DEPTH_COMPONENT32) { + /* writing Z values directly to depth buffer, bypassing fragment ops */ + } + else { + _mesa_problem(ctx, "Bad format in zoom_span"); + return; + } /* * Compute which columns to draw: [c0, c1) @@ -230,9 +237,8 @@ zoom_span( GLcontext *ctx, const struct sw_span *span, } } } - else { + else if (format == GL_DEPTH_COMPONENT) { const GLuint *zValues = (const GLuint *) src; - assert(format == GL_DEPTH_COMPONENT); if (ctx->Pixel.ZoomX == -1.0F) { /* common case */ for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) { @@ -260,7 +266,26 @@ zoom_span( GLcontext *ctx, const struct sw_span *span, else format = GL_COLOR_INDEX; } - + else if (format == GL_DEPTH_COMPONENT32) { + /* 32-bit Z values */ + struct gl_renderbuffer *rb + = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; + const GLuint *zSrc32 = (const GLuint *) src; + GLuint zDst32[MAX_WIDTH]; + const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX; + for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) { + i = (GLint) ((j + skipCol) * xscale); + if (ctx->Pixel.ZoomX < 0.0) { + ASSERT(i <= 0); + i = span->end + i - 1; + } + ASSERT(i >= 0); + ASSERT(i < (GLint) span->end); + zDst32[j] = zSrc32[i]; + } + rb->PutRow(ctx, rb, zoomed.end, zoomed.x, zoomed.y, zDst32, NULL); + return; + } /* write the span in rows [r0, r1) */ if (format == GL_RGBA || format == GL_RGB) { |