agx: Add helper returning if a descriptor crawl is needed
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Thu, 17 Aug 2023 13:26:55 +0000 (09:26 -0400)
committerMarge Bot <emma+marge@anholt.net>
Wed, 23 Aug 2023 15:06:55 +0000 (15:06 +0000)
For agx_nir_lower_texture to lower to a descriptor crawl, the driver needs to
make sure the address of the descriptor is available. This means a slightly
different code path should be used in the driver. Rather than the drivers
needing to know what exactly will be lowered, add a helper in the same file as
agx_nir_lower_texture that returns whether descriptor-based lowering will be
needed so the driver can act appropriately.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24847>

src/asahi/compiler/agx_compile.h
src/asahi/compiler/agx_nir_lower_texture.c

index 7cf37d3..5a16f7d 100644 (file)
@@ -219,6 +219,8 @@ void agx_preprocess_nir(nir_shader *nir, bool support_lod_bias,
 
 bool agx_nir_lower_discard_zs_emit(nir_shader *s);
 
+bool agx_nir_needs_texture_crawl(nir_instr *instr);
+
 void agx_compile_shader_nir(nir_shader *nir, struct agx_shader_key *key,
                             struct util_debug_callback *debug,
                             struct util_dynarray *binary,
index 1b5b3ed..43b5bf5 100644 (file)
@@ -892,3 +892,55 @@ agx_nir_lower_multisampled_image_store(nir_shader *s)
       s, lower_multisampled_store,
       nir_metadata_block_index | nir_metadata_dominance, NULL);
 }
+
+/*
+ * Given a non-bindless instruction, return whether agx_nir_lower_texture will
+ * lower it to something involving a descriptor crawl. This requires the driver
+ * to lower the instruction to bindless before calling agx_nir_lower_texture.
+ * The implementation just enumerates the cases handled in this file.
+ */
+bool
+agx_nir_needs_texture_crawl(nir_instr *instr)
+{
+   if (instr->type == nir_instr_type_intrinsic) {
+      nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
+
+      switch (intr->intrinsic) {
+      /* Queries, atomics always become a crawl */
+      case nir_intrinsic_image_size:
+      case nir_intrinsic_image_deref_size:
+      case nir_intrinsic_image_atomic:
+      case nir_intrinsic_image_deref_atomic:
+      case nir_intrinsic_image_atomic_swap:
+      case nir_intrinsic_image_deref_atomic_swap:
+         return true;
+
+      /* Multisampled stores need a crawl, others do not */
+      case nir_intrinsic_image_store:
+      case nir_intrinsic_image_deref_store:
+         return nir_intrinsic_image_dim(intr) == GLSL_SAMPLER_DIM_MS;
+
+      /* Loads do not need a crawl, even from buffers */
+      default:
+         return false;
+      }
+   } else if (instr->type == nir_instr_type_tex) {
+      nir_tex_instr *tex = nir_instr_as_tex(instr);
+
+      /* Array textures get clamped to their size via txs */
+      if (tex->is_array)
+         return true;
+
+      switch (tex->op) {
+      /* Queries always become a crawl */
+      case nir_texop_txs:
+         return true;
+
+      /* Buffer textures need their format read */
+      default:
+         return tex->sampler_dim == GLSL_SAMPLER_DIM_BUF;
+      }
+   }
+
+   return false;
+}