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;
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;
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);
}