summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi/si_texture.c
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2019-01-23 11:34:48 -0500
committerMarek Olšák <[email protected]>2019-02-06 11:17:21 -0500
commit7d4c935654f7792f99ff0c45507e43ec557f0266 (patch)
tree197fc1fb8598040748acbe998ad4ade4d2820975 /src/gallium/drivers/radeonsi/si_texture.c
parent3361305f570505e0131c570041779496d0b9c663 (diff)
radeonsi: initialize textures using DCC to black when possible
Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeonsi/si_texture.c')
-rw-r--r--src/gallium/drivers/radeonsi/si_texture.c57
1 files changed, 53 insertions, 4 deletions
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. */