Ping. On Mon, May 8, 2017 at 3:25 PM, Gurchetan Singh <gurchetansi...@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 > >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev