Mesa (master): freedreno/ir3: respect tex prefetch limits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 11 22:24:44 UTC 2020


Module: Mesa
Branch: master
Commit: 562aaea07cc876a0a33fa3150659ceff9ee161f0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=562aaea07cc876a0a33fa3150659ceff9ee161f0

Author: Rob Clark <robdclark at chromium.org>
Date:   Thu Jun 11 11:00:55 2020 -0700

freedreno/ir3: respect tex prefetch limits

Refactor a bit the limit checking in the bindless case, and add tex/samp
limit checking for the non-bindless case, to ensure we do not try to
prefetch textures which cannot be encoded in the # of bits available.

Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5431>

---

 src/freedreno/ir3/ir3_compiler_nir.c           |  8 +++-
 src/freedreno/ir3/ir3_nir_lower_tex_prefetch.c | 64 ++++++++++++++++++--------
 2 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index ff699a8925a..19633077118 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -3446,10 +3446,16 @@ collect_tex_prefetches(struct ir3_context *ctx, struct ir3 *ir)
 				fetch->dst = instr->regs[0]->num;
 				fetch->src = instr->prefetch.input_offset;
 
+				/* These are the limits on a5xx/a6xx, we might need to
+				 * revisit if SP_FS_PREFETCH[n] changes on later gens:
+				 */
+				assert(fetch->dst <= 0x3f);
+				assert(fetch->tex_id <= 0x1f);
+				assert(fetch->samp_id < 0xf);
+
 				ctx->so->total_in =
 					MAX2(ctx->so->total_in, instr->prefetch.input_offset + 2);
 
-				/* Disable half precision until supported. */
 				fetch->half_precision = !!(instr->regs[0]->flags & IR3_REG_HALF);
 
 				/* Remove the prefetch placeholder instruction: */
diff --git a/src/freedreno/ir3/ir3_nir_lower_tex_prefetch.c b/src/freedreno/ir3/ir3_nir_lower_tex_prefetch.c
index 543b40bfb6c..38474749955 100644
--- a/src/freedreno/ir3/ir3_nir_lower_tex_prefetch.c
+++ b/src/freedreno/ir3/ir3_nir_lower_tex_prefetch.c
@@ -110,6 +110,46 @@ has_src(nir_tex_instr *tex, nir_tex_src_type type)
 	return nir_tex_instr_src_index(tex, type) > 0;
 }
 
+static bool
+ok_bindless_src(nir_tex_instr *tex, nir_tex_src_type type)
+{
+	int idx = nir_tex_instr_src_index(tex, type);
+	assert(idx >= 0);
+	nir_intrinsic_instr *bindless = ir3_bindless_resource(tex->src[idx].src);
+
+	/* TODO from SP_FS_BINDLESS_PREFETCH[n] it looks like this limit should
+	 * be 1<<8 ?
+	 */
+	return nir_src_is_const(bindless->src[0]) &&
+			(nir_src_as_uint(bindless->src[0]) < (1 << 16));
+}
+
+/**
+ * Check that we will be able to encode the tex/samp parameters
+ * successfully.  These limits are based on the layout of
+ * SP_FS_PREFETCH[n] and SP_FS_BINDLESS_PREFETCH[n], so at some
+ * point (if those regs changes) they may become generation
+ * specific.
+ */
+static bool
+ok_tex_samp(nir_tex_instr *tex)
+{
+	if (has_src(tex, nir_tex_src_texture_handle)) {
+		/* bindless case: */
+
+		assert(has_src(tex, nir_tex_src_sampler_handle));
+
+		return ok_bindless_src(tex, nir_tex_src_texture_handle) &&
+				ok_bindless_src(tex, nir_tex_src_sampler_handle);
+	} else {
+		assert(!has_src(tex, nir_tex_src_texture_offset));
+		assert(!has_src(tex, nir_tex_src_sampler_offset));
+
+		return (tex->texture_index <= 0x1f) &&
+				(tex->sampler_index <= 0xf);
+	}
+}
+
 static bool
 lower_tex_prefetch_block(nir_block *block)
 {
@@ -135,30 +175,14 @@ lower_tex_prefetch_block(nir_block *block)
 				has_src(tex, nir_tex_src_sampler_offset))
 			continue;
 
-		/* Disallow indirect or large bindless handles */
-		int idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_handle);
-		if (idx >= 0) {
-			nir_intrinsic_instr *bindless =
-				ir3_bindless_resource(tex->src[idx].src);
-			if (!nir_src_is_const(bindless->src[0]) ||
-				nir_src_as_uint(bindless->src[0]) >= (1 << 16))
-				continue;
-		}
-
-		idx = nir_tex_instr_src_index(tex, nir_tex_src_sampler_handle);
-		if (idx >= 0) {
-			nir_intrinsic_instr *bindless =
-				ir3_bindless_resource(tex->src[idx].src);
-			if (!nir_src_is_const(bindless->src[0]) ||
-				nir_src_as_uint(bindless->src[0]) >= (1 << 16))
-				continue;
-		}
-
 		/* only prefetch for simple 2d tex fetch case */
 		if (tex->sampler_dim != GLSL_SAMPLER_DIM_2D || tex->is_array)
 			continue;
 
-		idx = nir_tex_instr_src_index(tex, nir_tex_src_coord);
+		if (!ok_tex_samp(tex))
+			continue;
+
+		int idx = nir_tex_instr_src_index(tex, nir_tex_src_coord);
 		/* First source should be the sampling coordinate. */
 		nir_tex_src *coord = &tex->src[idx];
 		debug_assert(coord->src.is_ssa);



More information about the mesa-commit mailing list