From 72955540cce7d0754af0cf5ae0f09b1664d2e39f Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 27 May 2022 09:16:09 +0200 Subject: [PATCH] spirv,nir: add support for SpvDecorationPerVertexKHR Signed-off-by: Samuel Pitoiset Reviewed-by: Rhys Perry Part-of: --- src/compiler/nir/nir.h | 6 ++++++ src/compiler/nir/nir_linking_helpers.c | 9 ++++++++- src/compiler/nir/nir_lower_io.c | 11 +++++++++-- src/compiler/nir/nir_validate.c | 3 +++ src/compiler/spirv/vtn_variables.c | 6 ++++++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index f05e176..c1ec8d4 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -638,6 +638,12 @@ typedef struct nir_variable { unsigned per_primitive:1; /** + * Whether the variable is declared to indicate that a fragment shader + * input will not have interpolated values. + */ + unsigned per_vertex:1; + + /** * \brief Layout qualifier for gl_FragDepth. See nir_depth_layout. * * This is not equal to \c ir_depth_layout_none if and only if this diff --git a/src/compiler/nir/nir_linking_helpers.c b/src/compiler/nir/nir_linking_helpers.c index fa73783..a257ea3 100644 --- a/src/compiler/nir/nir_linking_helpers.c +++ b/src/compiler/nir/nir_linking_helpers.c @@ -598,6 +598,12 @@ gather_varying_component_info(nir_shader *producer, nir_shader *consumer, if (in_var->data.location < VARYING_SLOT_VAR0) continue; + /* Do not remap per-vertex shader inputs because it's an array of + * 3-elements and this isn't supported. + */ + if (in_var->data.per_vertex) + continue; + unsigned location = in_var->data.location - VARYING_SLOT_VAR0; if (location >= MAX_VARYINGS_INCL_PATCH) continue; @@ -1119,7 +1125,8 @@ replace_duplicate_input(nir_shader *shader, nir_variable *input_var, if (!does_varying_match(dup_out_var, in_var) || in_var->data.interpolation != input_var->data.interpolation || - get_interp_loc(in_var) != get_interp_loc(input_var)) + get_interp_loc(in_var) != get_interp_loc(input_var) || + in_var->data.per_vertex) continue; b.cursor = nir_before_instr(instr); diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c index 6b1b3eb..a9856e4 100644 --- a/src/compiler/nir/nir_lower_io.c +++ b/src/compiler/nir/nir_lower_io.c @@ -136,10 +136,16 @@ nir_is_arrayed_io(const nir_variable *var, gl_shader_stage stage) return var->data.per_primitive; } - if (var->data.mode == nir_var_shader_in) + if (var->data.mode == nir_var_shader_in) { + if (var->data.per_vertex) { + assert(stage == MESA_SHADER_FRAGMENT); + return true; + } + return stage == MESA_SHADER_GEOMETRY || stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL; + } if (var->data.mode == nir_var_shader_out) return stage == MESA_SHADER_TESS_CTRL || @@ -254,7 +260,8 @@ emit_load(struct lower_io_state *state, nir->options->use_interpolated_input_intrinsics && var->data.interpolation != INTERP_MODE_FLAT && !var->data.per_primitive) { - if (var->data.interpolation == INTERP_MODE_EXPLICIT) { + if (var->data.interpolation == INTERP_MODE_EXPLICIT || + var->data.per_vertex) { assert(array_index != NULL); op = nir_intrinsic_load_input_vertex; } else { diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 9f90185..b304916 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -1548,6 +1548,9 @@ validate_var_decl(nir_variable *var, nir_variable_mode valid_modes, validate_assert(state, glsl_type_is_image(glsl_without_array(var->type))); } + if (var->data.per_vertex) + validate_assert(state, state->shader->info.stage == MESA_SHADER_FRAGMENT); + /* * TODO validate some things ir_validate.cpp does (requires more GLSL type * support) diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 5ffd4bd..bb166ee 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -1385,6 +1385,12 @@ apply_var_decoration(struct vtn_builder *b, var_data->per_view = true; break; + case SpvDecorationPerVertexKHR: + vtn_fail_if(b->shader->info.stage != MESA_SHADER_FRAGMENT, + "PerVertexKHR decoration only allowed in Fragment shaders"); + var_data->per_vertex = true; + break; + default: vtn_fail_with_decoration("Unhandled decoration", dec->decoration); } -- 2.7.4