From d1069d8856d763c234a5d7805df22f245efd6c2a Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Wed, 7 Feb 2024 16:56:36 -0600 Subject: [PATCH] Deinitialization support. --- include/cl_khr_icd2.h | 13 ++ loader/cllayerinfo.c | 3 +- loader/icd.c | 79 ++++++++-- loader/icd.h | 19 ++- loader/icd_dispatch_generated.c | 217 ++++++++++++++++++++++++- loader/linux/icd_linux.c | 4 + loader/windows/icd_windows.c | 7 + scripts/dispatch_table.mako | 204 ++++++++++++++++++++++++ scripts/icd_dispatch_generated.c.mako | 218 ++------------------------ test/driver_stub/cl.c | 74 +++++++-- test/layer/CMakeLists.txt | 1 + test/layer/icd_print_layer.c | 12 +- 12 files changed, 608 insertions(+), 243 deletions(-) create mode 100644 scripts/dispatch_table.mako diff --git a/include/cl_khr_icd2.h b/include/cl_khr_icd2.h index 643b3c63..9e905d2a 100644 --- a/include/cl_khr_icd2.h +++ b/include/cl_khr_icd2.h @@ -1,3 +1,16 @@ +#if !defined(CL_PLATFORM_UNLOADABLE) +#define CL_PLATFORM_UNLOADABLE_KHR 0x0921 +#endif + +#if defined(CL_ENABLE_LAYERS) && !defined(CL_LAYER_API_VERSION_200) +#define CL_LAYER_API_VERSION_200 200 + +typedef cl_int CL_API_CALL +clDeinitLayer_t(void); + +typedef clDeinitLayer_t *pfn_clDeinitLayer; +#endif //defined(CL_ENABLE_LAYERS) && !defined(CL_LAYER_API_VERSION_200) + #if !defined(CL_ICD2_TAG_KHR) #define CL_ICD2_TAG_KHR ((size_t)0x4F50454E434C3331ULL) diff --git a/loader/cllayerinfo.c b/loader/cllayerinfo.c index 5a85ba82..f7dd3c9f 100644 --- a/loader/cllayerinfo.c +++ b/loader/cllayerinfo.c @@ -19,7 +19,6 @@ #include "icd.h" #include #include -#include #if defined(_WIN32) #include #include @@ -90,7 +89,7 @@ static void restore_outputs(void) void printLayerInfo(const struct KHRLayer *layer) { cl_layer_api_version api_version = 0; - pfn_clGetLayerInfo p_clGetLayerInfo = (pfn_clGetLayerInfo)(size_t)layer->p_clGetLayerInfo; + pfn_clGetLayerInfo p_clGetLayerInfo = layer->p_clGetLayerInfo; cl_int result = CL_SUCCESS; size_t sz; diff --git a/loader/icd.c b/loader/icd.c index fd17f5c7..faf7ac36 100644 --- a/loader/icd.c +++ b/loader/icd.c @@ -19,13 +19,11 @@ #include "icd.h" #include "icd_dispatch.h" #include "icd_envvars.h" -#if defined(CL_ENABLE_LAYERS) -#include -#endif // defined(CL_ENABLE_LAYERS) #include #include KHRicdVendor *khrIcdVendors = NULL; +static KHRicdVendor *lastVendor = NULL; int khrEnableTrace = 0; #if defined(CL_ENABLE_LAYERS) @@ -181,6 +179,14 @@ void khrIcdVendorAdd(const char *libraryName) #endif // call clGetPlatformInfo on the returned platform to get the suffix + + KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo( + platforms[i], + CL_PLATFORM_UNLOADABLE_KHR, + sizeof(vendor->unloadable), + &vendor->unloadable, + NULL); + result = KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo( platforms[i], CL_PLATFORM_ICD_SUFFIX_KHR, @@ -224,11 +230,13 @@ void khrIcdVendorAdd(const char *libraryName) vendor->suffix = suffix; // add this vendor to the list of vendors at the tail - { - KHRicdVendor **prevNextPointer = NULL; - for (prevNextPointer = &khrIcdVendors; *prevNextPointer; prevNextPointer = &( (*prevNextPointer)->next) ); - *prevNextPointer = vendor; + if (lastVendor) { + lastVendor->next = vendor; + vendor->prev = lastVendor; + } else { + khrIcdVendors = vendor; } + lastVendor = vendor; KHR_ICD_TRACE("successfully added vendor %s with suffix %s\n", libraryName, suffix); @@ -253,6 +261,7 @@ void khrIcdLayerAdd(const char *libraryName) cl_int result = CL_SUCCESS; pfn_clGetLayerInfo p_clGetLayerInfo = NULL; pfn_clInitLayer p_clInitLayer = NULL; + pfn_clDeinitLayer p_clDeinitLayer = NULL; struct KHRLayer *layerIterator = NULL; struct KHRLayer *layer = NULL; cl_layer_api_version api_version = 0; @@ -302,6 +311,13 @@ void khrIcdLayerAdd(const char *libraryName) goto Done; } + p_clDeinitLayer = (pfn_clDeinitLayer)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clDeinitLayer"); + if (!p_clDeinitLayer) + { + KHR_ICD_TRACE("failed to get function address clDeinitLayer\n"); + goto Done; + } + result = p_clGetLayerInfo(CL_LAYER_API_VERSION, sizeof(api_version), &api_version, NULL); if (CL_SUCCESS != result) { @@ -309,7 +325,7 @@ void khrIcdLayerAdd(const char *libraryName) goto Done; } - if (CL_LAYER_API_VERSION_100 != api_version) + if (CL_LAYER_API_VERSION_200 != api_version) { KHR_ICD_TRACE("unsupported api version\n"); goto Done; @@ -332,17 +348,18 @@ void khrIcdLayerAdd(const char *libraryName) goto Done; } memcpy(layer->libraryName, libraryName, sz_name); - layer->p_clGetLayerInfo = (void *)(size_t)p_clGetLayerInfo; + layer->p_clGetLayerInfo = p_clGetLayerInfo; + layer->p_clDeinitLayer = p_clDeinitLayer; } #endif if (khrFirstLayer) { targetDispatch = &(khrFirstLayer->dispatch); } else { - targetDispatch = &khrMasterDispatch; + targetDispatch = &khrMainDispatch; } - loaderDispatchNumEntries = sizeof(khrMasterDispatch)/sizeof(void*); + loaderDispatchNumEntries = sizeof(khrMainDispatch)/sizeof(void*); result = p_clInitLayer( loaderDispatchNumEntries, targetDispatch, @@ -466,3 +483,43 @@ void khrIcdContextPropertiesGetPlatform(const cl_context_properties *properties, } } +#if defined(CL_ENABLE_LAYERS) +static struct KHRLayer deinitLayer = {0}; +#endif + +void khrIcdDeinitialize(void) { + + KHR_ICD_TRACE("ICD Loader deinitialization\n"); + +#if defined(CL_ENABLE_LAYERS) + // free layers first in reverse order of their creation (front to back) + // they may still need to use vendors while terminating + KHR_ICD_TRACE("Finalizing and unloading layers\n"); + struct KHRLayer *head = khrFirstLayer; + deinitLayer.dispatch = khrDeinitDispatch; + khrFirstLayer = &deinitLayer; + + while(head) { + struct KHRLayer *cur = head; +#ifdef CL_LAYER_INFO + free(cur->libraryName); +#endif + cur->p_clDeinitLayer(); + khrIcdOsLibraryUnload(cur->library); + head = cur->next; + free(cur); + } +#endif // defined(CL_ENABLE_LAYERS) + + // free vendor in reverse order of their creation (back to front) + KHR_ICD_TRACE("Finalizing and unloading vendors\n"); + while (lastVendor) { + KHRicdVendor *cur = lastVendor; + free(cur->suffix); + if (cur->unloadable) + khrIcdOsLibraryUnload(cur->library); + lastVendor = cur->prev; + free(cur); + } + khrIcdVendors = NULL; +} diff --git a/loader/icd.h b/loader/icd.h index 2ca39583..bf619945 100644 --- a/loader/icd.h +++ b/loader/icd.h @@ -49,6 +49,9 @@ #include #include #include +#if defined(CL_ENABLE_LAYERS) +#include +#endif // defined(CL_ENABLE_LAYERS) #include /* @@ -85,6 +88,9 @@ struct KHRicdVendorRec // the extension suffix for this platform char *suffix; + // can this vendor library be unloaded? + cl_bool unloadable; + // function pointer to the ICD platform IDs extracted from the library pfn_clGetExtensionFunctionAddress clGetExtensionFunctionAddress; @@ -98,6 +104,7 @@ struct KHRicdVendorRec // next vendor in the list vendors KHRicdVendor *next; + KHRicdVendor *prev; }; // the global state @@ -123,14 +130,17 @@ struct KHRLayer #ifdef CL_LAYER_INFO // The layer library name char *libraryName; - // the pointer to the clGetLayerInfo funciton - void *p_clGetLayerInfo; + // the pointer to the clGetLayerInfo function + pfn_clGetLayerInfo p_clGetLayerInfo; #endif + // the pointer to the clDeinitLayer function + pfn_clDeinitLayer p_clDeinitLayer; }; // the global layer state extern struct KHRLayer * khrFirstLayer; -extern struct _cl_icd_dispatch khrMasterDispatch; +extern const struct _cl_icd_dispatch khrMainDispatch; +extern const struct _cl_icd_dispatch khrDeinitDispatch; #endif // defined(CL_ENABLE_LAYERS) /* @@ -147,6 +157,9 @@ void khrIcdInitialize(void); // entrypoint to check and initialize trace. void khrIcdInitializeTrace(void); +// entrypoint to release icd resources +void khrIcdDeinitialize(void); + // go through the list of vendors (in /etc/OpenCL.conf or through // the registry) and call khrIcdVendorAdd for each vendor encountered // n.b, this call is OS-specific diff --git a/loader/icd_dispatch_generated.c b/loader/icd_dispatch_generated.c index 358509b0..4f014efa 100644 --- a/loader/icd_dispatch_generated.c +++ b/loader/icd_dispatch_generated.c @@ -6824,7 +6824,7 @@ static cl_int CL_API_CALL clGetKernelSubGroupInfoKHR_disp( /////////////////////////////////////////////////////////////////////////////// #if defined(CL_ENABLE_LAYERS) -struct _cl_icd_dispatch khrMasterDispatch = { +const struct _cl_icd_dispatch khrMainDispatch = { &clGetPlatformIDs_disp, &clGetPlatformInfo_disp, &clGetDeviceIDs_disp, @@ -7027,10 +7027,11 @@ struct _cl_icd_dispatch khrMasterDispatch = { &clCreateBufferWithProperties_disp, &clCreateImageWithProperties_disp, &clSetContextDestructorCallback_disp -}; +} +; #endif // defined(CL_ENABLE_LAYERS) -#if KHR_LOADER_MANAGED_DISPATCH +#if KHR_LOADER_MANAGED_DISPATCH || defined(CL_ENABLE_LAYERS) /////////////////////////////////////////////////////////////////////////////// // Core APIs: static cl_int CL_API_CALL clGetPlatformIDs_unsupp( @@ -9167,7 +9168,217 @@ static cl_int CL_API_CALL clGetKernelSubGroupInfoKHR_unsupp( } /////////////////////////////////////////////////////////////////////////////// +#endif // KHR_LOADER_MANAGED_DISPATCH || defined(CL_ENABLE_LAYERS) + +#if defined(CL_ENABLE_LAYERS) +const struct _cl_icd_dispatch khrDeinitDispatch = { + &clGetPlatformIDs_unsupp, + &clGetPlatformInfo_unsupp, + &clGetDeviceIDs_unsupp, + &clGetDeviceInfo_unsupp, + &clCreateContext_unsupp, + &clCreateContextFromType_unsupp, + &clRetainContext_unsupp, + &clReleaseContext_unsupp, + &clGetContextInfo_unsupp, + &clCreateCommandQueue_unsupp, + &clRetainCommandQueue_unsupp, + &clReleaseCommandQueue_unsupp, + &clGetCommandQueueInfo_unsupp, + &clSetCommandQueueProperty_unsupp, + &clCreateBuffer_unsupp, + &clCreateImage2D_unsupp, + &clCreateImage3D_unsupp, + &clRetainMemObject_unsupp, + &clReleaseMemObject_unsupp, + &clGetSupportedImageFormats_unsupp, + &clGetMemObjectInfo_unsupp, + &clGetImageInfo_unsupp, + &clCreateSampler_unsupp, + &clRetainSampler_unsupp, + &clReleaseSampler_unsupp, + &clGetSamplerInfo_unsupp, + &clCreateProgramWithSource_unsupp, + &clCreateProgramWithBinary_unsupp, + &clRetainProgram_unsupp, + &clReleaseProgram_unsupp, + &clBuildProgram_unsupp, + &clUnloadCompiler_unsupp, + &clGetProgramInfo_unsupp, + &clGetProgramBuildInfo_unsupp, + &clCreateKernel_unsupp, + &clCreateKernelsInProgram_unsupp, + &clRetainKernel_unsupp, + &clReleaseKernel_unsupp, + &clSetKernelArg_unsupp, + &clGetKernelInfo_unsupp, + &clGetKernelWorkGroupInfo_unsupp, + &clWaitForEvents_unsupp, + &clGetEventInfo_unsupp, + &clRetainEvent_unsupp, + &clReleaseEvent_unsupp, + &clGetEventProfilingInfo_unsupp, + &clFlush_unsupp, + &clFinish_unsupp, + &clEnqueueReadBuffer_unsupp, + &clEnqueueWriteBuffer_unsupp, + &clEnqueueCopyBuffer_unsupp, + &clEnqueueReadImage_unsupp, + &clEnqueueWriteImage_unsupp, + &clEnqueueCopyImage_unsupp, + &clEnqueueCopyImageToBuffer_unsupp, + &clEnqueueCopyBufferToImage_unsupp, + &clEnqueueMapBuffer_unsupp, + &clEnqueueMapImage_unsupp, + &clEnqueueUnmapMemObject_unsupp, + &clEnqueueNDRangeKernel_unsupp, + &clEnqueueTask_unsupp, + &clEnqueueNativeKernel_unsupp, + &clEnqueueMarker_unsupp, + &clEnqueueWaitForEvents_unsupp, + &clEnqueueBarrier_unsupp, + &clGetExtensionFunctionAddress_unsupp, + &clCreateFromGLBuffer_unsupp, + &clCreateFromGLTexture2D_unsupp, + &clCreateFromGLTexture3D_unsupp, + &clCreateFromGLRenderbuffer_unsupp, + &clGetGLObjectInfo_unsupp, + &clGetGLTextureInfo_unsupp, + &clEnqueueAcquireGLObjects_unsupp, + &clEnqueueReleaseGLObjects_unsupp, + &clGetGLContextInfoKHR_unsupp, + + /* cl_khr_d3d10_sharing */ +#if defined(_WIN32) + &clGetDeviceIDsFromD3D10KHR_unsupp, + &clCreateFromD3D10BufferKHR_unsupp, + &clCreateFromD3D10Texture2DKHR_unsupp, + &clCreateFromD3D10Texture3DKHR_unsupp, + &clEnqueueAcquireD3D10ObjectsKHR_unsupp, + &clEnqueueReleaseD3D10ObjectsKHR_unsupp, +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif + + /* OpenCL 1.1 */ + &clSetEventCallback_unsupp, + &clCreateSubBuffer_unsupp, + &clSetMemObjectDestructorCallback_unsupp, + &clCreateUserEvent_unsupp, + &clSetUserEventStatus_unsupp, + &clEnqueueReadBufferRect_unsupp, + &clEnqueueWriteBufferRect_unsupp, + &clEnqueueCopyBufferRect_unsupp, + + /* cl_ext_device_fission */ + &clCreateSubDevicesEXT_unsupp, + &clRetainDeviceEXT_unsupp, + &clReleaseDeviceEXT_unsupp, + + /* cl_khr_gl_event */ + &clCreateEventFromGLsyncKHR_unsupp, + + /* OpenCL 1.2 */ + &clCreateSubDevices_unsupp, + &clRetainDevice_unsupp, + &clReleaseDevice_unsupp, + &clCreateImage_unsupp, + &clCreateProgramWithBuiltInKernels_unsupp, + &clCompileProgram_unsupp, + &clLinkProgram_unsupp, + &clUnloadPlatformCompiler_unsupp, + &clGetKernelArgInfo_unsupp, + &clEnqueueFillBuffer_unsupp, + &clEnqueueFillImage_unsupp, + &clEnqueueMigrateMemObjects_unsupp, + &clEnqueueMarkerWithWaitList_unsupp, + &clEnqueueBarrierWithWaitList_unsupp, + &clGetExtensionFunctionAddressForPlatform_unsupp, + &clCreateFromGLTexture_unsupp, + + /* cl_khr_d3d11_sharing */ +#if defined(_WIN32) + &clGetDeviceIDsFromD3D11KHR_unsupp, + &clCreateFromD3D11BufferKHR_unsupp, + &clCreateFromD3D11Texture2DKHR_unsupp, + &clCreateFromD3D11Texture3DKHR_unsupp, + &clCreateFromDX9MediaSurfaceKHR_unsupp, + &clEnqueueAcquireD3D11ObjectsKHR_unsupp, + &clEnqueueReleaseD3D11ObjectsKHR_unsupp, +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif + + /* cl_khr_dx9_media_sharing */ +#if defined(_WIN32) + &clGetDeviceIDsFromDX9MediaAdapterKHR_unsupp, + &clEnqueueAcquireDX9MediaSurfacesKHR_unsupp, + &clEnqueueReleaseDX9MediaSurfacesKHR_unsupp, +#else + NULL, + NULL, + NULL, +#endif + /* cl_khr_egl_image */ + &clCreateFromEGLImageKHR_unsupp, + &clEnqueueAcquireEGLObjectsKHR_unsupp, + &clEnqueueReleaseEGLObjectsKHR_unsupp, + + /* cl_khr_egl_event */ + &clCreateEventFromEGLSyncKHR_unsupp, + + /* OpenCL 2.0 */ + &clCreateCommandQueueWithProperties_unsupp, + &clCreatePipe_unsupp, + &clGetPipeInfo_unsupp, + &clSVMAlloc_unsupp, + &clSVMFree_unsupp, + &clEnqueueSVMFree_unsupp, + &clEnqueueSVMMemcpy_unsupp, + &clEnqueueSVMMemFill_unsupp, + &clEnqueueSVMMap_unsupp, + &clEnqueueSVMUnmap_unsupp, + &clCreateSamplerWithProperties_unsupp, + &clSetKernelArgSVMPointer_unsupp, + &clSetKernelExecInfo_unsupp, + + /* cl_khr_sub_groups */ + &clGetKernelSubGroupInfoKHR_unsupp, + + /* OpenCL 2.1 */ + &clCloneKernel_unsupp, + &clCreateProgramWithIL_unsupp, + &clEnqueueSVMMigrateMem_unsupp, + &clGetDeviceAndHostTimer_unsupp, + &clGetHostTimer_unsupp, + &clGetKernelSubGroupInfo_unsupp, + &clSetDefaultDeviceCommandQueue_unsupp, + + /* OpenCL 2.2 */ + &clSetProgramReleaseCallback_unsupp, + &clSetProgramSpecializationConstant_unsupp, + + /* OpenCL 3.0 */ + &clCreateBufferWithProperties_unsupp, + &clCreateImageWithProperties_unsupp, + &clSetContextDestructorCallback_unsupp +} +; +#endif // defined(CL_ENABLE_LAYERS) + +#if KHR_LOADER_MANAGED_DISPATCH void khrIcd2PopulateDispatchTable( cl_platform_id platform, clIcdGetFunctionAddressForPlatformKHR_fn p_clIcdGetFunctionAddressForPlatform, diff --git a/loader/linux/icd_linux.c b/loader/linux/icd_linux.c index 44915fe1..631018c2 100644 --- a/loader/linux/icd_linux.c +++ b/loader/linux/icd_linux.c @@ -261,3 +261,7 @@ void khrIcdOsLibraryUnload(void *library) { dlclose(library); } + +void __attribute__((destructor)) khrIcdDestructor(void) { + khrIcdDeinitialize(); +} diff --git a/loader/windows/icd_windows.c b/loader/windows/icd_windows.c index d7716253..aff0e25a 100644 --- a/loader/windows/icd_windows.c +++ b/loader/windows/icd_windows.c @@ -443,3 +443,10 @@ void khrIcdOsLibraryUnload(void *library) { FreeLibrary( (HMODULE)library); } + +BOOL APIENTRY DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { + if (reason == DLL_PROCESS_DETACH) { + khrIcdDeinitialize(); + } + return TRUE; +} diff --git a/scripts/dispatch_table.mako b/scripts/dispatch_table.mako new file mode 100644 index 00000000..626d0862 --- /dev/null +++ b/scripts/dispatch_table.mako @@ -0,0 +1,204 @@ +{ + &clGetPlatformIDs_${suffix}, + &clGetPlatformInfo_${suffix}, + &clGetDeviceIDs_${suffix}, + &clGetDeviceInfo_${suffix}, + &clCreateContext_${suffix}, + &clCreateContextFromType_${suffix}, + &clRetainContext_${suffix}, + &clReleaseContext_${suffix}, + &clGetContextInfo_${suffix}, + &clCreateCommandQueue_${suffix}, + &clRetainCommandQueue_${suffix}, + &clReleaseCommandQueue_${suffix}, + &clGetCommandQueueInfo_${suffix}, + &clSetCommandQueueProperty_${suffix}, + &clCreateBuffer_${suffix}, + &clCreateImage2D_${suffix}, + &clCreateImage3D_${suffix}, + &clRetainMemObject_${suffix}, + &clReleaseMemObject_${suffix}, + &clGetSupportedImageFormats_${suffix}, + &clGetMemObjectInfo_${suffix}, + &clGetImageInfo_${suffix}, + &clCreateSampler_${suffix}, + &clRetainSampler_${suffix}, + &clReleaseSampler_${suffix}, + &clGetSamplerInfo_${suffix}, + &clCreateProgramWithSource_${suffix}, + &clCreateProgramWithBinary_${suffix}, + &clRetainProgram_${suffix}, + &clReleaseProgram_${suffix}, + &clBuildProgram_${suffix}, + &clUnloadCompiler_${suffix}, + &clGetProgramInfo_${suffix}, + &clGetProgramBuildInfo_${suffix}, + &clCreateKernel_${suffix}, + &clCreateKernelsInProgram_${suffix}, + &clRetainKernel_${suffix}, + &clReleaseKernel_${suffix}, + &clSetKernelArg_${suffix}, + &clGetKernelInfo_${suffix}, + &clGetKernelWorkGroupInfo_${suffix}, + &clWaitForEvents_${suffix}, + &clGetEventInfo_${suffix}, + &clRetainEvent_${suffix}, + &clReleaseEvent_${suffix}, + &clGetEventProfilingInfo_${suffix}, + &clFlush_${suffix}, + &clFinish_${suffix}, + &clEnqueueReadBuffer_${suffix}, + &clEnqueueWriteBuffer_${suffix}, + &clEnqueueCopyBuffer_${suffix}, + &clEnqueueReadImage_${suffix}, + &clEnqueueWriteImage_${suffix}, + &clEnqueueCopyImage_${suffix}, + &clEnqueueCopyImageToBuffer_${suffix}, + &clEnqueueCopyBufferToImage_${suffix}, + &clEnqueueMapBuffer_${suffix}, + &clEnqueueMapImage_${suffix}, + &clEnqueueUnmapMemObject_${suffix}, + &clEnqueueNDRangeKernel_${suffix}, + &clEnqueueTask_${suffix}, + &clEnqueueNativeKernel_${suffix}, + &clEnqueueMarker_${suffix}, + &clEnqueueWaitForEvents_${suffix}, + &clEnqueueBarrier_${suffix}, + &clGetExtensionFunctionAddress_${suffix}, + &clCreateFromGLBuffer_${suffix}, + &clCreateFromGLTexture2D_${suffix}, + &clCreateFromGLTexture3D_${suffix}, + &clCreateFromGLRenderbuffer_${suffix}, + &clGetGLObjectInfo_${suffix}, + &clGetGLTextureInfo_${suffix}, + &clEnqueueAcquireGLObjects_${suffix}, + &clEnqueueReleaseGLObjects_${suffix}, + &clGetGLContextInfoKHR_${suffix}, + + /* cl_khr_d3d10_sharing */ +#if defined(_WIN32) + &clGetDeviceIDsFromD3D10KHR_${suffix}, + &clCreateFromD3D10BufferKHR_${suffix}, + &clCreateFromD3D10Texture2DKHR_${suffix}, + &clCreateFromD3D10Texture3DKHR_${suffix}, + &clEnqueueAcquireD3D10ObjectsKHR_${suffix}, + &clEnqueueReleaseD3D10ObjectsKHR_${suffix}, +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif + + /* OpenCL 1.1 */ + &clSetEventCallback_${suffix}, + &clCreateSubBuffer_${suffix}, + &clSetMemObjectDestructorCallback_${suffix}, + &clCreateUserEvent_${suffix}, + &clSetUserEventStatus_${suffix}, + &clEnqueueReadBufferRect_${suffix}, + &clEnqueueWriteBufferRect_${suffix}, + &clEnqueueCopyBufferRect_${suffix}, + + /* cl_ext_device_fission */ + &clCreateSubDevicesEXT_${suffix}, + &clRetainDeviceEXT_${suffix}, + &clReleaseDeviceEXT_${suffix}, + + /* cl_khr_gl_event */ + &clCreateEventFromGLsyncKHR_${suffix}, + + /* OpenCL 1.2 */ + &clCreateSubDevices_${suffix}, + &clRetainDevice_${suffix}, + &clReleaseDevice_${suffix}, + &clCreateImage_${suffix}, + &clCreateProgramWithBuiltInKernels_${suffix}, + &clCompileProgram_${suffix}, + &clLinkProgram_${suffix}, + &clUnloadPlatformCompiler_${suffix}, + &clGetKernelArgInfo_${suffix}, + &clEnqueueFillBuffer_${suffix}, + &clEnqueueFillImage_${suffix}, + &clEnqueueMigrateMemObjects_${suffix}, + &clEnqueueMarkerWithWaitList_${suffix}, + &clEnqueueBarrierWithWaitList_${suffix}, + &clGetExtensionFunctionAddressForPlatform_${suffix}, + &clCreateFromGLTexture_${suffix}, + + /* cl_khr_d3d11_sharing */ +#if defined(_WIN32) + &clGetDeviceIDsFromD3D11KHR_${suffix}, + &clCreateFromD3D11BufferKHR_${suffix}, + &clCreateFromD3D11Texture2DKHR_${suffix}, + &clCreateFromD3D11Texture3DKHR_${suffix}, + &clCreateFromDX9MediaSurfaceKHR_${suffix}, + &clEnqueueAcquireD3D11ObjectsKHR_${suffix}, + &clEnqueueReleaseD3D11ObjectsKHR_${suffix}, +#else + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +#endif + + /* cl_khr_dx9_media_sharing */ +#if defined(_WIN32) + &clGetDeviceIDsFromDX9MediaAdapterKHR_${suffix}, + &clEnqueueAcquireDX9MediaSurfacesKHR_${suffix}, + &clEnqueueReleaseDX9MediaSurfacesKHR_${suffix}, +#else + NULL, + NULL, + NULL, +#endif + + /* cl_khr_egl_image */ + &clCreateFromEGLImageKHR_${suffix}, + &clEnqueueAcquireEGLObjectsKHR_${suffix}, + &clEnqueueReleaseEGLObjectsKHR_${suffix}, + + /* cl_khr_egl_event */ + &clCreateEventFromEGLSyncKHR_${suffix}, + + /* OpenCL 2.0 */ + &clCreateCommandQueueWithProperties_${suffix}, + &clCreatePipe_${suffix}, + &clGetPipeInfo_${suffix}, + &clSVMAlloc_${suffix}, + &clSVMFree_${suffix}, + &clEnqueueSVMFree_${suffix}, + &clEnqueueSVMMemcpy_${suffix}, + &clEnqueueSVMMemFill_${suffix}, + &clEnqueueSVMMap_${suffix}, + &clEnqueueSVMUnmap_${suffix}, + &clCreateSamplerWithProperties_${suffix}, + &clSetKernelArgSVMPointer_${suffix}, + &clSetKernelExecInfo_${suffix}, + + /* cl_khr_sub_groups */ + &clGetKernelSubGroupInfoKHR_${suffix}, + + /* OpenCL 2.1 */ + &clCloneKernel_${suffix}, + &clCreateProgramWithIL_${suffix}, + &clEnqueueSVMMigrateMem_${suffix}, + &clGetDeviceAndHostTimer_${suffix}, + &clGetHostTimer_${suffix}, + &clGetKernelSubGroupInfo_${suffix}, + &clSetDefaultDeviceCommandQueue_${suffix}, + + /* OpenCL 2.2 */ + &clSetProgramReleaseCallback_${suffix}, + &clSetProgramSpecializationConstant_${suffix}, + + /* OpenCL 3.0 */ + &clCreateBufferWithProperties_${suffix}, + &clCreateImageWithProperties_${suffix}, + &clSetContextDestructorCallback_${suffix} +} diff --git a/scripts/icd_dispatch_generated.c.mako b/scripts/icd_dispatch_generated.c.mako index 9686ee63..7116d276 100644 --- a/scripts/icd_dispatch_generated.c.mako +++ b/scripts/icd_dispatch_generated.c.mako @@ -1,4 +1,5 @@ <% +from mako.template import Template # APIs to skip - they need to be done "manually": apiskip = { 'clGetPlatformIDs', # to query platforms @@ -22,6 +23,8 @@ apihandles = { 'cl_program' : 'CL_INVALID_PROGRAM', 'cl_sampler' : 'CL_INVALID_SAMPLER', } + +table_template = Template(filename='dispatch_table.mako') %>/* * Copyright (c) 2012-2023 The Khronos Group Inc. * @@ -240,7 +243,7 @@ ${("CL_API_ENTRY", "static")[disp]} ${api.RetType} CL_API_CALL ${api.Name + ("", % else: KHR_ICD_VALIDATE_HANDLE_RETURN_HANDLE(${handle.Name}, ${invalid}); KHR_ICD_VALIDATE_POINTER_RETURN_HANDLE(KHR_ICD2_DISPATCH(${handle.Name})->${api.Name}); -% endif +% endif %else: % if api.Name == "clGetGLContextInfoKHR": cl_platform_id platform = NULL; @@ -279,213 +282,10 @@ ${("CL_API_ENTRY", "static")[disp]} ${api.RetType} CL_API_CALL ${api.Name + ("", %endfor #if defined(CL_ENABLE_LAYERS) -struct _cl_icd_dispatch khrMasterDispatch = { - &clGetPlatformIDs_disp, - &clGetPlatformInfo_disp, - &clGetDeviceIDs_disp, - &clGetDeviceInfo_disp, - &clCreateContext_disp, - &clCreateContextFromType_disp, - &clRetainContext_disp, - &clReleaseContext_disp, - &clGetContextInfo_disp, - &clCreateCommandQueue_disp, - &clRetainCommandQueue_disp, - &clReleaseCommandQueue_disp, - &clGetCommandQueueInfo_disp, - &clSetCommandQueueProperty_disp, - &clCreateBuffer_disp, - &clCreateImage2D_disp, - &clCreateImage3D_disp, - &clRetainMemObject_disp, - &clReleaseMemObject_disp, - &clGetSupportedImageFormats_disp, - &clGetMemObjectInfo_disp, - &clGetImageInfo_disp, - &clCreateSampler_disp, - &clRetainSampler_disp, - &clReleaseSampler_disp, - &clGetSamplerInfo_disp, - &clCreateProgramWithSource_disp, - &clCreateProgramWithBinary_disp, - &clRetainProgram_disp, - &clReleaseProgram_disp, - &clBuildProgram_disp, - &clUnloadCompiler_disp, - &clGetProgramInfo_disp, - &clGetProgramBuildInfo_disp, - &clCreateKernel_disp, - &clCreateKernelsInProgram_disp, - &clRetainKernel_disp, - &clReleaseKernel_disp, - &clSetKernelArg_disp, - &clGetKernelInfo_disp, - &clGetKernelWorkGroupInfo_disp, - &clWaitForEvents_disp, - &clGetEventInfo_disp, - &clRetainEvent_disp, - &clReleaseEvent_disp, - &clGetEventProfilingInfo_disp, - &clFlush_disp, - &clFinish_disp, - &clEnqueueReadBuffer_disp, - &clEnqueueWriteBuffer_disp, - &clEnqueueCopyBuffer_disp, - &clEnqueueReadImage_disp, - &clEnqueueWriteImage_disp, - &clEnqueueCopyImage_disp, - &clEnqueueCopyImageToBuffer_disp, - &clEnqueueCopyBufferToImage_disp, - &clEnqueueMapBuffer_disp, - &clEnqueueMapImage_disp, - &clEnqueueUnmapMemObject_disp, - &clEnqueueNDRangeKernel_disp, - &clEnqueueTask_disp, - &clEnqueueNativeKernel_disp, - &clEnqueueMarker_disp, - &clEnqueueWaitForEvents_disp, - &clEnqueueBarrier_disp, - &clGetExtensionFunctionAddress_disp, - &clCreateFromGLBuffer_disp, - &clCreateFromGLTexture2D_disp, - &clCreateFromGLTexture3D_disp, - &clCreateFromGLRenderbuffer_disp, - &clGetGLObjectInfo_disp, - &clGetGLTextureInfo_disp, - &clEnqueueAcquireGLObjects_disp, - &clEnqueueReleaseGLObjects_disp, - &clGetGLContextInfoKHR_disp, - - /* cl_khr_d3d10_sharing */ -#if defined(_WIN32) - &clGetDeviceIDsFromD3D10KHR_disp, - &clCreateFromD3D10BufferKHR_disp, - &clCreateFromD3D10Texture2DKHR_disp, - &clCreateFromD3D10Texture3DKHR_disp, - &clEnqueueAcquireD3D10ObjectsKHR_disp, - &clEnqueueReleaseD3D10ObjectsKHR_disp, -#else - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif - - /* OpenCL 1.1 */ - &clSetEventCallback_disp, - &clCreateSubBuffer_disp, - &clSetMemObjectDestructorCallback_disp, - &clCreateUserEvent_disp, - &clSetUserEventStatus_disp, - &clEnqueueReadBufferRect_disp, - &clEnqueueWriteBufferRect_disp, - &clEnqueueCopyBufferRect_disp, - - /* cl_ext_device_fission */ - &clCreateSubDevicesEXT_disp, - &clRetainDeviceEXT_disp, - &clReleaseDeviceEXT_disp, - - /* cl_khr_gl_event */ - &clCreateEventFromGLsyncKHR_disp, - - /* OpenCL 1.2 */ - &clCreateSubDevices_disp, - &clRetainDevice_disp, - &clReleaseDevice_disp, - &clCreateImage_disp, - &clCreateProgramWithBuiltInKernels_disp, - &clCompileProgram_disp, - &clLinkProgram_disp, - &clUnloadPlatformCompiler_disp, - &clGetKernelArgInfo_disp, - &clEnqueueFillBuffer_disp, - &clEnqueueFillImage_disp, - &clEnqueueMigrateMemObjects_disp, - &clEnqueueMarkerWithWaitList_disp, - &clEnqueueBarrierWithWaitList_disp, - &clGetExtensionFunctionAddressForPlatform_disp, - &clCreateFromGLTexture_disp, - - /* cl_khr_d3d11_sharing */ -#if defined(_WIN32) - &clGetDeviceIDsFromD3D11KHR_disp, - &clCreateFromD3D11BufferKHR_disp, - &clCreateFromD3D11Texture2DKHR_disp, - &clCreateFromD3D11Texture3DKHR_disp, - &clCreateFromDX9MediaSurfaceKHR_disp, - &clEnqueueAcquireD3D11ObjectsKHR_disp, - &clEnqueueReleaseD3D11ObjectsKHR_disp, -#else - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -#endif - - /* cl_khr_dx9_media_sharing */ -#if defined(_WIN32) - &clGetDeviceIDsFromDX9MediaAdapterKHR_disp, - &clEnqueueAcquireDX9MediaSurfacesKHR_disp, - &clEnqueueReleaseDX9MediaSurfacesKHR_disp, -#else - NULL, - NULL, - NULL, -#endif - - /* cl_khr_egl_image */ - &clCreateFromEGLImageKHR_disp, - &clEnqueueAcquireEGLObjectsKHR_disp, - &clEnqueueReleaseEGLObjectsKHR_disp, - - /* cl_khr_egl_event */ - &clCreateEventFromEGLSyncKHR_disp, - - /* OpenCL 2.0 */ - &clCreateCommandQueueWithProperties_disp, - &clCreatePipe_disp, - &clGetPipeInfo_disp, - &clSVMAlloc_disp, - &clSVMFree_disp, - &clEnqueueSVMFree_disp, - &clEnqueueSVMMemcpy_disp, - &clEnqueueSVMMemFill_disp, - &clEnqueueSVMMap_disp, - &clEnqueueSVMUnmap_disp, - &clCreateSamplerWithProperties_disp, - &clSetKernelArgSVMPointer_disp, - &clSetKernelExecInfo_disp, - - /* cl_khr_sub_groups */ - &clGetKernelSubGroupInfoKHR_disp, - - /* OpenCL 2.1 */ - &clCloneKernel_disp, - &clCreateProgramWithIL_disp, - &clEnqueueSVMMigrateMem_disp, - &clGetDeviceAndHostTimer_disp, - &clGetHostTimer_disp, - &clGetKernelSubGroupInfo_disp, - &clSetDefaultDeviceCommandQueue_disp, - - /* OpenCL 2.2 */ - &clSetProgramReleaseCallback_disp, - &clSetProgramSpecializationConstant_disp, - - /* OpenCL 3.0 */ - &clCreateBufferWithProperties_disp, - &clCreateImageWithProperties_disp, - &clSetContextDestructorCallback_disp -}; +const struct _cl_icd_dispatch khrMainDispatch = ${table_template.render(suffix = 'disp')}; #endif // defined(CL_ENABLE_LAYERS) -#if KHR_LOADER_MANAGED_DISPATCH +#if KHR_LOADER_MANAGED_DISPATCH || defined(CL_ENABLE_LAYERS) /////////////////////////////////////////////////////////////////////////////// // Core APIs: %for apis in coreapis.values(): @@ -555,7 +355,13 @@ static ${api.RetType} CL_API_CALL ${api.Name}_unsupp( /////////////////////////////////////////////////////////////////////////////// %endfor +#endif // KHR_LOADER_MANAGED_DISPATCH || defined(CL_ENABLE_LAYERS) + +#if defined(CL_ENABLE_LAYERS) +const struct _cl_icd_dispatch khrDeinitDispatch = ${table_template.render(suffix = 'unsupp')}; +#endif // defined(CL_ENABLE_LAYERS) +#if KHR_LOADER_MANAGED_DISPATCH void khrIcd2PopulateDispatchTable( cl_platform_id platform, clIcdGetFunctionAddressForPlatformKHR_fn p_clIcdGetFunctionAddressForPlatform, diff --git a/test/driver_stub/cl.c b/test/driver_stub/cl.c index d231b680..908408ae 100644 --- a/test/driver_stub/cl.c +++ b/test/driver_stub/cl.c @@ -17,6 +17,7 @@ #include #include #include "icd_structs.h" +#include "cl_khr_icd2.h" #define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920 CL_API_ENTRY cl_int CL_API_CALL @@ -31,6 +32,7 @@ struct _cl_platform_id const char *vendor; const char *extensions; const char *suffix; + cl_device_id device; }; struct _cl_device_id @@ -74,7 +76,7 @@ struct _cl_sampler }; static CLIicdDispatchTable* dispatchTable = NULL; -static cl_platform_id platform = NULL; +static cl_platform_id stub_platform = NULL; static cl_bool initialized = CL_FALSE; CL_API_ENTRY cl_int CL_API_CALL @@ -134,6 +136,18 @@ clGetPlatformInfo(cl_platform_id platform, case CL_PLATFORM_ICD_SUFFIX_KHR: returnString = platform->suffix; break; + case CL_PLATFORM_UNLOADABLE_KHR: + if (param_value_size && param_value_size < sizeof(cl_bool)) { + ret = CL_INVALID_VALUE; + goto done; + } + if (param_value) { + *(cl_bool *)param_value = CL_TRUE; + } + if (param_value_size_ret) { + *param_value_size_ret = sizeof(cl_bool); + } + goto done; default: ret = CL_INVALID_VALUE; goto done; @@ -177,9 +191,11 @@ clGetDeviceIDs(cl_platform_id platform, } if (devices != NULL) { - cl_device_id obj = (cl_device_id) malloc(sizeof(struct _cl_device_id)); - CL_INIT_OBJECT(obj, platform); - devices[0] = obj; + if (!platform->device) { + platform->device = (cl_device_id) malloc(sizeof(struct _cl_device_id)); + CL_INIT_OBJECT(platform->device, stub_platform); + } + devices[0] = platform->device; } if (num_devices) { *num_devices = 1; @@ -297,7 +313,7 @@ clCreateContextFromType(const cl_context_properties * properties, cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0 { cl_context obj = (cl_context) malloc(sizeof(struct _cl_context)); - cl_platform_id plt = platform; + cl_platform_id plt = stub_platform; for (const cl_context_properties * property = properties; *property; property += 2) if (*property == (cl_context_properties)CL_CONTEXT_PLATFORM) plt = (cl_platform_id)property[1]; @@ -1948,6 +1964,7 @@ clEnqueueBarrier(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0 } extern cl_int cliIcdDispatchTableCreate(CLIicdDispatchTable **outDispatchTable); +extern void cliIcdDispatchTableDestroy(CLIicdDispatchTable *dispatchTable); CL_API_ENTRY cl_int CL_API_CALL clIcdGetPlatformIDsKHR(cl_uint num_entries, @@ -1957,16 +1974,16 @@ clIcdGetPlatformIDsKHR(cl_uint num_entries, cl_int result = CL_SUCCESS; if (!initialized) { result = cliIcdDispatchTableCreate(&dispatchTable); - platform = (cl_platform_id) malloc(sizeof(struct _cl_platform_id)); - memset(platform, 0, sizeof(struct _cl_platform_id)); - - CL_INIT_PLATFORM(platform, dispatchTable); - platform->version = "OpenCL 1.2 Stub"; - platform->vendor = "stubvendorxxx"; - platform->profile = "stubprofilexxx"; - platform->name = "ICD_LOADER_TEST_OPENCL_STUB"; - platform->extensions = "cl_khr_icd cl_khr_gl cl_khr_d3d10"; - platform->suffix = "ilts"; + stub_platform = (cl_platform_id) malloc(sizeof(struct _cl_platform_id)); + memset(stub_platform, 0, sizeof(struct _cl_platform_id)); + + CL_INIT_PLATFORM(stub_platform, dispatchTable); + stub_platform->version = "OpenCL 1.2 Stub"; + stub_platform->vendor = "stubvendorxxx"; + stub_platform->profile = "stubprofilexxx"; + stub_platform->name = "ICD_LOADER_TEST_OPENCL_STUB"; + stub_platform->extensions = "cl_khr_icd cl_khr_gl cl_khr_d3d10"; + stub_platform->suffix = "ilts"; initialized = CL_TRUE; } @@ -1978,7 +1995,7 @@ clIcdGetPlatformIDsKHR(cl_uint num_entries, } if (platforms && num_entries == 1) { - platforms[0] = platform; + platforms[0] = stub_platform; } Done: @@ -1989,3 +2006,28 @@ clIcdGetPlatformIDsKHR(cl_uint num_entries, return result; } +static void deinit(void) { + if (initialized) { + free(stub_platform->device); + stub_platform->device = NULL; + free(stub_platform); + stub_platform = NULL; + cliIcdDispatchTableDestroy(dispatchTable); + dispatchTable = NULL; + initialized = CL_FALSE; + } +} + +#if defined(_WIN32) +#include +BOOL APIENTRY DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { + if (reason == DLL_PROCESS_DETACH) { + deinit(); + } + return TRUE; +} +#else +void __attribute__((destructor)) khrIcdDestructor(void) { + deinit(); +} +#endif diff --git a/test/layer/CMakeLists.txt b/test/layer/CMakeLists.txt index ea4e0e4b..48648ab3 100644 --- a/test/layer/CMakeLists.txt +++ b/test/layer/CMakeLists.txt @@ -1,4 +1,5 @@ set (OPENCL_PRINT_LAYER_SOURCES + ${CMAKE_SOURCE_DIR}/include/cl_khr_icd2.h icd_print_layer.c icd_print_layer.h icd_print_layer_generated.c) diff --git a/test/layer/icd_print_layer.c b/test/layer/icd_print_layer.c index d8bf4627..bad4aa95 100644 --- a/test/layer/icd_print_layer.c +++ b/test/layer/icd_print_layer.c @@ -21,11 +21,15 @@ #include #include +#if !defined(CL_LAYER_API_VERSION_200) +#define CL_LAYER_API_VERSION_200 200 +#endif //!defined(CL_LAYER_API_VERSION_200) + struct _cl_icd_dispatch dispatch; const struct _cl_icd_dispatch *tdispatch; -static cl_layer_api_version api_version = CL_LAYER_API_VERSION_100; +static cl_layer_api_version api_version = CL_LAYER_API_VERSION_200; static const char name[] = "print_layer"; static inline cl_int @@ -89,4 +93,8 @@ clInitLayer( return CL_SUCCESS; } - +CL_API_ENTRY cl_int CL_API_CALL +clDeinitLayer(void) { + tdispatch = NULL; + return CL_SUCCESS; +}