From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/drivers/radeonsi/si_clear.c | 9 ---- src/gallium/drivers/radeonsi/si_pipe.h | 10 ++++ src/gallium/drivers/radeonsi/si_texture.c | 57 +++++++++++++++++++++-- 3 files changed, 63 insertions(+), 13 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c index a2f34c79104..9a00bb73b94 100644 --- a/src/gallium/drivers/radeonsi/si_clear.c +++ b/src/gallium/drivers/radeonsi/si_clear.c @@ -27,29 +27,20 @@ #include "util/u_format.h" #include "util/u_pack_color.h" #include "util/u_surface.h" enum { SI_CLEAR = SI_SAVE_FRAGMENT_STATE, SI_CLEAR_SURFACE = SI_SAVE_FRAMEBUFFER | SI_SAVE_FRAGMENT_STATE, }; -enum si_dcc_clear_code -{ - DCC_CLEAR_COLOR_0000 = 0x00000000, - DCC_CLEAR_COLOR_0001 = 0x40404040, - DCC_CLEAR_COLOR_1110 = 0x80808080, - DCC_CLEAR_COLOR_1111 = 0xC0C0C0C0, - DCC_CLEAR_COLOR_REG = 0x20202020, -}; - static void si_alloc_separate_cmask(struct si_screen *sscreen, struct si_texture *tex) { if (tex->cmask_buffer || !tex->surface.cmask_size) return; tex->cmask_buffer = si_aligned_buffer_create(&sscreen->b, SI_RESOURCE_FLAG_UNMAPPABLE, PIPE_USAGE_DEFAULT, diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index ff36b3272b4..1af3c5ff9b7 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -104,20 +104,30 @@ #define SI_RESOURCE_FLAG_TRANSFER (PIPE_RESOURCE_FLAG_DRV_PRIV << 0) #define SI_RESOURCE_FLAG_FLUSHED_DEPTH (PIPE_RESOURCE_FLAG_DRV_PRIV << 1) #define SI_RESOURCE_FLAG_FORCE_MSAA_TILING (PIPE_RESOURCE_FLAG_DRV_PRIV << 2) #define SI_RESOURCE_FLAG_DISABLE_DCC (PIPE_RESOURCE_FLAG_DRV_PRIV << 3) #define SI_RESOURCE_FLAG_UNMAPPABLE (PIPE_RESOURCE_FLAG_DRV_PRIV << 4) #define SI_RESOURCE_FLAG_READ_ONLY (PIPE_RESOURCE_FLAG_DRV_PRIV << 5) #define SI_RESOURCE_FLAG_32BIT (PIPE_RESOURCE_FLAG_DRV_PRIV << 6) #define SI_RESOURCE_FLAG_SO_FILLED_SIZE (PIPE_RESOURCE_FLAG_DRV_PRIV << 7) +enum si_clear_code +{ + DCC_CLEAR_COLOR_0000 = 0x00000000, + DCC_CLEAR_COLOR_0001 = 0x40404040, + DCC_CLEAR_COLOR_1110 = 0x80808080, + DCC_CLEAR_COLOR_1111 = 0xC0C0C0C0, + DCC_CLEAR_COLOR_REG = 0x20202020, + DCC_UNCOMPRESSED = 0xFFFFFFFF, +}; + /* Debug flags. */ enum { /* Shader logging options: */ DBG_VS = PIPE_SHADER_VERTEX, DBG_PS = PIPE_SHADER_FRAGMENT, DBG_GS = PIPE_SHADER_GEOMETRY, DBG_TCS = PIPE_SHADER_TESS_CTRL, DBG_TES = PIPE_SHADER_TESS_EVAL, DBG_CS = PIPE_SHADER_COMPUTE, DBG_NO_IR, diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index 422b0bc3a85..a50088d2d8f 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -1235,24 +1235,73 @@ si_texture_create_object(struct pipe_screen *screen, clear_value = 0x0000030F; si_screen_clear_buffer(sscreen, &tex->buffer.b.b, tex->htile_offset, tex->surface.htile_size, clear_value); } /* Initialize DCC only if the texture is not being imported. */ if (!buf && tex->dcc_offset) { - si_screen_clear_buffer(sscreen, &tex->buffer.b.b, - tex->dcc_offset, - tex->surface.dcc_size, - 0xFFFFFFFF); + /* Clear DCC to black for all tiles with DCC enabled. + * + * This fixes corruption in 3DMark Slingshot Extreme, which + * uses uninitialized textures, causing corruption. + */ + if (tex->surface.num_dcc_levels == tex->buffer.b.b.last_level + 1 && + tex->buffer.b.b.nr_samples <= 2) { + /* Simple case - all tiles have DCC enabled. */ + si_screen_clear_buffer(sscreen, &tex->buffer.b.b, + tex->dcc_offset, + tex->surface.dcc_size, + DCC_CLEAR_COLOR_0000); + } else if (sscreen->info.chip_class >= GFX9) { + /* Clear to uncompressed. Clearing this to black is complicated. */ + si_screen_clear_buffer(sscreen, &tex->buffer.b.b, + tex->dcc_offset, + tex->surface.dcc_size, + DCC_UNCOMPRESSED); + } else { + /* GFX8: Initialize mipmap levels and multisamples separately. */ + if (tex->buffer.b.b.nr_samples >= 2) { + /* Clearing this to black is complicated. */ + si_screen_clear_buffer(sscreen, &tex->buffer.b.b, + tex->dcc_offset, + tex->surface.dcc_size, + DCC_UNCOMPRESSED); + } else { + /* Clear the enabled mipmap levels to black. */ + unsigned size = 0; + + for (unsigned i = 0; i < tex->surface.num_dcc_levels; i++) { + if (!tex->surface.u.legacy.level[i].dcc_fast_clear_size) + break; + + size = tex->surface.u.legacy.level[i].dcc_offset + + tex->surface.u.legacy.level[i].dcc_fast_clear_size; + } + + /* Mipmap levels with DCC. */ + if (size) { + si_screen_clear_buffer(sscreen, &tex->buffer.b.b, + tex->dcc_offset, size, + DCC_CLEAR_COLOR_0000); + } + /* Mipmap levels without DCC. */ + if (size != tex->surface.dcc_size) { + si_screen_clear_buffer(sscreen, &tex->buffer.b.b, + tex->dcc_offset + size, + tex->surface.dcc_size - size, + DCC_UNCOMPRESSED); + } + } + } } /* Initialize the CMASK base register value. */ tex->cmask_base_address_reg = (tex->buffer.gpu_address + tex->cmask_offset) >> 8; if (sscreen->debug_flags & DBG(VM)) { fprintf(stderr, "VM start=0x%"PRIX64" end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n", tex->buffer.gpu_address, tex->buffer.gpu_address + tex->buffer.buf->size, -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev