From d934d3206e764bbb15c0cacf357e4ce9279f22b0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 6 Jul 2018 13:43:06 -0700 Subject: [PATCH] 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 --- src/broadcom/compiler/nir_to_vir.c | 1 + src/compiler/nir/nir.h | 3 ++ src/compiler/nir/nir_lower_wpos_ytransform.c | 29 ++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c index 51cb8845cdb..158c1c3e9f3 100644 --- a/src/broadcom/compiler/nir_to_vir.c +++ b/src/broadcom/compiler/nir_to_vir.c @@ -1927,6 +1927,7 @@ const nir_shader_compiler_options v3d_nir_options = { .lower_ifind_msb = true, .lower_ldexp = true, .lower_mul_high = true, + .lower_wpos_pntc = true, .native_integers = true, }; 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); -- 2.30.2