mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 04:38:03 +02:00
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:
parent
3bd0f5c502
commit
8910533a5a
7 changed files with 174 additions and 98 deletions
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
files_panfrost = files(
|
||||
'pan_disk_cache.c',
|
||||
'pan_fence.c',
|
||||
'pan_helpers.c',
|
||||
'pan_public.h',
|
||||
'pan_screen.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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
122
src/gallium/drivers/panfrost/pan_fence.c
Normal file
122
src/gallium/drivers/panfrost/pan_fence.c
Normal 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;
|
||||
}
|
||||
49
src/gallium/drivers/panfrost/pan_fence.h
Normal file
49
src/gallium/drivers/panfrost/pan_fence.h
Normal 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);
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue