diff options
author | Samuel Pitoiset <[email protected]> | 2020-01-27 11:34:00 +0100 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-01-29 09:49:50 +0000 |
commit | cf6cae832c9e7c95e2df88b4e86886d1310c505a (patch) | |
tree | 267f03c277e660f667a5ee7a67700ee96814d597 | |
parent | d29f10a7ca063b63a4e29062cf3ed0151e8ebd68 (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.c | 6 | ||||
-rw-r--r-- | src/compiler/nir/nir_intrinsics.py | 2 | ||||
-rw-r--r-- | src/compiler/nir/nir_lower_io.c | 51 |
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); |