broadcom/compiler: move vulkan's point coord lowering to the driver
authorIago Toral Quiroga <itoral@igalia.com>
Mon, 31 Jul 2023 07:48:00 +0000 (09:48 +0200)
committerMarge Bot <emma+marge@anholt.net>
Thu, 3 Aug 2023 06:32:40 +0000 (06:32 +0000)
Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24396>

src/broadcom/compiler/v3d_nir_lower_io.c
src/broadcom/vulkan/v3dv_pipeline.c

index ca0ffd9..a2c1335 100644 (file)
@@ -24,8 +24,6 @@
 #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.
@@ -306,59 +304,6 @@ 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_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,
@@ -372,8 +317,6 @@ 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_store_output:
index f72a3ba..a9b52b3 100644 (file)
@@ -35,6 +35,7 @@
 #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"
@@ -891,6 +892,38 @@ lower_pipeline_layout_info(nir_shader *shader,
    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)
@@ -1897,6 +1930,11 @@ pipeline_compile_fragment_shader(struct v3dv_pipeline *pipeline,
                                 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),