[Mesa-dev] [PATCH 1/4] gallium/radeon: notify all contexts when cmasks are enabled/disabled

Nicolai Hähnle nhaehnle at gmail.com
Wed Mar 9 23:07:57 UTC 2016


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

There is an annoying corner case that I stumbled across while looking into
piglit's arb_shader_image_load_store/execution/load-from-cleared-image.shader_test
(which can be easily adapted to demonstrate the bug without the
ARB_shader_image_load_store extension)

When we bind a texture and then clear it using glClear (by attaching it
to the current framebuffer) for the first time, we allocate a separate
cmask for the texture to do fast clear, but the corresponding bit in
compressed_colortex_mask is not set. Subsequent rendering will use
incorrect data.

Conversely, when a currently bound texture with an existing cmask is
exported leading to that cmask being disabled, the compressed_colortex_mask
bit will remain set, leading to an assertion later on in debug builds.

Since iterating through all contexts and/or remembering where every
texture is bound would be costly, and cmask enable/disable should be
rare, we will maintain a global counter to signal contexts that they
must update their compressed_colortex_masks.

This patch introduces the global counter, and subsequent patches will
do the mask update.
---
 src/gallium/drivers/radeon/r600_pipe_common.h | 7 +++++++
 src/gallium/drivers/radeon/r600_texture.c     | 3 +++
 2 files changed, 10 insertions(+)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index d20069e..cf8dcf7 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -335,6 +335,12 @@ struct r600_common_screen {
 	 */
 	unsigned			dirty_fb_counter;
 
+	/* Atomically increment this counter when an existing texture's
+	 * metadata is enabled or disabled in a way that requires changing
+	 * contexts' compressed texture binding masks.
+	 */
+	unsigned			compressed_colortex_counter;
+
 	void (*query_opaque_metadata)(struct r600_common_screen *rscreen,
 				      struct r600_texture *rtex,
 				      struct radeon_bo_metadata *md);
@@ -406,6 +412,7 @@ struct r600_common_context {
 	unsigned			initial_gfx_cs_size;
 	unsigned			gpu_reset_counter;
 	unsigned			last_dirty_fb_counter;
+	unsigned			last_compressed_colortex_counter;
 
 	struct u_upload_mgr		*uploader;
 	struct u_suballocator		*allocator_so_filled_size;
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 1a8822c..6b2d909 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -287,6 +287,7 @@ static void r600_texture_disable_cmask(struct r600_common_screen *rscreen,
 
 	/* Notify all contexts about the change. */
 	r600_dirty_all_framebuffer_states(rscreen);
+	p_atomic_inc(&rscreen->compressed_colortex_counter);
 }
 
 static void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
@@ -603,6 +604,8 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen
 		rtex->cb_color_info |= SI_S_028C70_FAST_CLEAR(1);
 	else
 		rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
+
+	p_atomic_inc(&rscreen->compressed_colortex_counter);
 }
 
 static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen,
-- 
2.5.0



More information about the mesa-dev mailing list