From 5f56a0e0576d7ff6793378334b4c262527b99f3a Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 4 May 2026 11:27:55 +0200 Subject: [PATCH] radeonsi: add si_resource_copy_buffer Same as si_resource_copy_resource except it only supports buffers. Also make sure that si_compute_clear_copy_buffer doesn't do anything when has_gfx_compute is false. Reviewed-by: David Rosca Reviewed-by: Qiang Yu Part-of: --- src/gallium/drivers/radeonsi/si_buffer.c | 20 +++++++++++++++++++ .../drivers/radeonsi/si_compute_blit.c | 3 +++ src/gallium/drivers/radeonsi/si_pipe.h | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c index 24e707c7d0d..5105e7dc020 100644 --- a/src/gallium/drivers/radeonsi/si_buffer.c +++ b/src/gallium/drivers/radeonsi/si_buffer.c @@ -841,6 +841,24 @@ void si_clear_buffer(struct si_context *sctx, struct pipe_resource *dst, si_cp_dma_clear_buffer(sctx, &sctx->gfx_cs, dst, offset, size, *clear_value); } +void si_resource_copy_buffer(struct pipe_context *ctx, struct pipe_resource *dst, + unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, unsigned src_level, + const struct pipe_box *src_box) +{ + struct si_context *sctx = (struct si_context *)ctx; + + /* This function only handles buffers. */ + if (dst->target != PIPE_BUFFER || src->target != PIPE_BUFFER) { + assert(false); + return; + } + + si_barrier_before_simple_buffer_op(sctx, 0, dst, src); + si_copy_buffer(sctx, dst, src, dstx, src_box->x, src_box->width); + si_barrier_after_simple_buffer_op(sctx, 0, dst, src); +} + static uint64_t si_resource_get_address(struct pipe_screen *screen, struct pipe_resource *resource) { @@ -898,4 +916,6 @@ void si_init_buffer_functions(struct si_context *sctx) sctx->b.texture_subdata = u_default_texture_subdata; sctx->b.buffer_subdata = si_buffer_subdata; sctx->b.resource_commit = si_resource_commit; + if (!sctx->b.resource_copy_region) + sctx->b.resource_copy_region = si_resource_copy_buffer; } diff --git a/src/gallium/drivers/radeonsi/si_compute_blit.c b/src/gallium/drivers/radeonsi/si_compute_blit.c index 404c471cb3e..0bd32b27109 100644 --- a/src/gallium/drivers/radeonsi/si_compute_blit.c +++ b/src/gallium/drivers/radeonsi/si_compute_blit.c @@ -156,6 +156,9 @@ bool si_compute_clear_copy_buffer(struct si_context *sctx, struct pipe_resource assert(!src || src->target != PIPE_BUFFER || src_offset + size <= src->width0); bool is_copy = src != NULL; + if (!sctx->screen->has_gfx_compute) + return false; + struct ac_cs_clear_copy_buffer_options options = { .nir_options = sctx->screen->nir_options, .info = &sctx->screen->info, diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index d00f18de53d..73737381657 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1445,6 +1445,10 @@ void si_clear_buffer(struct si_context *sctx, struct pipe_resource *dst, bool render_condition_enable); void si_copy_buffer(struct si_context *sctx, struct pipe_resource *dst, struct pipe_resource *src, uint64_t dst_offset, uint64_t src_offset, unsigned size); +void si_resource_copy_buffer(struct pipe_context *ctx, struct pipe_resource *dst, + unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, unsigned src_level, + const struct pipe_box *src_box); /* si_clear.c */ #define SI_CLEAR_TYPE_CMASK (1 << 0)