aboutsummaryrefslogtreecommitdiffstats
path: root/src/freedreno
diff options
context:
space:
mode:
authorKristian H. Kristensen <[email protected]>2019-10-11 12:37:38 -0700
committerKristian H. Kristensen <[email protected]>2019-10-17 13:43:53 -0700
commitd6ed39e20e76a0f9726de75afc6a6280abf36cf2 (patch)
tree83612b1f2582b9bac78eceeed28442f905efc341 /src/freedreno
parent4b7312b763b1417374ee5ce84c0bdb1f120e5d44 (diff)
freedreno/ir3: End VS with CHMASK and CHSH in GS pipelines
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 <[email protected]>
Diffstat (limited to 'src/freedreno')
-rw-r--r--src/freedreno/ir3/ir3_compiler_nir.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index aa9479ff2dc..13158dd0637 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -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