diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 02f3c948e65..27e00f14ef3 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -2240,6 +2240,8 @@ nir_intrinsic_from_system_value(gl_system_value val) return nir_intrinsic_load_vertex_id; case SYSTEM_VALUE_INSTANCE_ID: return nir_intrinsic_load_instance_id; + case SYSTEM_VALUE_INSTANCE_INDEX: + return nir_intrinsic_load_instance_index; case SYSTEM_VALUE_DRAW_ID: return nir_intrinsic_load_draw_id; case SYSTEM_VALUE_BASE_INSTANCE: @@ -2407,6 +2409,8 @@ nir_system_value_from_intrinsic(nir_intrinsic_op intrin) return SYSTEM_VALUE_VERTEX_ID; case nir_intrinsic_load_instance_id: return SYSTEM_VALUE_INSTANCE_ID; + case nir_intrinsic_load_instance_index: + return SYSTEM_VALUE_INSTANCE_INDEX; case nir_intrinsic_load_draw_id: return SYSTEM_VALUE_DRAW_ID; case nir_intrinsic_load_base_instance: diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index ede40d5d53b..1dae574d837 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -4033,6 +4033,15 @@ typedef struct nir_shader_compiler_options { */ bool lower_base_vertex; + /** + * Whether the driver wants to work with instance_index instead of + * instance_id. + * + * When set, instance_id will be lowered to instance_index - base_instance. + * Otherwise, instance_index will be lowered to instance_id + base_instance. + */ + bool supports_instance_index; + /** * If enabled, gl_HelperInvocation will be lowered as: * diff --git a/src/compiler/nir/nir_lower_system_values.c b/src/compiler/nir/nir_lower_system_values.c index 9293406ad13..cb4ed2a4c94 100644 --- a/src/compiler/nir/nir_lower_system_values.c +++ b/src/compiler/nir/nir_lower_system_values.c @@ -101,6 +101,22 @@ lower_system_value_instr(nir_builder *b, nir_instr *instr, void *_state) return NULL; } + case nir_intrinsic_load_instance_id: + if (b->shader->options->supports_instance_index) { + return nir_isub(b, nir_load_instance_index(b), + nir_load_base_instance(b)); + } else { + return NULL; + } + + case nir_intrinsic_load_instance_index: + if (!b->shader->options->supports_instance_index) { + return nir_iadd(b, nir_load_instance_id(b), + nir_load_base_instance(b)); + } else { + return NULL; + } + case nir_intrinsic_load_helper_invocation: if (b->shader->options->lower_helper_invocation) { return nir_build_lowered_load_helper_invocation(b); @@ -199,9 +215,19 @@ lower_system_value_instr(nir_builder *b, nir_instr *instr, void *_state) nir_variable *var = deref->var; switch (var->data.location) { + case SYSTEM_VALUE_INSTANCE_ID: + if (b->shader->options->supports_instance_index) { + return nir_isub(b, nir_load_instance_index(b), + nir_load_base_instance(b)); + } + break; + case SYSTEM_VALUE_INSTANCE_INDEX: - return nir_iadd(b, nir_load_instance_id(b), - nir_load_base_instance(b)); + if (!b->shader->options->supports_instance_index) { + return nir_iadd(b, nir_load_instance_id(b), + nir_load_base_instance(b)); + } + break; case SYSTEM_VALUE_GLOBAL_INVOCATION_ID: { return nir_iadd(b, nir_load_global_invocation_id(b, bit_size),