Mesa (main): microsoft/compiler: Support lowered io (nir_intrinsic_load_input/store_output)

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Dec 20 16:44:24 UTC 2021


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

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Sat Dec 11 09:42:03 2021 -0800

microsoft/compiler: Support lowered io (nir_intrinsic_load_input/store_output)

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

---

 src/microsoft/ci/spirv2dxil_reference.txt | 14 ++---
 src/microsoft/compiler/nir_to_dxil.c      | 95 +++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+), 7 deletions(-)

diff --git a/src/microsoft/ci/spirv2dxil_reference.txt b/src/microsoft/ci/spirv2dxil_reference.txt
index 596f91091ab..334834b1164 100644
--- a/src/microsoft/ci/spirv2dxil_reference.txt
+++ b/src/microsoft/ci/spirv2dxil_reference.txt
@@ -376,11 +376,11 @@ Assertion failed: glsl_get_components(type) == 4
 
 
 Test:SpvModuleScopeVarParserTest_BuiltinPointSize_Write1_IsErased.spvasm:main|Vertex: Fail
-Assertion failed: instr->deref_type == nir_deref_type_var || instr->deref_type == nir_deref_type_array
+Assertion failed: glsl_get_components(type) == 4
 
 
 Test:SpvModuleScopeVarParserTest_BuiltinPointSize_WriteViaCopyObjectPostAccessChainErased.spvasm:main|Vertex: Fail
-Assertion failed: instr->deref_type == nir_deref_type_var || instr->deref_type == nir_deref_type_array
+Assertion failed: glsl_get_components(type) == 4
 
 
 Test:SpvModuleScopeVarParserTest_BuiltinPosition_BuiltIn_Position.spvasm:main|Vertex: Fail
@@ -388,23 +388,23 @@ Assertion failed: glsl_get_components(type) == 4
 
 
 Test:SpvModuleScopeVarParserTest_BuiltinPosition_BuiltIn_Position_Initializer.spvasm:main|Vertex: Fail
-Assertion failed: instr->deref_type == nir_deref_type_var || instr->deref_type == nir_deref_type_array
+Assertion failed: glsl_get_components(type) == 4
 
 
 Test:SpvModuleScopeVarParserTest_BuiltinPosition_StorePosition.spvasm:main|Vertex: Fail
-Assertion failed: instr->deref_type == nir_deref_type_var || instr->deref_type == nir_deref_type_array
+Assertion failed: glsl_get_components(type) == 4
 
 
 Test:SpvModuleScopeVarParserTest_BuiltinPosition_StorePosition_PerVertexStructOutOfOrderDecl.spvasm:main|Vertex: Fail
-Assertion failed: instr->deref_type == nir_deref_type_var || instr->deref_type == nir_deref_type_array
+Assertion failed: glsl_get_components(type) == 4
 
 
 Test:SpvModuleScopeVarParserTest_BuiltinPosition_StorePositionMember_OneAccessChain.spvasm:main|Vertex: Fail
-Assertion failed: instr->deref_type == nir_deref_type_var || instr->deref_type == nir_deref_type_array
+Assertion failed: glsl_get_components(type) == 4
 
 
 Test:SpvModuleScopeVarParserTest_BuiltinPosition_StorePositionMember_TwoAccessChain.spvasm:main|Vertex: Fail
-Assertion failed: instr->deref_type == nir_deref_type_var || instr->deref_type == nir_deref_type_array
+Assertion failed: glsl_get_components(type) == 4
 
 
 Test:SpvModuleScopeVarParserTest_BuiltinVertexIndex.spvasm:main|Vertex: Fail
diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c
index 613d15a0ec9..38e08d99616 100644
--- a/src/microsoft/compiler/nir_to_dxil.c
+++ b/src/microsoft/compiler/nir_to_dxil.c
@@ -2763,6 +2763,38 @@ emit_store_deref(struct ntd_context *ctx, nir_intrinsic_instr *intr)
    }
 }
 
+static bool
+emit_store_output_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr)
+{
+   nir_alu_type out_type = nir_intrinsic_src_type(intr);
+   enum overload_type overload = get_overload(out_type, intr->src[0].ssa->bit_size);
+   const struct dxil_func *func = dxil_get_function(&ctx->mod, "dx.op.storeOutput", overload);
+
+   if (!func)
+      return false;
+
+   const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod, DXIL_INTR_STORE_OUTPUT);
+   const struct dxil_value *output_id = dxil_module_get_int32_const(&ctx->mod, nir_intrinsic_base(intr));
+   const struct dxil_value *row = get_src(ctx, &intr->src[1], 0, nir_type_int);
+
+   bool success = true;
+   uint32_t writemask = nir_intrinsic_write_mask(intr);
+   for (unsigned i = 0; i < intr->num_components && success; ++i) {
+      if (writemask & (1 << i)) {
+         const struct dxil_value *col = dxil_module_get_int8_const(&ctx->mod, i + nir_intrinsic_component(intr));
+         const struct dxil_value *value = get_src(ctx, &intr->src[0], i, out_type);
+         if (!col || !value)
+            return false;
+
+         const struct dxil_value *args[] = {
+            opcode, output_id, row, col, value
+         };
+         success &= dxil_emit_call_void(&ctx->mod, func, args, ARRAY_SIZE(args));
+      }
+   }
+   return success;
+}
+
 static bool
 emit_load_input_array(struct ntd_context *ctx, nir_intrinsic_instr *intr, nir_variable *var, nir_src *index)
 {
@@ -2937,6 +2969,64 @@ emit_load_input(struct ntd_context *ctx, nir_intrinsic_instr *intr,
       return emit_load_input_flat(ctx, intr, input);
 }
 
+static bool
+emit_load_input_via_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr)
+{
+   bool attr_at_vertex = false;
+   if (ctx->mod.shader_kind == DXIL_PIXEL_SHADER &&
+      ctx->opts->interpolate_at_vertex &&
+      ctx->opts->provoking_vertex != 0 &&
+      (nir_intrinsic_dest_type(intr) & nir_type_float)) {
+      nir_variable *var = nir_find_variable_with_driver_location(ctx->shader, nir_var_shader_in, nir_intrinsic_base(intr));
+
+      attr_at_vertex = var && var->data.interpolation == INTERP_MODE_FLAT;
+   }
+
+   const struct dxil_value *opcode = dxil_module_get_int32_const(&ctx->mod,
+      attr_at_vertex ? DXIL_INTR_ATTRIBUTE_AT_VERTEX : DXIL_INTR_LOAD_INPUT);
+   const struct dxil_value *input_id = dxil_module_get_int32_const(&ctx->mod, nir_intrinsic_base(intr));
+   int row_index = intr->intrinsic == nir_intrinsic_load_per_vertex_input ? 1 : 0;
+   const struct dxil_value *row = get_src(ctx, &intr->src[row_index], 0, nir_type_int);
+   const struct dxil_value *vertex_id;
+   if (intr->intrinsic == nir_intrinsic_load_per_vertex_input) {
+      vertex_id = get_src(ctx, &intr->src[0], 0, nir_type_int);
+   } else if (attr_at_vertex) {
+      vertex_id = dxil_module_get_int8_const(&ctx->mod, ctx->opts->provoking_vertex);
+   } else {
+      const struct dxil_type *int32_type = dxil_module_get_int_type(&ctx->mod, 32);
+      if (!int32_type)
+         return false;
+
+      vertex_id = dxil_module_get_undef(&ctx->mod, int32_type);
+   }
+
+   if (!opcode || !input_id || !row || !vertex_id)
+      return false;
+
+   nir_alu_type out_type = nir_intrinsic_dest_type(intr);
+   enum overload_type overload = get_overload(out_type, intr->dest.ssa.bit_size);
+
+   const struct dxil_func *func = dxil_get_function(&ctx->mod,
+      attr_at_vertex ? "dx.op.attributeAtVertex" : "dx.op.loadInput", overload);
+
+   if (!func)
+      return false;
+
+   for (unsigned i = 0; i < intr->num_components; ++i) {
+      const struct dxil_value *comp = dxil_module_get_int8_const(&ctx->mod, i + nir_intrinsic_component(intr));
+
+      const struct dxil_value *args[] = {
+         opcode, input_id, row, comp, vertex_id
+      };
+
+      const struct dxil_value *retval = dxil_emit_call(&ctx->mod, func, args, ARRAY_SIZE(args));
+      if (!retval)
+         return false;
+      store_dest(ctx, &intr->dest, i, retval, out_type);
+   }
+   return true;
+}
+
 static bool
 emit_load_ptr(struct ntd_context *ctx, nir_intrinsic_instr *intr)
 {
@@ -3681,6 +3771,11 @@ emit_intrinsic(struct ntd_context *ctx, nir_intrinsic_instr *intr)
       return emit_image_size(ctx, intr);
    case nir_intrinsic_get_ssbo_size:
       return emit_get_ssbo_size(ctx, intr);
+   case nir_intrinsic_load_input:
+   case nir_intrinsic_load_per_vertex_input:
+      return emit_load_input_via_intrinsic(ctx, intr);
+   case nir_intrinsic_store_output:
+      return emit_store_output_via_intrinsic(ctx, intr);
 
    case nir_intrinsic_vulkan_resource_index:
       return emit_vulkan_resource_index(ctx, intr);



More information about the mesa-commit mailing list