radeonsi: add a workaround for inexact SNORM8 blitting again
authorMarek Olšák <marek.olsak@amd.com>
Fri, 16 Jun 2017 22:44:05 +0000 (00:44 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 19 Jun 2017 18:15:36 +0000 (20:15 +0200)
GFX9 is affected.

We only have tests for GL_x_SNORM where x is R8, RG8, RGB8, and RGBA8.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_blit.c

index b240c4d355e5f1ed4ddbbeffcb8800cf7a25995d..c62efbfa7d35d236268171e373e23353cd447781 100644 (file)
@@ -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,