panfrost: Handle context_init errors correctly
This fix OpenCL CTS "multiple_device_context/test_multiples" failures. Also improve create_context/destroy error management a bit. Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com> Reviewed-by: Eric R. Smith <eric.smith@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30150>
This commit is contained in:
committed by
Marge Bot
parent
668bde4421
commit
71a24a0c5e
@@ -551,21 +551,25 @@ panfrost_destroy(struct pipe_context *pipe)
|
||||
|
||||
pan_screen(pipe->screen)->vtbl.context_cleanup(panfrost);
|
||||
|
||||
_mesa_hash_table_destroy(panfrost->writers, NULL);
|
||||
if (panfrost->writers)
|
||||
_mesa_hash_table_destroy(panfrost->writers, NULL);
|
||||
|
||||
if (panfrost->blitter)
|
||||
util_blitter_destroy(panfrost->blitter);
|
||||
|
||||
util_unreference_framebuffer_state(&panfrost->pipe_framebuffer);
|
||||
u_upload_destroy(pipe->stream_uploader);
|
||||
if (pipe->stream_uploader)
|
||||
u_upload_destroy(pipe->stream_uploader);
|
||||
|
||||
panfrost_pool_cleanup(&panfrost->descs);
|
||||
panfrost_pool_cleanup(&panfrost->shaders);
|
||||
panfrost_afbc_context_destroy(panfrost);
|
||||
|
||||
drmSyncobjDestroy(panfrost_device_fd(dev), panfrost->in_sync_obj);
|
||||
if (panfrost->in_sync_fd != -1)
|
||||
if (panfrost->in_sync_fd != -1) {
|
||||
close(panfrost->in_sync_fd);
|
||||
panfrost->in_sync_fd = -1;
|
||||
}
|
||||
|
||||
drmSyncobjDestroy(panfrost_device_fd(dev), panfrost->syncobj);
|
||||
ralloc_free(pipe);
|
||||
@@ -872,9 +876,25 @@ struct pipe_context *
|
||||
panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
|
||||
{
|
||||
struct panfrost_context *ctx = rzalloc(NULL, struct panfrost_context);
|
||||
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
struct pipe_context *gallium = (struct pipe_context *)ctx;
|
||||
struct panfrost_device *dev = pan_device(screen);
|
||||
|
||||
int ret;
|
||||
|
||||
/* Create a syncobj in a signaled state. Will be updated to point to the
|
||||
* last queued job out_sync every time we submit a new job.
|
||||
*/
|
||||
ret = drmSyncobjCreate(panfrost_device_fd(dev), DRM_SYNCOBJ_CREATE_SIGNALED,
|
||||
&ctx->syncobj);
|
||||
if (ret) {
|
||||
ralloc_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gallium->screen = screen;
|
||||
|
||||
gallium->destroy = panfrost_destroy;
|
||||
@@ -969,21 +989,17 @@ panfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
|
||||
ctx->sample_mask = ~0;
|
||||
ctx->active_queries = true;
|
||||
|
||||
int ASSERTED ret;
|
||||
|
||||
/* Create a syncobj in a signaled state. Will be updated to point to the
|
||||
* last queued job out_sync every time we submit a new job.
|
||||
*/
|
||||
ret = drmSyncobjCreate(panfrost_device_fd(dev), DRM_SYNCOBJ_CREATE_SIGNALED,
|
||||
&ctx->syncobj);
|
||||
assert(!ret && ctx->syncobj);
|
||||
|
||||
/* Sync object/FD used for NATIVE_FENCE_FD. */
|
||||
ctx->in_sync_fd = -1;
|
||||
ret = drmSyncobjCreate(panfrost_device_fd(dev), 0, &ctx->in_sync_obj);
|
||||
assert(!ret);
|
||||
|
||||
pan_screen(screen)->vtbl.context_init(ctx);
|
||||
ret = pan_screen(screen)->vtbl.context_init(ctx);
|
||||
|
||||
if (ret) {
|
||||
gallium->destroy(gallium);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gallium;
|
||||
}
|
||||
@@ -992,5 +1008,6 @@ void
|
||||
panfrost_context_reinit(struct panfrost_context *ctx)
|
||||
{
|
||||
pan_screen(ctx->base.screen)->vtbl.context_cleanup(ctx);
|
||||
pan_screen(ctx->base.screen)->vtbl.context_init(ctx);
|
||||
ASSERTED int ret = pan_screen(ctx->base.screen)->vtbl.context_init(ctx);
|
||||
assert(!ret);
|
||||
}
|
||||
|
||||
@@ -945,7 +945,7 @@ GENX(csf_launch_draw)(struct panfrost_batch *batch,
|
||||
|
||||
#define POSITION_FIFO_SIZE (64 * 1024)
|
||||
|
||||
void
|
||||
int
|
||||
GENX(csf_init_context)(struct panfrost_context *ctx)
|
||||
{
|
||||
struct panfrost_device *dev = pan_device(ctx->base.screen);
|
||||
@@ -969,27 +969,42 @@ GENX(csf_init_context)(struct panfrost_context *ctx)
|
||||
int ret =
|
||||
drmIoctl(panfrost_device_fd(dev), DRM_IOCTL_PANTHOR_GROUP_CREATE, &gc);
|
||||
|
||||
assert(!ret);
|
||||
if (ret)
|
||||
goto err_group_create;
|
||||
|
||||
ctx->csf.group_handle = gc.group_handle;
|
||||
|
||||
struct drm_panthor_group_destroy gd = {
|
||||
.group_handle = ctx->csf.group_handle,
|
||||
};
|
||||
|
||||
/* Get tiler heap */
|
||||
struct drm_panthor_tiler_heap_create thc = {
|
||||
.vm_id = pan_kmod_vm_handle(dev->kmod.vm),
|
||||
.chunk_size = pan_screen(ctx->base.screen)->csf_tiler_heap.chunk_size,
|
||||
.initial_chunk_count = pan_screen(ctx->base.screen)->csf_tiler_heap.initial_chunks,
|
||||
.initial_chunk_count =
|
||||
pan_screen(ctx->base.screen)->csf_tiler_heap.initial_chunks,
|
||||
.max_chunks = pan_screen(ctx->base.screen)->csf_tiler_heap.max_chunks,
|
||||
.target_in_flight = 65535,
|
||||
};
|
||||
ret = drmIoctl(panfrost_device_fd(dev), DRM_IOCTL_PANTHOR_TILER_HEAP_CREATE,
|
||||
&thc);
|
||||
|
||||
assert(!ret);
|
||||
if (ret)
|
||||
goto err_tiler_heap;
|
||||
|
||||
ctx->csf.heap.handle = thc.handle;
|
||||
|
||||
struct drm_panthor_tiler_heap_destroy thd = {
|
||||
.handle = ctx->csf.heap.handle,
|
||||
};
|
||||
|
||||
ctx->csf.heap.desc_bo =
|
||||
panfrost_bo_create(dev, pan_size(TILER_HEAP), 0, "Tiler Heap");
|
||||
|
||||
if (ctx->csf.heap.desc_bo == NULL)
|
||||
goto err_tiler_heap_desc_bo;
|
||||
|
||||
pan_pack(ctx->csf.heap.desc_bo->ptr.cpu, TILER_HEAP, heap) {
|
||||
heap.size = pan_screen(ctx->base.screen)->csf_tiler_heap.chunk_size;
|
||||
heap.base = thc.first_heap_chunk_gpu_va;
|
||||
@@ -999,12 +1014,16 @@ GENX(csf_init_context)(struct panfrost_context *ctx)
|
||||
|
||||
ctx->csf.tmp_geom_bo = panfrost_bo_create(
|
||||
dev, POSITION_FIFO_SIZE, PAN_BO_INVISIBLE, "Temporary Geometry buffer");
|
||||
assert(ctx->csf.tmp_geom_bo);
|
||||
|
||||
if (ctx->csf.tmp_geom_bo == NULL)
|
||||
goto err_tiler_heap_tmp_geom_bo;
|
||||
|
||||
/* Setup the tiler heap */
|
||||
struct panfrost_bo *cs_bo =
|
||||
panfrost_bo_create(dev, 4096, 0, "Temporary CS buffer");
|
||||
assert(cs_bo);
|
||||
|
||||
if (cs_bo == NULL)
|
||||
goto err_tiler_heap_cs_bo;
|
||||
|
||||
struct cs_buffer init_buffer = {
|
||||
.cpu = cs_bo->ptr.cpu,
|
||||
@@ -1039,19 +1058,40 @@ GENX(csf_init_context)(struct panfrost_context *ctx)
|
||||
csf_prepare_qsubmit(ctx, &qsubmit, 0, cs_start, cs_size, &sync, 1);
|
||||
csf_prepare_gsubmit(ctx, &gsubmit, &qsubmit, 1);
|
||||
ret = csf_submit_gsubmit(ctx, &gsubmit);
|
||||
assert(!ret);
|
||||
|
||||
if (ret)
|
||||
goto err_g_submit;
|
||||
|
||||
/* Wait before freeing the buffer. */
|
||||
ret = drmSyncobjWait(panfrost_device_fd(dev), &ctx->syncobj, 1, INT64_MAX,
|
||||
0, NULL);
|
||||
ret = drmSyncobjWait(panfrost_device_fd(dev), &ctx->syncobj, 1, INT64_MAX, 0,
|
||||
NULL);
|
||||
assert(!ret);
|
||||
|
||||
panfrost_bo_unreference(cs_bo);
|
||||
|
||||
ctx->csf.is_init = true;
|
||||
return 0;
|
||||
err_g_submit:
|
||||
panfrost_bo_unreference(cs_bo);
|
||||
err_tiler_heap_cs_bo:
|
||||
panfrost_bo_unreference(ctx->csf.tmp_geom_bo);
|
||||
err_tiler_heap_tmp_geom_bo:
|
||||
panfrost_bo_unreference(ctx->csf.heap.desc_bo);
|
||||
err_tiler_heap_desc_bo:
|
||||
drmIoctl(panfrost_device_fd(dev), DRM_IOCTL_PANTHOR_TILER_HEAP_DESTROY,
|
||||
&thd);
|
||||
err_tiler_heap:
|
||||
drmIoctl(panfrost_device_fd(dev), DRM_IOCTL_PANTHOR_GROUP_DESTROY, &gd);
|
||||
err_group_create:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
GENX(csf_cleanup_context)(struct panfrost_context *ctx)
|
||||
{
|
||||
if (!ctx->csf.is_init)
|
||||
return;
|
||||
|
||||
struct panfrost_device *dev = pan_device(ctx->base.screen);
|
||||
struct drm_panthor_tiler_heap_destroy thd = {
|
||||
.handle = ctx->csf.heap.handle,
|
||||
@@ -1076,4 +1116,5 @@ GENX(csf_cleanup_context)(struct panfrost_context *ctx)
|
||||
assert(!ret);
|
||||
|
||||
panfrost_bo_unreference(ctx->csf.heap.desc_bo);
|
||||
ctx->csf.is_init = false;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ struct panfrost_csf_batch {
|
||||
};
|
||||
|
||||
struct panfrost_csf_context {
|
||||
bool is_init;
|
||||
uint32_t group_handle;
|
||||
|
||||
struct {
|
||||
@@ -70,7 +71,7 @@ struct pipe_draw_info;
|
||||
struct pipe_grid_info;
|
||||
struct pipe_draw_start_count_bias;
|
||||
|
||||
void GENX(csf_init_context)(struct panfrost_context *ctx);
|
||||
int GENX(csf_init_context)(struct panfrost_context *ctx);
|
||||
void GENX(csf_cleanup_context)(struct panfrost_context *ctx);
|
||||
|
||||
void GENX(csf_init_batch)(struct panfrost_batch *batch);
|
||||
|
||||
@@ -49,9 +49,10 @@ struct pipe_draw_info;
|
||||
struct pipe_grid_info;
|
||||
struct pipe_draw_start_count_bias;
|
||||
|
||||
static inline void
|
||||
static inline int
|
||||
GENX(jm_init_context)(struct panfrost_context *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
||||
@@ -71,7 +71,7 @@ struct panfrost_vtable {
|
||||
void (*context_populate_vtbl)(struct pipe_context *pipe);
|
||||
|
||||
/* Initialize/cleanup a Gallium context */
|
||||
void (*context_init)(struct panfrost_context *ctx);
|
||||
int (*context_init)(struct panfrost_context *ctx);
|
||||
void (*context_cleanup)(struct panfrost_context *ctx);
|
||||
|
||||
/* Device-dependent initialization/cleanup of a panfrost_batch */
|
||||
|
||||
Reference in New Issue
Block a user