summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2017-06-17 00:44:05 +0200
committerMarek Olšák <[email protected]>2017-06-19 20:15:36 +0200
commitf9dc29a9a53e3f16cdca56e39664257082d680bc (patch)
treeaf8e6fddcbb8eaed9b2588bb53b2a4b3e3979a0b
parent0f827b51c0b7e6120df1fedadf34b578b5bcff53 (diff)
radeonsi: add a workaround for inexact SNORM8 blitting again
GFX9 is affected. We only have tests for GL_x_SNORM where x is R8, RG8, RGB8, and RGBA8. Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r--src/gallium/drivers/radeonsi/si_blit.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index b240c4d355e..c62efbfa7d3 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -1068,6 +1068,43 @@ void si_resource_copy_region(struct pipe_context *ctx,
}
}
+ /* SNORM8 blitting has precision issues on some chips. Use the SINT
+ * equivalent instead, which doesn't force DCC decompression.
+ * Note that some chips avoid this issue by using SDMA.
+ */
+ if (util_format_is_snorm8(dst_templ.format)) {
+ switch (dst_templ.format) {
+ case PIPE_FORMAT_R8_SNORM:
+ dst_templ.format = src_templ.format = PIPE_FORMAT_R8_SINT;
+ break;
+ case PIPE_FORMAT_R8G8_SNORM:
+ dst_templ.format = src_templ.format = PIPE_FORMAT_R8G8_SINT;
+ break;
+ case PIPE_FORMAT_R8G8B8X8_SNORM:
+ dst_templ.format = src_templ.format = PIPE_FORMAT_R8G8B8X8_SINT;
+ break;
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ /* There are no SINT variants for ABGR and XBGR, so we have to use RGBA. */
+ case PIPE_FORMAT_A8B8G8R8_SNORM:
+ case PIPE_FORMAT_X8B8G8R8_SNORM:
+ dst_templ.format = src_templ.format = PIPE_FORMAT_R8G8B8A8_SINT;
+ break;
+ case PIPE_FORMAT_A8_SNORM:
+ dst_templ.format = src_templ.format = PIPE_FORMAT_A8_SINT;
+ break;
+ case PIPE_FORMAT_L8_SNORM:
+ dst_templ.format = src_templ.format = PIPE_FORMAT_L8_SINT;
+ break;
+ case PIPE_FORMAT_L8A8_SNORM:
+ dst_templ.format = src_templ.format = PIPE_FORMAT_L8A8_SINT;
+ break;
+ case PIPE_FORMAT_I8_SNORM:
+ dst_templ.format = src_templ.format = PIPE_FORMAT_I8_SINT;
+ break;
+ default:; /* fall through */
+ }
+ }
+
vi_disable_dcc_if_incompatible_format(&sctx->b, dst, dst_level,
dst_templ.format);
vi_disable_dcc_if_incompatible_format(&sctx->b, src, src_level,