diff options
author | Marek Olšák <[email protected]> | 2019-01-23 11:34:48 -0500 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2019-02-06 11:17:21 -0500 |
commit | 7d4c935654f7792f99ff0c45507e43ec557f0266 (patch) | |
tree | 197fc1fb8598040748acbe998ad4ade4d2820975 /src/gallium/drivers | |
parent | 3361305f570505e0131c570041779496d0b9c663 (diff) |
radeonsi: initialize textures using DCC to black when possible
Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/radeonsi/si_clear.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_pipe.h | 10 | ||||
-rw-r--r-- | 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 @@ -34,15 +34,6 @@ enum { 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) { 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 @@ -111,6 +111,16 @@ #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: */ 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 @@ -1242,10 +1242,59 @@ si_texture_create_object(struct pipe_screen *screen, /* 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. */ |