mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 07:38:10 +02:00
spirv_to_dxil: Add support for non-zero vertex and instance indices
Since DXIL does not have a way to get the base/first vertex and base instance as well as using a zero-based vertex index, these values need to be passed in via a constant buffer. Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12707>
This commit is contained in:
parent
49ef896a5e
commit
398d591b65
2 changed files with 43 additions and 15 deletions
|
|
@ -45,10 +45,14 @@ shared_var_info(const struct glsl_type* type, unsigned* size, unsigned* align)
|
|||
static nir_variable *
|
||||
add_runtime_data_var(nir_shader *nir, unsigned desc_set, unsigned binding)
|
||||
{
|
||||
const struct glsl_type *array_type = glsl_array_type(
|
||||
glsl_uint_type(),
|
||||
sizeof(struct dxil_spirv_compute_runtime_data) / sizeof(unsigned),
|
||||
sizeof(unsigned));
|
||||
unsigned runtime_data_size =
|
||||
nir->info.stage == MESA_SHADER_COMPUTE
|
||||
? sizeof(struct dxil_spirv_compute_runtime_data)
|
||||
: sizeof(struct dxil_spirv_vertex_runtime_data);
|
||||
|
||||
const struct glsl_type *array_type =
|
||||
glsl_array_type(glsl_uint_type(), runtime_data_size / sizeof(unsigned),
|
||||
sizeof(unsigned));
|
||||
const struct glsl_struct_field field = {array_type, "arr"};
|
||||
nir_variable *var = nir_variable_create(
|
||||
nir, nir_var_mem_ubo,
|
||||
|
|
@ -89,6 +93,16 @@ lower_shader_system_values(struct nir_builder *builder, nir_instr *instr,
|
|||
offset =
|
||||
offsetof(struct dxil_spirv_compute_runtime_data, group_count_x);
|
||||
break;
|
||||
case nir_intrinsic_load_first_vertex:
|
||||
offset = offsetof(struct dxil_spirv_vertex_runtime_data, first_vertex);
|
||||
break;
|
||||
case nir_intrinsic_load_is_indexed_draw:
|
||||
offset =
|
||||
offsetof(struct dxil_spirv_vertex_runtime_data, is_indexed_draw);
|
||||
break;
|
||||
case nir_intrinsic_load_base_instance:
|
||||
offset = offsetof(struct dxil_spirv_vertex_runtime_data, base_instance);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
@ -164,8 +178,9 @@ spirv_to_dxil(const uint32_t *words, size_t word_count,
|
|||
glsl_type_singleton_init_or_ref();
|
||||
|
||||
struct nir_shader_compiler_options nir_options = *dxil_get_nir_compiler_options();
|
||||
// We will manually handle base_vertex
|
||||
nir_options.lower_base_vertex = false;
|
||||
// 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_shader *nir = spirv_to_nir(
|
||||
words, word_count, (struct nir_spirv_specialization *)specializations,
|
||||
|
|
@ -181,15 +196,16 @@ spirv_to_dxil(const uint32_t *words, size_t word_count,
|
|||
|
||||
NIR_PASS_V(nir, nir_lower_system_values);
|
||||
|
||||
// vertex_id and instance_id should have already been transformed to base
|
||||
// zero before spirv_to_dxil was called. Also, WebGPU does not support
|
||||
// base/firstVertex/Instance.
|
||||
gl_system_value system_values[] = {
|
||||
SYSTEM_VALUE_FIRST_VERTEX,
|
||||
SYSTEM_VALUE_BASE_VERTEX,
|
||||
SYSTEM_VALUE_BASE_INSTANCE
|
||||
};
|
||||
NIR_PASS_V(nir, dxil_nir_lower_system_values_to_zero, system_values, ARRAY_SIZE(system_values));
|
||||
if (conf->zero_based_vertex_instance_id) {
|
||||
// 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.
|
||||
gl_system_value system_values[] = {SYSTEM_VALUE_FIRST_VERTEX,
|
||||
SYSTEM_VALUE_BASE_VERTEX,
|
||||
SYSTEM_VALUE_BASE_INSTANCE};
|
||||
NIR_PASS_V(nir, dxil_nir_lower_system_values_to_zero, system_values,
|
||||
ARRAY_SIZE(system_values));
|
||||
}
|
||||
|
||||
bool requires_runtime_data = false;
|
||||
NIR_PASS(requires_runtime_data, nir,
|
||||
|
|
|
|||
|
|
@ -90,11 +90,23 @@ struct dxil_spirv_compute_runtime_data {
|
|||
uint32_t group_count_z;
|
||||
};
|
||||
|
||||
/* This struct describes the layout of data expected in the CB bound to
|
||||
* runtime_data_cbv during vertex stages */
|
||||
struct dxil_spirv_vertex_runtime_data {
|
||||
uint32_t first_vertex;
|
||||
uint32_t base_instance;
|
||||
bool is_indexed_draw;
|
||||
};
|
||||
|
||||
struct dxil_spirv_runtime_conf {
|
||||
struct {
|
||||
uint32_t register_space;
|
||||
uint32_t base_shader_register;
|
||||
} runtime_data_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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue