[Mesa-dev] [PATCH] r600g: Adjust pipe format when decompressing depth in BE

Oded Gabbay oded.gabbay at gmail.com
Thu Mar 3 15:47:10 UTC 2016


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 <oded.gabbay at gmail.com>
Cc: "11.1 11.2" <mesa-stable at lists.freedesktop.org>
---
 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



More information about the mesa-dev mailing list