nir: lower interp_deref_at_vertex to load_input_vertex

This introduces a new NIR intrinsic for loading inputs at a specific
vertex index.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3578>
This commit is contained in:
Samuel Pitoiset
2020-01-27 11:34:00 +01:00
committed by Marge Bot
parent d29f10a7ca
commit cf6cae832c
3 changed files with 40 additions and 15 deletions

View File

@@ -125,6 +125,11 @@ visit_intrinsic(bool *divergent, nir_intrinsic_instr *instr,
else
is_divergent = true;
break;
case nir_intrinsic_load_input_vertex:
is_divergent = divergent[instr->src[1].ssa->index];
assert(stage == MESA_SHADER_FRAGMENT);
is_divergent |= !(options & nir_divergence_single_prim_per_subgroup);
break;
case nir_intrinsic_load_output:
assert(stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_FRAGMENT);
is_divergent = divergent[instr->src[0].ssa->index];
@@ -264,6 +269,7 @@ visit_intrinsic(bool *divergent, nir_intrinsic_instr *instr,
case nir_intrinsic_load_barycentric_pixel:
case nir_intrinsic_load_barycentric_centroid:
case nir_intrinsic_load_barycentric_sample:
case nir_intrinsic_load_barycentric_model:
case nir_intrinsic_load_barycentric_at_sample:
case nir_intrinsic_load_barycentric_at_offset:
case nir_intrinsic_interp_deref_at_offset:

View File

@@ -726,6 +726,8 @@ load("uniform", 1, [BASE, RANGE, TYPE], [CAN_ELIMINATE, CAN_REORDER])
load("ubo", 2, [ACCESS, ALIGN_MUL, ALIGN_OFFSET], flags=[CAN_ELIMINATE, CAN_REORDER])
# src[] = { offset }.
load("input", 1, [BASE, COMPONENT, TYPE], [CAN_ELIMINATE, CAN_REORDER])
# src[] = { vertex_id, offset }.
load("input_vertex", 2, [BASE, COMPONENT, TYPE], [CAN_ELIMINATE, CAN_REORDER])
# src[] = { vertex, offset }.
load("per_vertex_input", 2, [BASE, COMPONENT], [CAN_ELIMINATE, CAN_REORDER])
# src[] = { barycoord, offset }.

View File

@@ -245,6 +245,10 @@ emit_load(struct lower_io_state *state,
if (nir->info.stage == MESA_SHADER_FRAGMENT &&
nir->options->use_interpolated_input_intrinsics &&
var->data.interpolation != INTERP_MODE_FLAT) {
if (var->data.interpolation == INTERP_MODE_EXPLICIT) {
assert(vertex_index != NULL);
op = nir_intrinsic_load_input_vertex;
} else {
assert(vertex_index == NULL);
nir_intrinsic_op bary_op;
@@ -259,6 +263,7 @@ emit_load(struct lower_io_state *state,
barycentric = nir_load_barycentric(&state->builder, bary_op,
var->data.interpolation);
op = nir_intrinsic_load_interpolated_input;
}
} else {
op = vertex_index ? nir_intrinsic_load_per_vertex_input :
nir_intrinsic_load_input;
@@ -291,6 +296,7 @@ emit_load(struct lower_io_state *state,
state->type_size(var->type, var->data.bindless));
if (load->intrinsic == nir_intrinsic_load_input ||
load->intrinsic == nir_intrinsic_load_input_vertex ||
load->intrinsic == nir_intrinsic_load_uniform)
nir_intrinsic_set_type(load, type);
@@ -489,9 +495,20 @@ lower_interpolate_at(nir_intrinsic_instr *intrin, struct lower_io_state *state,
nir_builder *b = &state->builder;
assert(var->data.mode == nir_var_shader_in);
/* Ignore interpolateAt() for flat variables - flat is flat. */
if (var->data.interpolation == INTERP_MODE_FLAT)
return lower_load(intrin, state, NULL, var, offset, component, type);
/* Ignore interpolateAt() for flat variables - flat is flat. Lower
* interpolateAtVertex() for explicit variables.
*/
if (var->data.interpolation == INTERP_MODE_FLAT ||
var->data.interpolation == INTERP_MODE_EXPLICIT) {
nir_ssa_def *vertex_index = NULL;
if (var->data.interpolation == INTERP_MODE_EXPLICIT) {
assert(intrin->intrinsic == nir_intrinsic_interp_deref_at_vertex);
vertex_index = intrin->src[1].ssa;
}
return lower_load(intrin, state, vertex_index, var, offset, component, type);
}
/* None of the supported APIs allow interpolation on 64-bit things */
assert(intrin->dest.is_ssa && intrin->dest.ssa.bit_size <= 32);