diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-04-10 17:16:08 -0400 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-04-10 17:16:08 -0400 |
commit | 04f335fd16c2a13b9425797acf5c3989cb6def7f (patch) | |
tree | 9e92cecb0b2ac512fac1fc4ef911878849eaeb42 /src/mesa/state_tracker/st_cb_readpixels.c | |
parent | c0419f190c836130932164ac47cfb53de668d423 (diff) | |
parent | 5e361c47abf2ee20140628d327eda9b39351d415 (diff) |
Merge branch 'radeon-rewrite' of git+ssh://agd5f@git.freedesktop.org/git/mesa/mesa into r6xx-rewrite
Diffstat (limited to 'src/mesa/state_tracker/st_cb_readpixels.c')
-rw-r--r-- | src/mesa/state_tracker/st_cb_readpixels.c | 83 |
1 files changed, 68 insertions, 15 deletions
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 2a4beccd90..9ce5f3fe84 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -56,7 +56,8 @@ */ void st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, GLenum type, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const struct gl_pixelstore_attrib *packing, GLvoid *pixels) { @@ -68,7 +69,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, GLint j; if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - y = ctx->DrawBuffer->Height - y - 1; + y = ctx->DrawBuffer->Height - y - height; } /* Create a read transfer from the renderbuffer's texture */ @@ -84,7 +85,8 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /* process image row by row */ for (j = 0; j < height; j++) { GLvoid *dest; - GLstencil values[MAX_WIDTH]; + GLstencil sValues[MAX_WIDTH]; + GLfloat zValues[MAX_WIDTH]; GLint srcY; if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { @@ -94,29 +96,47 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, srcY = j; } - /* get stencil values */ + /* get stencil (and Z) values */ switch (pt->format) { case PIPE_FORMAT_S8_UNORM: { const ubyte *src = stmap + srcY * pt->stride; - memcpy(values, src, width); + memcpy(sValues, src, width); } break; case PIPE_FORMAT_S8Z24_UNORM: - { + if (format == GL_DEPTH_STENCIL) { const uint *src = (uint *) (stmap + srcY * pt->stride); + const GLfloat scale = 1.0 / (0xffffff); GLint k; for (k = 0; k < width; k++) { - values[k] = src[k] >> 24; + sValues[k] = src[k] >> 24; + zValues[k] = (src[k] & 0xffffff) * scale; + } + } + else { + const uint *src = (uint *) (stmap + srcY * pt->stride); + GLint k; + for (k = 0; k < width; k++) { + sValues[k] = src[k] >> 24; } } break; case PIPE_FORMAT_Z24S8_UNORM: - { + if (format == GL_DEPTH_STENCIL) { + const uint *src = (uint *) (stmap + srcY * pt->stride); + const GLfloat scale = 1.0 / (0xffffff); + GLint k; + for (k = 0; k < width; k++) { + sValues[k] = src[k] & 0xff; + zValues[k] = (src[k] >> 8) * scale; + } + } + else { const uint *src = (uint *) (stmap + srcY * pt->stride); GLint k; for (k = 0; k < width; k++) { - values[k] = src[k] & 0xff; + sValues[k] = src[k] & 0xff; } } break; @@ -126,12 +146,16 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /* store */ dest = _mesa_image_address2d(packing, pixels, width, height, - GL_STENCIL_INDEX, type, j, 0); - - _mesa_pack_stencil_span(ctx, width, type, dest, values, packing); + format, type, j, 0); + if (format == GL_DEPTH_STENCIL) { + _mesa_pack_depth_stencil_span(ctx, width, dest, + zValues, sValues, packing); + } + else { + _mesa_pack_stencil_span(ctx, width, type, dest, sValues, packing); + } } - /* unmap the stencil buffer */ screen->transfer_unmap(screen, pt); screen->tex_transfer_destroy(pt); @@ -329,8 +353,10 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* make sure rendering has completed */ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); - if (format == GL_STENCIL_INDEX) { - st_read_stencil_pixels(ctx, x, y, width, height, type, pack, dest); + if (format == GL_STENCIL_INDEX || + format == GL_DEPTH_STENCIL) { + st_read_stencil_pixels(ctx, x, y, width, height, + format, type, pack, dest); return; } else if (format == GL_DEPTH_COMPONENT) { @@ -420,6 +446,33 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } } } + else if (trans->format == PIPE_FORMAT_Z24S8_UNORM || + trans->format == PIPE_FORMAT_Z24X8_UNORM) { + if (format == GL_DEPTH_COMPONENT) { + for (i = 0; i < height; i++) { + GLuint ztemp[MAX_WIDTH]; + GLfloat zfloat[MAX_WIDTH]; + const double scale = 1.0 / ((1 << 24) - 1); + pipe_get_tile_raw(trans, 0, y, width, 1, ztemp, 0); + y += yStep; + for (j = 0; j < width; j++) { + zfloat[j] = (float) (scale * ((ztemp[j] >> 8) & 0xffffff)); + } + _mesa_pack_depth_span(ctx, width, dst, type, + zfloat, &clippedPacking); + dst += dstStride; + } + } + else { + /* untested, but simple: */ + assert(format == GL_DEPTH_STENCIL_EXT); + for (i = 0; i < height; i++) { + pipe_get_tile_raw(trans, 0, y, width, 1, dst, 0); + y += yStep; + dst += dstStride; + } + } + } else if (trans->format == PIPE_FORMAT_Z16_UNORM) { for (i = 0; i < height; i++) { GLushort ztemp[MAX_WIDTH]; |