diff --git a/.github/workflows/presubmit.yml b/.github/workflows/presubmit.yml index 9d112a32..d449f978 100644 --- a/.github/workflows/presubmit.yml +++ b/.github/workflows/presubmit.yml @@ -403,7 +403,7 @@ jobs: & $REG DELETE $KEY_NAME /v $VALUE_NAME /f $VALUE_NAME = "${env:GITHUB_WORKSPACE}/build/$Config/OpenCLDriverStubICD2.dll" & $REG ADD $KEY_NAME /v $VALUE_NAME /t REG_DWORD /d 0 - & ctest -C $Config --output-on-failure --no-tests=error --parallel ${env:NUMBER_OF_PROCESSORS} -R opencl_icd_loader_icd2_test + & ctest -C $Config --output-on-failure --no-tests=error --parallel ${env:NUMBER_OF_PROCESSORS} -R opencl_icd_loader_icd2_test^|opencl_icd_loader_icd2_instance_test if ($LASTEXITCODE -ne 0) { throw "Testing OpenCL-ICD-Loader in $Config failed." } & $REG DELETE $KEY_NAME /v $VALUE_NAME /f } diff --git a/include/cl_khr_icd2.h b/include/cl_khr_icd2.h index 10072643..00b53f0b 100644 --- a/include/cl_khr_icd2.h +++ b/include/cl_khr_icd2.h @@ -34,3 +34,53 @@ clIcdSetPlatformDispatchDataKHR_t( typedef clIcdSetPlatformDispatchDataKHR_t * clIcdSetPlatformDispatchDataKHR_fn; #endif // !defined(CL_ICD2_TAG_KHR) + +#if !defined(CL_INVALID_INSTANCE_KHR) +#define CL_INVALID_INSTANCE_KHR -1154 + +#define CL_INSTANCE_PROPERTIES_LIST_END_KHR 0 + +typedef struct _cl_instance_khr *cl_instance_khr; +typedef intptr_t cl_instance_properties_khr; + +typedef cl_instance_khr CL_API_CALL +clCreateInstanceKHR_t( + const cl_instance_properties_khr *properties, + cl_int *errcode_ret); + +typedef clCreateInstanceKHR_t * +clCreateInstanceKHR_fn; + +typedef cl_int CL_API_CALL +clDestroyInstanceKHR_t( + cl_instance_khr instance); + +typedef clDestroyInstanceKHR_t * +clDestroyInstanceKHR_fn; + +typedef cl_int CL_API_CALL +clGetPlatformIDsForInstanceKHR_t( + cl_instance_khr instance, + cl_uint num_entries, + cl_platform_id *platforms, + cl_uint *num_platforms); + +typedef clGetPlatformIDsForInstanceKHR_t * +clGetPlatformIDsForInstanceKHR_fn; + +typedef cl_platform_id CL_API_CALL +clIcdCreateInstancePlatformKHR_t( + cl_platform_id platform, + cl_int *errcode_ret); + +typedef clIcdCreateInstancePlatformKHR_t * +clIcdCreateInstancePlatformKHR_fn; + +typedef cl_int CL_API_CALL +clIcdDestroyInstancePlatformKHR_t( + cl_platform_id platform); + +typedef clIcdDestroyInstancePlatformKHR_t * +clIcdDestroyInstancePlatformKHR_fn; + +#endif // !defined(CL_INVALID_INSTANCE_KHR) diff --git a/loader/icd.c b/loader/icd.c index 25c53404..96f669b7 100644 --- a/loader/icd.c +++ b/loader/icd.c @@ -59,6 +59,8 @@ void khrIcdVendorAdd(const char *libraryName) #if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) clIcdGetFunctionAddressForPlatformKHR_fn p_clIcdGetFunctionAddressForPlatform = NULL; clIcdSetPlatformDispatchDataKHR_fn p_clIcdSetPlatformDispatchData = NULL; + clIcdCreateInstancePlatformKHR_fn p_clIcdCreateInstancePlatform = NULL; + clIcdDestroyInstancePlatformKHR_fn p_clIcdDestroyInstancePlatform = NULL; #endif cl_uint i = 0; cl_uint platformCount = 0; @@ -110,6 +112,8 @@ void khrIcdVendorAdd(const char *libraryName) // try to get clIcdGetFunctionAddressForPlatformKHR and clIcdSetPlatformDispatchDataKHR to detect cl_khr_icd2 support p_clIcdGetFunctionAddressForPlatform = (clIcdGetFunctionAddressForPlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdGetFunctionAddressForPlatformKHR"); p_clIcdSetPlatformDispatchData = (clIcdSetPlatformDispatchDataKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdSetPlatformDispatchDataKHR"); + p_clIcdCreateInstancePlatform = (clIcdCreateInstancePlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdCreateInstancePlatformKHR"); + p_clIcdDestroyInstancePlatform = (clIcdDestroyInstancePlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdDestroyInstancePlatformKHR"); #endif // query the number of platforms available and allocate space to store them @@ -175,6 +179,12 @@ void khrIcdVendorAdd(const char *libraryName) khrIcd2PopulateDispatchTable(platforms[i], p_clIcdGetFunctionAddressForPlatform, &vendor->dispData.dispatch); p_clIcdSetPlatformDispatchData(platforms[i], &vendor->dispData); KHR_ICD_TRACE("found icd 2 platform, using loader managed dispatch\n"); + if (p_clIcdCreateInstancePlatform && p_clIcdDestroyInstancePlatform) + { + vendor->clIcdSetPlatformDispatchData = p_clIcdSetPlatformDispatchData; + vendor->clIcdCreateInstancePlatform = p_clIcdCreateInstancePlatform; + vendor->clIcdDestroyInstancePlatform = p_clIcdDestroyInstancePlatform; + } } #endif diff --git a/loader/icd.h b/loader/icd.h index a0e7de14..2a008fbd 100644 --- a/loader/icd.h +++ b/loader/icd.h @@ -100,6 +100,9 @@ struct KHRicdVendorRec #if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) // the loader populated dispatch table for cl_khr_icd2 compliant platforms struct KHRDisp dispData; + clIcdSetPlatformDispatchDataKHR_fn clIcdSetPlatformDispatchData; + clIcdCreateInstancePlatformKHR_fn clIcdCreateInstancePlatform; + clIcdDestroyInstancePlatformKHR_fn clIcdDestroyInstancePlatform; #endif // next vendor in the list vendors @@ -107,6 +110,16 @@ struct KHRicdVendorRec KHRicdVendor *prev; }; +#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) +struct _cl_instance_khr +{ + cl_uint num_platforms; + cl_platform_id *platforms; + KHRicdVendor **vendors; + struct KHRDisp *dispDatas; +}; +#endif // defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) + // the global state extern KHRicdVendor * khrIcdVendors; diff --git a/loader/icd_dispatch.c b/loader/icd_dispatch.c index e4351489..e5010671 100644 --- a/loader/icd_dispatch.c +++ b/loader/icd_dispatch.c @@ -65,6 +65,153 @@ clGetICDLoaderInfoOCLICD( return CL_SUCCESS; } +#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) + +static clCreateInstanceKHR_t clCreateInstanceKHR; +cl_instance_khr CL_API_CALL +clCreateInstanceKHR( + const cl_instance_properties_khr *properties, + cl_int *errcode_ret) +{ +#define KHR_ICD_ALLOC_AND_ZERO(var, num, type) \ + do \ + { \ + var = (type *)malloc(num * sizeof(type)); \ + if (!var) \ + { \ + err = CL_OUT_OF_HOST_MEMORY; \ + goto error; \ + } \ + memset(var, 0, num * sizeof(type)); \ + } while (0) + + (void) properties; + cl_int err = CL_SUCCESS; + cl_instance_khr instance = NULL; + cl_uint num_platforms = 0; + + if (!khrIcdVendors) + { + err = CL_PLATFORM_NOT_FOUND_KHR; + goto error; + } + + for (KHRicdVendor* vendor = khrIcdVendors; vendor; vendor = vendor->next) + { + if (vendor->clIcdCreateInstancePlatform) + num_platforms++; + } + + KHR_ICD_ALLOC_AND_ZERO(instance, 1, struct _cl_instance_khr); + KHR_ICD_ALLOC_AND_ZERO(instance->platforms, num_platforms, cl_platform_id); + KHR_ICD_ALLOC_AND_ZERO(instance->vendors, num_platforms, KHRicdVendor *); + KHR_ICD_ALLOC_AND_ZERO(instance->dispDatas, num_platforms, struct KHRDisp); + + num_platforms = 0; + for (KHRicdVendor* vendor = khrIcdVendors; vendor; vendor = vendor->next) + { + if (vendor->clIcdCreateInstancePlatform) + { + cl_platform_id platform; + platform = vendor->clIcdCreateInstancePlatform(vendor->platform, &err); + if (CL_SUCCESS != err) + continue; + vendor->clIcdSetPlatformDispatchData(platform, instance->dispDatas + num_platforms); + instance->platforms[num_platforms] = platform; + instance->vendors[num_platforms] = vendor; + memcpy(instance->dispDatas + num_platforms, &vendor->dispData, sizeof(struct KHRDisp)); + num_platforms++; + } + } + + if (!num_platforms) + { + err = CL_PLATFORM_NOT_FOUND_KHR; + goto error; + } + + instance->num_platforms = num_platforms; + + if (errcode_ret) + *errcode_ret = CL_SUCCESS; + return instance; +error: + if (instance) + { + free(instance->dispDatas); + free(instance->vendors); + free(instance->platforms); + free(instance); + } + if (errcode_ret) + *errcode_ret = err; +#undef KHR_ICD_ALLOC_AND_ZERO + return NULL; +} + +static clDestroyInstanceKHR_t clDestroyInstanceKHR; +cl_int CL_API_CALL +clDestroyInstanceKHR( + cl_instance_khr instance) +{ + KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(instance, CL_INVALID_INSTANCE_KHR); + for (cl_uint i = 0; i < instance->num_platforms; i++) + instance->vendors[i]->clIcdDestroyInstancePlatform(instance->platforms[i]); + free(instance->dispDatas); + free(instance->vendors); + free(instance->platforms); + free(instance); + return CL_SUCCESS; +} + +static clGetPlatformIDsForInstanceKHR_t clGetPlatformIDsForInstanceKHR; +cl_int CL_API_CALL +clGetPlatformIDsForInstanceKHR( + cl_instance_khr instance, + cl_uint num_entries, + cl_platform_id* platforms, + cl_uint* num_platforms) +{ + cl_uint i; + + KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(instance, CL_INVALID_INSTANCE_KHR); + // should be impossible since create would have refused to + // create an empty instance + if (!instance->num_platforms) + { + return CL_INVALID_INSTANCE_KHR; + } + if (!num_entries && platforms) + { + return CL_INVALID_VALUE; + } + if (!platforms && !num_platforms) + { + return CL_INVALID_VALUE; + } + if (num_platforms) + { + *num_platforms = instance->num_platforms; + } + if (platforms) + { + for (i = 0; i < num_entries; ++i) + { + platforms[i] = NULL; + } + if (instance->num_platforms < num_entries) + { + num_entries = instance->num_platforms; + } + for (i = 0; i < num_entries; ++i) + { + platforms[i] = instance->platforms[i]; + } + } + return CL_SUCCESS; +} +#endif // defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) + static void* khrIcdGetExtensionFunctionAddress(const char* function_name) { // Most extensions, including multi-vendor KHR and EXT extensions, @@ -139,6 +286,13 @@ static void* khrIcdGetExtensionFunctionAddress(const char* function_name) // cl_icdl KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetICDLoaderInfoOCLICD); +#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) + // cl_khr_instances + KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateInstanceKHR); + KHR_ICD_CHECK_EXTENSION_FUNCTION(clDestroyInstanceKHR); + KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetPlatformIDsForInstanceKHR); +#endif + #undef KHR_ICD_CHECK_EXTENSION_FUNCTION return NULL; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ea94490b..bc460a7c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -23,6 +23,13 @@ add_test ( COMMAND icd_loader_test ) +if (ENABLE_OPENCL_LOADER_MANAGED_DISPATCH) +add_test ( + NAME opencl_icd_loader_icd2_instance_test + COMMAND icd_loader_test +) +endif () + if (ENABLE_OPENCL_LAYERINFO) add_test ( NAME cllayerinfo_test @@ -47,6 +54,13 @@ set_tests_properties(opencl_icd_loader_icd2_test ENVIRONMENT "OCL_ICD_FILENAMES=$;APP_LOG_FILE=icd_test_app_log_icd2.txt;APP_STUB_FILE=icd_test_stub_log_icd2.txt" WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}" ) +if (ENABLE_OPENCL_LOADER_MANAGED_DISPATCH) + set_tests_properties(opencl_icd_loader_icd2_instance_test + PROPERTIES + ENVIRONMENT "OCL_ICD_FILENAMES=$;APP_LOG_FILE=icd_test_app_log_icd2_instance.txt;APP_STUB_FILE=icd_test_stub_log_icd2_instance.txt;USE_INSTANCE=1" + WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}" + ) +endif() if (ENABLE_OPENCL_LAYERINFO) set_tests_properties(cllayerinfo_test PROPERTIES diff --git a/test/driver_stub/cl.c b/test/driver_stub/cl.c index a43d513e..63956635 100644 --- a/test/driver_stub/cl.c +++ b/test/driver_stub/cl.c @@ -19,6 +19,12 @@ #include "icd_structs.h" #include "cl_khr_icd2.h" +#if defined(CL_ENABLE_ICD2) +#include "cl_khr_icd2.h" +CL_API_ENTRY clIcdCreateInstancePlatformKHR_t clIcdCreateInstancePlatformKHR; +CL_API_ENTRY clIcdDestroyInstancePlatformKHR_t clIcdDestroyInstancePlatformKHR; +#endif + #define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920 CL_API_ENTRY cl_int CL_API_CALL clIcdGetPlatformIDsKHR(cl_uint, cl_platform_id *, cl_uint *); @@ -33,6 +39,7 @@ struct _cl_platform_id const char *extensions; const char *suffix; cl_device_id device; + cl_bool instance; }; struct _cl_device_id @@ -180,7 +187,7 @@ CL_API_ENTRY cl_int CL_API_CALL clGetDeviceIDs( if (devices != NULL) { if (!platform_id->device) { platform_id->device = (cl_device_id) malloc(sizeof(struct _cl_device_id)); - CL_INIT_OBJECT(platform_id->device, stub_platform); + CL_INIT_OBJECT(platform_id->device, platform_id); } devices[0] = platform_id->device; } @@ -1948,6 +1955,29 @@ clEnqueueBarrier(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0 extern cl_int cliIcdDispatchTableCreate(CLIicdDispatchTable **outDispatchTable); extern void cliIcdDispatchTableDestroy(CLIicdDispatchTable *dispatchTable); +static cl_platform_id createPlatform(void) +{ + cl_platform_id 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"; + return platform; +} + +static void destroyPlatform(cl_platform_id platform) +{ + free(platform->device); + platform->device = NULL; + free(platform); +} + CL_API_ENTRY cl_int CL_API_CALL clIcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id * platforms, @@ -1956,16 +1986,7 @@ clIcdGetPlatformIDsKHR(cl_uint num_entries, cl_int result = CL_SUCCESS; if (!initialized) { result = cliIcdDispatchTableCreate(&dispatchTable); - 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"; + stub_platform = createPlatform(); initialized = CL_TRUE; } @@ -1988,11 +2009,38 @@ clIcdGetPlatformIDsKHR(cl_uint num_entries, return result; } +#if defined(CL_ENABLE_ICD2) +CL_API_ENTRY cl_platform_id CL_API_CALL +clIcdCreateInstancePlatformKHR( + cl_platform_id platform, + cl_int *errcode_ret) +{ + if (!platform || platform->dispatch != dispatchTable) { + *errcode_ret = CL_INVALID_PLATFORM; + return NULL; + } + cl_platform_id platform_ret = createPlatform(); + platform_ret->instance = CL_TRUE; + if (errcode_ret) { + *errcode_ret = CL_SUCCESS; + } + return platform_ret; +} + +CL_API_ENTRY cl_int CL_API_CALL +clIcdDestroyInstancePlatformKHR( + cl_platform_id platform) +{ + if (!platform || platform->dispatch != dispatchTable || !platform->instance) + return CL_INVALID_PLATFORM; + destroyPlatform(platform); + return CL_SUCCESS; +} +#endif + static void deinit(void) { if (initialized) { - free(stub_platform->device); - stub_platform->device = NULL; - free(stub_platform); + destroyPlatform(stub_platform); stub_platform = NULL; cliIcdDispatchTableDestroy(dispatchTable); dispatchTable = NULL; diff --git a/test/driver_stub/cl_ext.c b/test/driver_stub/cl_ext.c index b412f934..4caf4c4d 100644 --- a/test/driver_stub/cl_ext.c +++ b/test/driver_stub/cl_ext.c @@ -8,6 +8,8 @@ #if defined(CL_ENABLE_ICD2) CL_API_ENTRY clIcdGetFunctionAddressForPlatformKHR_t clIcdGetFunctionAddressForPlatformKHR; CL_API_ENTRY clIcdSetPlatformDispatchDataKHR_t clIcdSetPlatformDispatchDataKHR; +CL_API_ENTRY clIcdCreateInstancePlatformKHR_t clIcdCreateInstancePlatformKHR; +CL_API_ENTRY clIcdDestroyInstancePlatformKHR_t clIcdDestroyInstancePlatformKHR; #endif struct driverStubextFunc_st @@ -24,6 +26,8 @@ static struct driverStubextFunc_st clExtensions[] = #ifdef CL_ENABLE_ICD2 EXT_FUNC(clIcdGetFunctionAddressForPlatformKHR), EXT_FUNC(clIcdSetPlatformDispatchDataKHR), + EXT_FUNC(clIcdCreateInstancePlatformKHR), + EXT_FUNC(clIcdDestroyInstancePlatformKHR), #endif //CL_ENABLE_ICD2 }; diff --git a/test/loader_test/CMakeLists.txt b/test/loader_test/CMakeLists.txt index 3a401210..709f6a2d 100644 --- a/test/loader_test/CMakeLists.txt +++ b/test/loader_test/CMakeLists.txt @@ -1,4 +1,5 @@ add_executable (icd_loader_test + ${CMAKE_SOURCE_DIR}/include/cl_khr_icd2.h test_kernel.c main.c test_platforms.c diff --git a/test/loader_test/param_struct.h b/test/loader_test/param_struct.h index 00d96a97..06439dff 100644 --- a/test/loader_test/param_struct.h +++ b/test/loader_test/param_struct.h @@ -3,6 +3,7 @@ #include #include +#include "cl_khr_icd2.h" struct clCreateCommandQueue_st { @@ -74,6 +75,25 @@ struct clSetContextDestructorCallback_st void *user_data; }; +struct clCreateInstanceKHR_st +{ + cl_instance_properties_khr *properties; + cl_int *errcode_ret; +}; + +struct clDestroyInstanceKHR_st +{ + cl_instance_khr instance; +}; + +struct clGetPlatformIDsForInstanceKHR_st +{ + cl_instance_khr instance; + cl_uint num_entries; + cl_platform_id *platforms; + cl_uint *num_platforms; +}; + struct clGetPlatformIDs_st { cl_uint num_entries; @@ -120,6 +140,9 @@ struct clReleaseCommandQueue_st #define NUM_ITEMS_clReleaseContext 1 #define NUM_ITEMS_clGetContextInfo 1 #define NUM_ITEMS_clSetContextDestructorCallback 1 +#define NUM_ITEMS_clCreateInstanceKHR 1 +#define NUM_ITEMS_clDestroyInstanceKHR 1 +#define NUM_ITEMS_clGetPlatformIDsForInstanceKHR 1 #define NUM_ITEMS_clGetPlatformIDs 1 #define NUM_ITEMS_clGetPlatformInfo 1 #define NUM_ITEMS_clGetDeviceIDs 1 diff --git a/test/loader_test/test_create_calls.c b/test/loader_test/test_create_calls.c index 8dbf3cad..7274a987 100644 --- a/test/loader_test/test_create_calls.c +++ b/test/loader_test/test_create_calls.c @@ -11,8 +11,8 @@ extern void CL_CALLBACK createcontext_callback(const char* a, const void* b, size_t c, void* d); +cl_instance_khr instance; cl_platform_id platform; -cl_uint num_platforms; cl_context context; cl_command_queue command_queue; cl_mem buffer; @@ -135,11 +135,130 @@ const struct clCreateUserEvent_st clCreateUserEventData[NUM_ITEMS_clCreateUserEv {NULL, NULL} }; +const struct clCreateInstanceKHR_st clCreateInstanceKHRData[NUM_ITEMS_clCreateInstanceKHR] = +{ + {NULL, NULL} +}; + +struct clDestroyInstanceKHR_st clDestroyInstanceKHRData[NUM_ITEMS_clDestroyInstanceKHR] = +{ + {NULL} +}; + +struct clGetPlatformIDsForInstanceKHR_st clGetPlatformIDsForInstanceKHRData[NUM_ITEMS_clGetPlatformIDsForInstanceKHR] = +{ + {NULL, 0, NULL, NULL} +}; + const struct clGetPlatformIDs_st clGetPlatformIDsData[NUM_ITEMS_clGetPlatformIDs] = { {0, NULL, 0} }; +int test_clCreateInstanceKHR(const struct clCreateInstanceKHR_st *data) +{ + clCreateInstanceKHR_fn clCreateInstanceKHR = (clCreateInstanceKHR_fn) + (intptr_t)clGetExtensionFunctionAddress("clCreateInstanceKHR"); + + if (!clCreateInstanceKHR) { + test_icd_app_log("clGetExtensionFunctionAddress failed!\n"); + return 1; + } + instance = clCreateInstanceKHR(data->properties, data->errcode_ret); + if (!instance) { + test_icd_app_log("clCreateInstanceKHR failed!\n"); + return 1; + } + clDestroyInstanceKHRData[0].instance = instance; + clGetPlatformIDsForInstanceKHRData[0].instance = instance; + return 0; +} + +int test_clDestroyInstanceKHR(const struct clDestroyInstanceKHR_st *data) +{ + cl_int ret_val; + clDestroyInstanceKHR_fn clDestroyInstanceKHR = (clDestroyInstanceKHR_fn) + (intptr_t)clGetExtensionFunctionAddress("clDestroyInstanceKHR"); + + if (!clDestroyInstanceKHR) { + test_icd_app_log("clGetExtensionFunctionAddress failed!\n"); + return 1; + } + ret_val = clDestroyInstanceKHR(data->instance); + if (ret_val != CL_SUCCESS) { + test_icd_app_log("clDestroyInstanceKHR failed!\n"); + return 1; + } + return 0; +} + +static cl_platform_id findPlatform(cl_uint num_platforms, cl_platform_id *platforms) +{ + cl_int ret_val; + size_t param_val_ret_size; + #define PLATFORM_NAME_SIZE 80 + char platform_name[PLATFORM_NAME_SIZE]; + cl_uint i; + + for (i = 0; i < num_platforms; i++) { + ret_val = clGetPlatformInfo(platforms[i], + CL_PLATFORM_NAME, + PLATFORM_NAME_SIZE, + (void*)platform_name, + ¶m_val_ret_size ); + + if (ret_val == CL_SUCCESS ){ + if(!strcmp(platform_name, "ICD_LOADER_TEST_OPENCL_STUB")) { + return platforms[i]; + } + } + } + return NULL; +} + +int test_clGetPlatformIDsForInstanceKHR(const struct clGetPlatformIDsForInstanceKHR_st *data) +{ + cl_int ret_val; + cl_platform_id *all_platforms; + cl_uint num_platforms; + clGetPlatformIDsForInstanceKHR_fn clGetPlatformIDsForInstanceKHR = (clGetPlatformIDsForInstanceKHR_fn) + (intptr_t)clGetExtensionFunctionAddress("clGetPlatformIDsForInstanceKHR"); + + if (!clGetPlatformIDsForInstanceKHR) { + test_icd_app_log("clGetExtensionFunctionAddress failed!\n"); + return 1; + } + ret_val = clGetPlatformIDsForInstanceKHR(data->instance, + 0, NULL, &num_platforms); + + if (ret_val != CL_SUCCESS) { + test_icd_app_log("clGetPlatformIDsForInstanceKHR failed!\n"); + return 1; + } + + all_platforms = (cl_platform_id *)malloc(num_platforms * sizeof(cl_platform_id)); + + ret_val = clGetPlatformIDsForInstanceKHR(data->instance, + num_platforms, + all_platforms, + NULL); + + if (ret_val != CL_SUCCESS) { + test_icd_app_log("clGetPlatformIDsForInstanceKHR failed!\n"); + return 1; + } + + platform = findPlatform(num_platforms, all_platforms); + + if (!platform) { + test_icd_app_log("Failed to find stub platform!\n"); + } + + free(all_platforms); + + return 0; +} + /* * Some log messages cause log mismatches when ICD loader calls a driver * function while initializing platforms. The functions clGetPlatform* are most @@ -153,16 +272,13 @@ const struct clGetPlatformIDs_st clGetPlatformIDsData[NUM_ITEMS_clGetPlatformIDs int test_clGetPlatformIDs(const struct clGetPlatformIDs_st* data) { cl_int ret_val; - size_t param_val_ret_size; - #define PLATFORM_NAME_SIZE 80 - char platform_name[PLATFORM_NAME_SIZE]; - cl_uint i; cl_platform_id *all_platforms; + cl_uint num_platforms; #if ENABLE_MISMATCHING_PRINTS test_icd_app_log("clGetPlatformIDs(%u, %p, %p)\n", data->num_entries, - &platforms, + data->platforms, &num_platforms); #else (void)data; @@ -185,20 +301,13 @@ int test_clGetPlatformIDs(const struct clGetPlatformIDs_st* data) if (ret_val != CL_SUCCESS){ return -1; } - - for (i = 0; i < num_platforms; i++) { - ret_val = clGetPlatformInfo(all_platforms[i], - CL_PLATFORM_NAME, - PLATFORM_NAME_SIZE, - (void*)platform_name, - ¶m_val_ret_size ); - if (ret_val == CL_SUCCESS ){ - if(!strcmp(platform_name, "ICD_LOADER_TEST_OPENCL_STUB")) { - platform = all_platforms[i]; - } - } + platform = findPlatform(num_platforms, all_platforms); + + if (!platform) { + return -1; } + free(all_platforms); #if ENABLE_MISMATCHING_PRINTS @@ -772,7 +881,15 @@ int test_clReleaseDevice(const struct clReleaseDevice_st* data) int test_create_calls(void) { - test_clGetPlatformIDs(clGetPlatformIDsData); + const char *var = log_getenv("USE_INSTANCE", NULL); + if (var) { + test_clCreateInstanceKHR(clCreateInstanceKHRData); + + test_clGetPlatformIDsForInstanceKHR(clGetPlatformIDsForInstanceKHRData); + log_freeenv(var); + } else { + test_clGetPlatformIDs(clGetPlatformIDsData); + } context_properties[1] = (cl_context_properties) platform; @@ -832,6 +949,7 @@ int test_create_calls(void) int test_release_calls(void) { + const char *var = log_getenv("USE_INSTANCE", NULL); test_clReleaseSampler(clReleaseSamplerData); test_clReleaseMemObject(clReleaseMemObjectData); @@ -852,6 +970,10 @@ int test_release_calls(void) test_clReleaseDevice(clReleaseDeviceData); + if (var) { + test_clDestroyInstanceKHR(clDestroyInstanceKHRData); + log_freeenv(var); + } return 0; }