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;
