summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2019-02-06 08:01:31 -0500
committerRob Clark <[email protected]>2019-02-16 16:26:14 -0500
commitb51de44dea1d1fc70b5e8fcbcf0a7c24e6ffd183 (patch)
tree75fa614d86bf282343ee17d333e232a628c3bfa6 /src/gallium
parentc0d6be11d6bce38c014524b2a7bf0c8fcebccece (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.c136
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);