diff options
author | Rob Clark <[email protected]> | 2020-06-11 11:00:55 -0700 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-06-11 21:59:54 +0000 |
commit | 562aaea07cc876a0a33fa3150659ceff9ee161f0 (patch) | |
tree | fde67132ce0b829445ca82a54af39b5ae1944c57 | |
parent | 4cabc25fa4c89c29e0338f00b20c6e87b087bcc2 (diff) |
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 <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5431>
-rw-r--r-- | src/freedreno/ir3/ir3_compiler_nir.c | 8 | ||||
-rw-r--r-- | 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 @@ -111,6 +111,46 @@ has_src(nir_tex_instr *tex, nir_tex_src_type type) } 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) { bool progress = false; @@ -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); |