aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2020-01-27 11:34:00 +0100
committerMarge Bot <[email protected]>2020-01-29 09:49:50 +0000
commitcf6cae832c9e7c95e2df88b4e86886d1310c505a (patch)
tree267f03c277e660f667a5ee7a67700ee96814d597
parentd29f10a7ca063b63a4e29062cf3ed0151e8ebd68 (diff)
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 <[email protected]> Reviewed-by: Bas Nieuwenhuizen <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3578>
-rw-r--r--src/compiler/nir/nir_divergence_analysis.c6
-rw-r--r--src/compiler/nir/nir_intrinsics.py2
-rw-r--r--src/compiler/nir/nir_lower_io.c51
3 files changed, 42 insertions, 17 deletions
diff --git a/src/compiler/nir/nir_divergence_analysis.c b/src/compiler/nir/nir_divergence_analysis.c
index f0c8bfad7b2..bfa12d1a57d 100644
--- a/src/compiler/nir/nir_divergence_analysis.c
+++ b/src/compiler/nir/nir_divergence_analysis.c
@@ -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:
diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py
index 6ebc76eb88b..292933bd065 100644
--- a/src/compiler/nir/nir_intrinsics.py
+++ b/src/compiler/nir/nir_intrinsics.py
@@ -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 }.
diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
index f10022936d0..780d76748be 100644
--- a/src/compiler/nir/nir_lower_io.c
+++ b/src/compiler/nir/nir_lower_io.c
@@ -245,20 +245,25 @@ 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) {
- assert(vertex_index == NULL);
-
- nir_intrinsic_op bary_op;
- if (var->data.sample ||
- (state->options & nir_lower_io_force_sample_interpolation))
- bary_op = nir_intrinsic_load_barycentric_sample;
- else if (var->data.centroid)
- bary_op = nir_intrinsic_load_barycentric_centroid;
- else
- bary_op = nir_intrinsic_load_barycentric_pixel;
-
- barycentric = nir_load_barycentric(&state->builder, bary_op,
- var->data.interpolation);
- op = nir_intrinsic_load_interpolated_input;
+ 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;
+ if (var->data.sample ||
+ (state->options & nir_lower_io_force_sample_interpolation))
+ bary_op = nir_intrinsic_load_barycentric_sample;
+ else if (var->data.centroid)
+ bary_op = nir_intrinsic_load_barycentric_centroid;
+ else
+ bary_op = nir_intrinsic_load_barycentric_pixel;
+
+ 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);