[Mesa-dev] [PATCH] st/dri: Add fence extension to SW path
Gurchetan Singh
gurchetansingh at chromium.org
Mon May 15 23:00:25 UTC 2017
Ping.
On Mon, May 8, 2017 at 3:25 PM, Gurchetan Singh <gurchetansingh at chromium.org
> wrote:
> Use the same fence implementation for drisw.c as dri2.c by making
> dri2FenceExtension an external variable. Since the fence implementation
> is not dri2.c specific, put it in a separate file. This is desirable for
> synchronization in virtual machines.
>
> v2: Don't depend on dri2.c for extensions (Emil)
> ---
> src/gallium/state_trackers/dri/Makefile.sources | 2 +
> src/gallium/state_trackers/dri/dri2.c | 203
> +--------------------
> src/gallium/state_trackers/dri/dri_extensions.c | 229
> ++++++++++++++++++++++++
> src/gallium/state_trackers/dri/dri_extensions.h | 30 ++++
> src/gallium/state_trackers/dri/drisw.c | 2 +
> 5 files changed, 264 insertions(+), 202 deletions(-)
> create mode 100644 src/gallium/state_trackers/dri/dri_extensions.c
> create mode 100644 src/gallium/state_trackers/dri/dri_extensions.h
>
> diff --git a/src/gallium/state_trackers/dri/Makefile.sources
> b/src/gallium/state_trackers/dri/Makefile.sources
> index 52d60ac928..46da886c00 100644
> --- a/src/gallium/state_trackers/dri/Makefile.sources
> +++ b/src/gallium/state_trackers/dri/Makefile.sources
> @@ -3,6 +3,8 @@ common_SOURCES := \
> dri_context.h \
> dri_drawable.c \
> dri_drawable.h \
> + dri_extensions.c \
> + dri_extensions.h \
> dri_query_renderer.c \
> dri_query_renderer.h \
> dri_screen.c \
> diff --git a/src/gallium/state_trackers/dri/dri2.c
> b/src/gallium/state_trackers/dri/dri2.c
> index ed6004f836..2d95e668f8 100644
> --- a/src/gallium/state_trackers/dri/dri2.c
> +++ b/src/gallium/state_trackers/dri/dri2.c
> @@ -49,6 +49,7 @@
> #include "dri_screen.h"
> #include "dri_context.h"
> #include "dri_drawable.h"
> +#include "dri_extensions.h"
> #include "dri_query_renderer.h"
> #include "dri2_buffer.h"
>
> @@ -1415,208 +1416,6 @@ static __DRIimageExtension dri2ImageExtension = {
> .unmapImage = dri2_unmap_image,
> };
>
> -
> -static bool
> -dri2_is_opencl_interop_loaded_locked(struct dri_screen *screen)
> -{
> - return screen->opencl_dri_event_add_ref &&
> - screen->opencl_dri_event_release &&
> - screen->opencl_dri_event_wait &&
> - screen->opencl_dri_event_get_fence;
> -}
> -
> -static bool
> -dri2_load_opencl_interop(struct dri_screen *screen)
> -{
> -#if defined(RTLD_DEFAULT)
> - bool success;
> -
> - mtx_lock(&screen->opencl_func_mutex);
> -
> - if (dri2_is_opencl_interop_loaded_locked(screen)) {
> - mtx_unlock(&screen->opencl_func_mutex);
> - return true;
> - }
> -
> - screen->opencl_dri_event_add_ref =
> - dlsym(RTLD_DEFAULT, "opencl_dri_event_add_ref");
> - screen->opencl_dri_event_release =
> - dlsym(RTLD_DEFAULT, "opencl_dri_event_release");
> - screen->opencl_dri_event_wait =
> - dlsym(RTLD_DEFAULT, "opencl_dri_event_wait");
> - screen->opencl_dri_event_get_fence =
> - dlsym(RTLD_DEFAULT, "opencl_dri_event_get_fence");
> -
> - success = dri2_is_opencl_interop_loaded_locked(screen);
> - mtx_unlock(&screen->opencl_func_mutex);
> - return success;
> -#else
> - return false;
> -#endif
> -}
> -
> -struct dri2_fence {
> - struct dri_screen *driscreen;
> - struct pipe_fence_handle *pipe_fence;
> - void *cl_event;
> -};
> -
> -static unsigned dri2_fence_get_caps(__DRIscreen *_screen)
> -{
> - struct dri_screen *driscreen = dri_screen(_screen);
> - struct pipe_screen *screen = driscreen->base.screen;
> - unsigned caps = 0;
> -
> - if (screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD))
> - caps |= __DRI_FENCE_CAP_NATIVE_FD;
> -
> - return caps;
> -}
> -
> -static void *
> -dri2_create_fence(__DRIcontext *_ctx)
> -{
> - struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> - struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
> -
> - if (!fence)
> - return NULL;
> -
> - ctx->flush(ctx, &fence->pipe_fence, 0);
> -
> - if (!fence->pipe_fence) {
> - FREE(fence);
> - return NULL;
> - }
> -
> - fence->driscreen = dri_screen(_ctx->driScreenPriv);
> - return fence;
> -}
> -
> -static void *
> -dri2_create_fence_fd(__DRIcontext *_ctx, int fd)
> -{
> - struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> - struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
> -
> - if (fd == -1) {
> - /* exporting driver created fence, flush: */
> - ctx->flush(ctx, &fence->pipe_fence,
> - PIPE_FLUSH_DEFERRED | PIPE_FLUSH_FENCE_FD);
> - } else {
> - /* importing a foreign fence fd: */
> - ctx->create_fence_fd(ctx, &fence->pipe_fence, fd);
> - }
> - if (!fence->pipe_fence) {
> - FREE(fence);
> - return NULL;
> - }
> -
> - fence->driscreen = dri_screen(_ctx->driScreenPriv);
> - return fence;
> -}
> -
> -static int
> -dri2_get_fence_fd(__DRIscreen *_screen, void *_fence)
> -{
> - struct dri_screen *driscreen = dri_screen(_screen);
> - struct pipe_screen *screen = driscreen->base.screen;
> - struct dri2_fence *fence = (struct dri2_fence*)_fence;
> -
> - return screen->fence_get_fd(screen, fence->pipe_fence);
> -}
> -
> -static void *
> -dri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event)
> -{
> - struct dri_screen *driscreen = dri_screen(_screen);
> - struct dri2_fence *fence;
> -
> - if (!dri2_load_opencl_interop(driscreen))
> - return NULL;
> -
> - fence = CALLOC_STRUCT(dri2_fence);
> - if (!fence)
> - return NULL;
> -
> - fence->cl_event = (void*)cl_event;
> -
> - if (!driscreen->opencl_dri_event_add_ref(fence->cl_event)) {
> - free(fence);
> - return NULL;
> - }
> -
> - fence->driscreen = driscreen;
> - return fence;
> -}
> -
> -static void
> -dri2_destroy_fence(__DRIscreen *_screen, void *_fence)
> -{
> - struct dri_screen *driscreen = dri_screen(_screen);
> - struct pipe_screen *screen = driscreen->base.screen;
> - struct dri2_fence *fence = (struct dri2_fence*)_fence;
> -
> - if (fence->pipe_fence)
> - screen->fence_reference(screen, &fence->pipe_fence, NULL);
> - else if (fence->cl_event)
> - driscreen->opencl_dri_event_release(fence->cl_event);
> - else
> - assert(0);
> -
> - FREE(fence);
> -}
> -
> -static GLboolean
> -dri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags,
> - uint64_t timeout)
> -{
> - struct dri2_fence *fence = (struct dri2_fence*)_fence;
> - struct dri_screen *driscreen = fence->driscreen;
> - struct pipe_screen *screen = driscreen->base.screen;
> -
> - /* No need to flush. The context was flushed when the fence was
> created. */
> -
> - if (fence->pipe_fence)
> - return screen->fence_finish(screen, NULL, fence->pipe_fence,
> timeout);
> - else if (fence->cl_event) {
> - struct pipe_fence_handle *pipe_fence =
> - driscreen->opencl_dri_event_get_fence(fence->cl_event);
> -
> - if (pipe_fence)
> - return screen->fence_finish(screen, NULL, pipe_fence, timeout);
> - else
> - return driscreen->opencl_dri_event_wait(fence->cl_event,
> timeout);
> - }
> - else {
> - assert(0);
> - return false;
> - }
> -}
> -
> -static void
> -dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
> -{
> - struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> - struct dri2_fence *fence = (struct dri2_fence*)_fence;
> -
> - if (ctx->fence_server_sync)
> - ctx->fence_server_sync(ctx, fence->pipe_fence);
> -}
> -
> -static __DRI2fenceExtension dri2FenceExtension = {
> - .base = { __DRI2_FENCE, 2 },
> -
> - .create_fence = dri2_create_fence,
> - .get_fence_from_cl_event = dri2_get_fence_from_cl_event,
> - .destroy_fence = dri2_destroy_fence,
> - .client_wait_sync = dri2_client_wait_sync,
> - .server_wait_sync = dri2_server_wait_sync,
> - .get_capabilities = dri2_fence_get_caps,
> - .create_fence_fd = dri2_create_fence_fd,
> - .get_fence_fd = dri2_get_fence_fd,
> -};
> -
> static const __DRIrobustnessExtension dri2Robustness = {
> .base = { __DRI2_ROBUSTNESS, 1 }
> };
> diff --git a/src/gallium/state_trackers/dri/dri_extensions.c
> b/src/gallium/state_trackers/dri/dri_extensions.c
> new file mode 100644
> index 0000000000..2fa7233aab
> --- /dev/null
> +++ b/src/gallium/state_trackers/dri/dri_extensions.c
> @@ -0,0 +1,229 @@
> +/*
> + * Copyright (C) 1999-2007 Brian Paul 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,
> 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 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 "dri_context.h"
> +#include "dri_screen.h"
> +#include "pipe/p_screen.h"
> +#include "util/u_memory.h"
> +
> +static bool
> +dri2_is_opencl_interop_loaded_locked(struct dri_screen *screen)
> +{
> + return screen->opencl_dri_event_add_ref &&
> + screen->opencl_dri_event_release &&
> + screen->opencl_dri_event_wait &&
> + screen->opencl_dri_event_get_fence;
> +}
> +
> +static bool
> +dri2_load_opencl_interop(struct dri_screen *screen)
> +{
> +#if defined(RTLD_DEFAULT)
> + bool success;
> +
> + pipe_mutex_lock(screen->opencl_func_mutex);
> +
> + if (dri2_is_opencl_interop_loaded_locked(screen)) {
> + pipe_mutex_unlock(screen->opencl_func_mutex);
> + return true;
> + }
> +
> + screen->opencl_dri_event_add_ref =
> + dlsym(RTLD_DEFAULT, "opencl_dri_event_add_ref");
> + screen->opencl_dri_event_release =
> + dlsym(RTLD_DEFAULT, "opencl_dri_event_release");
> + screen->opencl_dri_event_wait =
> + dlsym(RTLD_DEFAULT, "opencl_dri_event_wait");
> + screen->opencl_dri_event_get_fence =
> + dlsym(RTLD_DEFAULT, "opencl_dri_event_get_fence");
> +
> + success = dri2_is_opencl_interop_loaded_locked(screen);
> + pipe_mutex_unlock(screen->opencl_func_mutex);
> + return success;
> +#else
> + return false;
> +#endif
> +}
> +
> +struct dri2_fence {
> + struct dri_screen *driscreen;
> + struct pipe_fence_handle *pipe_fence;
> + void *cl_event;
> +};
> +
> +static unsigned dri2_fence_get_caps(__DRIscreen *_screen)
> +{
> + struct dri_screen *driscreen = dri_screen(_screen);
> + struct pipe_screen *screen = driscreen->base.screen;
> + unsigned caps = 0;
> +
> + if (screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD))
> + caps |= __DRI_FENCE_CAP_NATIVE_FD;
> +
> + return caps;
> +}
> +
> +static void *
> +dri2_create_fence(__DRIcontext *_ctx)
> +{
> + struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> + struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
> +
> + if (!fence)
> + return NULL;
> +
> + ctx->flush(ctx, &fence->pipe_fence, 0);
> +
> + if (!fence->pipe_fence) {
> + FREE(fence);
> + return NULL;
> + }
> +
> + fence->driscreen = dri_screen(_ctx->driScreenPriv);
> + return fence;
> +}
> +
> +static void *
> +dri2_create_fence_fd(__DRIcontext *_ctx, int fd)
> +{
> + struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> + struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
> +
> + if (fd == -1) {
> + /* exporting driver created fence, flush: */
> + ctx->flush(ctx, &fence->pipe_fence,
> + PIPE_FLUSH_DEFERRED | PIPE_FLUSH_FENCE_FD);
> + } else {
> + /* importing a foreign fence fd: */
> + ctx->create_fence_fd(ctx, &fence->pipe_fence, fd);
> + }
> + if (!fence->pipe_fence) {
> + FREE(fence);
> + return NULL;
> + }
> +
> + fence->driscreen = dri_screen(_ctx->driScreenPriv);
> + return fence;
> +}
> +
> +static int
> +dri2_get_fence_fd(__DRIscreen *_screen, void *_fence)
> +{
> + struct dri_screen *driscreen = dri_screen(_screen);
> + struct pipe_screen *screen = driscreen->base.screen;
> + struct dri2_fence *fence = (struct dri2_fence*)_fence;
> +
> + return screen->fence_get_fd(screen, fence->pipe_fence);
> +}
> +
> +static void *
> +dri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event)
> +{
> + struct dri_screen *driscreen = dri_screen(_screen);
> + struct dri2_fence *fence;
> +
> + if (!dri2_load_opencl_interop(driscreen))
> + return NULL;
> +
> + fence = CALLOC_STRUCT(dri2_fence);
> + if (!fence)
> + return NULL;
> +
> + fence->cl_event = (void*)cl_event;
> +
> + if (!driscreen->opencl_dri_event_add_ref(fence->cl_event)) {
> + free(fence);
> + return NULL;
> + }
> +
> + fence->driscreen = driscreen;
> + return fence;
> +}
> +
> +static void
> +dri2_destroy_fence(__DRIscreen *_screen, void *_fence)
> +{
> + struct dri_screen *driscreen = dri_screen(_screen);
> + struct pipe_screen *screen = driscreen->base.screen;
> + struct dri2_fence *fence = (struct dri2_fence*)_fence;
> +
> + if (fence->pipe_fence)
> + screen->fence_reference(screen, &fence->pipe_fence, NULL);
> + else if (fence->cl_event)
> + driscreen->opencl_dri_event_release(fence->cl_event);
> + else
> + assert(0);
> +
> + FREE(fence);
> +}
> +
> +static GLboolean
> +dri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags,
> + uint64_t timeout)
> +{
> + struct dri2_fence *fence = (struct dri2_fence*)_fence;
> + struct dri_screen *driscreen = fence->driscreen;
> + struct pipe_screen *screen = driscreen->base.screen;
> +
> + /* No need to flush. The context was flushed when the fence was
> created. */
> +
> + if (fence->pipe_fence)
> + return screen->fence_finish(screen, NULL, fence->pipe_fence,
> timeout);
> + else if (fence->cl_event) {
> + struct pipe_fence_handle *pipe_fence =
> + driscreen->opencl_dri_event_get_fence(fence->cl_event);
> +
> + if (pipe_fence)
> + return screen->fence_finish(screen, NULL, pipe_fence, timeout);
> + else
> + return driscreen->opencl_dri_event_wait(fence->cl_event,
> timeout);
> + }
> + else {
> + assert(0);
> + return false;
> + }
> +}
> +
> +static void
> +dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
> +{
> + struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> + struct dri2_fence *fence = (struct dri2_fence*)_fence;
> +
> + if (ctx->fence_server_sync)
> + ctx->fence_server_sync(ctx, fence->pipe_fence);
> +}
> +
> +const __DRI2fenceExtension dri2FenceExtension = {
> + .base = { __DRI2_FENCE, 2 },
> +
> + .create_fence = dri2_create_fence,
> + .get_fence_from_cl_event = dri2_get_fence_from_cl_event,
> + .destroy_fence = dri2_destroy_fence,
> + .client_wait_sync = dri2_client_wait_sync,
> + .server_wait_sync = dri2_server_wait_sync,
> + .get_capabilities = dri2_fence_get_caps,
> + .create_fence_fd = dri2_create_fence_fd,
> + .get_fence_fd = dri2_get_fence_fd,
> +};
> +
> +/* vim: set sw=3 ts=8 sts=3 expandtab: */
> diff --git a/src/gallium/state_trackers/dri/dri_extensions.h
> b/src/gallium/state_trackers/dri/dri_extensions.h
> new file mode 100644
> index 0000000000..89b01cd3ed
> --- /dev/null
> +++ b/src/gallium/state_trackers/dri/dri_extensions.h
> @@ -0,0 +1,30 @@
> +/*
> + * Copyright (C) 1999-2007 Brian Paul 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,
> 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 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.
> + */
> +
> +#ifndef DRI_EXTENSIONS_H
> +#define DRI_EXTENSIONS_H
> +
> +extern const __DRI2fenceExtension dri2FenceExtension;
> +
> +#endif
> +
> +/* vim: set sw=3 ts=8 sts=3 expandtab: */
> diff --git a/src/gallium/state_trackers/dri/drisw.c
> b/src/gallium/state_trackers/dri/drisw.c
> index b85a73c57d..8fbfa9ecea 100644
> --- a/src/gallium/state_trackers/dri/drisw.c
> +++ b/src/gallium/state_trackers/dri/drisw.c
> @@ -46,6 +46,7 @@
> #include "dri_screen.h"
> #include "dri_context.h"
> #include "dri_drawable.h"
> +#include "dri_extensions.h"
> #include "dri_query_renderer.h"
>
> DEBUG_GET_ONCE_BOOL_OPTION(swrast_no_present, "SWRAST_NO_PRESENT",
> FALSE);
> @@ -369,6 +370,7 @@ static const __DRIextension *drisw_screen_extensions[]
> = {
> &driTexBufferExtension.base,
> &dri2RendererQueryExtension.base,
> &dri2ConfigQueryExtension.base,
> + &dri2FenceExtension.base,
> NULL
> };
>
> --
> 2.12.2
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170515/179a1b32/attachment-0001.html>
More information about the mesa-dev
mailing list