From e70de9b0327009dd9b99ee1f388cfffd1bc93761 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 10 Apr 2015 19:45:50 +0200 Subject: [PATCH] st/dri: implement the fence interface for CL events --- src/gallium/state_trackers/dri/dri2.c | 72 ++++++++++++++++++++- src/gallium/state_trackers/dri/dri_screen.c | 1 + src/gallium/state_trackers/dri/dri_screen.h | 9 +++ 3 files changed, 81 insertions(+), 1 deletion(-) 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 +#include #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; diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 1b14ab162f1..85393d867e4 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -365,6 +365,7 @@ dri_destroy_screen_helper(struct dri_screen * screen) screen->base.screen->destroy(screen->base.screen); dri_destroy_option_cache(screen); + pipe_mutex_destroy(screen->opencl_func_mutex); } void diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h index e4a1a39aa21..bdab74f2802 100644 --- a/src/gallium/state_trackers/dri/dri_screen.h +++ b/src/gallium/state_trackers/dri/dri_screen.h @@ -39,6 +39,8 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "state_tracker/st_api.h" +#include "state_tracker/opencl_interop.h" +#include "os/os_thread.h" #include "postprocess/filters.h" struct dri_context; @@ -84,6 +86,13 @@ struct dri_screen /* hooks filled in by dri2 & drisw */ __DRIimage * (*lookup_egl_image)(struct dri_screen *ctx, void *handle); + + /* OpenCL interop */ + pipe_mutex opencl_func_mutex; + opencl_dri_event_add_ref_t opencl_dri_event_add_ref; + opencl_dri_event_release_t opencl_dri_event_release; + opencl_dri_event_wait_t opencl_dri_event_wait; + opencl_dri_event_get_fence_t opencl_dri_event_get_fence; }; /** cast wrapper */ -- 2.30.2