#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.
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_imm(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,
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_store_output:
#include "util/u_atomic.h"
#include "util/u_prim.h"
#include "util/os_time.h"
+#include "util/u_helpers.h"
#include "vk_nir_convert_ycbcr.h"
#include "vk_pipeline.h"
return progress;
}
+/* This flips gl_PointCoord.y to match Vulkan requirements */
+static bool
+lower_point_coord_cb(nir_builder *b, nir_instr *instr, void *_state)
+{
+ if (instr->type != nir_instr_type_intrinsic)
+ return false;
+
+ nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
+ if (intr->intrinsic != nir_intrinsic_load_input)
+ return false;
+
+ if (nir_intrinsic_io_semantics(intr).location != VARYING_SLOT_PNTC)
+ return false;
+
+ b->cursor = nir_after_instr(&intr->instr);
+ nir_ssa_def *result = &intr->dest.ssa;
+ result =
+ nir_vector_insert_imm(b, result,
+ nir_fsub_imm(b, 1.0, nir_channel(b, result, 1)), 1);
+ nir_ssa_def_rewrite_uses_after(&intr->dest.ssa,
+ result, result->parent_instr);
+ return true;
+}
+
+static bool
+v3d_nir_lower_point_coord(nir_shader *s)
+{
+ assert(s->info.stage == MESA_SHADER_FRAGMENT);
+ return nir_shader_instructions_pass(s, lower_point_coord_cb,
+ nir_metadata_block_index |
+ nir_metadata_dominance, NULL);
+}
static void
lower_fs_io(nir_shader *nir)
p_stage_gs != NULL,
get_ucp_enable_mask(p_stage_vs));
+ if (key.is_points) {
+ assert(key.point_coord_upper_left);
+ NIR_PASS(_, p_stage_fs->nir, v3d_nir_lower_point_coord);
+ }
+
VkResult vk_result;
pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT] =
pipeline_compile_shader_variant(p_stage_fs, &key.base, sizeof(key),