freedreno/ir3: End VS with CHMASK and CHSH in GS pipelines
authorKristian H. Kristensen <hoegsberg@google.com>
Fri, 11 Oct 2019 19:37:38 +0000 (12:37 -0700)
committerKristian H. Kristensen <hoegsberg@google.com>
Thu, 17 Oct 2019 20:43:53 +0000 (13:43 -0700)
When used in a GS pipeline, the VS doesn't end with the END
instruction. Instead it chains to the GS, which continues running with
the same register allocation.  The intended use cases seems to be that
you can compile a regular VS (ie outputs in registers and ending with
END) but then tack on link-time generated code past the END to write
the outputs using STLW, in case the VS is used with GS.

Signed-off-by: Kristian H. Kristensen <hoegsberg@google.com>
src/freedreno/ir3/ir3_compiler_nir.c

index aa9479ff2dc8517b4753334f6b7a45e05a587fe8..13158dd063792d480e35e1e3e3e92cef25c39574 100644 (file)
@@ -2484,7 +2484,24 @@ emit_function(struct ir3_context *ctx, nir_function_impl *impl)
                emit_stream_out(ctx);
        }
 
-       ir3_END(ctx->block);
+       /* Vertex shaders in a tessellation or geometry pipeline treat END as a
+        * NOP and has an epilogue that writes the VS outputs to local storage, to
+        * be read by the HS.  Then it resets execution mask (chmask) and chains
+        * to the next shader (chsh).
+        */
+       if (ctx->so->type == MESA_SHADER_VERTEX && ctx->so->key.has_gs) {
+               struct ir3_instruction *chmask =
+                       ir3_CHMASK(ctx->block);
+               chmask->barrier_class = IR3_BARRIER_EVERYTHING;
+               chmask->barrier_conflict = IR3_BARRIER_EVERYTHING;
+
+               struct ir3_instruction *chsh =
+                       ir3_CHSH(ctx->block);
+               chsh->barrier_class = IR3_BARRIER_EVERYTHING;
+               chsh->barrier_conflict = IR3_BARRIER_EVERYTHING;
+       } else {
+               ir3_END(ctx->block);
+       }
 }
 
 static void