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