diff --git a/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c b/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c index 0f25581b5fd..c62b1ef4797 100644 --- a/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c +++ b/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c @@ -213,6 +213,8 @@ lower_shader_system_values(struct nir_builder *builder, nir_instr *instr, offsetof(struct dxil_spirv_compute_runtime_data, base_group_x); break; case nir_intrinsic_load_first_vertex: + if (conf->first_vertex_and_base_instance_mode == DXIL_SPIRV_SYSVAL_TYPE_NATIVE) + return false; offset = offsetof(struct dxil_spirv_vertex_runtime_data, first_vertex); break; case nir_intrinsic_load_is_indexed_draw: @@ -220,6 +222,8 @@ lower_shader_system_values(struct nir_builder *builder, nir_instr *instr, offsetof(struct dxil_spirv_vertex_runtime_data, is_indexed_draw); break; case nir_intrinsic_load_base_instance: + if (conf->first_vertex_and_base_instance_mode == DXIL_SPIRV_SYSVAL_TYPE_NATIVE) + return false; offset = offsetof(struct dxil_spirv_vertex_runtime_data, base_instance); break; case nir_intrinsic_load_draw_id: @@ -887,7 +891,7 @@ dxil_spirv_nir_passes(nir_shader *nir, NIR_PASS_V(nir, nir_lower_system_values); nir_lower_compute_system_values_options compute_options = { - .has_base_workgroup_id = !conf->zero_based_compute_workgroup_id, + .has_base_workgroup_id = conf->workgroup_id_mode != DXIL_SPIRV_SYSVAL_TYPE_ZERO, }; NIR_PASS_V(nir, nir_lower_compute_system_values, &compute_options); NIR_PASS_V(nir, dxil_nir_lower_subgroup_id); @@ -917,7 +921,7 @@ dxil_spirv_nir_passes(nir_shader *nir, nir->info.fs.uses_sample_shading = true; } - if (conf->zero_based_vertex_instance_id) { + if (conf->first_vertex_and_base_instance_mode == DXIL_SPIRV_SYSVAL_TYPE_ZERO) { // vertex_id and instance_id should have already been transformed to // base zero before spirv_to_dxil was called. Therefore, we can zero out // base/firstVertex/Instance. diff --git a/src/microsoft/spirv_to_dxil/spirv2dxil.c b/src/microsoft/spirv_to_dxil/spirv2dxil.c index 544fa25a0f2..66696babc24 100644 --- a/src/microsoft/spirv_to_dxil/spirv2dxil.c +++ b/src/microsoft/spirv_to_dxil/spirv2dxil.c @@ -182,7 +182,7 @@ main(int argc, char **argv) conf.runtime_data_cbv.register_space = 31; conf.push_constant_cbv.base_shader_register = 0; conf.push_constant_cbv.register_space = 30; - conf.zero_based_vertex_instance_id = true; + conf.first_vertex_and_base_instance_mode = DXIL_SPIRV_SYSVAL_TYPE_ZERO; conf.declared_read_only_images_as_srvs = true; conf.shader_model_max = SHADER_MODEL_6_2; @@ -218,6 +218,8 @@ main(int argc, char **argv) break; case 'm': conf.shader_model_max = SHADER_MODEL_6_0 + atoi(optarg); + conf.first_vertex_and_base_instance_mode = conf.shader_model_max >= SHADER_MODEL_6_8 ? + DXIL_SPIRV_SYSVAL_TYPE_NATIVE : DXIL_SPIRV_SYSVAL_TYPE_ZERO; break; case 'x': val_ver = DXIL_VALIDATOR_1_0 + atoi(optarg); diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c index 6ba3f85903d..db26f1a5b84 100644 --- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c @@ -69,7 +69,7 @@ spirv_to_dxil(const uint32_t *words, size_t word_count, dxil_get_nir_compiler_options(&nir_options, conf->shader_model_max, supported_bit_sizes, supported_bit_sizes); // We will manually handle base_vertex when vertex_id and instance_id have // have been already converted to zero-base. - nir_options.lower_base_vertex = !conf->zero_based_vertex_instance_id; + nir_options.lower_base_vertex = conf->first_vertex_and_base_instance_mode != DXIL_SPIRV_SYSVAL_TYPE_ZERO; nir_shader *nir = spirv_to_nir( words, word_count, (struct nir_spirv_specialization *)specializations, diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.h b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h index a4baa61857a..b1e8ac2d59c 100644 --- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.h +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h @@ -141,6 +141,16 @@ enum dxil_spirv_yz_flip_mode { #define DXIL_SPIRV_MAX_VIEWPORT 16 +enum dxil_spirv_sysval_type { + // The sysval can be inlined in the shader as a constant zero + DXIL_SPIRV_SYSVAL_TYPE_ZERO, + // The sysval has a supported DXIL equivalent + DXIL_SPIRV_SYSVAL_TYPE_NATIVE, + // The sysval might be nonzero and has no DXIL equivalent, so it + // will need to be provided by the runtime_data constant buffer + DXIL_SPIRV_SYSVAL_TYPE_RUNTIME_DATA, +}; + struct dxil_spirv_runtime_conf { struct { uint32_t register_space; @@ -152,11 +162,8 @@ struct dxil_spirv_runtime_conf { uint32_t base_shader_register; } push_constant_cbv; - // Set true if vertex and instance ids have already been converted to - // zero-based. Otherwise, runtime_data will be required to lower them. - bool zero_based_vertex_instance_id; - // Set true if workgroup base is known to be zero - bool zero_based_compute_workgroup_id; + enum dxil_spirv_sysval_type first_vertex_and_base_instance_mode; + enum dxil_spirv_sysval_type workgroup_id_mode; struct { // mode != DXIL_SPIRV_YZ_FLIP_NONE only valid on vertex/geometry stages. diff --git a/src/microsoft/vulkan/dzn_pipeline.c b/src/microsoft/vulkan/dzn_pipeline.c index 11a3d95fbdc..b4868320c1b 100644 --- a/src/microsoft/vulkan/dzn_pipeline.c +++ b/src/microsoft/vulkan/dzn_pipeline.c @@ -238,8 +238,8 @@ dzn_pipeline_get_nir_shader(struct dzn_device *device, .register_space = DZN_REGISTER_SPACE_PUSH_CONSTANT, .base_shader_register = 0, }, - .zero_based_vertex_instance_id = false, - .zero_based_compute_workgroup_id = false, + .first_vertex_and_base_instance_mode = DXIL_SPIRV_SYSVAL_TYPE_RUNTIME_DATA, + .workgroup_id_mode = DXIL_SPIRV_SYSVAL_TYPE_RUNTIME_DATA, .yz_flip = { .mode = options->yz_flip_mode, .y_mask = options->y_flip_mask,