Mesa (main): microsoft/compiler: Implement texture loads from UAVs

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jul 29 22:13:58 UTC 2021


Module: Mesa
Branch: main
Commit: 6126dd29a40655c323c30687034d6307e5853e79
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6126dd29a40655c323c30687034d6307e5853e79

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Sun Apr 11 14:11:07 2021 -0700

microsoft/compiler: Implement texture loads from UAVs

This comes to the backend as image_load rather than txf but the
DXIL intrinsic is the same at the end of the day.

Reviewed-by: Enrico Galli <enrico.galli at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10163>

---

 src/microsoft/clc/clc_compiler.c     |   1 +
 src/microsoft/compiler/nir_to_dxil.c | 105 ++++++++++++++++++++++++++++++++---
 2 files changed, 99 insertions(+), 7 deletions(-)

diff --git a/src/microsoft/clc/clc_compiler.c b/src/microsoft/clc/clc_compiler.c
index b82db218278..248c63654eb 100644
--- a/src/microsoft/clc/clc_compiler.c
+++ b/src/microsoft/clc/clc_compiler.c
@@ -1053,6 +1053,7 @@ clc_to_dxil(struct clc_context *ctx,
          .int64 = true,
          .kernel = true,
          .kernel_image = true,
+         .kernel_image_read_write = true,
          .literal_sampler = true,
          .printf = true,
       },
diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c
index a19f4f8a16f..300efbaabf7 100644
--- a/src/microsoft/compiler/nir_to_dxil.c
+++ b/src/microsoft/compiler/nir_to_dxil.c
@@ -581,9 +581,10 @@ emit_groupid_call(struct ntd_context *ctx, const struct dxil_value *comp)
 static const struct dxil_value *
 emit_bufferload_call(struct ntd_context *ctx,
                      const struct dxil_value *handle,
-                     const struct dxil_value *coord[2])
+                     const struct dxil_value *coord[2],
+                     enum overload_type overload)
 {
-   const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.bufferLoad", DXIL_I32);
+   const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.bufferLoad", overload);
    if (!func)
       return NULL;
 
@@ -619,6 +620,28 @@ emit_bufferstore_call(struct ntd_context *ctx,
                               args, ARRAY_SIZE(args));
 }
 
+static const struct dxil_value *
+emit_textureload_call(struct ntd_context *ctx,
+                      const struct dxil_value *handle,
+                      const struct dxil_value *coord[3],
+                      enum overload_type overload)
+{
+   const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.textureLoad", overload);
+   if (!func)
+      return NULL;
+   const struct dxil_type *int_type = dxil_module_get_int_type(&ctx->mod, 32);
+   const struct dxil_value *int_undef = dxil_module_get_undef(&ctx->mod, int_type);
+
+   const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
+      DXIL_INTR_TEXTURE_LOAD);
+   const struct dxil_value *args[] = { opcode, handle,
+      /*lod_or_sample*/ int_undef,
+      coord[0], coord[1], coord[2],
+      /* offsets */ int_undef, int_undef, int_undef};
+
+   return dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
+}
+
 static bool
 emit_texturestore_call(struct ntd_context *ctx,
                        const struct dxil_value *handle,
@@ -2406,7 +2429,7 @@ emit_load_ssbo(struct ntd_context *ctx, nir_intrinsic_instr *intr)
       int32_undef
    };
 
-   const struct dxil_value *load = emit_bufferload_call(ctx, handle, coord);
+   const struct dxil_value *load = emit_bufferload_call(ctx, handle, coord, DXIL_I32);
    if (!load)
       return false;
 
@@ -3090,6 +3113,72 @@ emit_image_store(struct ntd_context *ctx, nir_intrinsic_instr *intr)
       return emit_texturestore_call(ctx, handle, coord, value, write_mask, overload);
 }
 
+static bool
+emit_image_load(struct ntd_context *ctx, nir_intrinsic_instr *intr)
+{
+   const struct dxil_value *handle;
+   bool is_array = false;
+   if (ctx->opts->vulkan_environment) {
+      assert(intr->intrinsic == nir_intrinsic_image_deref_load);
+      handle = get_src_ssa(ctx, intr->src[0].ssa, 0);
+      is_array = glsl_sampler_type_is_array(nir_src_as_deref(intr->src[0])->type);
+   } else {
+      assert(intr->intrinsic == nir_intrinsic_image_load);
+      int binding = nir_src_as_int(intr->src[0]);
+      is_array = nir_intrinsic_image_array(intr);
+      handle = ctx->uav_handles[binding];
+   }
+   if (!handle)
+      return false;
+
+   const struct dxil_value *int32_undef = get_int32_undef(&ctx->mod);
+   if (!int32_undef)
+      return false;
+
+   const struct dxil_value *coord[3] = { int32_undef, int32_undef, int32_undef };
+   enum glsl_sampler_dim image_dim = intr->intrinsic == nir_intrinsic_image_load ?
+      nir_intrinsic_image_dim(intr) :
+      glsl_get_sampler_dim(nir_src_as_deref(intr->src[0])->type);
+   unsigned num_coords = glsl_get_sampler_dim_coordinate_components(image_dim);
+   if (is_array)
+      ++num_coords;
+
+   assert(num_coords <= nir_src_num_components(intr->src[1]));
+   for (unsigned i = 0; i < num_coords; ++i) {
+      coord[i] = get_src(ctx, &intr->src[1], i, nir_type_uint);
+      if (!coord[i])
+         return false;
+   }
+
+   nir_alu_type out_type = nir_intrinsic_dest_type(intr);
+   enum overload_type overload = get_overload(out_type, 32);
+
+   const struct dxil_value *load_result;
+   if (image_dim == GLSL_SAMPLER_DIM_BUF) {
+      coord[1] = int32_undef;
+      load_result = emit_bufferload_call(ctx, handle, coord, overload);
+   } else
+      load_result = emit_textureload_call(ctx, handle, coord, overload);
+
+   if (!load_result)
+      return false;
+
+   assert(nir_dest_bit_size(intr->dest) == 32);
+   unsigned num_components = nir_dest_num_components(intr->dest);
+   assert(num_components <= 4);
+   for (unsigned i = 0; i < num_components; ++i) {
+      const struct dxil_value *component = dxil_emit_extractval(&ctx->mod, load_result, i);
+      if (!component)
+         return false;
+      store_dest(ctx, &intr->dest, i, component, out_type);
+   }
+
+   if (num_components > 1)
+      ctx->mod.feats.typed_uav_load_additional_formats = true;
+
+   return true;
+}
+
 struct texop_parameters {
    const struct dxil_value *tex;
    const struct dxil_value *sampler;
@@ -3483,8 +3572,11 @@ emit_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr)
    case nir_intrinsic_image_store:
    case nir_intrinsic_image_deref_store:
       return emit_image_store(ctx, intr);
-   case nir_intrinsic_image_deref_size:
+   case nir_intrinsic_image_load:
+   case nir_intrinsic_image_deref_load:
+      return emit_image_load(ctx, intr);
    case nir_intrinsic_image_size:
+   case nir_intrinsic_image_deref_size:
       return emit_image_size(ctx, intr);
    case nir_intrinsic_get_ssbo_size:
       return emit_get_ssbo_size(ctx, intr);
@@ -3988,9 +4080,8 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr)
    case nir_texop_txf_ms:
       if (instr->sampler_dim == GLSL_SAMPLER_DIM_BUF) {
          params.coord[1] = int_undef;
-         sample = emit_bufferload_call(ctx, params.tex, params.coord);
-      }
-      else {
+         sample = emit_bufferload_call(ctx, params.tex, params.coord, params.overload);
+      } else {
          PAD_SRC(ctx, params.coord, coord_components, int_undef);
          sample = emit_texel_fetch(ctx, &params);
       }



More information about the mesa-commit mailing list