• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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