spirv,nir: add support for SpvDecorationPerVertexKHR

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23254>
This commit is contained in:
Samuel Pitoiset
2022-05-27 09:16:09 +02:00
committed by Marge Bot
parent c2ec23ab84
commit 72955540cc
5 changed files with 32 additions and 3 deletions

View File

@@ -637,6 +637,12 @@ typedef struct nir_variable {
*/ */
unsigned per_primitive:1; 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. * \brief Layout qualifier for gl_FragDepth. See nir_depth_layout.
* *

View File

@@ -598,6 +598,12 @@ gather_varying_component_info(nir_shader *producer, nir_shader *consumer,
if (in_var->data.location < VARYING_SLOT_VAR0) if (in_var->data.location < VARYING_SLOT_VAR0)
continue; 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; unsigned location = in_var->data.location - VARYING_SLOT_VAR0;
if (location >= MAX_VARYINGS_INCL_PATCH) if (location >= MAX_VARYINGS_INCL_PATCH)
continue; continue;
@@ -1119,7 +1125,8 @@ replace_duplicate_input(nir_shader *shader, nir_variable *input_var,
if (!does_varying_match(dup_out_var, in_var) || if (!does_varying_match(dup_out_var, in_var) ||
in_var->data.interpolation != input_var->data.interpolation || 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; continue;
b.cursor = nir_before_instr(instr); b.cursor = nir_before_instr(instr);

View File

@@ -136,10 +136,16 @@ nir_is_arrayed_io(const nir_variable *var, gl_shader_stage stage)
return var->data.per_primitive; 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 || return stage == MESA_SHADER_GEOMETRY ||
stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_CTRL ||
stage == MESA_SHADER_TESS_EVAL; stage == MESA_SHADER_TESS_EVAL;
}
if (var->data.mode == nir_var_shader_out) if (var->data.mode == nir_var_shader_out)
return stage == MESA_SHADER_TESS_CTRL || return stage == MESA_SHADER_TESS_CTRL ||
@@ -254,7 +260,8 @@ emit_load(struct lower_io_state *state,
nir->options->use_interpolated_input_intrinsics && nir->options->use_interpolated_input_intrinsics &&
var->data.interpolation != INTERP_MODE_FLAT && var->data.interpolation != INTERP_MODE_FLAT &&
!var->data.per_primitive) { !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); assert(array_index != NULL);
op = nir_intrinsic_load_input_vertex; op = nir_intrinsic_load_input_vertex;
} else { } else {

View File

@@ -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))); 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 * TODO validate some things ir_validate.cpp does (requires more GLSL type
* support) * support)

View File

@@ -1385,6 +1385,12 @@ apply_var_decoration(struct vtn_builder *b,
var_data->per_view = true; var_data->per_view = true;
break; 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: default:
vtn_fail_with_decoration("Unhandled decoration", dec->decoration); vtn_fail_with_decoration("Unhandled decoration", dec->decoration);
} }