From: Rob Clark Date: Tue, 18 Aug 2020 19:00:37 +0000 (-0700) Subject: freedreno/a6xx: only generate streamout for draw pass shader X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=5550bc0423015fbb6076195930a4fb9ec2877255 freedreno/a6xx: only generate streamout for draw pass shader Previously we were doing this both for draw and binning pass.. resulting that the stateobj contained first the incorrect state (based on binning pass shader with varyings DCEd) followed by the correct state. Also, in the streamout case we should link binning pass VS against the real FS, rather than the dummy FS, so that OUTLOC's match (since same streamout stateobj is used for both draw and binning pass). Signed-off-by: Rob Clark Part-of: --- diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c index 7d57b2d1b5d..72212432d0c 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c @@ -462,7 +462,17 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_screen *screen, struct ir3_shader_linkage l = {0}; const struct ir3_shader_variant *last_shader = fd6_last_shader(state); - ir3_link_shaders(&l, last_shader, fs, true); + + bool do_streamout = (last_shader->shader->stream_output.num_outputs > 0); + + /* If we have streamout, link against the real FS, rather than the + * dummy FS used for binning pass state, to ensure the OUTLOC's + * match. Depending on whether we end up doing sysmem or gmem, + * the actual streamout could happen with either the binning pass + * or draw pass program, but the same streamout stateobj is used + * in either case: + */ + ir3_link_shaders(&l, last_shader, do_streamout ? state->fs : fs, true); bool primid_passthru = l.primid_loc != 0xff; @@ -473,8 +483,7 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_screen *screen, OUT_RING(ring, ~l.varmask[3]); /* VPC_VAR[3].DISABLE */ /* Add stream out outputs after computing the VPC_VAR_DISABLE bitmask. */ - if (last_shader->shader->stream_output.num_outputs > 0) - link_stream_out(&l, last_shader); + link_stream_out(&l, last_shader); if (VALIDREG(layer_regid)) { layer_loc = l.max_loc; @@ -491,7 +500,13 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_screen *screen, ir3_link_add(&l, psize_regid, 0x1, l.max_loc); } - if (last_shader->shader->stream_output.num_outputs > 0) { + /* If we have stream-out, we use the full shader for binning + * pass, rather than the optimized binning pass one, so that we + * have all the varying outputs available for xfb. So streamout + * state should always be derived from the non-binning pass + * program: + */ + if (do_streamout && !binning_pass) { setup_stream_out(state, last_shader, &l); }