diff options
Diffstat (limited to 'src/gallium/drivers/freedreno/a6xx/fd6_emit.c')
-rw-r--r-- | src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 15438fa5f2e..1be407670a6 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -764,6 +764,8 @@ fd6_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, if (info->num_outputs) { struct fd_streamout_stateobj *so = &ctx->streamout; + emit->streamout_mask = 0; + for (unsigned i = 0; i < so->num_targets; i++) { struct pipe_stream_output_target *target = so->targets[i]; @@ -788,6 +790,40 @@ fd6_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, emit->streamout_mask |= (1 << i); } + + if (emit->streamout_mask) { + struct fd6_streamout_state *tf = &fd6_context(ctx)->tf; + + OUT_PKT7(ring, CP_CONTEXT_REG_BUNCH, 12 + (2 * tf->prog_count)); + OUT_RING(ring, REG_A6XX_VPC_SO_BUF_CNTL); + OUT_RING(ring, tf->vpc_so_buf_cntl); + OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(0)); + OUT_RING(ring, tf->ncomp[0]); + OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(1)); + OUT_RING(ring, tf->ncomp[1]); + OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(2)); + OUT_RING(ring, tf->ncomp[2]); + OUT_RING(ring, REG_A6XX_VPC_SO_NCOMP(3)); + OUT_RING(ring, tf->ncomp[3]); + OUT_RING(ring, REG_A6XX_VPC_SO_CNTL); + OUT_RING(ring, A6XX_VPC_SO_CNTL_ENABLE); + for (unsigned i = 0; i < tf->prog_count; i++) { + OUT_RING(ring, REG_A6XX_VPC_SO_PROG); + OUT_RING(ring, tf->prog[i]); + } + + OUT_PKT4(ring, REG_A6XX_VPC_SO_OVERRIDE, 1); + OUT_RING(ring, 0x0); + } else { + OUT_PKT7(ring, CP_CONTEXT_REG_BUNCH, 4); + OUT_RING(ring, REG_A6XX_VPC_SO_CNTL); + OUT_RING(ring, 0); + OUT_RING(ring, REG_A6XX_VPC_SO_BUF_CNTL); + OUT_RING(ring, 0); + + OUT_PKT4(ring, REG_A6XX_VPC_SO_OVERRIDE, 1); + OUT_RING(ring, A6XX_VPC_SO_OVERRIDE_SO_DISABLE); + } } if ((dirty & FD_DIRTY_BLEND)) { |