v3d: implement gallium APIs for OpenCL support

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25362>
This commit is contained in:
Karol Herbst 2023-09-23 11:56:04 +02:00 committed by Marge Bot
parent 742984a325
commit 3889a8e26c
4 changed files with 77 additions and 1 deletions

View file

@ -100,6 +100,7 @@ v3d_memory_barrier(struct pipe_context *pctx, unsigned int flags)
* else we flush the job automatically when we needed.
*/
const unsigned int flush_flags = PIPE_BARRIER_SHADER_BUFFER |
PIPE_BARRIER_GLOBAL_BUFFER |
PIPE_BARRIER_IMAGE;
if (!(flags & flush_flags))
@ -287,6 +288,10 @@ v3d_context_destroy(struct pipe_context *pctx)
v3d_flush(pctx);
util_dynarray_foreach(&v3d->global_buffers, struct pipe_resource *, res) {
pipe_resource_reference(res, NULL);
}
if (v3d->blitter)
util_blitter_destroy(v3d->blitter);
@ -424,6 +429,7 @@ v3d_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
v3d->sample_mask = (1 << V3D_MAX_SAMPLES) - 1;
v3d->active_queries = true;
util_dynarray_init(&v3d->global_buffers, v3d);
return &v3d->base;

View file

@ -35,6 +35,7 @@
#include "pipe/p_state.h"
#include "util/bitset.h"
#include "util/slab.h"
#include "util/u_dynarray.h"
#include "xf86drm.h"
#include "drm-uapi/v3d_drm.h"
#include "v3d_screen.h"
@ -638,6 +639,8 @@ struct v3d_context {
int in_fence_fd;
/** Handle of the syncobj that holds in_fence_fd for submission. */
uint32_t in_syncobj;
struct util_dynarray global_buffers;
/** @} */
};

View file

@ -1110,6 +1110,22 @@ v3d_create_compute_state(struct pipe_context *pctx,
(void *)cso->prog);
}
static void
v3d_get_compute_state_info(struct pipe_context *pctx,
void *cso,
struct pipe_compute_state_object_info *info)
{
struct v3d_context *v3d = v3d_context(pctx);
/* this API requires compiled shaders */
v3d_compute_state_bind(pctx, cso);
v3d_update_compiled_cs(v3d);
info->max_threads = V3D_CHANNELS * v3d->prog.compute->prog_data.base->threads;
info->preferred_simd_size = V3D_CHANNELS;
info->private_memory = 0;
}
void
v3d_program_init(struct pipe_context *pctx)
{
@ -1132,6 +1148,7 @@ v3d_program_init(struct pipe_context *pctx)
pctx->create_compute_state = v3d_create_compute_state;
pctx->delete_compute_state = v3d_shader_state_delete;
pctx->bind_compute_state = v3d_compute_state_bind;
pctx->get_compute_state_info = v3d_get_compute_state_info;
}
v3d->prog.cache[MESA_SHADER_VERTEX] =

View file

@ -1534,6 +1534,13 @@ v3d_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
"shared_vars");
}
util_dynarray_foreach(&v3d->global_buffers, struct pipe_resource *, res) {
if (!*res)
continue;
struct v3d_resource *rsc = v3d_resource(*res);
v3d_job_add_bo(job, rsc->bo);
}
struct v3d_cl_reloc uniforms = v3d_write_uniforms(v3d, job,
v3d->prog.compute,
PIPE_SHADER_COMPUTE);
@ -1593,6 +1600,14 @@ v3d_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
rsc->compute_written = true;
}
util_dynarray_foreach(&v3d->global_buffers, struct pipe_resource *, res) {
struct v3d_resource *rsc = v3d_resource(*res);
if (!rsc)
continue;
rsc->writes++;
rsc->compute_written = true;
}
v3d_bo_unreference(&uniforms.bo);
v3d_bo_unreference(&v3d->compute_shared_memory);
}
@ -1787,6 +1802,39 @@ v3d_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
stencil, x, y, w, h);
}
static void
v3d_set_global_binding(struct pipe_context *pctx,
unsigned first, unsigned count,
struct pipe_resource **resources,
uint32_t **handles)
{
struct v3d_context *v3d = v3d_context(pctx);
unsigned old_size = util_dynarray_num_elements(&v3d->global_buffers, *resources);
if (old_size < first + count) {
/* we are screwed no matter what */
if (!util_dynarray_grow(&v3d->global_buffers, *resources, (first + count) - old_size))
unreachable("out of memory");
for (unsigned i = old_size; i < first + count; i++)
*util_dynarray_element(&v3d->global_buffers, struct pipe_resource *, i) = NULL;
}
for (unsigned i = first; i < first + count; ++i) {
struct pipe_resource **res = util_dynarray_element(&v3d->global_buffers, struct pipe_resource *, first + i);
if (resources && resources[i]) {
struct v3d_resource *rsc = v3d_resource(resources[i]);
pipe_resource_reference(res, resources[i]);
/* We have to add the base address as there might be an existing offset */
*handles[i] += rsc->bo->offset;
} else {
pipe_resource_reference(res, NULL);
}
}
}
void
v3dX(draw_init)(struct pipe_context *pctx)
{
@ -1794,6 +1842,8 @@ v3dX(draw_init)(struct pipe_context *pctx)
pctx->clear = v3d_clear;
pctx->clear_render_target = v3d_clear_render_target;
pctx->clear_depth_stencil = v3d_clear_depth_stencil;
if (v3d_context(pctx)->screen->has_csd)
if (v3d_context(pctx)->screen->has_csd) {
pctx->launch_grid = v3d_launch_grid;
pctx->set_global_binding = v3d_set_global_binding;
}
}