[Mesa-dev] [PATCH 11/15] gallium/radeon: add helpers for whether HTILE is enabled

Marek Olšák maraeo at gmail.com
Mon Aug 21 21:54:10 UTC 2017


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

---
 src/gallium/drivers/r600/evergreen_state.c    |  3 +--
 src/gallium/drivers/r600/r600_blit.c          |  3 +--
 src/gallium/drivers/r600/r600_state.c         |  3 +--
 src/gallium/drivers/radeon/r600_pipe_common.h | 13 +++++++++++++
 src/gallium/drivers/radeonsi/si_blit.c        | 13 +++++++------
 src/gallium/drivers/radeonsi/si_descriptors.c |  2 +-
 src/gallium/drivers/radeonsi/si_state.c       |  8 +++-----
 7 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 764acfc..a9b503f 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1385,22 +1385,21 @@ static void evergreen_init_depth_surface(struct r600_context *rctx,
 					S_028044_TILE_SPLIT(stile_split);
 	} else {
 		surf->db_stencil_base = offset;
 		/* DRM 2.6.18 allows the INVALID format to disable stencil.
 		 * Older kernels are out of luck. */
 		surf->db_stencil_info = rctx->screen->b.info.drm_minor >= 18 ?
 					S_028044_FORMAT(V_028044_STENCIL_INVALID) :
 					S_028044_FORMAT(V_028044_STENCIL_8);
 	}
 
-	/* use htile only for first level */
-	if (rtex->htile_offset && !level) {
+	if (r600_htile_enabled(rtex, level)) {
 		uint64_t va = rtex->resource.gpu_address + rtex->htile_offset;
 		surf->db_htile_data_base = va >> 8;
 		surf->db_htile_surface = S_028ABC_HTILE_WIDTH(1) |
 					 S_028ABC_HTILE_HEIGHT(1) |
 					 S_028ABC_FULL_CACHE(1);
 		surf->db_z_info |= S_028040_TILE_SURFACE_ENABLE(1);
 		surf->db_preload_control = 0;
 	}
 
 	surf->depth_initialized = true;
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 79505d5..783d8c8 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -436,22 +436,21 @@ static void r600_clear(struct pipe_context *ctx, unsigned buffers,
 	if (fb->zsbuf && (buffers & PIPE_CLEAR_DEPTH)) {
 		struct r600_texture *rtex;
 		unsigned level = fb->zsbuf->u.tex.level;
 
 		rtex = (struct r600_texture*)fb->zsbuf->texture;
 
 		/* We can't use hyperz fast clear if each slice of a texture
 		 * array are clear to different value. To simplify code just
 		 * disable fast clear for texture array.
 		 */
-		/* Only use htile for first level */
-		if (rtex->htile_offset && !level &&
+		if (r600_htile_enabled(rtex, level) &&
                    fb->zsbuf->u.tex.first_layer == 0 &&
                    fb->zsbuf->u.tex.last_layer == util_max_layer(&rtex->resource.b.b, level)) {
 			if (rtex->depth_clear_value != depth) {
 				rtex->depth_clear_value = depth;
 				r600_mark_atom_dirty(rctx, &rctx->db_state.atom);
 			}
 			rctx->db_misc_state.htile_clear = true;
 			r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
 		}
 	}
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 300dbe8..c21e8da 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1053,22 +1053,21 @@ static void r600_init_depth_surface(struct r600_context *rctx,
 	format = r600_translate_dbformat(surf->base.format);
 	assert(format != ~0);
 
 	surf->db_depth_info = S_028010_ARRAY_MODE(array_mode) | S_028010_FORMAT(format);
 	surf->db_depth_base = offset >> 8;
 	surf->db_depth_view = S_028004_SLICE_START(surf->base.u.tex.first_layer) |
 			      S_028004_SLICE_MAX(surf->base.u.tex.last_layer);
 	surf->db_depth_size = S_028000_PITCH_TILE_MAX(pitch) | S_028000_SLICE_TILE_MAX(slice);
 	surf->db_prefetch_limit = (rtex->surface.u.legacy.level[level].nblk_y / 8) - 1;
 
-	/* use htile only for first level */
-	if (rtex->htile_offset && !level) {
+	if (r600_htile_enabled(rtex, level)) {
 		surf->db_htile_data_base = rtex->htile_offset >> 8;
 		surf->db_htile_surface = S_028D24_HTILE_WIDTH(1) |
 					 S_028D24_HTILE_HEIGHT(1) |
 					 S_028D24_FULL_CACHE(1);
 		/* preload is not working properly on r6xx/r7xx */
 		surf->db_depth_info |= S_028010_TILE_SURFACE_ENABLE(1);
 	}
 
 	surf->depth_initialized = true;
 }
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 7a311ea..27373c3 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -996,20 +996,33 @@ r600_can_sample_zs(struct r600_texture *tex, bool stencil_sampler)
 	return (stencil_sampler && tex->can_sample_s) ||
 	       (!stencil_sampler && tex->can_sample_z);
 }
 
 static inline bool
 vi_dcc_enabled(struct r600_texture *tex, unsigned level)
 {
 	return tex->dcc_offset && level < tex->surface.num_dcc_levels;
 }
 
+static inline bool
+r600_htile_enabled(struct r600_texture *tex, unsigned level)
+{
+	return tex->htile_offset && level == 0;
+}
+
+static inline bool
+vi_tc_compat_htile_enabled(struct r600_texture *tex, unsigned level)
+{
+	assert(!tex->tc_compatible_htile || tex->htile_offset);
+	return tex->tc_compatible_htile && level == 0;
+}
+
 #define COMPUTE_DBG(rscreen, fmt, args...) \
 	do { \
 		if ((rscreen->b.debug_flags & DBG_COMPUTE)) fprintf(stderr, fmt, ##args); \
 	} while (0);
 
 #define R600_ERR(fmt, args...) \
 	fprintf(stderr, "EE %s:%d %s - " fmt, __FILE__, __LINE__, __func__, ##args)
 
 /* For MSAA sample positions. */
 #define FILL_SREG(s0x, s0y, s1x, s1y, s2x, s2y, s3x, s3y)  \
diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index 734eeaa..378441a 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -367,36 +367,37 @@ si_decompress_depth(struct si_context *sctx,
 			first_layer, last_layer,
 			0, u_max_sample(&tex->resource.b.b));
 
 		if (copy_planes & PIPE_MASK_Z)
 			tex->dirty_level_mask &= ~fully_copied_levels;
 		if (copy_planes & PIPE_MASK_S)
 			tex->stencil_dirty_level_mask &= ~fully_copied_levels;
 	}
 
 	if (inplace_planes) {
-		if (!tex->tc_compatible_htile) {
+		bool tc_compat_htile = vi_tc_compat_htile_enabled(tex, first_level);
+
+		if (!tc_compat_htile) {
 			si_blit_decompress_zs_in_place(
 						sctx, tex,
 						levels_z, levels_s,
 						first_layer, last_layer);
 		}
 
 		/* Only in-place decompression needs to flush DB caches, or
 		 * when we don't decompress but TC-compatible planes are dirty.
 		 */
 		si_make_DB_shader_coherent(sctx, tex->resource.b.b.nr_samples,
 					   inplace_planes & PIPE_MASK_S,
-					   tex->tc_compatible_htile &&
-					   first_level == 0);
+					   tc_compat_htile);
 
-		if (tex->tc_compatible_htile) {
+		if (tc_compat_htile) {
 			/* Only clear the mask that we are flushing, because
 			 * si_make_DB_shader_coherent() can treat depth and
 			 * stencil differently.
 			 */
 			if (inplace_planes & PIPE_MASK_Z)
 				tex->dirty_level_mask &= ~levels_z;
 			if (inplace_planes & PIPE_MASK_S)
 				tex->stencil_dirty_level_mask &= ~levels_s;
 		}
 	}
@@ -839,22 +840,22 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers,
 
 			if (!fb->cbufs[i])
 				continue;
 
 			tex = (struct r600_texture *)fb->cbufs[i]->texture;
 			if (tex->fmask.size == 0)
 				tex->dirty_level_mask &= ~(1 << fb->cbufs[i]->u.tex.level);
 		}
 	}
 
-	if (zstex && zstex->htile_offset &&
-	    zsbuf->u.tex.level == 0 &&
+	if (zstex &&
+	    r600_htile_enabled(zstex, zsbuf->u.tex.level) &&
 	    zsbuf->u.tex.first_layer == 0 &&
 	    zsbuf->u.tex.last_layer == util_max_layer(&zstex->resource.b.b, 0)) {
 		/* TC-compatible HTILE only supports depth clears to 0 or 1. */
 		if (buffers & PIPE_CLEAR_DEPTH &&
 		    (!zstex->tc_compatible_htile ||
 		     depth == 0 || depth == 1)) {
 			/* Need to disable EXPCLEAR temporarily if clearing
 			 * to a new value. */
 			if (!zstex->depth_cleared || zstex->depth_clear_value != depth) {
 				sctx->db_depth_disable_expclear = true;
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 7215972..7d28d35 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -322,21 +322,21 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen,
 		if (vi_dcc_enabled(tex, first_level)) {
 			meta_va = (!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) +
 				  tex->dcc_offset;
 
 			if (sscreen->b.chip_class == VI) {
 				meta_va += base_level_info->dcc_offset;
 				assert(base_level_info->mode == RADEON_SURF_MODE_2D);
 			}
 
 			meta_va |= (uint32_t)tex->surface.tile_swizzle << 8;
-		} else if (tex->tc_compatible_htile && first_level == 0) {
+		} else if (vi_tc_compat_htile_enabled(tex, first_level)) {
 			meta_va = tex->resource.gpu_address + tex->htile_offset;
 		}
 
 		if (meta_va) {
 			state[6] |= S_008F28_COMPRESSION_EN(1);
 			state[7] = meta_va >> 8;
 		}
 	}
 
 	if (sscreen->b.chip_class >= GFX9) {
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index bb533d7..e571201 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2320,22 +2320,21 @@ static void si_init_depth_surface(struct si_context *sctx,
 			 S_028038_SW_MODE(rtex->surface.u.gfx9.surf.swizzle_mode) |
 			 S_028038_MAXMIP(rtex->resource.b.b.last_level);
 		s_info = S_02803C_FORMAT(stencil_format) |
 			 S_02803C_SW_MODE(rtex->surface.u.gfx9.stencil.swizzle_mode);
 		surf->db_z_info2 = S_028068_EPITCH(rtex->surface.u.gfx9.surf.epitch);
 		surf->db_stencil_info2 = S_02806C_EPITCH(rtex->surface.u.gfx9.stencil.epitch);
 		surf->db_depth_view |= S_028008_MIPID(level);
 		surf->db_depth_size = S_02801C_X_MAX(rtex->resource.b.b.width0 - 1) |
 				      S_02801C_Y_MAX(rtex->resource.b.b.height0 - 1);
 
-		/* Only use HTILE for the first level. */
-		if (rtex->htile_offset && !level) {
+		if (r600_htile_enabled(rtex, level)) {
 			z_info |= S_028038_TILE_SURFACE_ENABLE(1) |
 				  S_028038_ALLOW_EXPCLEAR(1);
 
 			if (rtex->tc_compatible_htile) {
 				unsigned max_zplanes = 4;
 
 				if (rtex->db_render_format == PIPE_FORMAT_Z16_UNORM &&
 				    rtex->resource.b.b.nr_samples > 1)
 					max_zplanes = 2;
 
@@ -2399,22 +2398,21 @@ static void si_init_depth_surface(struct si_context *sctx,
 			z_info |= S_028040_TILE_MODE_INDEX(tile_mode_index);
 			tile_mode_index = si_tile_mode_index(rtex, level, true);
 			s_info |= S_028044_TILE_MODE_INDEX(tile_mode_index);
 		}
 
 		surf->db_depth_size = S_028058_PITCH_TILE_MAX((levelinfo->nblk_x / 8) - 1) |
 				      S_028058_HEIGHT_TILE_MAX((levelinfo->nblk_y / 8) - 1);
 		surf->db_depth_slice = S_02805C_SLICE_TILE_MAX((levelinfo->nblk_x *
 								levelinfo->nblk_y) / 64 - 1);
 
-		/* Only use HTILE for the first level. */
-		if (rtex->htile_offset && !level) {
+		if (r600_htile_enabled(rtex, level)) {
 			z_info |= S_028040_TILE_SURFACE_ENABLE(1) |
 				  S_028040_ALLOW_EXPCLEAR(1);
 
 			if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
 				/* Workaround: For a not yet understood reason, the
 				 * combination of MSAA, fast stencil clear and stencil
 				 * decompress messes with subsequent stencil buffer
 				 * uses. Problem was reproduced on Verde, Bonaire,
 				 * Tonga, and Carrizo.
 				 *
@@ -2661,21 +2659,21 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 	}
 
 	if (state->zsbuf) {
 		surf = (struct r600_surface*)state->zsbuf;
 		rtex = (struct r600_texture*)surf->base.texture;
 
 		if (!surf->depth_initialized) {
 			si_init_depth_surface(sctx, surf);
 		}
 
-		if (rtex->tc_compatible_htile && !surf->base.u.tex.level)
+		if (vi_tc_compat_htile_enabled(rtex, surf->base.u.tex.level))
 			sctx->framebuffer.DB_has_shader_readable_metadata = true;
 
 		r600_context_add_resource_size(ctx, surf->base.texture);
 	}
 
 	si_update_poly_offset_state(sctx);
 	si_mark_atom_dirty(sctx, &sctx->cb_render_state);
 	si_mark_atom_dirty(sctx, &sctx->framebuffer.atom);
 
 	if (sctx->framebuffer.any_dst_linear != old_any_dst_linear)
-- 
2.7.4



More information about the mesa-dev mailing list