gallium: add pipe_context::image_copy_buffer

this is a more explicit version of the copying used in resource_copy_region
which also provides stride info

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35769>
This commit is contained in:
Mike Blumenkrantz
2025-06-26 08:14:28 -04:00
committed by Marge Bot
parent f946167e30
commit 8b8a06f6c3
7 changed files with 191 additions and 0 deletions
@@ -465,6 +465,21 @@ dd_dump_resource_copy_region(struct dd_draw_state *dstate,
DUMP_M_ADDR(box, info, src_box);
}
static void
dd_dump_image_copy_buffer(struct dd_draw_state *dstate,
struct call_image_copy_buffer *info,
FILE *f)
{
fprintf(f, "%s:\n", __func__+8);
DUMP_M(resource, info, dst);
DUMP_M(resource, info, src);
DUMP_M(uint, info, buffer_offset);
DUMP_M(uint, info, buffer_stride);
DUMP_M(uint, info, buffer_layer_stride);
DUMP_M(uint, info, level);
DUMP_M_ADDR(box, info, box);
}
static void
dd_dump_blit(struct dd_draw_state *dstate, struct pipe_blit_info *info, FILE *f)
{
@@ -652,6 +667,10 @@ dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call)
dd_dump_resource_copy_region(state,
&call->info.resource_copy_region, f);
break;
case CALL_IMAGE_COPY_BUFFER:
dd_dump_image_copy_buffer(state,
&call->info.image_copy_buffer, f);
break;
case CALL_BLIT:
dd_dump_blit(state, &call->info.blit, f);
break;
@@ -732,6 +751,10 @@ dd_unreference_copy_of_call(struct dd_call *dst)
pipe_resource_reference(&dst->info.resource_copy_region.dst, NULL);
pipe_resource_reference(&dst->info.resource_copy_region.src, NULL);
break;
case CALL_IMAGE_COPY_BUFFER:
pipe_resource_reference(&dst->info.image_copy_buffer.dst, NULL);
pipe_resource_reference(&dst->info.image_copy_buffer.src, NULL);
break;
case CALL_BLIT:
pipe_resource_reference(&dst->info.blit.dst.resource, NULL);
pipe_resource_reference(&dst->info.blit.src.resource, NULL);
@@ -1427,6 +1450,36 @@ dd_context_resource_copy_region(struct pipe_context *_pipe,
dd_after_draw(dctx, record);
}
static void
dd_context_image_copy_buffer(struct pipe_context *_pipe,
struct pipe_resource *dst,
struct pipe_resource *src,
unsigned buffer_offset,
unsigned buffer_stride,
unsigned buffer_layer_stride,
unsigned level,
const struct pipe_box *box)
{
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
struct dd_draw_record *record = dd_create_record(dctx);
record->call.type = CALL_IMAGE_COPY_BUFFER;
record->call.info.image_copy_buffer.dst = NULL;
pipe_resource_reference(&record->call.info.image_copy_buffer.dst, dst);
pipe_resource_reference(&record->call.info.image_copy_buffer.src, src);
record->call.info.image_copy_buffer.buffer_offset = buffer_offset;
record->call.info.image_copy_buffer.buffer_stride = buffer_stride;
record->call.info.image_copy_buffer.buffer_layer_stride = buffer_layer_stride;
record->call.info.image_copy_buffer.level = level;
record->call.info.image_copy_buffer.box = *box;
dd_before_draw(dctx, record);
pipe->image_copy_buffer(pipe,
dst, src, buffer_offset, buffer_stride, buffer_layer_stride, level, box);
dd_after_draw(dctx, record);
}
static void
dd_context_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info)
{
@@ -1843,6 +1896,7 @@ dd_init_draw_functions(struct dd_context *dctx)
CTX_INIT(draw_vbo);
CTX_INIT(launch_grid);
CTX_INIT(resource_copy_region);
CTX_INIT(image_copy_buffer);
CTX_INIT(blit);
CTX_INIT(clear);
CTX_INIT(clear_render_target);
@@ -64,6 +64,7 @@ enum call_type
CALL_DRAW_VBO,
CALL_LAUNCH_GRID,
CALL_RESOURCE_COPY_REGION,
CALL_IMAGE_COPY_BUFFER,
CALL_BLIT,
CALL_FLUSH_RESOURCE,
CALL_CLEAR,
@@ -90,6 +91,17 @@ struct call_resource_copy_region
struct pipe_box src_box;
};
struct call_image_copy_buffer
{
struct pipe_resource *dst;
struct pipe_resource *src;
unsigned buffer_offset;
unsigned buffer_stride;
unsigned buffer_layer_stride;
unsigned level;
struct pipe_box box;
};
struct call_clear
{
unsigned buffers;
@@ -182,6 +194,7 @@ struct dd_call
struct call_draw_info draw_vbo;
struct pipe_grid_info launch_grid;
struct call_resource_copy_region resource_copy_region;
struct call_image_copy_buffer image_copy_buffer;
struct pipe_blit_info blit;
struct pipe_resource *flush_resource;
struct call_clear clear;
@@ -312,6 +312,17 @@ static void noop_resource_copy_region(struct pipe_context *ctx,
{
}
static void noop_image_copy_buffer(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_resource *src,
unsigned buffer_offset,
unsigned buffer_stride,
unsigned buffer_layer_stride,
unsigned level,
const struct pipe_box *box)
{
}
static void noop_blit(struct pipe_context *ctx,
const struct pipe_blit_info *info)
@@ -427,6 +438,7 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen,
ctx->clear_render_target = noop_clear_render_target;
ctx->clear_depth_stencil = noop_clear_depth_stencil;
ctx->resource_copy_region = noop_resource_copy_region;
ctx->image_copy_buffer = noop_image_copy_buffer;
ctx->generate_mipmap = noop_generate_mipmap;
ctx->blit = noop_blit;
ctx->flush_resource = noop_flush_resource;
@@ -1341,6 +1341,37 @@ trace_context_resource_copy_region(struct pipe_context *_pipe,
}
static void
trace_context_image_copy_buffer(struct pipe_context *_pipe,
struct pipe_resource *dst,
struct pipe_resource *src,
unsigned buffer_offset,
unsigned buffer_stride,
unsigned buffer_layer_stride,
unsigned level,
const struct pipe_box *box)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
trace_dump_call_begin("pipe_context", "image_copy_buffer");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, dst);
trace_dump_arg(ptr, src);
trace_dump_arg(uint, buffer_offset);
trace_dump_arg(uint, buffer_stride);
trace_dump_arg(uint, buffer_layer_stride);
trace_dump_arg(uint, level);
trace_dump_arg(box, box);
pipe->image_copy_buffer(pipe,
dst, src, buffer_offset, buffer_stride, buffer_layer_stride, level, box);
trace_dump_call_end();
}
static void
trace_context_blit(struct pipe_context *_pipe,
const struct pipe_blit_info *_info)
@@ -2532,6 +2563,7 @@ trace_context_create(struct trace_screen *tr_scr,
/* this is lavapipe-only and can't be traced */
tr_ctx->base.stream_output_target_offset = pipe->stream_output_target_offset;
TR_CTX_INIT(resource_copy_region);
TR_CTX_INIT(image_copy_buffer);
TR_CTX_INIT(blit);
TR_CTX_INIT(flush_resource);
TR_CTX_INIT(clear);
@@ -4443,6 +4443,70 @@ tc_launch_grid(struct pipe_context *_pipe,
tc_add_all_compute_bindings_to_buffer_list(tc);
}
struct tc_image_copy_buffer {
struct tc_call_base base;
unsigned buffer_stride;
unsigned buffer_layer_stride;
unsigned level;
unsigned buffer_offset;
struct pipe_box box;
struct pipe_resource *dst;
struct pipe_resource *src;
};
static uint16_t ALWAYS_INLINE
tc_call_image_copy_buffer(struct pipe_context *pipe, void *call)
{
struct tc_image_copy_buffer *p = to_call(call, tc_image_copy_buffer);
pipe->image_copy_buffer(pipe, p->dst, p->src, p->buffer_offset, p->buffer_stride,
p->buffer_layer_stride, p->level, &p->box);
tc_drop_resource_reference(p->dst);
tc_drop_resource_reference(p->src);
return call_size(tc_image_copy_buffer);
}
static void
tc_image_copy_buffer(struct pipe_context *_pipe,
struct pipe_resource *dst,
struct pipe_resource *src,
unsigned buffer_offset,
unsigned buffer_stride,
unsigned buffer_layer_stride,
unsigned level,
const struct pipe_box *box)
{
struct threaded_context *tc = threaded_context(_pipe);
struct threaded_resource *tbuf = dst->target == PIPE_BUFFER ? threaded_resource(dst) : threaded_resource(src);
struct threaded_resource *timg = dst->target == PIPE_BUFFER ? threaded_resource(src) : threaded_resource(dst);
struct tc_image_copy_buffer *p =
tc_add_call(tc, TC_CALL_image_copy_buffer,
tc_image_copy_buffer);
if (dst->target == PIPE_BUFFER)
tc_buffer_disable_cpu_storage(&tbuf->b);
if (tc->options.parse_renderpass_info && tc->in_renderpass)
tc_check_fb_access(tc, NULL, &timg->b);
tc_set_resource_batch_usage(tc, dst);
tc_set_resource_reference(&p->dst, dst);
p->buffer_offset = buffer_offset;
p->buffer_stride = buffer_stride;
p->buffer_layer_stride = buffer_layer_stride;
p->level = level;
p->box = *box;
tc_set_resource_batch_usage(tc, src);
tc_set_resource_reference(&p->src, src);
struct tc_buffer_list *next = &tc->buffer_lists[tc->next_buf_list];
tc_add_to_buffer_list(next, &tbuf->b);
if (dst->target == PIPE_BUFFER)
util_range_add(&tbuf->b, &tbuf->valid_buffer_range,
buffer_offset, buffer_offset + box->width);
}
static uint16_t ALWAYS_INLINE
tc_call_resource_copy_region(struct pipe_context *pipe, void *call)
{
@@ -5456,6 +5520,7 @@ threaded_context_create(struct pipe_context *pipe,
CTX_INIT(draw_vertex_state);
CTX_INIT(launch_grid);
CTX_INIT(resource_copy_region);
CTX_INIT(image_copy_buffer);
CTX_INIT(blit);
CTX_INIT(clear);
CTX_INIT(clear_render_target);
@@ -101,3 +101,4 @@ CALL(delete_tes_state)
CALL(begin_intel_perf_query)
CALL(end_intel_perf_query)
CALL(image_copy_buffer)
+14
View File
@@ -693,6 +693,20 @@ struct pipe_context {
unsigned src_level,
const struct pipe_box *src_box);
/**
* Perform a copy between an image and a buffer in either direction.
* buffer_stride=0 or buffer_layer_stride=0 means tightly packed on that axis
* Resources with nr_samples > 1 are not allowed.
*/
void (*image_copy_buffer)(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_resource *src,
unsigned buffer_offset,
unsigned buffer_stride,
unsigned buffer_layer_stride,
unsigned level,
const struct pipe_box *box);
/* Optimal hardware path for blitting pixels.
* Scaling, format conversion, up- and downsampling (resolve) are allowed.
*/