The following is what happens when trying to do glReadPixels() with GL_DEPTH_COMPONENT:
1. When decompressing depth in BE, the GPU performs a swap of the depth value when it is written to the memory-mapped buffer. 2. When the pipe format is PIPE_FORMAT_Z24_UNORM_S8_UINT, the values are unpakeded using unpack_uint_z_Z24_UNORM_X8_UINT() into the staging buffer that is passed back to glReadPixels(). 3. unpack_uint_z_Z24_UNORM_X8_UINT() expects to unpack values that are packed according to Z24_UNORM_X8_UINT format. The combination of the above makes the values that are returned to the user erroneous, because the values inside the memory-mapped buffer are, in reality, in the packed form of X8_UINT_Z24_UNORM. llvmpipe/softpipe don't have this problem in big-endian because they call util_pack64_z_stencil() when doing the CLEAR operation, which is not a valid solution when a real GPU is doing that operation. This patch fix this problem by checking for these specific conditions when doing the map memory (r600_texture_transfer_map). In case the conditions match, the code will adjust the pipe format of the cbsurf before creating the surface, and later, when the unpack function will be called to copy the values, unpack_uint_z_X8_UINT_Z24_UNORM() will be called instead of unpack_uint_z_Z24_UNORM_X8_UINT. This patch fix gl-1.0-readpixsanity (check_depth and check_stencil). Signed-off-by: Oded Gabbay <[email protected]> Cc: "11.1 11.2" <[email protected]> --- src/gallium/drivers/r600/r600_blit.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index c52d5a9..5cbc24f 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -173,6 +173,13 @@ static void r600_blit_decompress_depth(struct pipe_context *ctx, zsurf = ctx->create_surface(ctx, &texture->resource.b.b, &surf_tmpl); surf_tmpl.format = flushed_depth_texture->resource.b.b.format; + /* In BE machine, the GPU returns a swapped result of the depth + * decompression, that doesn't comply with gallium packed formats, + * so we need to adjust the format of cbsurf */ + if (R600_BIG_ENDIAN && + surf_tmpl.format == PIPE_FORMAT_Z24_UNORM_S8_UINT) + surf_tmpl.format = PIPE_FORMAT_S8_UINT_Z24_UNORM; + cbsurf = ctx->create_surface(ctx, &flushed_depth_texture->resource.b.b, &surf_tmpl); -- 2.5.0 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
