Skip to content
25 changes: 25 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,31 @@ if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR OPENCL_ICD_LOADER_BUILD_TESTING)
add_subdirectory (test)
endif()

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
find_package(Python3 COMPONENTS Interpreter)
set(OPENCL_ICD_LOADER_XML_PATH CACHE FILEPATH "Path to cl.xml for OpenCL ICD Loader code generation")
set(OPENCL_ICD_LOADER_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)
add_custom_target(icd_loader_generate
COMMAND ${CMAKE_COMMAND} -E make_directory ${OPENCL_ICD_LOADER_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR}/scripts
${Python3_EXECUTABLE} gen_loader.py
-registry ${OPENCL_ICD_LOADER_XML_PATH}
-o ${OPENCL_ICD_LOADER_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_SOURCE_DIR}/scripts
${Python3_EXECUTABLE} gen_print_layer.py
-registry ${OPENCL_ICD_LOADER_XML_PATH}
-o ${OPENCL_ICD_LOADER_OUTPUT_DIRECTORY}
)
add_custom_target(icd_loader_copy
COMMAND ${CMAKE_COMMAND} -E copy
${OPENCL_ICD_LOADER_OUTPUT_DIRECTORY}/icd_dispatch_generated.c
${CMAKE_CURRENT_SOURCE_DIR}/loader
COMMAND ${CMAKE_COMMAND} -E copy
${OPENCL_ICD_LOADER_OUTPUT_DIRECTORY}/icd_print_layer_generated.c
${CMAKE_CURRENT_SOURCE_DIR}/test/layer
)
endif()

include (GNUInstallDirs)

install(
Expand Down
66 changes: 64 additions & 2 deletions loader/icd.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,10 @@ void khrIcdLayerAdd(const char *libraryName)
if (khrFirstLayer) {
targetDispatch = &(khrFirstLayer->dispatch);
} else {
targetDispatch = &khrMasterDispatch;
targetDispatch = &khrActualDispatch;
}

loaderDispatchNumEntries = sizeof(khrMasterDispatch)/sizeof(void*);
loaderDispatchNumEntries = sizeof(khrActualDispatch)/sizeof(void*);
result = p_clInitLayer(
loaderDispatchNumEntries,
targetDispatch,
Expand Down Expand Up @@ -430,3 +430,65 @@ void khrIcdContextPropertiesGetPlatform(const cl_context_properties *properties,
}
}

#if defined(CL_ENABLE_LAYERS)
extern struct _cl_icd_dispatch khrShutdownDispatch;
static struct KHRLayer shutdown_layer = {0};
#endif

void khrIcdShutdown(void)
{
KHRicdVendor* prevVendor = NULL;
KHRicdVendor* vendor = NULL;

#if defined(CL_ENABLE_LAYERS)
struct KHRLayer* layer = khrFirstLayer;
struct KHRLayer* nextLayer = NULL;
#endif

KHR_ICD_TRACE("Shutdown starting\n");

#if defined(CL_ENABLE_LAYERS)
KHR_ICD_TRACE("Installing shutdown layer\n");
shutdown_layer.dispatch = khrShutdownDispatch;
khrFirstLayer = &shutdown_layer;
#endif

#if defined(CL_ENABLE_LAYERS)
// Layers are freed in the reverse order they were added,
// so front-to-back.
KHR_ICD_TRACE("Cleaning up Layers\n");
// Handle the case where shutdown is called twice:
if (layer != &shutdown_layer) {
while (layer) {
nextLayer = layer->next;
#if defined(CL_LAYER_INFO)
free(layer->libraryName);
#endif
free(layer);
layer = nextLayer;
}
}
#endif

// Vendors are freed in the reverse order they were added,
// so back-to-front.
KHR_ICD_TRACE("Cleaning up Vendors\n");
while (khrIcdVendors) {
if (khrIcdVendors->next == NULL) {
vendor = khrIcdVendors;
khrIcdVendors = NULL;
} else {
prevVendor = khrIcdVendors;
vendor = khrIcdVendors->next;
while (vendor->next) {
prevVendor = vendor;
vendor = vendor->next;
}
prevVendor->next = NULL;
}
free(vendor->suffix);
free(vendor);
}

KHR_ICD_TRACE("Shutdown complete\n");
}
6 changes: 4 additions & 2 deletions loader/icd.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,14 @@ struct KHRLayer
#ifdef CL_LAYER_INFO
// The layer library name
char *libraryName;
// the pointer to the clGetLayerInfo funciton
// the pointer to the clGetLayerInfo function
void *p_clGetLayerInfo;
#endif
};

// the global layer state
extern struct KHRLayer * khrFirstLayer;
extern struct _cl_icd_dispatch khrMasterDispatch;
extern struct _cl_icd_dispatch khrActualDispatch;
#endif // defined(CL_ENABLE_LAYERS)

/*
Expand Down Expand Up @@ -175,6 +175,8 @@ void khrIcdContextPropertiesGetPlatform(
const cl_context_properties *properties,
cl_platform_id *outPlatform);

void khrIcdShutdown(void);

// internal tracing macros
#define KHR_ICD_TRACE(...) \
do \
Expand Down
10 changes: 10 additions & 0 deletions loader/icd_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ clGetICDLoaderInfoOCLICD(
return CL_SUCCESS;
}

// !!! TODO: Switch this to use the function typedef when it's in the headers!
static cl_int CL_API_CALL clShutdownOCLICD(void)
{
khrIcdShutdown();
return CL_SUCCESS;
}

static void* khrIcdGetExtensionFunctionAddress(const char* function_name)
{
// Most extensions, including multi-vendor KHR and EXT extensions,
Expand Down Expand Up @@ -139,6 +146,9 @@ static void* khrIcdGetExtensionFunctionAddress(const char* function_name)
// cl_icdl
KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetICDLoaderInfoOCLICD);

// cl_icd_shutdown
KHR_ICD_CHECK_EXTENSION_FUNCTION(clShutdownOCLICD);

#undef KHR_ICD_CHECK_EXTENSION_FUNCTION

return NULL;
Expand Down
Loading