summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2018-07-06 13:43:06 -0700
committerEric Anholt <[email protected]>2018-07-26 11:00:34 -0700
commitd934d3206e764bbb15c0cacf357e4ce9279f22b0 (patch)
tree570917a387f8e0c404fdc96ccacc35d50f16186e /src/compiler/nir
parentb5a56a11daff72d6c566da116a58b1d99087dd88 (diff)
nir: Add flipping of gl_PointCoord.y in nir_lower_wpos_ytransform.
This is controlled by a new nir_shader_compiler_options flag, and fixes dEQP-GLES3.functional.shaders.builtin_variable.pointcoord on V3D. Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/compiler/nir')
-rw-r--r--src/compiler/nir/nir.h3
-rw-r--r--src/compiler/nir/nir_lower_wpos_ytransform.c29
2 files changed, 32 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 3bfe7d7f7bf..4213d6208cb 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2024,6 +2024,9 @@ typedef struct nir_shader_compiler_options {
bool lower_device_index_to_zero;
+ /* Set if nir_lower_wpos_ytransform() should also invert gl_PointCoord. */
+ bool lower_wpos_pntc;
+
/**
* Should nir_lower_io() create load_interpolated_input intrinsics?
*
diff --git a/src/compiler/nir/nir_lower_wpos_ytransform.c b/src/compiler/nir/nir_lower_wpos_ytransform.c
index f6f642c8cf9..fc61beb7872 100644
--- a/src/compiler/nir/nir_lower_wpos_ytransform.c
+++ b/src/compiler/nir/nir_lower_wpos_ytransform.c
@@ -231,6 +231,31 @@ lower_fragcoord(lower_wpos_ytransform_state *state,
emit_wpos_adjustment(state, intr, fragcoord, invert, adjX, adjY);
}
+static void
+lower_load_pointcoord(lower_wpos_ytransform_state *state,
+ nir_intrinsic_instr *intr)
+{
+ nir_builder *b = &state->b;
+ b->cursor = nir_after_instr(&intr->instr);
+
+ nir_ssa_def *pntc = &intr->dest.ssa;
+ nir_ssa_def *transform = get_transform(state);
+ nir_ssa_def *y = nir_channel(b, pntc, 1);
+ /* The offset is 1 if we're flipping, 0 otherwise. */
+ nir_ssa_def *offset = nir_fmax(b, nir_channel(b, transform, 2),
+ nir_imm_float(b, 0.0));
+ /* Flip the sign of y if we're flipping. */
+ nir_ssa_def *scaled = nir_fmul(b, y, nir_channel(b, transform, 0));
+
+ /* Reassemble the vector. */
+ nir_ssa_def *flipped_pntc = nir_vec2(b,
+ nir_channel(b, pntc, 0),
+ nir_fadd(b, offset, scaled));
+
+ nir_ssa_def_rewrite_uses_after(&intr->dest.ssa, nir_src_for_ssa(flipped_pntc),
+ flipped_pntc->parent_instr);
+}
+
/* turns 'fddy(p)' into 'fddy(fmul(p, transform.x))' */
static void
lower_fddy(lower_wpos_ytransform_state *state, nir_alu_instr *fddy)
@@ -310,6 +335,10 @@ lower_wpos_ytransform_block(lower_wpos_ytransform_state *state, nir_block *block
} else if (var->data.mode == nir_var_system_value &&
var->data.location == SYSTEM_VALUE_SAMPLE_POS) {
lower_load_sample_pos(state, intr);
+ } else if (var->data.mode == nir_var_shader_in &&
+ var->data.location == VARYING_SLOT_PNTC &&
+ state->shader->options->lower_wpos_pntc) {
+ lower_load_pointcoord(state, intr);
}
} else if (intr->intrinsic == nir_intrinsic_load_frag_coord) {
lower_fragcoord(state, intr, NULL);