freedreno/a6xx: only generate streamout for draw pass shader
[mesa.git] / src / gallium / drivers / freedreno / a6xx / fd6_program.c
index 973086ddd00cd8436ef7fdf171910e59bbb62cac..72212432d0c11e936077a0ba8ea5739013634969 100644 (file)
@@ -434,8 +434,8 @@ setup_stateobj(struct fd_ringbuffer *ring, struct fd_screen *screen,
        OUT_PKT4(ring, REG_A6XX_SP_UNKNOWN_A9A8, 1);
        OUT_RING(ring, 0);
 
-       OUT_PKT4(ring, REG_A6XX_SP_UNKNOWN_AB00, 1);
-       OUT_RING(ring, 0x5);
+       OUT_PKT4(ring, REG_A6XX_SP_MODE_CONTROL, 1);
+       OUT_RING(ring, A6XX_SP_MODE_CONTROL_CONSTANT_DEMOTION_ENABLE | 4);
 
        OUT_PKT4(ring, REG_A6XX_SP_FS_OUTPUT_CNTL0, 1);
        OUT_RING(ring, A6XX_SP_FS_OUTPUT_CNTL0_DEPTH_REGID(posz_regid) |
@@ -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);
        }