From 8910533a5a39637c5d6f03f82c25955431e4ca4d Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 30 Nov 2022 10:00:02 +0100 Subject: [PATCH] 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 Reviewed-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/panfrost/meson.build | 1 + src/gallium/drivers/panfrost/pan_context.c | 1 + src/gallium/drivers/panfrost/pan_context.h | 6 - src/gallium/drivers/panfrost/pan_fence.c | 122 +++++++++++++++++++++ src/gallium/drivers/panfrost/pan_fence.h | 49 +++++++++ src/gallium/drivers/panfrost/pan_screen.c | 90 +-------------- src/gallium/drivers/panfrost/pan_screen.h | 3 - 7 files changed, 174 insertions(+), 98 deletions(-) create mode 100644 src/gallium/drivers/panfrost/pan_fence.c create mode 100644 src/gallium/drivers/panfrost/pan_fence.h diff --git a/src/gallium/drivers/panfrost/meson.build b/src/gallium/drivers/panfrost/meson.build index 4590ae25898..8d6317292e9 100644 --- a/src/gallium/drivers/panfrost/meson.build +++ b/src/gallium/drivers/panfrost/meson.build @@ -21,6 +21,7 @@ files_panfrost = files( 'pan_disk_cache.c', + 'pan_fence.c', 'pan_helpers.c', 'pan_public.h', 'pan_screen.c', diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 3aede0c3678..e1174b32396 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -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" diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 0ec7b465c15..f5e5dcfe5b3 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -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; diff --git a/src/gallium/drivers/panfrost/pan_fence.c b/src/gallium/drivers/panfrost/pan_fence.c new file mode 100644 index 00000000000..5e9094e9b7a --- /dev/null +++ b/src/gallium/drivers/panfrost/pan_fence.c @@ -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 + * + * 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; +} diff --git a/src/gallium/drivers/panfrost/pan_fence.h b/src/gallium/drivers/panfrost/pan_fence.h new file mode 100644 index 00000000000..0dc2b69de32 --- /dev/null +++ b/src/gallium/drivers/panfrost/pan_fence.h @@ -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); diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index 4de835804fa..35a4c47c76a 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -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, diff --git a/src/gallium/drivers/panfrost/pan_screen.h b/src/gallium/drivers/panfrost/pan_screen.h index 79211a3aa74..656a4948a42 100644 --- a/src/gallium/drivers/panfrost/pan_screen.h +++ b/src/gallium/drivers/panfrost/pan_screen.h @@ -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);