Commit 21fcdb80 authored by Jason Ekstrand's avatar Jason Ekstrand
Browse files

nir: Add a new VARYING_SLOT_BARYCENTRIC

This magic varying is handled as a special case inside nir_lower_io()
and never makes it to the back-end.  Instead of actually interpolating
anything, it just returns the barycentric coordinates.  If needed, we
expand vec2 barycentrics to vec3 by z = 1 - x - y.
parent 5cee443f
Pipeline #660181 waiting for manual action with stages
......@@ -289,6 +289,37 @@ get_io_offset(nir_builder *b, nir_deref_instr *deref,
return offset;
}
static nir_ssa_def *
load_barycentric_for_var(struct lower_io_state *state,
const nir_variable *var)
{
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;
return nir_load_barycentric(&state->builder, bary_op,
var->data.interpolation);
}
static nir_ssa_def *
expand_barycentric(nir_builder *b, nir_ssa_def *barycentric,
unsigned num_components)
{
if (num_components == barycentric->num_components)
return barycentric;
assert(num_components == 3 && barycentric->num_components == 2);
nir_ssa_def *x = nir_channel(b, barycentric, 0);
nir_ssa_def *y = nir_channel(b, barycentric, 1);
nir_ssa_def *z = nir_fsub_imm(b, 1.0f, nir_fadd(b, x, y));
return nir_vec3(b, x, y, z);
}
static nir_ssa_def *
emit_load(struct lower_io_state *state,
nir_ssa_def *array_index, nir_variable *var, nir_ssa_def *offset,
......@@ -304,26 +335,21 @@ emit_load(struct lower_io_state *state,
switch (mode) {
case nir_var_shader_in:
if (nir->info.stage == MESA_SHADER_FRAGMENT &&
nir->options->use_interpolated_input_intrinsics &&
var->data.interpolation != INTERP_MODE_FLAT &&
!var->data.per_primitive) {
var->data.location == VARYING_SLOT_BARYCENTRIC) {
assert(var->data.interpolation != INTERP_MODE_FLAT);
assert(!var->data.per_primitive);
barycentric = load_barycentric_for_var(state, var);
return expand_barycentric(b, barycentric, num_components);
} else if (nir->info.stage == MESA_SHADER_FRAGMENT &&
nir->options->use_interpolated_input_intrinsics &&
var->data.interpolation != INTERP_MODE_FLAT &&
!var->data.per_primitive) {
if (var->data.interpolation == INTERP_MODE_EXPLICIT) {
assert(array_index != NULL);
op = nir_intrinsic_load_input_vertex;
} else {
assert(array_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);
barycentric = load_barycentric_for_var(state, var);
op = nir_intrinsic_load_interpolated_input;
}
} else {
......@@ -574,6 +600,8 @@ lower_interpolate_at(nir_intrinsic_instr *intrin, struct lower_io_state *state,
var->data.interpolation == INTERP_MODE_EXPLICIT) {
nir_ssa_def *vertex_index = NULL;
assert(var->data.location != VARYING_SLOT_BARYCENTRIC);
if (var->data.interpolation == INTERP_MODE_EXPLICIT) {
assert(intrin->intrinsic == nir_intrinsic_interp_deref_at_vertex);
vertex_index = intrin->src[1].ssa;
......@@ -615,6 +643,11 @@ lower_interpolate_at(nir_intrinsic_instr *intrin, struct lower_io_state *state,
nir_builder_instr_insert(b, &bary_setup->instr);
if (var->data.location == VARYING_SLOT_BARYCENTRIC) {
return expand_barycentric(&state->builder, &bary_setup->dest.ssa,
intrin->dest.ssa.num_components);
}
nir_io_semantics semantics = {0};
semantics.location = var->data.location;
semantics.num_slots = get_number_of_slots(state, var);
......
......@@ -340,6 +340,7 @@ typedef enum
VARYING_SLOT_PRIMITIVE_INDICES = VARYING_SLOT_TESS_LEVEL_INNER, /* Only appears in MESH. */
VARYING_SLOT_TASK_COUNT = VARYING_SLOT_BOUNDING_BOX0, /* Only appears in TASK. */
VARYING_SLOT_CULL_PRIMITIVE = VARYING_SLOT_BOUNDING_BOX0, /* Only appears in MESH. */
VARYING_SLOT_BARYCENTRIC = VARYING_SLOT_BFC0, /* Only appears in FS */
VARYING_SLOT_VAR0 = 32, /* First generic varying slot */
/* the remaining are simply for the benefit of gl_varying_slot_name()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment