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

Author: Jesse Natalie <[email protected]>
Date:   Wed Jan 11 10:46:51 2023 -0800

microsoft/compiler: Support view instancing

This adds support for D3D12-native view instancing to the compiler.
Essentially, it's just the ability to load SV_ViewID (dx.op.viewID),
set the right capability, and fill out some more PSV data. Note that
the PSV data is currently garbage. Ideally, we'd fill out a proper
input -> output and viewID -> output dependency table, but AFAIK
this is only used to enforce D3D API validation, and drivers ignore
it, so it's less critical to get it right.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20650>

---

 src/microsoft/compiler/dxil_container.c | 24 +++++++++++++++++++++---
 src/microsoft/compiler/dxil_function.c  |  1 +
 src/microsoft/compiler/dxil_nir.c       |  1 +
 src/microsoft/compiler/nir_to_dxil.c    |  6 ++++++
 4 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/microsoft/compiler/dxil_container.c 
b/src/microsoft/compiler/dxil_container.c
index 64cb8a17195..209973459d3 100644
--- a/src/microsoft/compiler/dxil_container.c
+++ b/src/microsoft/compiler/dxil_container.c
@@ -195,10 +195,15 @@ cleanup:
    return retval;
 }
 
+static uint32_t
+compute_mask_dwords_from_vectors(uint32_t vectors)
+{
+   return ((vectors + 7) >> 3);
+}
 static uint32_t
 compute_input_output_table_dwords(unsigned input_vectors, unsigned 
output_vectors)
 {
-   return ((output_vectors + 7) >> 3) * input_vectors * 4;
+   return compute_mask_dwords_from_vectors(output_vectors) * input_vectors * 4;
 }
 
 bool
@@ -237,7 +242,19 @@ dxil_container_add_state_validation(struct dxil_container 
*c,
    for (unsigned i = 0; i < 4; ++i)
       state->state.psv1.sig_output_vectors[i] = (uint8_t)m->num_psv_outputs[i];
 
-   // TODO: Add viewID records size
+   uint32_t view_id_table_size = 0;
+   if (state->state.psv1.uses_view_id) {
+      for (unsigned i = 0; i < 4; ++i) {
+         if (state->state.psv1.sig_output_vectors[i] > 0)
+            view_id_table_size += sizeof(uint32_t) *
+            
compute_mask_dwords_from_vectors(state->state.psv1.sig_output_vectors[i]);
+      }
+      if (state->state.psv1.shader_stage == DXIL_HULL_SHADER && 
state->state.psv1.sig_patch_const_or_prim_vectors) {
+         view_id_table_size += sizeof(uint32_t) *
+            
compute_mask_dwords_from_vectors(state->state.psv1.sig_patch_const_or_prim_vectors);
+      }
+   }
+   size += view_id_table_size;
 
    uint32_t dependency_table_size = 0;
    if (state->state.psv1.sig_input_vectors > 0) {
@@ -309,9 +326,10 @@ dxil_container_add_state_validation(struct dxil_container 
*c,
    }
 
    // TODO: Handle case when ViewID is used
+   for (uint32_t i = 0; i < view_id_table_size; ++i)
+      blob_write_uint8(&c->parts, 0);
 
    // TODO: Handle sig input output dependency table
-
    for (uint32_t i = 0; i < dependency_table_size; ++i)
       blob_write_uint8(&c->parts, 0);
 
diff --git a/src/microsoft/compiler/dxil_function.c 
b/src/microsoft/compiler/dxil_function.c
index d23e577dc83..3a34eecc56a 100644
--- a/src/microsoft/compiler/dxil_function.c
+++ b/src/microsoft/compiler/dxil_function.c
@@ -75,6 +75,7 @@ static struct  predefined_func_descr predefined_funcs[] = {
 {"dx.op.primitiveID", "i", "i", DXIL_ATTR_KIND_READ_NONE},
 {"dx.op.outputControlPointID", "i", "i", DXIL_ATTR_KIND_READ_NONE},
 {"dx.op.gsInstanceID", "i", "i", DXIL_ATTR_KIND_READ_NONE},
+{"dx.op.viewID", "i", "i", DXIL_ATTR_KIND_READ_NONE},
 {"dx.op.domainLocation", "f", "ii", DXIL_ATTR_KIND_READ_NONE},
 {"dx.op.legacyF16ToF32", "f", "ii", DXIL_ATTR_KIND_READ_ONLY},
 {"dx.op.legacyF32ToF16", "i", "if", DXIL_ATTR_KIND_READ_ONLY},
diff --git a/src/microsoft/compiler/dxil_nir.c 
b/src/microsoft/compiler/dxil_nir.c
index 8ec5a56e003..27a4ce40780 100644
--- a/src/microsoft/compiler/dxil_nir.c
+++ b/src/microsoft/compiler/dxil_nir.c
@@ -1705,6 +1705,7 @@ nir_var_to_dxil_sysvalue_type(nir_variable *var, uint64_t 
other_stage_mask)
    case VARYING_SLOT_TESS_LEVEL_OUTER:
    case VARYING_SLOT_VIEWPORT:
    case VARYING_SLOT_LAYER:
+   case VARYING_SLOT_VIEW_INDEX:
       if (!((1ull << var->data.location) & other_stage_mask))
          return DXIL_SYSVALUE;
       return DXIL_USED_SYSVALUE;
diff --git a/src/microsoft/compiler/nir_to_dxil.c 
b/src/microsoft/compiler/nir_to_dxil.c
index 8eacc729135..62e5a9e41f8 100644
--- a/src/microsoft/compiler/nir_to_dxil.c
+++ b/src/microsoft/compiler/nir_to_dxil.c
@@ -333,6 +333,7 @@ enum dxil_intr {
    DXIL_INTR_LEGACY_F16TOF32 = 131,
 
    DXIL_INTR_ATTRIBUTE_AT_VERTEX = 137,
+   DXIL_INTR_VIEW_ID = 138,
 
    DXIL_INTR_ANNOTATE_HANDLE = 216,
    DXIL_INTR_CREATE_HANDLE_FROM_BINDING = 217,
@@ -4439,6 +4440,10 @@ emit_intrinsic(struct ntd_context *ctx, 
nir_intrinsic_instr *intr)
       default:
          unreachable("Unexpected shader kind for invocation ID");
       }
+   case nir_intrinsic_load_view_index:
+      ctx->mod.feats.view_id = true;
+      return emit_load_unary_external_function(ctx, intr, "dx.op.viewID",
+                                               DXIL_INTR_VIEW_ID);
    case nir_intrinsic_load_sample_mask_in:
       return emit_load_sample_mask_in(ctx, intr);
    case nir_intrinsic_load_tess_coord:
@@ -5914,6 +5919,7 @@ void dxil_fill_validation_state(struct ntd_context *ctx,
    state->resources.v0 = (struct dxil_resource_v0*)ctx->resources.data;
    state->state.psv1.psv0.max_expected_wave_lane_count = UINT_MAX;
    state->state.psv1.shader_stage = (uint8_t)ctx->mod.shader_kind;
+   state->state.psv1.uses_view_id = (uint8_t)ctx->mod.feats.view_id;
    state->state.psv1.sig_input_elements = (uint8_t)ctx->mod.num_sig_inputs;
    state->state.psv1.sig_output_elements = (uint8_t)ctx->mod.num_sig_outputs;
    state->state.psv1.sig_patch_const_or_prim_elements = 
(uint8_t)ctx->mod.num_sig_patch_consts;

Reply via email to