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

Author: Jason Ekstrand <[email protected]>
Date:   Mon Aug 31 18:09:44 2020 -0500

clover/nir: Add an image lowering pass

Reviewed-by: Dave Airlie <[email protected]>
Reviewed-by: Karol Herbst <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7069>

---

 src/gallium/frontends/clover/nir/invocation.cpp | 155 ++++++++++++++++++++++++
 1 file changed, 155 insertions(+)

diff --git a/src/gallium/frontends/clover/nir/invocation.cpp 
b/src/gallium/frontends/clover/nir/invocation.cpp
index 6e57301a349..bb7a7556dba 100644
--- a/src/gallium/frontends/clover/nir/invocation.cpp
+++ b/src/gallium/frontends/clover/nir/invocation.cpp
@@ -83,6 +83,158 @@ clover_arg_size_align(const glsl_type *type, unsigned 
*size, unsigned *align)
    }
 }
 
+static bool
+clover_nir_lower_images(nir_shader *shader)
+{
+   nir_function_impl *impl = nir_shader_get_entrypoint(shader);
+
+   ASSERTED int last_loc = -1;
+   int num_rd_images = 0, num_wr_images = 0, num_samplers = 0;
+   nir_foreach_uniform_variable(var, shader) {
+      if (glsl_type_is_image(var->type) || glsl_type_is_sampler(var->type)) {
+         /* Assume they come in order */
+         assert(var->data.location > last_loc);
+         last_loc = var->data.location;
+      }
+
+      /* TODO: Constant samplers */
+      if (var->type == glsl_bare_sampler_type()) {
+         var->data.driver_location = num_samplers++;
+      } else if (glsl_type_is_image(var->type)) {
+         if (var->data.access & ACCESS_NON_WRITEABLE)
+            var->data.driver_location = num_rd_images++;
+         else
+            var->data.driver_location = num_wr_images++;
+      } else {
+         /* CL shouldn't have any sampled images */
+         assert(!glsl_type_is_sampler(var->type));
+      }
+   }
+   shader->info.num_textures = num_rd_images;
+   shader->info.textures_used = (1 << num_rd_images) - 1;
+   shader->info.num_images = num_wr_images;
+
+   nir_builder b;
+   nir_builder_init(&b, impl);
+
+   bool progress = false;
+   nir_foreach_block_reverse(block, impl) {
+      nir_foreach_instr_reverse_safe(instr, block) {
+         switch (instr->type) {
+         case nir_instr_type_deref: {
+            nir_deref_instr *deref = nir_instr_as_deref(instr);
+            if (deref->deref_type != nir_deref_type_var)
+               break;
+
+            if (!glsl_type_is_image(deref->type) &&
+                !glsl_type_is_sampler(deref->type))
+               break;
+
+            b.cursor = nir_instr_remove(&deref->instr);
+            nir_ssa_def *loc =
+               nir_imm_intN_t(&b, deref->var->data.driver_location,
+                                  deref->dest.ssa.bit_size);
+            nir_ssa_def_rewrite_uses(&deref->dest.ssa, nir_src_for_ssa(loc));
+            progress = true;
+            break;
+         }
+
+         case nir_instr_type_tex: {
+            nir_tex_instr *tex = nir_instr_as_tex(instr);
+            unsigned count = 0;
+            for (unsigned i = 0; i < tex->num_srcs; i++) {
+               if (tex->src[i].src_type == nir_tex_src_texture_deref ||
+                   tex->src[i].src_type == nir_tex_src_sampler_deref) {
+                  nir_deref_instr *deref = nir_src_as_deref(tex->src[i].src);
+                  if (deref->deref_type == nir_deref_type_var) {
+                     /* In this case, we know the actual variable */
+                     if (tex->src[i].src_type == nir_tex_src_texture_deref)
+                        tex->texture_index = deref->var->data.driver_location;
+                     else
+                        tex->sampler_index = deref->var->data.driver_location;
+                     /* This source gets discarded */
+                     nir_instr_rewrite_src(&tex->instr, &tex->src[i].src,
+                                           NIR_SRC_INIT);
+                     continue;
+                  } else {
+                     assert(tex->src[i].src.is_ssa);
+                     b.cursor = nir_before_instr(&tex->instr);
+                     /* Back-ends expect a 32-bit thing, not 64-bit */
+                     nir_ssa_def *offset = nir_u2u32(&b, tex->src[i].src.ssa);
+                     if (tex->src[i].src_type == nir_tex_src_texture_deref)
+                        tex->src[count].src_type = nir_tex_src_texture_offset;
+                     else
+                        tex->src[count].src_type = nir_tex_src_sampler_offset;
+                     nir_instr_rewrite_src(&tex->instr, &tex->src[count].src,
+                                           nir_src_for_ssa(offset));
+                  }
+               } else {
+                  /* If we've removed a source, move this one down */
+                  if (count != i) {
+                     assert(count < i);
+                     tex->src[count].src_type = tex->src[i].src_type;
+                     nir_instr_move_src(&tex->instr, &tex->src[count].src,
+                                        &tex->src[i].src);
+                  }
+               }
+               count++;
+            }
+            tex->num_srcs = count;
+            progress = true;
+            break;
+         }
+
+         case nir_instr_type_intrinsic: {
+            nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+            switch (intrin->intrinsic) {
+            case nir_intrinsic_image_deref_load:
+            case nir_intrinsic_image_deref_store:
+            case nir_intrinsic_image_deref_atomic_add:
+            case nir_intrinsic_image_deref_atomic_imin:
+            case nir_intrinsic_image_deref_atomic_umin:
+            case nir_intrinsic_image_deref_atomic_imax:
+            case nir_intrinsic_image_deref_atomic_umax:
+            case nir_intrinsic_image_deref_atomic_and:
+            case nir_intrinsic_image_deref_atomic_or:
+            case nir_intrinsic_image_deref_atomic_xor:
+            case nir_intrinsic_image_deref_atomic_exchange:
+            case nir_intrinsic_image_deref_atomic_comp_swap:
+            case nir_intrinsic_image_deref_atomic_fadd:
+            case nir_intrinsic_image_deref_atomic_inc_wrap:
+            case nir_intrinsic_image_deref_atomic_dec_wrap:
+            case nir_intrinsic_image_deref_size:
+            case nir_intrinsic_image_deref_samples: {
+               assert(intrin->src[0].is_ssa);
+               b.cursor = nir_before_instr(&intrin->instr);
+               /* Back-ends expect a 32-bit thing, not 64-bit */
+               nir_ssa_def *offset = nir_u2u32(&b, intrin->src[0].ssa);
+               nir_rewrite_image_intrinsic(intrin, offset, false);
+               progress = true;
+               break;
+            }
+
+            default:
+               break;
+            }
+            break;
+         }
+
+         default:
+            break;
+         }
+      }
+   }
+
+   if (progress) {
+      nir_metadata_preserve(impl, nir_metadata_block_index |
+                                  nir_metadata_dominance);
+   } else {
+      nir_metadata_preserve(impl, nir_metadata_all);
+   }
+
+   return progress;
+}
+
 struct clover_lower_nir_state {
    std::vector<module::argument> &args;
    uint32_t global_dims;
@@ -318,6 +470,9 @@ module clover::nir::spirv_to_nir(const module &mod, const 
device &dev,
                  nir_var_function_temp,
                  glsl_get_cl_type_size_align);
 
+      NIR_PASS_V(nir, nir_opt_deref);
+      NIR_PASS_V(nir, nir_lower_cl_images_to_tex);
+      NIR_PASS_V(nir, clover_nir_lower_images);
       NIR_PASS_V(nir, nir_lower_memcpy);
 
       /* use offsets for kernel inputs (uniform) */

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to