v3d/compiler: Handle point_coord_upper_left

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12524>
This commit is contained in:
Ella-0 2021-09-02 10:23:21 +00:00
parent 138463d3c3
commit 53ae5c3aae

View file

@ -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: