asahi: implement set_global_binding

Signed-off-by: Karol Herbst <git@karolherbst.de>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25052>
This commit is contained in:
Karol Herbst 2023-02-03 18:42:50 +01:00 committed by Marge Bot
parent 9b59602338
commit 91f4062959
3 changed files with 55 additions and 0 deletions

View file

@ -1454,6 +1454,7 @@ agx_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
pctx->priv = priv;
util_dynarray_init(&ctx->writer, ctx);
util_dynarray_init(&ctx->global_buffers, ctx);
pctx->stream_uploader = u_upload_create_default(pctx);
if (!pctx->stream_uploader) {

View file

@ -3316,6 +3316,14 @@ agx_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
&batch->pool, info->grid, sizeof(info->grid), 4);
}
util_dynarray_foreach(&ctx->global_buffers, struct pipe_resource *, res) {
if (!*res)
continue;
struct agx_resource *buffer = agx_resource(*res);
agx_batch_writes(batch, buffer);
}
struct agx_uncompiled_shader *uncompiled =
ctx->stage[PIPE_SHADER_COMPUTE].shader;
@ -3392,6 +3400,48 @@ agx_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
batch->uniforms.tables[AGX_SYSVAL_TABLE_GRID] = 0;
}
static void
agx_set_global_binding(struct pipe_context *pipe, unsigned first,
unsigned count, struct pipe_resource **resources,
uint32_t **handles)
{
struct agx_context *ctx = agx_context(pipe);
unsigned old_size =
util_dynarray_num_elements(&ctx->global_buffers, *resources);
if (old_size < first + count) {
/* we are screwed no matter what */
if (!util_dynarray_grow(&ctx->global_buffers, *resources,
(first + count) - old_size))
unreachable("out of memory");
for (unsigned i = old_size; i < first + count; i++)
*util_dynarray_element(&ctx->global_buffers, struct pipe_resource *,
i) = NULL;
}
for (unsigned i = 0; i < count; ++i) {
struct pipe_resource **res = util_dynarray_element(
&ctx->global_buffers, struct pipe_resource *, first + i);
if (resources && resources[i]) {
pipe_resource_reference(res, resources[i]);
/* The handle points to uint32_t, but space is allocated for 64
* bits. We need to respect the offset passed in. This interface
* is so bad.
*/
uint64_t addr = 0;
struct agx_resource *rsrc = agx_resource(resources[i]);
memcpy(&addr, handles[i], sizeof(addr));
addr += rsrc->bo->ptr.gpu;
memcpy(handles[i], &addr, sizeof(addr));
} else {
pipe_resource_reference(res, NULL);
}
}
}
void agx_init_state_functions(struct pipe_context *ctx);
void
@ -3440,6 +3490,7 @@ agx_init_state_functions(struct pipe_context *ctx)
ctx->surface_destroy = agx_surface_destroy;
ctx->draw_vbo = agx_draw_vbo;
ctx->launch_grid = agx_launch_grid;
ctx->set_global_binding = agx_set_global_binding;
ctx->texture_barrier = agx_texture_barrier;
ctx->get_compute_state_info = agx_get_compute_state_info;
}

View file

@ -445,6 +445,9 @@ struct agx_context {
*/
struct util_dynarray writer;
/* Bound CL global buffers */
struct util_dynarray global_buffers;
struct agx_meta_cache meta;
uint32_t syncobj;