diff options
author | Marek Olšák <[email protected]> | 2015-04-10 19:45:50 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2015-04-30 14:38:38 +0200 |
commit | e70de9b0327009dd9b99ee1f388cfffd1bc93761 (patch) | |
tree | b744aa6fff5bf0dd772b77ebd881c63457106b6a /src/gallium/state_trackers/dri/dri2.c | |
parent | 952b5e84db47be3adaf01f047efeedd26cf0d173 (diff) |
st/dri: implement the fence interface for CL events
Diffstat (limited to 'src/gallium/state_trackers/dri/dri2.c')
-rw-r--r-- | src/gallium/state_trackers/dri/dri2.c | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c index 9b5631326d4..8b6fe67dc91 100644 --- a/src/gallium/state_trackers/dri/dri2.c +++ b/src/gallium/state_trackers/dri/dri2.c @@ -29,6 +29,7 @@ */ #include <xf86drm.h> +#include <dlfcn.h> #include "util/u_memory.h" #include "util/u_inlines.h" #include "util/u_format.h" @@ -1252,8 +1253,48 @@ static __DRIimageExtension dri2ImageExtension = { }; +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 pipe_fence_handle *pipe_fence; + void *cl_event; }; static void * @@ -1278,7 +1319,24 @@ dri2_create_fence(__DRIcontext *_ctx) static void * dri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event) { - return NULL; + 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; + } + + return fence; } static void @@ -1290,6 +1348,8 @@ dri2_destroy_fence(__DRIscreen *_screen, void *_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); @@ -1308,6 +1368,15 @@ dri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags, if (fence->pipe_fence) return screen->fence_finish(screen, 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, pipe_fence, timeout); + else + return driscreen->opencl_dri_event_wait(fence->cl_event, timeout); + } else { assert(0); return false; @@ -1365,6 +1434,7 @@ dri2_init_screen(__DRIscreen * sPriv) screen->sPriv = sPriv; screen->fd = sPriv->fd; + pipe_mutex_init(screen->opencl_func_mutex); sPriv->driverPrivate = (void *)screen; |