diff options
author | Rob Clark <[email protected]> | 2019-02-06 08:01:31 -0500 |
---|---|---|
committer | Rob Clark <[email protected]> | 2019-02-16 16:26:14 -0500 |
commit | b51de44dea1d1fc70b5e8fcbcf0a7c24e6ffd183 (patch) | |
tree | 75fa614d86bf282343ee17d333e232a628c3bfa6 /src/gallium | |
parent | c0d6be11d6bce38c014524b2a7bf0c8fcebccece (diff) |
freedreno/a6xx: move stream-out emit to helper
Split out of the main fd6_emit() code, since it was already getting to
be a pretty giant function.
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 136 |
1 files changed, 72 insertions, 64 deletions
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 2956f4cde6e..1d2077048a4 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -609,6 +609,76 @@ build_lrz(struct fd6_emit *emit, bool binning_pass) return ring; } +static void +fd6_emit_streamout(struct fd_ringbuffer *ring, struct fd6_emit *emit, struct ir3_stream_output_info *info) +{ + struct fd_context *ctx = emit->ctx; + const struct fd6_program_state *prog = fd6_emit_get_prog(emit); + 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]; + + if (!target) + continue; + + unsigned offset = (so->offsets[i] * info->stride[i] * 4) + + target->buffer_offset; + + OUT_PKT4(ring, REG_A6XX_VPC_SO_BUFFER_BASE_LO(i), 3); + /* VPC_SO[i].BUFFER_BASE_LO: */ + OUT_RELOCW(ring, fd_resource(target->buffer)->bo, 0, 0, 0); + OUT_RING(ring, target->buffer_size + offset); + + OUT_PKT4(ring, REG_A6XX_VPC_SO_BUFFER_OFFSET(i), 3); + OUT_RING(ring, offset); + /* VPC_SO[i].FLUSH_BASE_LO/HI: */ + // TODO just give hw a dummy addr for now.. we should + // be using this an then CP_MEM_TO_REG to set the + // VPC_SO[i].BUFFER_OFFSET for the next draw.. + OUT_RELOCW(ring, fd6_context(ctx)->blit_mem, 0x100, 0, 0); + + emit->streamout_mask |= (1 << i); + } + + if (emit->streamout_mask) { + const struct fd6_streamout_state *tf = &prog->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); + } + +} + void fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit) { @@ -781,70 +851,8 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit) } struct ir3_stream_output_info *info = &vp->shader->stream_output; - 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]; - - if (!target) - continue; - - unsigned offset = (so->offsets[i] * info->stride[i] * 4) + - target->buffer_offset; - - OUT_PKT4(ring, REG_A6XX_VPC_SO_BUFFER_BASE_LO(i), 3); - /* VPC_SO[i].BUFFER_BASE_LO: */ - OUT_RELOCW(ring, fd_resource(target->buffer)->bo, 0, 0, 0); - OUT_RING(ring, target->buffer_size + offset); - - OUT_PKT4(ring, REG_A6XX_VPC_SO_BUFFER_OFFSET(i), 3); - OUT_RING(ring, offset); - /* VPC_SO[i].FLUSH_BASE_LO/HI: */ - // TODO just give hw a dummy addr for now.. we should - // be using this an then CP_MEM_TO_REG to set the - // VPC_SO[i].BUFFER_OFFSET for the next draw.. - OUT_RELOCW(ring, fd6_context(ctx)->blit_mem, 0x100, 0, 0); - - emit->streamout_mask |= (1 << i); - } - - if (emit->streamout_mask) { - const struct fd6_streamout_state *tf = &prog->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 (info->num_outputs) + fd6_emit_streamout(ring, emit, info); if (dirty & FD_DIRTY_BLEND) { struct fd6_blend_stateobj *blend = fd6_blend_stateobj(ctx->blend); |