[Mesa-dev] [PATCH 17/19] radeonsi: remove redundant si_texture::cmask_size

Marek Olšák maraeo at gmail.com
Fri Jun 22 22:32:08 UTC 2018


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

cmask_buffer and surface.cmask_size can replace its role.
---
 src/gallium/drivers/radeonsi/si_blit.c        |  8 ++---
 src/gallium/drivers/radeonsi/si_clear.c       | 17 +++-------
 src/gallium/drivers/radeonsi/si_descriptors.c |  2 +-
 src/gallium/drivers/radeonsi/si_pipe.h        |  1 -
 src/gallium/drivers/radeonsi/si_texture.c     | 31 +++++++++----------
 5 files changed, 25 insertions(+), 34 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index 431cc6332f9..0fd69f3a6c5 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -531,21 +531,21 @@ static void si_blit_decompress_color(struct si_context *sctx,
 	sctx->decompression_enabled = false;
 	si_make_CB_shader_coherent(sctx, tex->buffer.b.b.nr_samples,
 				   vi_dcc_enabled(tex, first_level));
 }
 
 static void
 si_decompress_color_texture(struct si_context *sctx, struct si_texture *tex,
 			    unsigned first_level, unsigned last_level)
 {
 	/* CMASK or DCC can be discarded and we can still end up here. */
-	if (!tex->cmask_size && !tex->surface.fmask_size && !tex->dcc_offset)
+	if (!tex->cmask_buffer && !tex->surface.fmask_size && !tex->dcc_offset)
 		return;
 
 	si_blit_decompress_color(sctx, tex, first_level, last_level, 0,
 				 util_max_layer(&tex->buffer.b.b, first_level),
 				 false);
 }
 
 static void
 si_decompress_sampler_color_textures(struct si_context *sctx,
 				     struct si_samplers *textures)
@@ -852,21 +852,21 @@ static void si_decompress_subresource(struct pipe_context *ctx,
 		 * by dirtying the framebuffer.
 		 */
 		if (sctx->framebuffer.state.zsbuf &&
 		    sctx->framebuffer.state.zsbuf->u.tex.level == level &&
 		    sctx->framebuffer.state.zsbuf->texture == tex)
 			si_update_fb_dirtiness_after_rendering(sctx);
 
 		si_decompress_depth(sctx, stex, planes,
 				    level, level,
 				    first_layer, last_layer);
-	} else if (stex->surface.fmask_size || stex->cmask_size || stex->dcc_offset) {
+	} else if (stex->surface.fmask_size || stex->cmask_buffer || stex->dcc_offset) {
 		/* If we've rendered into the framebuffer and it's a blitting
 		 * source, make sure the decompression pass is invoked
 		 * by dirtying the framebuffer.
 		 */
 		for (unsigned i = 0; i < sctx->framebuffer.state.nr_cbufs; i++) {
 			if (sctx->framebuffer.state.cbufs[i] &&
 			    sctx->framebuffer.state.cbufs[i]->u.tex.level == level &&
 			    sctx->framebuffer.state.cbufs[i]->texture == tex) {
 				si_update_fb_dirtiness_after_rendering(sctx);
 				break;
@@ -1132,21 +1132,21 @@ static bool do_hardware_msaa_resolve(struct pipe_context *ctx,
 	    info->dst.box.y == 0 &&
 	    info->dst.box.width == dst_width &&
 	    info->dst.box.height == dst_height &&
 	    info->dst.box.depth == 1 &&
 	    info->src.box.x == 0 &&
 	    info->src.box.y == 0 &&
 	    info->src.box.width == dst_width &&
 	    info->src.box.height == dst_height &&
 	    info->src.box.depth == 1 &&
 	    !dst->surface.is_linear &&
-	    (!dst->cmask_size || !dst->dirty_level_mask)) { /* dst cannot be fast-cleared */
+	    (!dst->cmask_buffer || !dst->dirty_level_mask)) { /* dst cannot be fast-cleared */
 		/* Check the last constraint. */
 		if (src->surface.micro_tile_mode != dst->surface.micro_tile_mode) {
 			/* The next fast clear will switch to this mode to
 			 * get direct hw resolve next time if the mode is
 			 * different now.
 			 */
 			src->last_msaa_resolve_target_micro_mode =
 				dst->surface.micro_tile_mode;
 			goto resolve_to_temp;
 		}
@@ -1318,21 +1318,21 @@ static void si_flush_resource(struct pipe_context *ctx,
 	struct si_texture *tex = (struct si_texture*)res;
 
 	assert(res->target != PIPE_BUFFER);
 	assert(!tex->dcc_separate_buffer || tex->dcc_gather_statistics);
 
 	/* st/dri calls flush twice per frame (not a bug), this prevents double
 	 * decompression. */
 	if (tex->dcc_separate_buffer && !tex->separate_dcc_dirty)
 		return;
 
-	if (!tex->is_depth && (tex->cmask_size || tex->dcc_offset)) {
+	if (!tex->is_depth && (tex->cmask_buffer || tex->dcc_offset)) {
 		si_blit_decompress_color(sctx, tex, 0, res->last_level,
 					 0, util_max_layer(res, 0),
 					 tex->dcc_separate_buffer != NULL);
 	}
 
 	/* Always do the analysis even if DCC is disabled at the moment. */
 	if (tex->dcc_gather_statistics) {
 		bool separate_dcc_dirty = tex->separate_dcc_dirty;
 
 		/* If the color buffer hasn't been unbound and fast clear hasn't
diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c
index 817b31806e0..23c9962408c 100644
--- a/src/gallium/drivers/radeonsi/si_clear.c
+++ b/src/gallium/drivers/radeonsi/si_clear.c
@@ -30,38 +30,32 @@
 #include "util/u_surface.h"
 
 enum {
 	SI_CLEAR         = SI_SAVE_FRAGMENT_STATE,
 	SI_CLEAR_SURFACE = SI_SAVE_FRAMEBUFFER | SI_SAVE_FRAGMENT_STATE,
 };
 
 static void si_alloc_separate_cmask(struct si_screen *sscreen,
 				    struct si_texture *tex)
 {
-	if (tex->cmask_buffer)
+	if (tex->cmask_buffer || !tex->surface.cmask_size)
                 return;
 
-	assert(tex->cmask_size == 0);
-
-	if (!tex->surface.cmask_size)
-		return;
-
 	tex->cmask_buffer =
 		si_aligned_buffer_create(&sscreen->b,
 					 SI_RESOURCE_FLAG_UNMAPPABLE,
 					 PIPE_USAGE_DEFAULT,
 					 tex->surface.cmask_size,
 					 tex->surface.cmask_alignment);
 	if (tex->cmask_buffer == NULL)
 		return;
 
-	tex->cmask_size = tex->surface.cmask_size;
 	tex->cmask_base_address_reg = tex->cmask_buffer->gpu_address >> 8;
 	tex->cb_color_info |= S_028C70_FAST_CLEAR(1);
 
 	p_atomic_inc(&sscreen->compressed_colortex_counter);
 }
 
 static bool si_set_clear_color(struct si_texture *tex,
 			       enum pipe_format surface_format,
 			       const union pipe_color_union *color)
 {
@@ -481,27 +475,27 @@ static void si_do_fast_color_clear(struct si_context *sctx,
 			if (!vi_get_fast_clear_parameters(tex->buffer.b.b.format,
 							  fb->cbufs[i]->format,
 							  color, &reset_value,
 							  &eliminate_needed))
 				continue;
 
 			if (eliminate_needed && too_small)
 				continue;
 
 			/* DCC fast clear with MSAA should clear CMASK to 0xC. */
-			if (tex->buffer.b.b.nr_samples >= 2 && tex->cmask_size) {
+			if (tex->buffer.b.b.nr_samples >= 2 && tex->cmask_buffer) {
 				/* TODO: This doesn't work with MSAA. */
 				if (eliminate_needed)
 					continue;
 
 				si_clear_buffer(sctx, &tex->cmask_buffer->b.b,
-						tex->cmask_offset, tex->cmask_size,
+						tex->cmask_offset, tex->surface.cmask_size,
 						0xCCCCCCCC, SI_COHERENCY_CB_META);
 				need_decompress_pass = true;
 			}
 
 			vi_dcc_clear_level(sctx, tex, 0, reset_value);
 
 			if (eliminate_needed)
 				need_decompress_pass = true;
 
 			tex->separate_dcc_dirty = true;
@@ -513,27 +507,26 @@ static void si_do_fast_color_clear(struct si_context *sctx,
 			if (tex->surface.bpe > 8) {
 				continue;
 			}
 
 			/* RB+ doesn't work with CMASK fast clear on Stoney. */
 			if (sctx->family == CHIP_STONEY)
 				continue;
 
 			/* ensure CMASK is enabled */
 			si_alloc_separate_cmask(sctx->screen, tex);
-			if (tex->cmask_size == 0) {
+			if (!tex->cmask_buffer)
 				continue;
-			}
 
 			/* Do the fast clear. */
 			si_clear_buffer(sctx, &tex->cmask_buffer->b.b,
-					tex->cmask_offset, tex->cmask_size, 0,
+					tex->cmask_offset, tex->surface.cmask_size, 0,
 					SI_COHERENCY_CB_META);
 			need_decompress_pass = true;
 		}
 
 		if (need_decompress_pass &&
 		    !(tex->dirty_level_mask & (1 << level))) {
 			tex->dirty_level_mask |= 1 << level;
 			p_atomic_inc(&sctx->screen->compressed_colortex_counter);
 		}
 
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 68b58fde06f..e8c028061d1 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -471,21 +471,21 @@ static void si_set_sampler_view_desc(struct si_context *sctx,
 			si_set_sampler_state_desc(sstate, sview,
 						  is_buffer ? NULL : tex,
 						  desc + 12);
 	}
 }
 
 static bool color_needs_decompression(struct si_texture *tex)
 {
 	return tex->surface.fmask_size ||
 	       (tex->dirty_level_mask &&
-		(tex->cmask_size || tex->dcc_offset));
+		(tex->cmask_buffer || tex->dcc_offset));
 }
 
 static bool depth_needs_decompression(struct si_texture *tex)
 {
 	/* If the depth/stencil texture is TC-compatible, no decompression
 	 * will be done. The decompression function will only flush DB caches
 	 * to make it coherent with shaders. That's necessary because the driver
 	 * doesn't flush DB caches in any other case.
 	 */
 	return tex->db_compatible;
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 7ec547d91a3..4f18883c6a8 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -234,21 +234,20 @@ struct si_texture {
 	struct r600_resource		buffer;
 
 	struct radeon_surf		surface;
 	uint64_t			size;
 	struct si_texture		*flushed_depth_texture;
 
 	/* Colorbuffer compression and fast clear. */
 	uint64_t			fmask_offset;
 	uint64_t			cmask_offset;
 	uint64_t			cmask_base_address_reg;
-	uint32_t			cmask_size;
 	struct r600_resource		*cmask_buffer;
 	uint64_t			dcc_offset; /* 0 = disabled */
 	unsigned			cb_color_info; /* fast clear enable bit */
 	unsigned			color_clear_value[2];
 	unsigned			last_msaa_resolve_target_micro_mode;
 	unsigned			num_level0_transfers;
 	unsigned			num_color_samples;
 
 	/* Depth buffer compression and fast clear. */
 	uint64_t			htile_offset;
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index 7090e2491ce..3152f742ae6 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -75,33 +75,33 @@ bool si_prepare_for_dma_blit(struct si_context *sctx,
 	 */
 	if (vi_dcc_enabled(src, src_level) ||
 	    vi_dcc_enabled(dst, dst_level))
 		return false;
 
 	/* CMASK as:
 	 *   src: Both texture and SDMA paths need decompression. Use SDMA.
 	 *   dst: If overwriting the whole texture, discard CMASK and use
 	 *        SDMA. Otherwise, use the 3D path.
 	 */
-	if (dst->cmask_size && dst->dirty_level_mask & (1 << dst_level)) {
+	if (dst->cmask_buffer && dst->dirty_level_mask & (1 << dst_level)) {
 		/* The CMASK clear is only enabled for the first level. */
 		assert(dst_level == 0);
 		if (!util_texrange_covers_whole_level(&dst->buffer.b.b, dst_level,
 						      dstx, dsty, dstz, src_box->width,
 						      src_box->height, src_box->depth))
 			return false;
 
 		si_texture_discard_cmask(sctx->screen, dst);
 	}
 
 	/* All requirements are met. Prepare textures for SDMA. */
-	if (src->cmask_size && src->dirty_level_mask & (1 << src_level))
+	if (src->cmask_buffer && src->dirty_level_mask & (1 << src_level))
 		sctx->b.flush_resource(&sctx->b, &src->buffer.b.b);
 
 	assert(!(src->dirty_level_mask & (1 << src_level)));
 	assert(!(dst->dirty_level_mask & (1 << dst_level)));
 
 	return true;
 }
 
 /* Same as resource_copy_region, except that both upsampling and downsampling are allowed. */
 static void si_copy_region_with_blit(struct pipe_context *pipe,
@@ -413,35 +413,36 @@ void si_eliminate_fast_color_clear(struct si_context *sctx,
 	if (n != sctx->num_decompress_calls)
 		ctx->flush(ctx, NULL, 0);
 
 	if (ctx == sscreen->aux_context)
 		mtx_unlock(&sscreen->aux_context_lock);
 }
 
 void si_texture_discard_cmask(struct si_screen *sscreen,
 			      struct si_texture *tex)
 {
-	if (!tex->cmask_size)
+	if (!tex->cmask_buffer)
 		return;
 
 	assert(tex->buffer.b.b.nr_samples <= 1);
 
 	/* Disable CMASK. */
-	tex->cmask_size = 0;
 	tex->cmask_base_address_reg = tex->buffer.gpu_address >> 8;
 	tex->dirty_level_mask = 0;
 
 	tex->cb_color_info &= ~S_028C70_FAST_CLEAR(1);
 
 	if (tex->cmask_buffer != &tex->buffer)
 	    r600_resource_reference(&tex->cmask_buffer, NULL);
 
+	tex->cmask_buffer = NULL;
+
 	/* Notify all contexts about the change. */
 	p_atomic_inc(&sscreen->dirty_tex_counter);
 	p_atomic_inc(&sscreen->compressed_colortex_counter);
 }
 
 static bool si_can_disable_dcc(struct si_texture *tex)
 {
 	/* We can't disable DCC if it can be written by another process. */
 	return tex->dcc_offset &&
 	       (!tex->buffer.b.is_shared ||
@@ -565,21 +566,20 @@ static void si_reallocate_texture_inplace(struct si_context *sctx,
 	tex->buffer.domains = new_tex->buffer.domains;
 	tex->buffer.flags = new_tex->buffer.flags;
 
 	tex->surface = new_tex->surface;
 	tex->size = new_tex->size;
 	si_texture_reference(&tex->flushed_depth_texture,
 			     new_tex->flushed_depth_texture);
 
 	tex->fmask_offset = new_tex->fmask_offset;
 	tex->cmask_offset = new_tex->cmask_offset;
-	tex->cmask_size = new_tex->cmask_size;
 	tex->cmask_base_address_reg = new_tex->cmask_base_address_reg;
 	r600_resource_reference(&tex->cmask_buffer, new_tex->cmask_buffer);
 	tex->dcc_offset = new_tex->dcc_offset;
 	tex->cb_color_info = new_tex->cb_color_info;
 	memcpy(tex->color_clear_value, new_tex->color_clear_value,
 	       sizeof(tex->color_clear_value));
 	tex->last_msaa_resolve_target_micro_mode = new_tex->last_msaa_resolve_target_micro_mode;
 
 	tex->htile_offset = new_tex->htile_offset;
 	tex->depth_clear_value = new_tex->depth_clear_value;
@@ -597,21 +597,21 @@ static void si_reallocate_texture_inplace(struct si_context *sctx,
 
 	tex->separate_dcc_dirty = new_tex->separate_dcc_dirty;
 	tex->dcc_gather_statistics = new_tex->dcc_gather_statistics;
 	r600_resource_reference(&tex->dcc_separate_buffer,
 				new_tex->dcc_separate_buffer);
 	r600_resource_reference(&tex->last_dcc_separate_buffer,
 				new_tex->last_dcc_separate_buffer);
 
 	if (new_bind_flag == PIPE_BIND_LINEAR) {
 		assert(!tex->htile_offset);
-		assert(!tex->cmask_size);
+		assert(!tex->cmask_buffer);
 		assert(!tex->surface.fmask_size);
 		assert(!tex->dcc_offset);
 		assert(!tex->is_depth);
 	}
 
 	si_texture_reference(&new_tex, NULL);
 
 	p_atomic_inc(&sctx->screen->dirty_tex_counter);
 }
 
@@ -756,30 +756,30 @@ static boolean si_texture_get_handle(struct pipe_screen* screen,
 		 */
 		if (usage & PIPE_HANDLE_USAGE_WRITE && tex->dcc_offset) {
 			if (si_texture_disable_dcc(sctx, tex)) {
 				update_metadata = true;
 				/* si_texture_disable_dcc flushes the context */
 				flush = false;
 			}
 		}
 
 		if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) &&
-		    (tex->cmask_size || tex->dcc_offset)) {
+		    (tex->cmask_buffer || tex->dcc_offset)) {
 			/* Eliminate fast clear (both CMASK and DCC) */
 			si_eliminate_fast_color_clear(sctx, tex);
 			/* eliminate_fast_color_clear flushes the context */
 			flush = false;
 
 			/* Disable CMASK if flush_resource isn't going
 			 * to be called.
 			 */
-			if (tex->cmask_size)
+			if (tex->cmask_buffer)
 				si_texture_discard_cmask(sscreen, tex);
 		}
 
 		/* Set metadata. */
 		if (!res->b.is_shared || update_metadata) {
 			si_texture_init_metadata(sscreen, tex, &metadata);
 			si_query_opaque_metadata(sscreen, tex, &metadata);
 
 			sscreen->ws->buffer_set_metadata(res->buf, &metadata);
 		}
@@ -979,21 +979,21 @@ void si_print_texture_info(struct si_screen *sscreen,
 		if (tex->surface.fmask_size) {
 			u_log_printf(log, "  FMASK: offset=%"PRIu64", size=%"PRIu64", "
 				"alignment=%u, swmode=%u, epitch=%u\n",
 				tex->fmask_offset,
 				tex->surface.fmask_size,
 				tex->surface.fmask_alignment,
 				tex->surface.u.gfx9.fmask.swizzle_mode,
 				tex->surface.u.gfx9.fmask.epitch);
 		}
 
-		if (tex->cmask_size) {
+		if (tex->cmask_buffer) {
 			u_log_printf(log, "  CMask: offset=%"PRIu64", size=%u, "
 				"alignment=%u, rb_aligned=%u, pipe_aligned=%u\n",
 				tex->cmask_offset,
 				tex->surface.cmask_size,
 				tex->surface.cmask_alignment,
 				tex->surface.u.gfx9.cmask.rb_aligned,
 				tex->surface.u.gfx9.cmask.pipe_aligned);
 		}
 
 		if (tex->htile_offset) {
@@ -1033,24 +1033,24 @@ void si_print_texture_info(struct si_screen *sscreen,
 
 	if (tex->surface.fmask_size)
 		u_log_printf(log, "  FMask: offset=%"PRIu64", size=%"PRIu64", alignment=%u, pitch_in_pixels=%u, "
 			"bankh=%u, slice_tile_max=%u, tile_mode_index=%u\n",
 			tex->fmask_offset, tex->surface.fmask_size, tex->surface.fmask_alignment,
 			tex->surface.u.legacy.fmask.pitch_in_pixels,
 			tex->surface.u.legacy.fmask.bankh,
 			tex->surface.u.legacy.fmask.slice_tile_max,
 			tex->surface.u.legacy.fmask.tiling_index);
 
-	if (tex->cmask_size)
+	if (tex->cmask_buffer)
 		u_log_printf(log, "  CMask: offset=%"PRIu64", size=%u, alignment=%u, "
 			"slice_tile_max=%u\n",
-			tex->cmask_offset, tex->cmask_size, tex->surface.cmask_alignment,
+			tex->cmask_offset, tex->surface.cmask_size, tex->surface.cmask_alignment,
 			tex->surface.u.legacy.cmask_slice_tile_max);
 
 	if (tex->htile_offset)
 		u_log_printf(log, "  HTile: offset=%"PRIu64", size=%u, "
 			"alignment=%u, TC_compatible = %u\n",
 			tex->htile_offset, tex->surface.htile_size,
 			tex->surface.htile_alignment,
 			tex->tc_compatible_htile);
 
 	if (tex->dcc_offset) {
@@ -1178,27 +1178,26 @@ si_texture_create_object(struct pipe_screen *screen,
 	} else {
 		if (base->nr_samples > 1 &&
 		    !buf &&
 		    !(sscreen->debug_flags & DBG(NO_FMASK))) {
 			/* Allocate FMASK. */
 			tex->fmask_offset = align64(tex->size,
 						     tex->surface.fmask_alignment);
 			tex->size = tex->fmask_offset + tex->surface.fmask_size;
 
 			/* Allocate CMASK. */
-			tex->cmask_size = tex->surface.cmask_size;
 			tex->cmask_offset = align64(tex->size, tex->surface.cmask_alignment);
-			tex->size = tex->cmask_offset + tex->cmask_size;
+			tex->size = tex->cmask_offset + tex->surface.cmask_size;
 			tex->cb_color_info |= S_028C70_FAST_CLEAR(1);
 			tex->cmask_buffer = &tex->buffer;
 
-			if (!tex->surface.fmask_size || !tex->cmask_size) {
+			if (!tex->surface.fmask_size || !tex->surface.cmask_size) {
 				FREE(tex);
 				return NULL;
 			}
 		}
 
 		/* Shared textures must always set up DCC here.
 		 * If it's not present, it will be disabled by
 		 * apply_opaque_metadata later.
 		 */
 		if (tex->surface.dcc_size &&
@@ -1224,24 +1223,24 @@ si_texture_create_object(struct pipe_screen *screen,
 		resource->gpu_address = sscreen->ws->buffer_get_virtual_address(resource->buf);
 		resource->bo_size = buf->size;
 		resource->bo_alignment = buf->alignment;
 		resource->domains = sscreen->ws->buffer_get_initial_domain(resource->buf);
 		if (resource->domains & RADEON_DOMAIN_VRAM)
 			resource->vram_usage = buf->size;
 		else if (resource->domains & RADEON_DOMAIN_GTT)
 			resource->gart_usage = buf->size;
 	}
 
-	if (tex->cmask_size) {
+	if (tex->cmask_buffer) {
 		/* Initialize the cmask to 0xCC (= compressed state). */
 		si_screen_clear_buffer(sscreen, &tex->cmask_buffer->b.b,
-					 tex->cmask_offset, tex->cmask_size,
+					 tex->cmask_offset, tex->surface.cmask_size,
 					 0xCCCCCCCC);
 	}
 	if (tex->htile_offset) {
 		uint32_t clear_value = 0;
 
 		if (sscreen->info.chip_class >= GFX9 || tex->tc_compatible_htile)
 			clear_value = 0x0000030F;
 
 		si_screen_clear_buffer(sscreen, &tex->buffer.b.b,
 					 tex->htile_offset,
-- 
2.17.1



More information about the mesa-dev mailing list