pan/bi: Remove the "wrong" stores in IDVS variants
authorAlyssa Rosenzweig <alyssa@collabora.com>
Mon, 13 Dec 2021 20:24:15 +0000 (15:24 -0500)
committerMarge Bot <emma+marge@anholt.net>
Mon, 20 Dec 2021 18:21:41 +0000 (18:21 +0000)
Position shaders should only write gl_Position (and gl_PointSize on
Valhall), varying shaders should only write varyings.

Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14154>

src/panfrost/bifrost/bifrost_compile.c

index 3c8ccc6..9c457fa 100644 (file)
@@ -675,6 +675,25 @@ bi_emit_fragment_out(bi_builder *b, nir_intrinsic_instr *instr)
         }
 }
 
+/**
+ * In a vertex shader, is the specified variable a position output? These kinds
+ * of outputs are written from position shaders when IDVS is enabled. All other
+ * outputs are written from the varying shader.
+ */
+static bool
+bi_should_remove_store(nir_intrinsic_instr *intr, enum bi_idvs_mode idvs)
+{
+        nir_io_semantics sem = nir_intrinsic_io_semantics(intr);
+
+        switch (sem.location) {
+        case VARYING_SLOT_POS:
+        case VARYING_SLOT_PSIZ:
+                return idvs == BI_IDVS_VARYING;
+        default:
+                return idvs == BI_IDVS_POSITION;
+        }
+}
+
 static void
 bi_emit_store_vary(bi_builder *b, nir_intrinsic_instr *instr)
 {
@@ -690,6 +709,12 @@ bi_emit_store_vary(bi_builder *b, nir_intrinsic_instr *instr)
         unsigned imm_index = 0;
         bool immediate = bi_is_intr_immediate(instr, &imm_index, 16);
 
+        /* Skip stores to the wrong kind of variable in a specialized IDVS
+         * shader. Backend dead code elimination will clean up the mess.
+         */
+        if (bi_should_remove_store(instr, b->shader->idvs))
+                return;
+
         bi_index address;
         if (immediate) {
                 address = bi_lea_attr_imm(b,