From 0a6dd797ea7fef18eb9e4665bb442e02c4340be0 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Tue, 4 Jul 2023 15:06:50 +0300 Subject: [PATCH] nir/opt_shrink_vectors: enable sparse intrinsics shrinking Image sparse loads can be stripped from their sparse component if unused and turned into non sparse variants. Texture sparse accesses can also be turned off if unused. Signed-off-by: Lionel Landwerlin Reviewed-by: Rhys Perry Part-of: --- src/compiler/nir/nir_opt_shrink_vectors.c | 75 ++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/src/compiler/nir/nir_opt_shrink_vectors.c b/src/compiler/nir/nir_opt_shrink_vectors.c index 5937f1d..2341542 100644 --- a/src/compiler/nir/nir_opt_shrink_vectors.c +++ b/src/compiler/nir/nir_opt_shrink_vectors.c @@ -90,6 +90,37 @@ shrink_dest_to_read_mask(nir_ssa_def *def) return false; } +static bool +shrink_intrinsic_to_non_sparse(nir_intrinsic_instr *instr) +{ + unsigned mask = nir_ssa_def_components_read(&instr->dest.ssa); + int last_bit = util_last_bit(mask); + + /* If the sparse component is used, do nothing. */ + if (last_bit == instr->dest.ssa.num_components) + return false; + + instr->dest.ssa.num_components -= 1; + instr->num_components = instr->dest.ssa.num_components; + + /* Switch to the non-sparse intrinsic. */ + switch (instr->intrinsic) { + case nir_intrinsic_image_sparse_load: + instr->intrinsic = nir_intrinsic_image_load; + break; + case nir_intrinsic_bindless_image_sparse_load: + instr->intrinsic = nir_intrinsic_bindless_image_load; + break; + case nir_intrinsic_image_deref_sparse_load: + instr->intrinsic = nir_intrinsic_image_deref_load; + break; + default: + break; + } + + return true; +} + static void reswizzle_alu_uses(nir_ssa_def *def, uint8_t *reswizzle) { @@ -267,22 +298,43 @@ opt_shrink_vectors_intrinsic(nir_builder *b, nir_intrinsic_instr *instr) case nir_intrinsic_load_global: case nir_intrinsic_load_global_constant: case nir_intrinsic_load_kernel_input: - case nir_intrinsic_load_scratch: - break; - default: - return false; - } + case nir_intrinsic_load_scratch: { + /* Must be a vectorized intrinsic that we can resize. */ + assert(instr->num_components != 0); - /* Must be a vectorized intrinsic that we can resize. */ - assert(instr->num_components != 0); + /* Trim the dest to the used channels */ + if (!shrink_dest_to_read_mask(&instr->dest.ssa)) + return false; - /* Trim the dest to the used channels */ - if (shrink_dest_to_read_mask(&instr->dest.ssa)) { instr->num_components = instr->dest.ssa.num_components; return true; } + case nir_intrinsic_image_sparse_load: + case nir_intrinsic_bindless_image_sparse_load: + case nir_intrinsic_image_deref_sparse_load: + return shrink_intrinsic_to_non_sparse(instr); + default: + return false; + } +} - return false; +static bool +opt_shrink_vectors_tex(nir_builder *b, nir_tex_instr *tex) +{ + if (!tex->is_sparse) + return false; + + unsigned mask = nir_ssa_def_components_read(&tex->dest.ssa); + int last_bit = util_last_bit(mask); + + /* If the sparse component is used, do nothing. */ + if (last_bit == tex->dest.ssa.num_components) + return false; + + tex->dest.ssa.num_components -= 1; + tex->is_sparse = false; + + return true; } static bool @@ -455,6 +507,9 @@ opt_shrink_vectors_instr(nir_builder *b, nir_instr *instr) case nir_instr_type_alu: return opt_shrink_vectors_alu(b, nir_instr_as_alu(instr)); + case nir_instr_type_tex: + return opt_shrink_vectors_tex(b, nir_instr_as_tex(instr)); + case nir_instr_type_intrinsic: return opt_shrink_vectors_intrinsic(b, nir_instr_as_intrinsic(instr)); -- 2.7.4