From 784269aa404e9484e195032841025cee24af8058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= Date: Sun, 7 Feb 2016 23:33:44 -0500 Subject: [PATCH] gallium/radeon: notify all contexts when cmasks are enabled/disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. Reviewed-by: Bas Nieuwenhuizen Reviewed-by: Marek Olšák --- 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 d20069ef0c9..cf8dcf7ea88 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 1a8822ca54b..6b2d9096525 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,