[Mesa-dev] [PATCH 1/5] radeonsi: initialize textures using DCC to black when possible
Marek Olšák
maraeo at gmail.com
Thu Jan 31 18:56:25 UTC 2019
From: Marek Olšák <marek.olsak at 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
More information about the mesa-dev
mailing list