[Mesa-dev] [PATCH 2/4] gallium/radeon: don't discard DCC if an external user can write to it

Marek Olšák maraeo at gmail.com
Mon Jun 6 15:07:21 UTC 2016


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

We don't import textures with DCC now, but soon we will.

v2: if we can't disable DCC for image writes, at least decompress DCC
    at bind time
---
 src/gallium/drivers/radeon/r600_pipe_common.h |  2 +-
 src/gallium/drivers/radeon/r600_texture.c     | 31 +++++++++++++++++++--------
 src/gallium/drivers/radeonsi/si_descriptors.c | 10 +++++++--
 3 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 8072833..2d60da4 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -676,7 +676,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
 				   struct r600_atom *fb_state,
 				   unsigned *buffers, unsigned *dirty_cbufs,
 				   const union pipe_color_union *color);
-void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
+bool r600_texture_disable_dcc(struct r600_common_screen *rscreen,
 			      struct r600_texture *rtex);
 void r600_init_screen_texture_functions(struct r600_common_screen *rscreen);
 void r600_init_context_texture_functions(struct r600_common_context *rctx);
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 71758c4..0f5c08f 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -32,7 +32,7 @@
 #include <errno.h>
 #include <inttypes.h>
 
-static void r600_texture_discard_dcc(struct r600_common_screen *rscreen,
+static bool r600_texture_discard_dcc(struct r600_common_screen *rscreen,
 				     struct r600_texture *rtex);
 static void r600_texture_discard_cmask(struct r600_common_screen *rscreen,
 				       struct r600_texture *rtex);
@@ -86,7 +86,8 @@ bool r600_prepare_for_dma_blit(struct r600_common_context *rctx,
 						      src_box->height, src_box->depth))
 			return false;
 
-		r600_texture_discard_dcc(rctx->screen, rdst);
+		if (!r600_texture_discard_dcc(rctx->screen, rdst))
+			return false;
 	}
 
 	/* CMASK as:
@@ -376,25 +377,37 @@ static void r600_texture_discard_cmask(struct r600_common_screen *rscreen,
 	p_atomic_inc(&rscreen->compressed_colortex_counter);
 }
 
-static void r600_texture_discard_dcc(struct r600_common_screen *rscreen,
+static bool r600_can_disable_dcc(struct r600_texture *rtex)
+{
+	/* We can't disable DCC if it can be written by another process. */
+	return rtex->dcc_offset &&
+	       (!rtex->resource.is_shared ||
+		!(rtex->resource.external_usage & PIPE_HANDLE_USAGE_WRITE));
+}
+
+static bool r600_texture_discard_dcc(struct r600_common_screen *rscreen,
 				     struct r600_texture *rtex)
 {
+	if (!r600_can_disable_dcc(rtex))
+		return false;
+
 	/* Disable DCC. */
 	rtex->dcc_offset = 0;
 	rtex->cb_color_info &= ~VI_S_028C70_DCC_ENABLE(1);
 
 	/* Notify all contexts about the change. */
 	r600_dirty_all_framebuffer_states(rscreen);
+	return true;
 }
 
-void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
+bool r600_texture_disable_dcc(struct r600_common_screen *rscreen,
 			      struct r600_texture *rtex)
 {
 	struct r600_common_context *rctx =
 		(struct r600_common_context *)rscreen->aux_context;
 
-	if (!rtex->dcc_offset)
-		return;
+	if (!r600_can_disable_dcc(rtex))
+		return false;
 
 	/* Decompress DCC. */
 	pipe_mutex_lock(rscreen->aux_context_lock);
@@ -402,7 +415,7 @@ void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
 	rctx->b.flush(&rctx->b, NULL, 0);
 	pipe_mutex_unlock(rscreen->aux_context_lock);
 
-	r600_texture_discard_dcc(rscreen, rtex);
+	return r600_texture_discard_dcc(rscreen, rtex);
 }
 
 static void r600_degrade_tile_mode_to_linear(struct r600_common_context *rctx,
@@ -497,8 +510,8 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
 		 * access.
 		 */
 		if (usage & PIPE_HANDLE_USAGE_WRITE && rtex->dcc_offset) {
-			r600_texture_disable_dcc(rscreen, rtex);
-			update_metadata = true;
+			if (r600_texture_disable_dcc(rscreen, rtex))
+				update_metadata = true;
 		}
 
 		if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) &&
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index baddc5f..be41084 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -570,8 +570,14 @@ static void si_set_shader_image(struct si_context *ctx,
 		assert(tex->fmask.size == 0);
 
 		if (tex->dcc_offset &&
-		    view->access & PIPE_IMAGE_ACCESS_WRITE)
-			r600_texture_disable_dcc(&screen->b, tex);
+		    view->access & PIPE_IMAGE_ACCESS_WRITE) {
+			/* If DCC can't be disabled, at least decompress it.
+			 * The decompression is relatively cheap if the surface
+			 * has been decompressed already.
+			 */
+			if (!r600_texture_disable_dcc(&screen->b, tex))
+				ctx->b.decompress_dcc(&ctx->b.b, tex);
+		}
 
 		if (is_compressed_colortex(tex)) {
 			images->compressed_colortex_mask |= 1 << slot;
-- 
2.7.4



More information about the mesa-dev mailing list