[Mesa-dev] [PATCH 18/26] radeonsi: allocate DCC in the same backing buffer as the texture

Marek Olšák maraeo at gmail.com
Wed Mar 2 16:36:27 UTC 2016


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

To allow sharing textures with DCC enabled.
---
 src/gallium/drivers/radeon/r600_pipe_common.h |  2 +-
 src/gallium/drivers/radeon/r600_texture.c     | 51 ++++++++++++---------------
 src/gallium/drivers/radeonsi/cik_sdma.c       |  2 +-
 src/gallium/drivers/radeonsi/si_blit.c        |  8 ++---
 src/gallium/drivers/radeonsi/si_descriptors.c |  8 +----
 src/gallium/drivers/radeonsi/si_dma.c         |  2 +-
 src/gallium/drivers/radeonsi/si_pipe.h        |  1 -
 src/gallium/drivers/radeonsi/si_state.c       | 21 +++++------
 8 files changed, 38 insertions(+), 57 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index daf8798..6e65742 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -222,7 +222,7 @@ struct r600_texture {
 	struct r600_fmask_info		fmask;
 	struct r600_cmask_info		cmask;
 	struct r600_resource		*cmask_buffer;
-	struct r600_resource		*dcc_buffer;
+	unsigned			dcc_offset; /* 0 = disabled */
 	unsigned			cb_color_info; /* fast clear enable bit */
 	unsigned			color_clear_value[2];
 
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 395607b..4424ca3 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -353,7 +353,6 @@ static void r600_texture_destroy(struct pipe_screen *screen,
 	if (rtex->cmask_buffer != &rtex->resource) {
 	    pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL);
 	}
-	pipe_resource_reference((struct pipe_resource**)&rtex->dcc_buffer, NULL);
 	pb_reference(&resource->buf, NULL);
 	FREE(rtex);
 }
@@ -576,25 +575,6 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen
 		rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
 }
 
-static void vi_texture_alloc_dcc_separate(struct r600_common_screen *rscreen,
-					      struct r600_texture *rtex)
-{
-	if (rscreen->debug_flags & DBG_NO_DCC)
-		return;
-
-	rtex->dcc_buffer = (struct r600_resource *)
-		r600_aligned_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
-				   PIPE_USAGE_DEFAULT, rtex->surface.dcc_size, rtex->surface.dcc_alignment);
-	if (rtex->dcc_buffer == NULL) {
-		return;
-	}
-
-	r600_screen_clear_buffer(rscreen, &rtex->dcc_buffer->b.b, 0, rtex->surface.dcc_size,
-				 0xFFFFFFFF, true);
-
-	rtex->cb_color_info |= VI_S_028C70_DCC_ENABLE(1);
-}
-
 static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen,
 					    struct r600_texture *rtex)
 {
@@ -729,10 +709,10 @@ void r600_print_texture_info(struct r600_texture *rtex, FILE *f)
 			rtex->htile_buffer->buf->alignment, rtex->htile.pitch,
 			rtex->htile.height, rtex->htile.xalign, rtex->htile.yalign);
 
-	if (rtex->dcc_buffer) {
-		fprintf(f, "  DCC: size=%u, alignment=%u\n",
-			rtex->dcc_buffer->b.b.width0,
-			rtex->dcc_buffer->buf->alignment);
+	if (rtex->dcc_offset) {
+		fprintf(f, "  DCC: offset=%u, size=%"PRIu64", alignment=%"PRIu64"\n",
+			rtex->dcc_offset, rtex->surface.dcc_size,
+			rtex->surface.dcc_alignment);
 		for (i = 0; i <= rtex->surface.last_level; i++)
 			fprintf(f, "  DCCLevel[%i]: offset=%"PRIu64"\n",
 				i, rtex->surface.level[i].dcc_offset);
@@ -830,8 +810,14 @@ r600_texture_create_object(struct pipe_screen *screen,
 				return NULL;
 			}
 		}
-		if (rtex->surface.dcc_size)
-			vi_texture_alloc_dcc_separate(rscreen, rtex);
+
+		if (!buf && rtex->surface.dcc_size &&
+		    !(rscreen->debug_flags & DBG_NO_DCC)) {
+			/* Reserve space for the DCC buffer. */
+			rtex->dcc_offset = align(rtex->size, rtex->surface.dcc_alignment);
+			rtex->size = rtex->dcc_offset + rtex->surface.dcc_size;
+			rtex->cb_color_info |= VI_S_028C70_DCC_ENABLE(1);
+		}
 	}
 
 	/* Now create the backing buffer. */
@@ -853,6 +839,12 @@ r600_texture_create_object(struct pipe_screen *screen,
 					 rtex->cmask.offset, rtex->cmask.size,
 					 0xCCCCCCCC, true);
 	}
+	if (rtex->dcc_offset) {
+		r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
+					 rtex->dcc_offset,
+					 rtex->surface.dcc_size,
+					 0xFFFFFFFF, true);
+	}
 
 	/* Initialize the CMASK base register value. */
 	rtex->cmask.base_address_reg =
@@ -1560,7 +1552,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
 			continue;
 		}
 
-		if (tex->dcc_buffer) {
+		if (tex->dcc_offset) {
 			uint32_t reset_value;
 			bool clear_words_needed;
 
@@ -1569,8 +1561,9 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
 
 			vi_get_fast_clear_parameters(fb->cbufs[i]->format, color, &reset_value, &clear_words_needed);
 
-			rctx->clear_buffer(&rctx->b, &tex->dcc_buffer->b.b,
-					0, tex->surface.dcc_size, reset_value, true);
+			rctx->clear_buffer(&rctx->b, &tex->resource.b.b,
+					   tex->dcc_offset, tex->surface.dcc_size,
+					   reset_value, true);
 
 			if (clear_words_needed)
 				tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
diff --git a/src/gallium/drivers/radeonsi/cik_sdma.c b/src/gallium/drivers/radeonsi/cik_sdma.c
index 7691391..6eb62dc 100644
--- a/src/gallium/drivers/radeonsi/cik_sdma.c
+++ b/src/gallium/drivers/radeonsi/cik_sdma.c
@@ -243,7 +243,7 @@ void cik_sdma_copy(struct pipe_context *ctx,
 	if (src->format != dst->format ||
 	    rdst->surface.nsamples > 1 || rsrc->surface.nsamples > 1 ||
 	    (rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) ||
-	    rdst->dcc_buffer || rsrc->dcc_buffer) {
+	    rdst->dcc_offset || rsrc->dcc_offset) {
 		goto fallback;
 	}
 
diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index 53c6705..60b9f7b 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -330,7 +330,7 @@ void si_decompress_color_textures(struct si_context *sctx,
 		assert(view);
 
 		tex = (struct r600_texture *)view->texture;
-		assert(tex->cmask.size || tex->fmask.size || tex->dcc_buffer);
+		assert(tex->cmask.size || tex->fmask.size || tex->dcc_offset);
 
 		si_blit_decompress_color(&sctx->b.b, tex,
 					 view->u.tex.first_level, view->u.tex.last_level,
@@ -483,7 +483,7 @@ static void si_decompress_subresource(struct pipe_context *ctx,
 			si_blit_decompress_depth_in_place(sctx, rtex, true,
 							  level, level,
 							  first_layer, last_layer);
-	} else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_buffer) {
+	} else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_offset) {
 		si_blit_decompress_color(ctx, rtex, level, level,
 					 first_layer, last_layer);
 	}
@@ -712,7 +712,7 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
 	    dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D &&
 	    !(dst->surface.flags & RADEON_SURF_SCANOUT) &&
 	    (!dst->cmask.size || !dst->dirty_level_mask) && /* dst cannot be fast-cleared */
-	    !dst->dcc_buffer) {
+	    !dst->dcc_offset) {
 		si_blitter_begin(ctx, SI_COLOR_RESOLVE |
 				 (info->render_condition_enable ? 0 : SI_DISABLE_RENDER_COND));
 		util_blitter_custom_resolve_color(sctx->blitter,
@@ -761,7 +761,7 @@ static void si_flush_resource(struct pipe_context *ctx,
 
 	assert(res->target != PIPE_BUFFER);
 
-	if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_buffer)) {
+	if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_offset)) {
 		si_blit_decompress_color(ctx, rtex, 0, res->last_level,
 					 0, util_max_layer(res, 0));
 	}
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 345f2bb..ba4a770 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -158,12 +158,6 @@ static void si_sampler_view_add_buffers(struct si_context *sctx,
 			rview->resource, RADEON_USAGE_READ,
 			r600_get_sampler_view_priority(rview->resource));
 	}
-
-	if (rview->dcc_buffer && rview->dcc_buffer != rview->resource) {
-		radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
-			rview->dcc_buffer, RADEON_USAGE_READ,
-			RADEON_PRIO_DCC);
-	}
 }
 
 static void si_sampler_views_begin_new_cs(struct si_context *sctx,
@@ -263,7 +257,7 @@ static void si_set_sampler_views(struct pipe_context *ctx,
 				samplers->depth_texture_mask &= ~(1 << slot);
 			}
 			if (rtex->cmask.size || rtex->fmask.size ||
-			    (rtex->dcc_buffer && rtex->dirty_level_mask)) {
+			    (rtex->dcc_offset && rtex->dirty_level_mask)) {
 				samplers->compressed_colortex_mask |= 1 << slot;
 			} else {
 				samplers->compressed_colortex_mask &= ~(1 << slot);
diff --git a/src/gallium/drivers/radeonsi/si_dma.c b/src/gallium/drivers/radeonsi/si_dma.c
index 240d961..0efca19 100644
--- a/src/gallium/drivers/radeonsi/si_dma.c
+++ b/src/gallium/drivers/radeonsi/si_dma.c
@@ -249,7 +249,7 @@ void si_dma_copy(struct pipe_context *ctx,
 	    (rdst->dirty_level_mask | rdst->stencil_dirty_level_mask) & (1 << dst_level) ||
 	    rdst->cmask.size || rdst->fmask.size ||
 	    rsrc->cmask.size || rsrc->fmask.size ||
-	    rdst->dcc_buffer || rsrc->dcc_buffer) {
+	    rdst->dcc_offset || rsrc->dcc_offset) {
 		goto fallback;
 	}
 
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index ef860a5..e6f92a3 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -121,7 +121,6 @@ struct si_sampler_view {
 	struct pipe_sampler_view	base;
 	struct list_head		list;
 	struct r600_resource		*resource;
-	struct r600_resource		*dcc_buffer;
         /* [0..7] = image descriptor
          * [4..7] = buffer descriptor */
 	uint32_t			state[8];
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index b23b17a..d423a34 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2322,9 +2322,8 @@ static void si_initialize_color_surface(struct si_context *sctx,
 	surf->cb_color_info = color_info;
 	surf->cb_color_attrib = color_attrib;
 
-	if (sctx->b.chip_class >= VI && rtex->dcc_buffer) {
+	if (sctx->b.chip_class >= VI && rtex->dcc_offset) {
 		unsigned max_uncompressed_block_size = 2;
-		uint64_t dcc_offset = rtex->surface.level[level].dcc_offset;
 
 		if (rtex->surface.nsamples > 1) {
 			if (rtex->surface.bpe == 1)
@@ -2335,7 +2334,9 @@ static void si_initialize_color_surface(struct si_context *sctx,
 
 		surf->cb_dcc_control = S_028C78_MAX_UNCOMPRESSED_BLOCK_SIZE(max_uncompressed_block_size) |
 		                       S_028C78_INDEPENDENT_64B_BLOCKS(1);
-		surf->cb_dcc_base = (rtex->dcc_buffer->gpu_address + dcc_offset) >> 8;
+		surf->cb_dcc_base = (rtex->resource.gpu_address +
+				     rtex->dcc_offset +
+				     rtex->surface.level[level].dcc_offset) >> 8;
 	}
 
 	if (rtex->fmask.size) {
@@ -2674,12 +2675,6 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
 				RADEON_PRIO_CMASK);
 		}
 
-		if (tex->dcc_buffer && tex->dcc_buffer != &tex->resource) {
-			radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
-				tex->dcc_buffer, RADEON_USAGE_READWRITE,
-				RADEON_PRIO_DCC);
-		}
-
 		radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C,
 					   sctx->b.chip_class >= VI ? 14 : 13);
 		radeon_emit(cs, cb->cb_color_base);	/* R_028C60_CB_COLOR0_BASE */
@@ -3073,13 +3068,13 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
 	view->state[5] = (S_008F24_BASE_ARRAY(state->u.tex.first_layer) |
 			  S_008F24_LAST_ARRAY(last_layer));
 
-	if (tmp->dcc_buffer) {
-		uint64_t dcc_offset = surflevel[base_level].dcc_offset;
+	if (tmp->dcc_offset) {
 		unsigned swap = r600_translate_colorswap(pipe_format);
 
 		view->state[6] = S_008F28_COMPRESSION_EN(1) | S_008F28_ALPHA_IS_ON_MSB(swap <= 1);
-		view->state[7] = (tmp->dcc_buffer->gpu_address + dcc_offset) >> 8;
-		view->dcc_buffer = tmp->dcc_buffer;
+		view->state[7] = (tmp->resource.gpu_address +
+				  tmp->dcc_offset +
+				  surflevel[base_level].dcc_offset) >> 8;
 	} else {
 		view->state[6] = 0;
 		view->state[7] = 0;
-- 
2.5.0



More information about the mesa-dev mailing list