Mesa (master): nir_lower_readonly_images_to_tex: Support non-CL semantics

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Apr 24 01:11:09 UTC 2021


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

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Tue Apr 20 08:08:32 2021 -0700

nir_lower_readonly_images_to_tex: Support non-CL semantics

For non-CL, intrinsic access isn't set, because the image type doesn't
have access qualifier. Instead, the access qualifier is set on the variable.

So, add a mode to this pass which can chase back to the variable in addition
to the intrinsic access. Also, update the variable type and the deref chain
types so everything is consistent, that the tex is accessing a sampler. Note
we can't do this for CL, because void-typed samplers don't exist.

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10356>

---

 src/compiler/nir/nir.h                             |  2 +-
 .../nir/nir_lower_readonly_images_to_tex.c         | 71 +++++++++++++++++++---
 src/gallium/frontends/clover/nir/invocation.cpp    |  2 +-
 src/microsoft/clc/clc_compiler.c                   |  2 +-
 4 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 49d0e457610..e827b99055a 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -4847,7 +4847,7 @@ typedef struct nir_lower_tex_options {
 bool nir_lower_tex(nir_shader *shader,
                    const nir_lower_tex_options *options);
 
-bool nir_lower_readonly_images_to_tex(nir_shader *shader);
+bool nir_lower_readonly_images_to_tex(nir_shader *shader, bool per_variable);
 
 enum nir_lower_non_uniform_access_type {
    nir_lower_non_uniform_ubo_access     = (1 << 0),
diff --git a/src/compiler/nir/nir_lower_readonly_images_to_tex.c b/src/compiler/nir/nir_lower_readonly_images_to_tex.c
index 5232f9417f0..b3c94b77e94 100644
--- a/src/compiler/nir/nir_lower_readonly_images_to_tex.c
+++ b/src/compiler/nir/nir_lower_readonly_images_to_tex.c
@@ -24,8 +24,44 @@
 #include "nir.h"
 #include "nir_builder.h"
 
+static const struct glsl_type *
+get_sampler_type_for_image(const struct glsl_type *type)
+{
+   if (glsl_type_is_array(type)) {
+      const struct glsl_type *elem_type =
+         get_sampler_type_for_image(glsl_get_array_element(type));
+      return glsl_array_type(elem_type, glsl_get_length(type), 0 /*explicit size*/);
+   }
+
+   assert((glsl_type_is_image(type)));
+   return glsl_sampler_type(glsl_get_sampler_dim(type), false,
+                            glsl_sampler_type_is_array(type),
+                            glsl_get_sampler_result_type(type));
+}
+
+static void
+replace_image_type_with_sampler(nir_deref_instr *deref)
+{
+   const struct glsl_type *type = deref->type;
+
+   /* If we've already chased up the deref chain this far from a different intrinsic, we're done */
+   if (glsl_type_is_sampler(glsl_without_array(type)))
+      return;
+
+   deref->type = get_sampler_type_for_image(type);
+   if (deref->deref_type == nir_deref_type_var) {
+      type = deref->var->type;
+      if (!glsl_type_is_sampler(glsl_without_array(type)))
+         deref->var->type = get_sampler_type_for_image(type);
+   } else {
+      nir_deref_instr *parent = nir_deref_instr_parent(deref);
+      if (parent)
+         replace_image_type_with_sampler(parent);
+   }
+}
+
 static bool
-lower_readonly_images_to_tex_impl(nir_function_impl *impl)
+lower_readonly_images_to_tex_impl(nir_function_impl *impl, bool per_variable)
 {
    bool progress = false;
 
@@ -55,6 +91,9 @@ lower_readonly_images_to_tex_impl(nir_function_impl *impl)
             continue;
          }
 
+         nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
+         nir_variable *var = nir_deref_instr_get_variable(deref);
+
          /* In CL 1.2, images are required to be either read-only or
           * write-only.  We can always translate the read-only image ops to
           * texture ops.  In CL 2.0 (and an extension), the ability is added
@@ -62,11 +101,15 @@ lower_readonly_images_to_tex_impl(nir_function_impl *impl)
           * allowed on read-only images.  As long as we only lower read-only
           * images to texture ops, everything should stay consistent.
           */
-         if (!(nir_intrinsic_access(intrin) & ACCESS_NON_WRITEABLE))
+         enum gl_access_qualifier access = 0;
+         if (per_variable) {
+            if (var)
+               access = var->data.access;
+         } else
+            access = nir_intrinsic_access(intrin);
+         if (!(access & ACCESS_NON_WRITEABLE))
             continue;
 
-         nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
-
          b.cursor = nir_instr_remove(&intrin->instr);
 
          nir_tex_instr *tex = nir_tex_instr_create(b.shader, num_srcs);
@@ -83,6 +126,11 @@ lower_readonly_images_to_tex_impl(nir_function_impl *impl)
 
          tex->src[0].src_type = nir_tex_src_texture_deref;
          tex->src[0].src = nir_src_for_ssa(&deref->dest.ssa);
+         
+         if (per_variable) {
+            assert(var);
+            replace_image_type_with_sampler(deref);
+         }
 
          switch (intrin->intrinsic) {
          case nir_intrinsic_image_deref_load: {
@@ -147,14 +195,23 @@ lower_readonly_images_to_tex_impl(nir_function_impl *impl)
    return progress;
 }
 
-/** Lowers image ops to texture ops for read-only images */
+/** Lowers image ops to texture ops for read-only images
+  * 
+  * If per_variable is set:
+  * - Variable access is used to indicate read-only instead of intrinsic access
+  * - Variable/deref types will be changed from image types to sampler types
+  * 
+  * per_variable should not be set for OpenCL, because all image types will be void-returning,
+  * and there is no corresponding valid sampler type, and it will collide with the "bare" sampler type.
+  */
 bool
-nir_lower_readonly_images_to_tex(nir_shader *shader)
+nir_lower_readonly_images_to_tex(nir_shader *shader, bool per_variable)
 {
+   assert(shader->info.stage != MESA_SHADER_KERNEL || !per_variable);
    bool progress = false;
 
    nir_foreach_function(function, shader) {
-      if (function->impl && lower_readonly_images_to_tex_impl(function->impl))
+      if (function->impl && lower_readonly_images_to_tex_impl(function->impl, per_variable))
          progress = true;
    }
 
diff --git a/src/gallium/frontends/clover/nir/invocation.cpp b/src/gallium/frontends/clover/nir/invocation.cpp
index 0c24a553f4b..ad9db3baf90 100644
--- a/src/gallium/frontends/clover/nir/invocation.cpp
+++ b/src/gallium/frontends/clover/nir/invocation.cpp
@@ -504,7 +504,7 @@ module clover::nir::spirv_to_nir(const module &mod, const device &dev,
                  glsl_get_cl_type_size_align);
 
       NIR_PASS_V(nir, nir_opt_deref);
-      NIR_PASS_V(nir, nir_lower_readonly_images_to_tex);
+      NIR_PASS_V(nir, nir_lower_readonly_images_to_tex, false);
       NIR_PASS_V(nir, clover_nir_lower_images);
       NIR_PASS_V(nir, nir_lower_memcpy);
 
diff --git a/src/microsoft/clc/clc_compiler.c b/src/microsoft/clc/clc_compiler.c
index de1449abe0e..1422b32625c 100644
--- a/src/microsoft/clc/clc_compiler.c
+++ b/src/microsoft/clc/clc_compiler.c
@@ -1284,7 +1284,7 @@ clc_to_dxil(struct clc_context *ctx,
    }
 
    // Needs to come before lower_explicit_io
-   NIR_PASS_V(nir, nir_lower_readonly_images_to_tex);
+   NIR_PASS_V(nir, nir_lower_readonly_images_to_tex, false);
    struct clc_image_lower_context image_lower_context = { metadata, &srv_id, &uav_id };
    NIR_PASS_V(nir, clc_lower_images, &image_lower_context);
    NIR_PASS_V(nir, clc_lower_nonnormalized_samplers, int_sampler_states);



More information about the mesa-commit mailing list