[Mesa-dev] [PATCH 06/15] ac/surface/gfx9: don't allow DCC for the smallest mipmap levels

Marek Olšák maraeo at gmail.com
Mon Aug 21 21:54:05 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

This fixes garbage there if we don't flush TC L2 after rendering.
---
 src/amd/common/ac_surface.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c
index 610071a..4edefc7 100644
--- a/src/amd/common/ac_surface.c
+++ b/src/amd/common/ac_surface.c
@@ -901,20 +901,37 @@ static int gfx9_compute_miptree(ADDR_HANDLE addrlib,
 
 			ret = Addr2ComputeDccInfo(addrlib, &din, &dout);
 			if (ret != ADDR_OK)
 				return ret;
 
 			surf->u.gfx9.dcc.rb_aligned = din.dccKeyFlags.rbAligned;
 			surf->u.gfx9.dcc.pipe_aligned = din.dccKeyFlags.pipeAligned;
 			surf->u.gfx9.dcc_pitch_max = dout.pitch - 1;
 			surf->dcc_size = dout.dccRamSize;
 			surf->dcc_alignment = dout.dccRamBaseAlign;
+			surf->num_dcc_levels = in->numMipLevels;
+
+			/* Disable DCC for the smallest levels. It seems to be
+			 * required for DCC readability between CB and shaders
+			 * when TC L2 isn't flushed. This was guessed.
+			 *
+			 * Alternative solutions that also work but are worse:
+			 * - Disable DCC.
+			 * - Flush TC L2 after rendering.
+			 */
+			for (unsigned i = 1; i < in->numMipLevels; i++) {
+				if (mip_info[i].pitch *
+				    mip_info[i].height * surf->bpe < 1024) {
+					surf->num_dcc_levels = i;
+					break;
+				}
+			}
 		}
 
 		/* FMASK */
 		if (in->numSamples > 1) {
 			ADDR2_COMPUTE_FMASK_INFO_INPUT fin = {0};
 			ADDR2_COMPUTE_FMASK_INFO_OUTPUT fout = {0};
 
 			fin.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT);
 			fout.size = sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT);
 
@@ -1054,20 +1071,21 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
 		if (r)
 			return r;
 		break;
 
 	default:
 		assert(0);
 	}
 
 	surf->u.gfx9.resource_type = AddrSurfInfoIn.resourceType;
 
+	surf->num_dcc_levels = 0;
 	surf->surf_size = 0;
 	surf->dcc_size = 0;
 	surf->htile_size = 0;
 	surf->htile_slice_size = 0;
 	surf->u.gfx9.surf_offset = 0;
 	surf->u.gfx9.stencil_offset = 0;
 	surf->u.gfx9.fmask_size = 0;
 	surf->u.gfx9.cmask_size = 0;
 
 	/* Calculate texture layout information. */
@@ -1080,21 +1098,20 @@ static int gfx9_compute_surface(ADDR_HANDLE addrlib,
 		AddrSurfInfoIn.bpp = 8;
 		AddrSurfInfoIn.flags.depth = 0;
 		AddrSurfInfoIn.flags.stencil = 1;
 
 		r = gfx9_compute_miptree(addrlib, surf, compressed, &AddrSurfInfoIn);
 		if (r)
 			return r;
 	}
 
 	surf->is_linear = surf->u.gfx9.surf.swizzle_mode == ADDR_SW_LINEAR;
-	surf->num_dcc_levels = surf->dcc_size ? config->info.levels : 0;
 
 	switch (surf->u.gfx9.surf.swizzle_mode) {
 		/* S = standard. */
 		case ADDR_SW_256B_S:
 		case ADDR_SW_4KB_S:
 		case ADDR_SW_64KB_S:
 		case ADDR_SW_VAR_S:
 		case ADDR_SW_64KB_S_T:
 		case ADDR_SW_4KB_S_X:
 		case ADDR_SW_64KB_S_X:
-- 
2.7.4



More information about the mesa-dev mailing list