diff --git a/src/broadcom/compiler/v3d_nir_lower_io.c b/src/broadcom/compiler/v3d_nir_lower_io.c index 655f74fd42d..895b1a39163 100644 --- a/src/broadcom/compiler/v3d_nir_lower_io.c +++ b/src/broadcom/compiler/v3d_nir_lower_io.c @@ -24,6 +24,8 @@ #include "compiler/v3d_compiler.h" #include "compiler/nir/nir_builder.h" +#include "util/u_helpers.h" + /** * Walks the NIR generated by TGSI-to-NIR or GLSL-to-NIR to lower its io * intrinsics into something amenable to the V3D architecture. @@ -325,6 +327,59 @@ v3d_nir_lower_vertex_input(struct v3d_compile *c, nir_builder *b, nir_intrinsic_set_component(instr, (comp + 2) % 4); } +/* Sometimes the origin of gl_PointCoord is in the upper left rather than the + * lower left so we need to flip it. + * + * This is needed for Vulkan, Gallium uses lower_wpos_pntc. + */ +static void +v3d_nir_lower_fragment_input(struct v3d_compile *c, nir_builder *b, + nir_intrinsic_instr *intr) +{ + assert(c->s->info.stage == MESA_SHADER_FRAGMENT); + + /* Gallium uses lower_wpos_pntc */ + if (c->key->environment == V3D_ENVIRONMENT_OPENGL) + return; + + b->cursor = nir_after_instr(&intr->instr); + + int comp = nir_intrinsic_component(intr); + + nir_variable *input_var = + nir_find_variable_with_driver_location(c->s, + nir_var_shader_in, + nir_intrinsic_base(intr)); + + if (input_var && util_varying_is_point_coord(input_var->data.location, + c->fs_key->point_sprite_mask)) { + assert(intr->num_components == 1); + + nir_ssa_def *result = &intr->dest.ssa; + + switch (comp) { + case 0: + case 1: + if (!c->fs_key->is_points) + result = nir_imm_float(b, 0.0); + break; + case 2: + result = nir_imm_float(b, 0.0); + break; + case 3: + result = nir_imm_float(b, 1.0); + break; + } + if (c->fs_key->point_coord_upper_left && comp == 1) + result = nir_fsub(b, nir_imm_float(b, 1.0), result); + if (result != &intr->dest.ssa) { + nir_ssa_def_rewrite_uses_after(&intr->dest.ssa, + result, + result->parent_instr); + } + } +} + static void v3d_nir_lower_io_instr(struct v3d_compile *c, nir_builder *b, struct nir_instr *instr, @@ -338,6 +393,8 @@ v3d_nir_lower_io_instr(struct v3d_compile *c, nir_builder *b, case nir_intrinsic_load_input: if (c->s->info.stage == MESA_SHADER_VERTEX) v3d_nir_lower_vertex_input(c, b, intr); + else if (c->s->info.stage == MESA_SHADER_FRAGMENT) + v3d_nir_lower_fragment_input(c, b, intr); break; case nir_intrinsic_load_uniform: