Skip to content

Commit 713ec89

Browse files
committed
WIP: instance support.
1 parent 46c3bf9 commit 713ec89

File tree

11 files changed

+467
-34
lines changed

11 files changed

+467
-34
lines changed

.github/workflows/windows.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ jobs:
174174
)
175175
%REG% DELETE HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors /v %GITHUB_WORKSPACE%/build/Release/OpenCLDriverStub.dll /f
176176
%REG% ADD HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors /v %GITHUB_WORKSPACE%/build/Release/OpenCLDriverStubICD2.dll /t REG_DWORD /d 0
177-
%CTEST_EXE% -C Release --output-on-failure --parallel %NUMBER_OF_PROCESSORS% -R opencl_icd_loader_icd2_test
177+
%CTEST_EXE% -C Release --output-on-failure --parallel %NUMBER_OF_PROCESSORS% -R opencl_icd_loader_icd2_test^|opencl_icd_loader_icd2_instance_test
178178
if errorlevel 1 (
179179
exit /b %errorlevel%
180180
)
@@ -186,7 +186,7 @@ jobs:
186186
)
187187
%REG% DELETE HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors /v %GITHUB_WORKSPACE%/build/Debug/OpenCLDriverStub.dll /f
188188
%REG% ADD HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors /v %GITHUB_WORKSPACE%/build/Debug/OpenCLDriverStubICD2.dll /t REG_DWORD /d 0
189-
%CTEST_EXE% -C Debug --output-on-failure --parallel %NUMBER_OF_PROCESSORS% -R opencl_icd_loader_icd2_test
189+
%CTEST_EXE% -C Debug --output-on-failure --parallel %NUMBER_OF_PROCESSORS% -R opencl_icd_loader_icd2_test^|opencl_icd_loader_icd2_instance_test
190190
if errorlevel 1 (
191191
exit /b %errorlevel%
192192
)

include/cl_khr_icd2.h

+48
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,51 @@ clIcdSetPlatformDispatchDataKHR_t(
3434
typedef clIcdSetPlatformDispatchDataKHR_t *
3535
clIcdSetPlatformDispatchDataKHR_fn;
3636
#endif // !defined(CL_ICD2_TAG_KHR)
37+
38+
#if !defined(CL_INVALID_INSTANCE_KHR)
39+
#define CL_INVALID_INSTANCE_KHR -1154
40+
41+
typedef struct _cl_instance *cl_instance;
42+
typedef cl_properties cl_instance_properties;
43+
44+
typedef cl_instance CL_API_CALL
45+
clCreateInstanceKHR_t(
46+
const cl_instance_properties *properties,
47+
cl_int *errcode_ret);
48+
49+
typedef clCreateInstanceKHR_t *
50+
clCreateInstanceKHR_fn;
51+
52+
typedef cl_int CL_API_CALL
53+
clDestroyInstanceKHR_t(
54+
cl_instance instance);
55+
56+
typedef clDestroyInstanceKHR_t *
57+
clDestroyInstanceKHR_fn;
58+
59+
typedef cl_int CL_API_CALL
60+
clGetPlatformIDsForInstanceKHR_t(
61+
cl_instance instance,
62+
cl_uint num_entries,
63+
cl_platform_id *platforms,
64+
cl_uint *num_platforms);
65+
66+
typedef clGetPlatformIDsForInstanceKHR_t *
67+
clGetPlatformIDsForInstanceKHR_fn;
68+
69+
typedef cl_platform_id CL_API_CALL
70+
clIcdCreateInstancePlatformKHR_t(
71+
cl_platform_id platform,
72+
cl_int *errcode_ret);
73+
74+
typedef clIcdCreateInstancePlatformKHR_t *
75+
clIcdCreateInstancePlatformKHR_fn;
76+
77+
typedef cl_int CL_API_CALL
78+
clIcdDestroyInstancePlatformKHR_t(
79+
cl_platform_id platform);
80+
81+
typedef clIcdDestroyInstancePlatformKHR_t *
82+
clIcdDestroyInstancePlatformKHR_fn;
83+
84+
#endif // !defined(CL_INVALID_INSTANCE_KHR)

loader/icd.c

+10
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ void khrIcdVendorAdd(const char *libraryName)
5959
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
6060
clIcdGetFunctionAddressForPlatformKHR_fn p_clIcdGetFunctionAddressForPlatform = NULL;
6161
clIcdSetPlatformDispatchDataKHR_fn p_clIcdSetPlatformDispatchData = NULL;
62+
clIcdCreateInstancePlatformKHR_fn p_clIcdCreateInstancePlatform = NULL;
63+
clIcdDestroyInstancePlatformKHR_fn p_clIcdDestroyInstancePlatform = NULL;
6264
#endif
6365
cl_uint i = 0;
6466
cl_uint platformCount = 0;
@@ -110,6 +112,8 @@ void khrIcdVendorAdd(const char *libraryName)
110112
// try to get clIcdGetFunctionAddressForPlatformKHR and clIcdSetPlatformDispatchDataKHR to detect cl_khr_icd2 support
111113
p_clIcdGetFunctionAddressForPlatform = (clIcdGetFunctionAddressForPlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdGetFunctionAddressForPlatformKHR");
112114
p_clIcdSetPlatformDispatchData = (clIcdSetPlatformDispatchDataKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdSetPlatformDispatchDataKHR");
115+
p_clIcdCreateInstancePlatform = (clIcdCreateInstancePlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdCreateInstancePlatformKHR");
116+
p_clIcdDestroyInstancePlatform = (clIcdDestroyInstancePlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdDestroyInstancePlatformKHR");
113117
#endif
114118

115119
// query the number of platforms available and allocate space to store them
@@ -175,6 +179,12 @@ void khrIcdVendorAdd(const char *libraryName)
175179
khrIcd2PopulateDispatchTable(platforms[i], p_clIcdGetFunctionAddressForPlatform, &vendor->dispData.dispatch);
176180
p_clIcdSetPlatformDispatchData(platforms[i], &vendor->dispData);
177181
KHR_ICD_TRACE("found icd 2 platform, using loader managed dispatch\n");
182+
if (p_clIcdCreateInstancePlatform && p_clIcdDestroyInstancePlatform)
183+
{
184+
vendor->clIcdSetPlatformDispatchData = p_clIcdSetPlatformDispatchData;
185+
vendor->clIcdCreateInstancePlatform = p_clIcdCreateInstancePlatform;
186+
vendor->clIcdDestroyInstancePlatform = p_clIcdDestroyInstancePlatform;
187+
}
178188
}
179189
#endif
180190

loader/icd.h

+13
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,26 @@ struct KHRicdVendorRec
100100
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
101101
// the loader populated dispatch table for cl_khr_icd2 compliant platforms
102102
struct KHRDisp dispData;
103+
clIcdSetPlatformDispatchDataKHR_fn clIcdSetPlatformDispatchData;
104+
clIcdCreateInstancePlatformKHR_fn clIcdCreateInstancePlatform;
105+
clIcdDestroyInstancePlatformKHR_fn clIcdDestroyInstancePlatform;
103106
#endif
104107

105108
// next vendor in the list vendors
106109
KHRicdVendor *next;
107110
KHRicdVendor *prev;
108111
};
109112

113+
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
114+
struct _cl_instance
115+
{
116+
cl_uint num_platforms;
117+
cl_platform_id *platforms;
118+
KHRicdVendor **vendors;
119+
struct KHRDisp *dispDatas;
120+
};
121+
#endif // defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
122+
110123
// the global state
111124
extern KHRicdVendor * khrIcdVendors;
112125

loader/icd_dispatch.c

+154
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,153 @@ clGetICDLoaderInfoOCLICD(
6565
return CL_SUCCESS;
6666
}
6767

68+
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
69+
70+
static clCreateInstanceKHR_t clCreateInstanceKHR;
71+
cl_instance CL_API_CALL
72+
clCreateInstanceKHR(
73+
const cl_instance_properties *properties,
74+
cl_int *errcode_ret)
75+
{
76+
#define KHR_ICD_ALLOC_AND_ZERO(var, num, type) \
77+
do \
78+
{ \
79+
var = (type *)malloc(num * sizeof(type)); \
80+
if (!var) \
81+
{ \
82+
err = CL_OUT_OF_HOST_MEMORY; \
83+
goto error; \
84+
} \
85+
memset(var, 0, num * sizeof(type)); \
86+
} while (0)
87+
88+
(void) properties;
89+
cl_int err = CL_SUCCESS;
90+
cl_instance instance = NULL;
91+
cl_uint num_platforms = 0;
92+
93+
if (!khrIcdVendors)
94+
{
95+
err = CL_PLATFORM_NOT_FOUND_KHR;
96+
goto error;
97+
}
98+
99+
for (KHRicdVendor* vendor = khrIcdVendors; vendor; vendor = vendor->next)
100+
{
101+
if (vendor->clIcdCreateInstancePlatform)
102+
num_platforms++;
103+
}
104+
105+
KHR_ICD_ALLOC_AND_ZERO(instance, 1, struct _cl_instance);
106+
KHR_ICD_ALLOC_AND_ZERO(instance->platforms, num_platforms, cl_platform_id);
107+
KHR_ICD_ALLOC_AND_ZERO(instance->vendors, num_platforms, KHRicdVendor *);
108+
KHR_ICD_ALLOC_AND_ZERO(instance->dispDatas, num_platforms, struct KHRDisp);
109+
110+
num_platforms = 0;
111+
for (KHRicdVendor* vendor = khrIcdVendors; vendor; vendor = vendor->next)
112+
{
113+
if (vendor->clIcdCreateInstancePlatform)
114+
{
115+
cl_platform_id platform;
116+
platform = vendor->clIcdCreateInstancePlatform(vendor->platform, &err);
117+
if (CL_SUCCESS != err)
118+
continue;
119+
vendor->clIcdSetPlatformDispatchData(platform, instance->dispDatas + num_platforms);
120+
instance->platforms[num_platforms] = platform;
121+
instance->vendors[num_platforms] = vendor;
122+
memcpy(instance->dispDatas + num_platforms, &vendor->dispData, sizeof(struct KHRDisp));
123+
num_platforms++;
124+
}
125+
}
126+
127+
if (!num_platforms)
128+
{
129+
err = CL_PLATFORM_NOT_FOUND_KHR;
130+
goto error;
131+
}
132+
133+
instance->num_platforms = num_platforms;
134+
135+
if (errcode_ret)
136+
*errcode_ret = CL_SUCCESS;
137+
return instance;
138+
error:
139+
if (instance)
140+
{
141+
free(instance->dispDatas);
142+
free(instance->vendors);
143+
free(instance->platforms);
144+
free(instance);
145+
}
146+
if (errcode_ret)
147+
*errcode_ret = err;
148+
#undef KHR_ICD_ALLOC_AND_ZERO
149+
return NULL;
150+
}
151+
152+
static clDestroyInstanceKHR_t clDestroyInstanceKHR;
153+
cl_int CL_API_CALL
154+
clDestroyInstanceKHR(
155+
cl_instance instance)
156+
{
157+
KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(instance, CL_INVALID_INSTANCE_KHR);
158+
for (cl_uint i = 0; i < instance->num_platforms; i++)
159+
instance->vendors[i]->clIcdDestroyInstancePlatform(instance->platforms[i]);
160+
free(instance->dispDatas);
161+
free(instance->vendors);
162+
free(instance->platforms);
163+
free(instance);
164+
return CL_SUCCESS;
165+
}
166+
167+
static clGetPlatformIDsForInstanceKHR_t clGetPlatformIDsForInstanceKHR;
168+
cl_int CL_API_CALL
169+
clGetPlatformIDsForInstanceKHR(
170+
cl_instance instance,
171+
cl_uint num_entries,
172+
cl_platform_id* platforms,
173+
cl_uint* num_platforms)
174+
{
175+
cl_uint i;
176+
177+
KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(instance, CL_INVALID_INSTANCE_KHR);
178+
// should be impossible since create would have refused to
179+
// create an empty instance
180+
if (!instance->num_platforms)
181+
{
182+
return CL_INVALID_INSTANCE_KHR;
183+
}
184+
if (!num_entries && platforms)
185+
{
186+
return CL_INVALID_VALUE;
187+
}
188+
if (!platforms && !num_platforms)
189+
{
190+
return CL_INVALID_VALUE;
191+
}
192+
if (num_platforms)
193+
{
194+
*num_platforms = instance->num_platforms;
195+
}
196+
if (platforms)
197+
{
198+
for (i = 0; i < num_entries; ++i)
199+
{
200+
platforms[i] = NULL;
201+
}
202+
if (instance->num_platforms < num_entries)
203+
{
204+
num_entries = instance->num_platforms;
205+
}
206+
for (i = 0; i < num_entries; ++i)
207+
{
208+
platforms[i] = instance->platforms[i];
209+
}
210+
}
211+
return CL_SUCCESS;
212+
}
213+
#endif // defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
214+
68215
static void* khrIcdGetExtensionFunctionAddress(const char* function_name)
69216
{
70217
// Most extensions, including multi-vendor KHR and EXT extensions,
@@ -139,6 +286,13 @@ static void* khrIcdGetExtensionFunctionAddress(const char* function_name)
139286
// cl_icdl
140287
KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetICDLoaderInfoOCLICD);
141288

289+
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
290+
// cl_khr_instances
291+
KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateInstanceKHR);
292+
KHR_ICD_CHECK_EXTENSION_FUNCTION(clDestroyInstanceKHR);
293+
KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetPlatformIDsForInstanceKHR);
294+
#endif
295+
142296
#undef KHR_ICD_CHECK_EXTENSION_FUNCTION
143297

144298
return NULL;

test/CMakeLists.txt

+14
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ add_test (
2323
COMMAND icd_loader_test
2424
)
2525

26+
if (ENABLE_OPENCL_LOADER_MANAGED_DISPATCH)
27+
add_test (
28+
NAME opencl_icd_loader_icd2_instance_test
29+
COMMAND icd_loader_test
30+
)
31+
endif ()
32+
2633
if (ENABLE_OPENCL_LAYERINFO)
2734
add_test (
2835
NAME cllayerinfo_test
@@ -47,6 +54,13 @@ set_tests_properties(opencl_icd_loader_icd2_test
4754
ENVIRONMENT "OCL_ICD_FILENAMES=$<TARGET_FILE:OpenCLDriverStubICD2>;APP_LOG_FILE=icd_test_app_log_icd2.txt;APP_STUB_FILE=icd_test_stub_log_icd2.txt"
4855
WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}"
4956
)
57+
if (ENABLE_OPENCL_LOADER_MANAGED_DISPATCH)
58+
set_tests_properties(opencl_icd_loader_icd2_instance_test
59+
PROPERTIES
60+
ENVIRONMENT "OCL_ICD_FILENAMES=$<TARGET_FILE:OpenCLDriverStubICD2>;APP_LOG_FILE=icd_test_app_log_icd2_instance.txt;APP_STUB_FILE=icd_test_stub_log_icd2_instance.txt;USE_INSTANCE=1"
61+
WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}"
62+
)
63+
endif()
5064
if (ENABLE_OPENCL_LAYERINFO)
5165
set_tests_properties(cllayerinfo_test
5266
PROPERTIES

0 commit comments

Comments
 (0)