From 36add3d002d489aa1b26030b44bc3ac8fda11821 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Fri, 28 Jan 2022 11:43:21 -0800 Subject: [PATCH] microsoft/compiler: Support multiple GS output streams Reviewed-by: Sil Vilerino Part-of: --- src/microsoft/compiler/dxil_container.c | 4 ++-- src/microsoft/compiler/dxil_enums.h | 7 +++++++ src/microsoft/compiler/dxil_module.h | 2 +- src/microsoft/compiler/dxil_nir.c | 20 ++++++++++++-------- src/microsoft/compiler/dxil_signature.c | 22 +++++++++++++++------- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/microsoft/compiler/dxil_container.c b/src/microsoft/compiler/dxil_container.c index 082d6fc09cc..73b7f38fd04 100644 --- a/src/microsoft/compiler/dxil_container.c +++ b/src/microsoft/compiler/dxil_container.c @@ -222,8 +222,8 @@ dxil_container_add_state_validation(struct dxil_container *c, state->state.sig_input_vectors = (uint8_t)m->num_psv_inputs; - // TODO: check proper stream - state->state.sig_output_vectors[0] = (uint8_t)m->num_psv_outputs; + for (unsigned i = 0; i < 4; ++i) + state->state.sig_output_vectors[i] = (uint8_t)m->num_psv_outputs[i]; // TODO: Add viewID records size diff --git a/src/microsoft/compiler/dxil_enums.h b/src/microsoft/compiler/dxil_enums.h index 17c69b3d3b3..ae421d693f4 100644 --- a/src/microsoft/compiler/dxil_enums.h +++ b/src/microsoft/compiler/dxil_enums.h @@ -339,6 +339,13 @@ enum dxil_tessellator_partitioning { DXIL_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4, }; +enum dxil_signature_element_extended_properties { + DXIL_SIGNATURE_ELEMENT_OUTPUT_STREAM = 0, + DXIL_SIGNATURE_ELEMENT_GLOBAL_SYMBOL = 1, + DXIL_SIGNATURE_ELEMENT_DYNAMIC_INDEX_COMPONENT_MASK = 2, + DXIL_SIGNATURE_ELEMENT_USAGE_COMPONENT_MASK = 3, +}; + #ifdef __cplusplus extern "C" { #endif diff --git a/src/microsoft/compiler/dxil_module.h b/src/microsoft/compiler/dxil_module.h index ebb1c7550dd..e571c471fee 100644 --- a/src/microsoft/compiler/dxil_module.h +++ b/src/microsoft/compiler/dxil_module.h @@ -191,7 +191,7 @@ struct dxil_module { * of the dependency tables. */ unsigned num_psv_inputs; - unsigned num_psv_outputs; + unsigned num_psv_outputs[4]; unsigned num_psv_patch_consts; struct dxil_signature_record inputs[DXIL_SHADER_MAX_IO_ROWS]; diff --git a/src/microsoft/compiler/dxil_nir.c b/src/microsoft/compiler/dxil_nir.c index 6265c8132b4..d86201448c7 100644 --- a/src/microsoft/compiler/dxil_nir.c +++ b/src/microsoft/compiler/dxil_nir.c @@ -1749,20 +1749,24 @@ dxil_nir_lower_sysval_to_load_input(nir_shader *s, nir_variable **sysval_vars) static int variable_location_cmp(const nir_variable* a, const nir_variable* b) { - // Sort by driver_location, location, location_frac, then index + // Sort by stream, driver_location, location, location_frac, then index unsigned a_location = a->data.location; if (a_location >= VARYING_SLOT_PATCH0) a_location -= VARYING_SLOT_PATCH0; unsigned b_location = b->data.location; if (b_location >= VARYING_SLOT_PATCH0) b_location -= VARYING_SLOT_PATCH0; - return a->data.driver_location != b->data.driver_location ? - a->data.driver_location - b->data.driver_location : - a_location != b_location ? - a_location - b_location : - a->data.location_frac != b->data.location_frac ? - a->data.location_frac - b->data.location_frac : - a->data.index - b->data.index; + unsigned a_stream = a->data.stream & ~NIR_STREAM_PACKED; + unsigned b_stream = b->data.stream & ~NIR_STREAM_PACKED; + return a_stream != b_stream ? + a_stream - b_stream : + a->data.driver_location != b->data.driver_location ? + a->data.driver_location - b->data.driver_location : + a_location != b_location ? + a_location - b_location : + a->data.location_frac != b->data.location_frac ? + a->data.location_frac - b->data.location_frac : + a->data.index - b->data.index; } /* Order varyings according to driver location */ diff --git a/src/microsoft/compiler/dxil_signature.c b/src/microsoft/compiler/dxil_signature.c index 6b0fe776fcf..f316a380c8b 100644 --- a/src/microsoft/compiler/dxil_signature.c +++ b/src/microsoft/compiler/dxil_signature.c @@ -43,6 +43,7 @@ struct semantic_info { uint8_t start_col; uint8_t cols; uint8_t interpolation; + uint8_t stream; const char *sysvalue_name; }; @@ -130,6 +131,7 @@ get_additional_semantic_info(nir_shader *s, nir_variable *var, struct semantic_i bool is_gs_input = s->info.stage == MESA_SHADER_GEOMETRY && (var->data.mode & (nir_var_shader_in | nir_var_system_value)); + info->stream = var->data.stream; info->rows = 1; if (info->kind == DXIL_SEM_TARGET) { info->start_row = info->index; @@ -442,7 +444,15 @@ fill_SV_param_nodes(struct dxil_module *mod, unsigned record_id, SV_params_nodes[7] = dxil_get_metadata_int8(mod, semantic->cols); // Number of columns SV_params_nodes[8] = dxil_get_metadata_int32(mod, semantic->start_row); // Element packing start row SV_params_nodes[9] = dxil_get_metadata_int8(mod, semantic->start_col); // Element packing start column - SV_params_nodes[10] = 0; // optional Metadata + + const struct dxil_mdnode *SV_metadata[2]; + unsigned num_metadata_nodes = 0; + if (semantic->stream != 0) { + SV_metadata[num_metadata_nodes++] = dxil_get_metadata_int32(mod, DXIL_SIGNATURE_ELEMENT_OUTPUT_STREAM); + SV_metadata[num_metadata_nodes++] = dxil_get_metadata_int32(mod, semantic->stream); + } + + SV_params_nodes[10] = num_metadata_nodes ? dxil_get_metadata_node(mod, SV_metadata, num_metadata_nodes) : NULL; return dxil_get_metadata_node(mod, SV_params_nodes, ARRAY_SIZE(SV_params_nodes)); } @@ -453,7 +463,7 @@ fill_signature_element(struct dxil_signature_element *elm, unsigned row) { memset(elm, 0, sizeof(struct dxil_signature_element)); - // elm->stream = 0; + elm->stream = semantic->stream; // elm->semantic_name_offset = 0; // Offset needs to be filled out when writing elm->semantic_index = semantic->index + row; elm->system_value = (uint32_t) prog_semantic_from_kind(semantic->kind, semantic->rows, row); @@ -489,9 +499,7 @@ fill_psv_signature_element(struct dxil_psv_signature_element *psv_elm, psv_elm->semantic_kind = (uint8_t)semantic->kind; psv_elm->component_type = semantic->comp_type; //`?? psv_elm->interpolation_mode = semantic->interpolation; - /* to be filled later - psv_elm->dynamic_mask_and_stream = 0; - */ + psv_elm->dynamic_mask_and_stream = (semantic->stream) << 4; if (semantic->kind == DXIL_SEM_ARBITRARY && strlen(semantic->name)) { psv_elm->semantic_name_offset = copy_semantic_name_to_string(mod->sem_string_table, semantic->name); @@ -646,8 +654,8 @@ get_output_signature(struct dxil_module *mod, nir_shader *s, bool vulkan) ++num_outputs; - mod->num_psv_outputs = MAX2(mod->num_psv_outputs, - semantic.start_row + semantic.rows); + mod->num_psv_outputs[semantic.stream] = MAX2(mod->num_psv_outputs[semantic.stream], + semantic.start_row + semantic.rows); assert(num_outputs < ARRAY_SIZE(outputs)); }