1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #define INITGUID
17 #include "harness.h"
18
19 #include <tchar.h>
20 #include <string>
21 #include <vector>
22
23 /*
24 * OpenCL state
25 */
26
27 clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = NULL;
28 clCreateFromD3D11BufferKHR_fn clCreateFromD3D11BufferKHR = NULL;
29 clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL;
30 clCreateFromD3D11Texture3DKHR_fn clCreateFromD3D11Texture3DKHR = NULL;
31 clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL;
32 clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL;
33
34 #define INITPFN(x) \
35 x = (x ## _fn)clGetExtensionFunctionAddressForPlatform(platform, #x); NonTestRequire(x, "Failed to get function pointer for %s", #x);
36
37 void
HarnessD3D11_ExtensionCheck()38 HarnessD3D11_ExtensionCheck()
39 {
40 cl_int result = CL_SUCCESS;
41 cl_platform_id platform = NULL;
42
43 HarnessD3D11_TestBegin("Extension query");
44
45 bool platform_d3d11 = false; // Does platform support the extension?
46 {
47 std::vector< char > buffer;
48 size_t size = 0;
49 result = clGetPlatformIDs( 1, &platform, NULL );
50 NonTestRequire( result == CL_SUCCESS, "Failed to get any platforms." );
51 result = clGetPlatformInfo( platform, CL_PLATFORM_EXTENSIONS, 0, NULL, & size );
52 NonTestRequire( result == CL_SUCCESS, "Failed to get size of extension string." );
53 buffer.resize( size );
54 result = clGetPlatformInfo( platform, CL_PLATFORM_EXTENSIONS, buffer.size(), & buffer.front(), & size );
55 NonTestRequire( result == CL_SUCCESS, "Failed to get extension string." );
56 std::string extensions = std::string( " " ) + & buffer.front() + " ";
57 platform_d3d11 = ( extensions.find( " cl_khr_d3d11_sharing " ) != std::string::npos );
58 }
59
60 // Platform is required to report the extension only if all devices support it,
61 // so let us iterate through all the devices and count devices supporting the extension.
62
63 // Get list of all devices.
64 std::vector< cl_device_id > devices;
65 cl_uint num_devices = 0;
66 result = clGetDeviceIDs( platform, CL_DEVICE_TYPE_ALL, 0, NULL, & num_devices );
67 NonTestRequire( result == CL_SUCCESS, "Failed to get number of devices." );
68 devices.resize( num_devices );
69 result = clGetDeviceIDs( platform, CL_DEVICE_TYPE_ALL, devices.size(), & devices.front(), & num_devices );
70 NonTestRequire( result == CL_SUCCESS, "Failed to get list of device ids." );
71 NonTestRequire( num_devices == devices.size(), "Failed to get list of device ids." );
72
73 // Iterate through the devices and count devices supporting the extension.
74 cl_uint num_devices_d3d11 = 0; // Number of devices supporting cl_khr_d3d11_sharing.
75 for ( cl_uint i = 0; i < devices.size(); ++ i )
76 {
77 if (is_extension_available(devices[i], "cl_khr_d3d11_sharing"))
78 {
79 ++ num_devices_d3d11;
80 }
81 }
82
83 OSVERSIONINFO osvi;
84 osvi.dwOSVersionInfoSize = sizeof(osvi);
85 GetVersionEx(&osvi);
86 if (osvi.dwMajorVersion <= 5)
87 {
88 // Neither platform nor devices should declare support.
89 TestRequire( ! platform_d3d11, "Platform should not declare extension on Windows < 6" );
90 TestRequire( num_devices_d3d11 == 0, "Devices should not declare extension on Windows < 6" );
91 }
92 else
93 {
94 if ( num_devices_d3d11 == num_devices )
95 {
96 // All the devices declare support, so platform must declare support as well.
97 TestRequire( platform_d3d11, "Extension should be exported on Windows >= 6" );
98 }
99 else
100 {
101 // Not all the devices support th eextension => platform should not declare it.
102 TestRequire( ! platform_d3d11, "Extension should not be exported on Windows >= 6" );
103 }
104 }
105
106 Cleanup:
107 HarnessD3D11_TestEnd();
108
109 // early-out of the extension is not present
110 if ( num_devices_d3d11 == 0 )
111 {
112 HarnessD3D11_TestStats();
113 }
114 }
115
116 void
HarnessD3D11_Initialize(cl_platform_id platform)117 HarnessD3D11_Initialize(cl_platform_id platform)
118 {
119 HarnessD3D11_ExtensionCheck();
120
121 // extract function pointers for exported functions
122 INITPFN(clGetDeviceIDsFromD3D11KHR);
123 INITPFN(clCreateFromD3D11BufferKHR);
124 INITPFN(clCreateFromD3D11Texture2DKHR);
125 INITPFN(clCreateFromD3D11Texture3DKHR);
126 INITPFN(clEnqueueAcquireD3D11ObjectsKHR);
127 INITPFN(clEnqueueReleaseD3D11ObjectsKHR);
128 }
129
130 /*
131 * Window management
132 */
133
134 static IDXGISwapChain* HarnessD3D11_pSwapChain = NULL;
135 static ID3D11Device* HarnessD3D11_pDevice = NULL;
136 static ID3D11DeviceContext* HarnessD3D11_pDC = NULL;
137 static HWND HarnessD3D11_hWnd = NULL;
138
HarnessD3D11_Proc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)139 static LRESULT WINAPI HarnessD3D11_Proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
140 {
141 switch(msg)
142 {
143 case WM_KEYDOWN:
144 return 0;
145 break;
146 case WM_DESTROY:
147 HarnessD3D11_hWnd = NULL;
148 PostQuitMessage(0);
149 return 0;
150 case WM_PAINT:
151 ValidateRect(hWnd, NULL);
152 return 0;
153 }
154 return DefWindowProc(hWnd, msg, wParam, lParam);
155 }
156
HarnessD3D11_InteractiveLoop()157 static void HarnessD3D11_InteractiveLoop()
158 {
159 MSG msg;
160 while(PeekMessage(&msg,HarnessD3D11_hWnd,0,0,PM_REMOVE))
161 {
162 TranslateMessage(&msg);
163 DispatchMessage(&msg);
164 }
165 }
166
HarnessD3D11_CreateDevice(IDXGIAdapter * pAdapter,ID3D11Device ** ppDevice,ID3D11DeviceContext ** ppDC)167 cl_int HarnessD3D11_CreateDevice(
168 IDXGIAdapter* pAdapter,
169 ID3D11Device **ppDevice,
170 ID3D11DeviceContext** ppDC)
171 {
172 HRESULT hr = S_OK;
173 unsigned int cuStatus = 1;
174
175 *ppDevice = NULL;
176
177 // create window
178 static WNDCLASSEX wc =
179 {
180 sizeof(WNDCLASSEX),
181 CS_CLASSDC,
182 HarnessD3D11_Proc,
183 0L,
184 0L,
185 GetModuleHandle(NULL),
186 NULL,
187 NULL,
188 NULL,
189 NULL,
190 _T( "cl_khr_d3d11_sharing_conformance" ),
191 NULL
192 };
193 RegisterClassEx(&wc);
194 HarnessD3D11_hWnd = CreateWindow(
195 _T( "cl_khr_d3d11_sharing_conformance" ),
196 _T( "cl_khr_d3d11_sharing_conformance" ),
197 WS_OVERLAPPEDWINDOW,
198 0, 0, 256, 256,
199 NULL,
200 NULL,
201 wc.hInstance,
202 NULL);
203 NonTestRequire(0 != HarnessD3D11_hWnd, "Failed to create window");
204
205 ShowWindow(HarnessD3D11_hWnd,SW_SHOWDEFAULT);
206 UpdateWindow(HarnessD3D11_hWnd);
207
208 RECT rc;
209 GetClientRect(HarnessD3D11_hWnd, &rc);
210 UINT width = rc.right - rc.left;
211 UINT height = rc.bottom - rc.top;
212
213 // Create device and swapchain
214 DXGI_SWAP_CHAIN_DESC sd;
215 ZeroMemory( &sd, sizeof(sd) );
216 sd.BufferCount = 1;
217 sd.BufferDesc.Width = width;
218 sd.BufferDesc.Height = height;
219 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
220 sd.BufferDesc.RefreshRate.Numerator = 60;
221 sd.BufferDesc.RefreshRate.Denominator = 1;
222 sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
223 sd.OutputWindow = HarnessD3D11_hWnd;
224 sd.SampleDesc.Count = 1;
225 sd.SampleDesc.Quality = 0;
226 sd.Windowed = TRUE;
227 D3D_FEATURE_LEVEL requestedFeatureLevels[] = {D3D_FEATURE_LEVEL_10_0};
228 D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
229 hr = D3D11CreateDeviceAndSwapChain(
230 NULL, // pAdapter,
231 D3D_DRIVER_TYPE_HARDWARE,
232 NULL,
233 0,
234 requestedFeatureLevels,
235 1,
236 D3D11_SDK_VERSION,
237 &sd,
238 &HarnessD3D11_pSwapChain,
239 &HarnessD3D11_pDevice,
240 &featureLevel,
241 &HarnessD3D11_pDC);
242 if (FAILED(hr) ) {
243 return CL_DEVICE_NOT_FOUND;
244 }
245
246 *ppDevice = HarnessD3D11_pDevice;
247 *ppDC = HarnessD3D11_pDC;
248 return CL_SUCCESS;
249 }
250
HarnessD3D11_DestroyDevice()251 void HarnessD3D11_DestroyDevice()
252 {
253 HarnessD3D11_pSwapChain->Release();
254 HarnessD3D11_pDevice->Release();
255 HarnessD3D11_pDC->Release();
256
257 if (HarnessD3D11_hWnd) DestroyWindow(HarnessD3D11_hWnd);
258 HarnessD3D11_hWnd = 0;
259 }
260
261 /*
262 *
263 * texture formats
264 *
265 */
266
267 #define ADD_TEXTURE_FORMAT(x,y,z,a,b,g) { x, y, z, a*b/8, g, #x, #y, #z, }
268 TextureFormat formats[] =
269 {
270 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R32G32B32A32_FLOAT , CL_RGBA , CL_FLOAT , 32, 4, TextureFormat::GENERIC_FLOAT ),
271 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R32G32B32A32_UINT , CL_RGBA , CL_UNSIGNED_INT32 , 32, 4, TextureFormat::GENERIC_UINT ),
272 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R32G32B32A32_SINT , CL_RGBA , CL_SIGNED_INT32 , 32, 4, TextureFormat::GENERIC_SINT ),
273 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16B16A16_FLOAT , CL_RGBA , CL_HALF_FLOAT , 16, 4, TextureFormat::GENERIC_FLOAT ),
274 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16B16A16_UNORM , CL_RGBA , CL_UNORM_INT16 , 16, 4, TextureFormat::GENERIC_FLOAT ),
275 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16B16A16_UINT , CL_RGBA , CL_UNSIGNED_INT16 , 16, 4, TextureFormat::GENERIC_UINT ),
276 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16B16A16_SNORM , CL_RGBA , CL_SNORM_INT16 , 16, 4, TextureFormat::GENERIC_FLOAT ),
277 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16B16A16_SINT , CL_RGBA , CL_SIGNED_INT16 , 16, 4, TextureFormat::GENERIC_SINT ),
278 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8G8B8A8_UNORM , CL_RGBA , CL_UNORM_INT8 , 8, 4, TextureFormat::GENERIC_FLOAT ),
279 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8G8B8A8_UINT , CL_RGBA , CL_UNSIGNED_INT8 , 8, 4, TextureFormat::GENERIC_UINT ),
280 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8G8B8A8_SNORM , CL_RGBA , CL_SNORM_INT8 , 8, 4, TextureFormat::GENERIC_FLOAT ),
281 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8G8B8A8_SINT , CL_RGBA , CL_SIGNED_INT8 , 8, 4, TextureFormat::GENERIC_SINT ),
282
283 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R32G32_FLOAT , CL_RG , CL_FLOAT , 32, 2, TextureFormat::GENERIC_FLOAT ),
284 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R32G32_UINT , CL_RG , CL_UNSIGNED_INT32 , 32, 2, TextureFormat::GENERIC_UINT ),
285 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R32G32_SINT , CL_RG , CL_SIGNED_INT32 , 32, 2, TextureFormat::GENERIC_SINT ),
286 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16_FLOAT , CL_RG , CL_HALF_FLOAT , 16, 2, TextureFormat::GENERIC_FLOAT ),
287 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16_UNORM , CL_RG , CL_UNORM_INT16 , 16, 2, TextureFormat::GENERIC_FLOAT ),
288 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16_UINT , CL_RG , CL_UNSIGNED_INT16 , 16, 2, TextureFormat::GENERIC_UINT ),
289 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16_SNORM , CL_RG , CL_SNORM_INT16 , 16, 2, TextureFormat::GENERIC_FLOAT ),
290 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16G16_SINT , CL_RG , CL_SIGNED_INT16 , 16, 2, TextureFormat::GENERIC_SINT ),
291 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8G8_UNORM , CL_RG , CL_UNORM_INT8 , 8, 2, TextureFormat::GENERIC_FLOAT ),
292 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8G8_UINT , CL_RG , CL_UNSIGNED_INT8 , 8, 2, TextureFormat::GENERIC_UINT ),
293 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8G8_SNORM , CL_RG , CL_SNORM_INT8 , 8, 2, TextureFormat::GENERIC_FLOAT ),
294 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8G8_SINT , CL_RG , CL_SIGNED_INT8 , 8, 2, TextureFormat::GENERIC_SINT ),
295
296 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R32_FLOAT , CL_R , CL_FLOAT , 32, 1, TextureFormat::GENERIC_FLOAT ),
297 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R32_UINT , CL_R , CL_UNSIGNED_INT32 , 32, 1, TextureFormat::GENERIC_UINT ),
298 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R32_SINT , CL_R , CL_SIGNED_INT32 , 32, 1, TextureFormat::GENERIC_SINT ),
299 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16_FLOAT , CL_R , CL_HALF_FLOAT , 16, 1, TextureFormat::GENERIC_FLOAT ),
300 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16_UNORM , CL_R , CL_UNORM_INT16 , 16, 1, TextureFormat::GENERIC_FLOAT ),
301 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16_UINT , CL_R , CL_UNSIGNED_INT16 , 16, 1, TextureFormat::GENERIC_UINT ),
302 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16_SNORM , CL_R , CL_SNORM_INT16 , 16, 1, TextureFormat::GENERIC_FLOAT ),
303 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R16_SINT , CL_R , CL_SIGNED_INT16 , 16, 1, TextureFormat::GENERIC_SINT ),
304 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8_UNORM , CL_R , CL_UNORM_INT8 , 8, 1, TextureFormat::GENERIC_FLOAT ),
305 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8_UINT , CL_R , CL_UNSIGNED_INT8 , 8, 1, TextureFormat::GENERIC_UINT ),
306 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8_SNORM , CL_R , CL_SNORM_INT8 , 8, 1, TextureFormat::GENERIC_FLOAT ),
307 ADD_TEXTURE_FORMAT( DXGI_FORMAT_R8_SINT , CL_R , CL_SIGNED_INT8 , 8, 1, TextureFormat::GENERIC_SINT ),
308 };
309 UINT formatCount = sizeof(formats)/sizeof(formats[0]);
310
311 /*
312 *
313 * Logging and error reporting
314 *
315 */
316
317 static struct
318 {
319 cl_int testCount;
320 cl_int passCount;
321
322 cl_int nonTestFailures;
323 cl_int inTest;
324 cl_int currentTestPass;
325
326 char currentTestName[1024];
327 } HarnessD3D11_testStats = {0};
328
HarnessD3D11_TestBegin(const char * fmt,...)329 void HarnessD3D11_TestBegin(const char* fmt, ...)
330 {
331 va_list ap;
332
333 va_start(ap, fmt);
334 vsprintf(HarnessD3D11_testStats.currentTestName, fmt, ap);
335 va_end(ap);
336
337 printf("[%s] ... ", HarnessD3D11_testStats.currentTestName);
338
339 HarnessD3D11_testStats.inTest = 1;
340 HarnessD3D11_testStats.currentTestPass = 1;
341 }
342
HarnessD3D11_TestFail()343 void HarnessD3D11_TestFail()
344 {
345 if (HarnessD3D11_testStats.inTest)
346 {
347 HarnessD3D11_testStats.currentTestPass = 0;
348 }
349 else
350 {
351 ++HarnessD3D11_testStats.nonTestFailures;
352 }
353 }
354
HarnessD3D11_TestEnd()355 void HarnessD3D11_TestEnd()
356 {
357 HarnessD3D11_testStats.inTest = 0;
358
359 HarnessD3D11_testStats.testCount += 1;
360 HarnessD3D11_testStats.passCount += HarnessD3D11_testStats.currentTestPass;
361
362 TestPrint("%s\n",
363 HarnessD3D11_testStats.currentTestPass ? "PASSED" : "FAILED");
364 }
365
HarnessD3D11_TestStats()366 void HarnessD3D11_TestStats()
367 {
368 TestPrint("PASSED %d of %d tests.\n", HarnessD3D11_testStats.passCount, HarnessD3D11_testStats.testCount);
369 if (HarnessD3D11_testStats.testCount > HarnessD3D11_testStats.passCount)
370 {
371 TestPrint("***FAILED***\n");
372 exit(1);
373 }
374 else
375 {
376 TestPrint("&&&& cl_khr_d3d11_sharing test PASSED\n");
377 }
378 exit(0);
379 }
380
381 /*
382 *
383 * Helper function
384 *
385 */
386
HarnessD3D11_CreateKernelFromSource(cl_kernel * outKernel,cl_device_id device,cl_context context,const char * source,const char * entrypoint)387 cl_int HarnessD3D11_CreateKernelFromSource(
388 cl_kernel *outKernel,
389 cl_device_id device,
390 cl_context context,
391 const char *source,
392 const char *entrypoint)
393 {
394 cl_int status;
395 cl_kernel kernel = NULL;
396
397 // compile program
398 cl_program program = NULL;
399 {
400 const char *sourceTexts[] = {source};
401 size_t sourceLengths[] = {strlen(source) };
402
403 status = create_single_kernel_helper(context, &program, &kernel, 1,
404 &sourceTexts[0], entrypoint);
405 TestRequire(CL_SUCCESS == status, "Kernel creation failed");
406 }
407
408 clReleaseProgram(program);
409 *outKernel = kernel;
410
411 Cleanup:
412
413 return CL_SUCCESS;
414 }
415
416
417
418