From: Rob Clark Date: Mon, 18 Dec 2017 20:06:37 +0000 (-0500) Subject: freedreno/ir3: add ctx->mem_to_mem() X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d7cb509fd3af578c7b1b8eac57910e38e258e348;p=mesa.git freedreno/ir3: add ctx->mem_to_mem() For dealing with indirect-draw + gl_VertexID, we'll introduce another case where we need to use CP_MEM_TO_MEM. Rather than adding more if(a5xx)/else make this a ctx vfunc. Signed-off-by: Rob Clark --- diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index dca3692b047..5fec2b6b08a 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -912,6 +912,26 @@ fd4_emit_ib(struct fd_ringbuffer *ring, struct fd_ringbuffer *target) __OUT_IB(ring, true, target); } +static void +fd4_mem_to_mem(struct fd_ringbuffer *ring, struct pipe_resource *dst, + unsigned dst_off, struct pipe_resource *src, unsigned src_off, + unsigned sizedwords) +{ + struct fd_bo *src_bo = fd_resource(src)->bo; + struct fd_bo *dst_bo = fd_resource(dst)->bo; + unsigned i; + + for (i = 0; i < sizedwords; i++) { + OUT_PKT3(ring, CP_MEM_TO_MEM, 3); + OUT_RING(ring, 0x00000000); + OUT_RELOCW(ring, dst_bo, dst_off, 0, 0); + OUT_RELOC (ring, src_bo, src_off, 0, 0); + + dst_off += 4; + src_off += 4; + } +} + void fd4_emit_init(struct pipe_context *pctx) { @@ -919,4 +939,5 @@ fd4_emit_init(struct pipe_context *pctx) ctx->emit_const = fd4_emit_const; ctx->emit_const_bo = fd4_emit_const_bo; ctx->emit_ib = fd4_emit_ib; + ctx->mem_to_mem = fd4_mem_to_mem; } diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c index 08e9bb7bafb..b7ce084a827 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c @@ -1068,6 +1068,26 @@ fd5_emit_ib(struct fd_ringbuffer *ring, struct fd_ringbuffer *target) __OUT_IB5(ring, target); } +static void +fd5_mem_to_mem(struct fd_ringbuffer *ring, struct pipe_resource *dst, + unsigned dst_off, struct pipe_resource *src, unsigned src_off, + unsigned sizedwords) +{ + struct fd_bo *src_bo = fd_resource(src)->bo; + struct fd_bo *dst_bo = fd_resource(dst)->bo; + unsigned i; + + for (i = 0; i < sizedwords; i++) { + OUT_PKT7(ring, CP_MEM_TO_MEM, 5); + OUT_RING(ring, 0x00000000); + OUT_RELOCW(ring, dst_bo, dst_off, 0, 0); + OUT_RELOC (ring, src_bo, src_off, 0, 0); + + dst_off += 4; + src_off += 4; + } +} + void fd5_emit_init(struct pipe_context *pctx) { @@ -1075,4 +1095,5 @@ fd5_emit_init(struct pipe_context *pctx) ctx->emit_const = fd5_emit_const; ctx->emit_const_bo = fd5_emit_const_bo; ctx->emit_ib = fd5_emit_ib; + ctx->mem_to_mem = fd5_mem_to_mem; } diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 1e9911ea9bf..a4e1e4bb86c 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -332,6 +332,11 @@ struct fd_context { /* blit: */ void (*blit)(struct fd_context *ctx, const struct pipe_blit_info *info); + /* simple gpu "memcpy": */ + void (*mem_to_mem)(struct fd_ringbuffer *ring, struct pipe_resource *dst, + unsigned dst_off, struct pipe_resource *src, unsigned src_off, + unsigned sizedwords); + /* * Common pre-cooked VBO state (used for a3xx and later): */ diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c index 3337543113d..3b1fcdfd5f9 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c @@ -879,20 +879,8 @@ ir3_emit_cs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *rin 0x1000); indirect_offset = 0; - if (is_a5xx(ctx->screen)) { - struct fd_bo *src = fd_resource(info->indirect)->bo; - struct fd_bo *dst = fd_resource(indirect)->bo; - for (unsigned i = 0; i < 3; i++) { - unsigned dst_off = i * 4; - unsigned src_off = (i * 4) + info->indirect_offset; - OUT_PKT7(ring, CP_MEM_TO_MEM, 5); - OUT_RING(ring, 0x00000000); - OUT_RELOCW(ring, dst, dst_off, 0, 0); - OUT_RELOC (ring, src, src_off, 0, 0); - } - } else { - assert(0); - } + ctx->mem_to_mem(ring, indirect, 0, info->indirect, + info->indirect_offset, 3); } else { pipe_resource_reference(&indirect, info->indirect); indirect_offset = info->indirect_offset;