panfrost: Move fence code to pan_fence.{c,h}

Before adding support for NATIVE_FENCE_FD, let's move the fencing logic
to a dedicated file to avoid spreading the code in different places.

Suggested-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19774>
This commit is contained in:
Boris Brezillon 2022-11-30 10:00:02 +01:00 committed by Marge Bot
parent 3bd0f5c502
commit 8910533a5a
7 changed files with 174 additions and 98 deletions

View file

@ -21,6 +21,7 @@
files_panfrost = files(
'pan_disk_cache.c',
'pan_fence.c',
'pan_helpers.c',
'pan_public.h',
'pan_screen.c',

View file

@ -47,6 +47,7 @@
#include "util/u_math.h"
#include "util/u_debug_cb.h"
#include "pan_fence.h"
#include "pan_screen.h"
#include "pan_util.h"
#include "decode.h"

View file

@ -107,12 +107,6 @@ struct panfrost_query {
bool msaa;
};
struct pipe_fence_handle {
struct pipe_reference reference;
uint32_t syncobj;
bool signaled;
};
struct panfrost_streamout_target {
struct pipe_stream_output_target base;
uint32_t offset;

View file

@ -0,0 +1,122 @@
/*
* Copyright (C) 2008 VMware, Inc.
* Copyright (C) 2014 Broadcom
* Copyright (C) 2018 Alyssa Rosenzweig
* Copyright (C) 2019 Collabora, Ltd.
* Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "pan_context.h"
#include "pan_fence.h"
#include "pan_screen.h"
#include "util/os_time.h"
#include "util/u_inlines.h"
void
panfrost_fence_reference(struct pipe_screen *pscreen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
struct panfrost_device *dev = pan_device(pscreen);
struct pipe_fence_handle *old = *ptr;
if (pipe_reference(&old->reference, &fence->reference)) {
drmSyncobjDestroy(dev->fd, old->syncobj);
free(old);
}
*ptr = fence;
}
bool
panfrost_fence_finish(struct pipe_screen *pscreen,
struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
struct panfrost_device *dev = pan_device(pscreen);
int ret;
if (fence->signaled)
return true;
uint64_t abs_timeout = os_time_get_absolute_timeout(timeout);
if (abs_timeout == OS_TIMEOUT_INFINITE)
abs_timeout = INT64_MAX;
ret = drmSyncobjWait(dev->fd, &fence->syncobj,
1,
abs_timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL,
NULL);
fence->signaled = (ret >= 0);
return fence->signaled;
}
struct pipe_fence_handle *
panfrost_fence_create(struct panfrost_context *ctx)
{
struct pipe_fence_handle *f = calloc(1, sizeof(*f));
if (!f)
return NULL;
struct panfrost_device *dev = pan_device(ctx->base.screen);
int fd = -1, ret;
/* Snapshot the last rendering out fence. We'd rather have another
* syncobj instead of a sync file, but this is all we get.
* (HandleToFD/FDToHandle just gives you another syncobj ID for the
* same syncobj).
*/
ret = drmSyncobjExportSyncFile(dev->fd, ctx->syncobj, &fd);
if (ret || fd == -1) {
fprintf(stderr, "export failed\n");
goto err_free_fence;
}
ret = drmSyncobjCreate(dev->fd, 0, &f->syncobj);
if (ret) {
fprintf(stderr, "create syncobj failed\n");
goto err_close_fd;
}
ret = drmSyncobjImportSyncFile(dev->fd, f->syncobj, fd);
if (ret) {
fprintf(stderr, "create syncobj failed\n");
goto err_destroy_syncobj;
}
assert(f->syncobj != ctx->syncobj);
close(fd);
pipe_reference_init(&f->reference, 1);
return f;
err_destroy_syncobj:
drmSyncobjDestroy(dev->fd, f->syncobj);
err_close_fd:
close(fd);
err_free_fence:
free(f);
return NULL;
}

View file

@ -0,0 +1,49 @@
/*
* Copyright 2018-2019 Alyssa Rosenzweig
* Copyright 2018-2019 Collabora, Ltd.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "pipe/p_state.h"
struct panfrost_context;
struct pipe_fence_handle {
struct pipe_reference reference;
uint32_t syncobj;
bool signaled;
};
void
panfrost_fence_reference(struct pipe_screen *pscreen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence);
bool
panfrost_fence_finish(struct pipe_screen *pscreen,
struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout);
struct pipe_fence_handle *
panfrost_fence_create(struct panfrost_context *ctx);

View file

@ -44,6 +44,7 @@
#include "drm-uapi/panfrost_drm.h"
#include "pan_bo.h"
#include "pan_fence.h"
#include "pan_shader.h"
#include "pan_screen.h"
#include "pan_resource.h"
@ -766,95 +767,6 @@ panfrost_destroy_screen(struct pipe_screen *pscreen)
ralloc_free(pscreen);
}
static void
panfrost_fence_reference(struct pipe_screen *pscreen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
struct panfrost_device *dev = pan_device(pscreen);
struct pipe_fence_handle *old = *ptr;
if (pipe_reference(&old->reference, &fence->reference)) {
drmSyncobjDestroy(dev->fd, old->syncobj);
free(old);
}
*ptr = fence;
}
static bool
panfrost_fence_finish(struct pipe_screen *pscreen,
struct pipe_context *ctx,
struct pipe_fence_handle *fence,
uint64_t timeout)
{
struct panfrost_device *dev = pan_device(pscreen);
int ret;
if (fence->signaled)
return true;
uint64_t abs_timeout = os_time_get_absolute_timeout(timeout);
if (abs_timeout == OS_TIMEOUT_INFINITE)
abs_timeout = INT64_MAX;
ret = drmSyncobjWait(dev->fd, &fence->syncobj,
1,
abs_timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL,
NULL);
fence->signaled = (ret >= 0);
return fence->signaled;
}
struct pipe_fence_handle *
panfrost_fence_create(struct panfrost_context *ctx)
{
struct pipe_fence_handle *f = calloc(1, sizeof(*f));
if (!f)
return NULL;
struct panfrost_device *dev = pan_device(ctx->base.screen);
int fd = -1, ret;
/* Snapshot the last rendering out fence. We'd rather have another
* syncobj instead of a sync file, but this is all we get.
* (HandleToFD/FDToHandle just gives you another syncobj ID for the
* same syncobj).
*/
ret = drmSyncobjExportSyncFile(dev->fd, ctx->syncobj, &fd);
if (ret || fd == -1) {
fprintf(stderr, "export failed\n");
goto err_free_fence;
}
ret = drmSyncobjCreate(dev->fd, 0, &f->syncobj);
if (ret) {
fprintf(stderr, "create syncobj failed\n");
goto err_close_fd;
}
ret = drmSyncobjImportSyncFile(dev->fd, f->syncobj, fd);
if (ret) {
fprintf(stderr, "create syncobj failed\n");
goto err_destroy_syncobj;
}
assert(f->syncobj != ctx->syncobj);
close(fd);
pipe_reference_init(&f->reference, 1);
return f;
err_destroy_syncobj:
drmSyncobjDestroy(dev->fd, f->syncobj);
err_close_fd:
close(fd);
err_free_fence:
free(f);
return NULL;
}
static const void *
panfrost_screen_get_compiler_options(struct pipe_screen *pscreen,
enum pipe_shader_ir ir,

View file

@ -129,9 +129,6 @@ pan_device(struct pipe_screen *p)
return &(pan_screen(p)->dev);
}
struct pipe_fence_handle *
panfrost_fence_create(struct panfrost_context *ctx);
int
panfrost_get_driver_query_info(struct pipe_screen *pscreen, unsigned index,
struct pipe_driver_query_info *info);