[Mesa-stable] [PATCH] radeonsi: mark fast-cleared textures as compressed when dirtying

Nicolai Hähnle nhaehnle at gmail.com
Thu May 4 13:23:01 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

There are a bunch of piglit fast clear tests that regressed on SI, for
example ./bin/ext_framebuffer_multisample-fast-clear single-sample.

The problem is that a texture is bound as a framebuffer, cleared, and
then rendered from in a loop that loops through different clear colors.
The texture is never rebound during all this, so the change to
tex->dirty_level_mask during fast clear was not taken into account
when checking for compressed textures.

I have considered simply reverting the problematic commit. However,
I think this solution is better. It does require looping through all
bound textures after a fast clear, but the alternative would require
visiting more textures needless on every draw. Draws are much more
common than clears.

Note that the rendering feedback loop rules do not apply here, because
the framebuffer binding is changed between the glClear and the draw
that samples from the texture that was cleared.

Fixes: bdd644976952 ("radeonsi: don't mark non-dirty textures with CMASK as compressed")
Cc: 17.1 <mesa-stable at lists.freedesktop.org>
---
 src/gallium/drivers/radeon/r600_texture.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 8110ec1..57e3960 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -2713,22 +2713,29 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
 			if (rctx->screen->debug_flags & DBG_NO_DCC_CLEAR)
 				continue;
 
 			if (!vi_get_fast_clear_parameters(fb->cbufs[i]->format,
 							  color, &reset_value,
 							  &clear_words_needed))
 				continue;
 
 			vi_dcc_clear_level(rctx, tex, 0, reset_value);
 
-			if (clear_words_needed)
-				tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
+			unsigned level_bit = 1 << fb->cbufs[i]->u.tex.level;
+			if (clear_words_needed) {
+				bool need_compressed_update = !tex->dirty_level_mask;
+
+				tex->dirty_level_mask |= level_bit;
+
+				if (need_compressed_update)
+					p_atomic_inc(&rctx->screen->compressed_colortex_counter);
+			}
 			tex->separate_dcc_dirty = true;
 		} else {
 			/* 128-bit formats are unusupported */
 			if (tex->surface.bpe > 8) {
 				continue;
 			}
 
 			/* RB+ doesn't work with CMASK fast clear on Stoney. */
 			if (rctx->family == CHIP_STONEY)
 				continue;
@@ -2737,21 +2744,26 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
 			r600_texture_alloc_cmask_separate(rctx->screen, tex);
 			if (tex->cmask.size == 0) {
 				continue;
 			}
 
 			/* Do the fast clear. */
 			rctx->clear_buffer(&rctx->b, &tex->cmask_buffer->b.b,
 					   tex->cmask.offset, tex->cmask.size, 0,
 					   R600_COHERENCY_CB_META);
 
+			bool need_compressed_update = !tex->dirty_level_mask;
+
 			tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
+
+			if (need_compressed_update)
+				p_atomic_inc(&rctx->screen->compressed_colortex_counter);
 		}
 
 		/* We can change the micro tile mode before a full clear. */
 		if (rctx->screen->chip_class >= SI)
 			si_set_optimal_micro_tile_mode(rctx->screen, tex);
 
 		evergreen_set_clear_color(tex, fb->cbufs[i]->format, color);
 
 		if (dirty_cbufs)
 			*dirty_cbufs |= 1 << i;
-- 
2.9.3



More information about the mesa-stable mailing list