1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of the copyright holders may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors as is and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the copyright holders or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include "precomp.hpp"
43
44 #include "opencv2/core.hpp"
45 #include "opencv2/core/ocl.hpp"
46 #include "opencv2/core/directx.hpp"
47
48 #ifdef HAVE_DIRECTX
49 #include <vector>
50 # include "directx.inc.hpp"
51 #else // HAVE_DIRECTX
52 #define NO_DIRECTX_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
53 #endif
54
55 #ifndef HAVE_OPENCL
56 # define NO_OPENCL_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
57 #endif // HAVE_OPENCL
58
59 namespace cv { namespace directx {
60
getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)61 int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
62 {
63 (void)iDXGI_FORMAT;
64 #if !defined(HAVE_DIRECTX)
65 NO_DIRECTX_SUPPORT_ERROR;
66 #else
67 const int errorType = -1;
68 switch ((enum DXGI_FORMAT)iDXGI_FORMAT)
69 {
70 //case DXGI_FORMAT_UNKNOWN:
71 //case DXGI_FORMAT_R32G32B32A32_TYPELESS:
72 case DXGI_FORMAT_R32G32B32A32_FLOAT: return CV_32FC4;
73 case DXGI_FORMAT_R32G32B32A32_UINT:
74 case DXGI_FORMAT_R32G32B32A32_SINT: return CV_32SC4;
75 //case DXGI_FORMAT_R32G32B32_TYPELESS:
76 case DXGI_FORMAT_R32G32B32_FLOAT: return CV_32FC3;
77 case DXGI_FORMAT_R32G32B32_UINT:
78 case DXGI_FORMAT_R32G32B32_SINT: return CV_32SC3;
79 //case DXGI_FORMAT_R16G16B16A16_TYPELESS:
80 //case DXGI_FORMAT_R16G16B16A16_FLOAT:
81 case DXGI_FORMAT_R16G16B16A16_UNORM:
82 case DXGI_FORMAT_R16G16B16A16_UINT: return CV_16UC4;
83 case DXGI_FORMAT_R16G16B16A16_SNORM:
84 case DXGI_FORMAT_R16G16B16A16_SINT: return CV_16SC4;
85 //case DXGI_FORMAT_R32G32_TYPELESS:
86 //case DXGI_FORMAT_R32G32_FLOAT:
87 //case DXGI_FORMAT_R32G32_UINT:
88 //case DXGI_FORMAT_R32G32_SINT:
89 //case DXGI_FORMAT_R32G8X24_TYPELESS:
90 //case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
91 //case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
92 //case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
93 //case DXGI_FORMAT_R10G10B10A2_TYPELESS:
94 //case DXGI_FORMAT_R10G10B10A2_UNORM:
95 //case DXGI_FORMAT_R10G10B10A2_UINT:
96 //case DXGI_FORMAT_R11G11B10_FLOAT:
97 //case DXGI_FORMAT_R8G8B8A8_TYPELESS:
98 case DXGI_FORMAT_R8G8B8A8_UNORM:
99 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
100 case DXGI_FORMAT_R8G8B8A8_UINT: return CV_8UC4;
101 case DXGI_FORMAT_R8G8B8A8_SNORM:
102 case DXGI_FORMAT_R8G8B8A8_SINT: return CV_8SC4;
103 //case DXGI_FORMAT_R16G16_TYPELESS:
104 //case DXGI_FORMAT_R16G16_FLOAT:
105 case DXGI_FORMAT_R16G16_UNORM:
106 case DXGI_FORMAT_R16G16_UINT: return CV_16UC2;
107 case DXGI_FORMAT_R16G16_SNORM:
108 case DXGI_FORMAT_R16G16_SINT: return CV_16SC2;
109 //case DXGI_FORMAT_R32_TYPELESS:
110 //case DXGI_FORMAT_D32_FLOAT:
111 case DXGI_FORMAT_R32_FLOAT: return CV_32FC1;
112 case DXGI_FORMAT_R32_UINT:
113 case DXGI_FORMAT_R32_SINT: return CV_32SC1;
114 //case DXGI_FORMAT_R24G8_TYPELESS:
115 //case DXGI_FORMAT_D24_UNORM_S8_UINT:
116 //case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
117 //case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
118 //case DXGI_FORMAT_R8G8_TYPELESS:
119 case DXGI_FORMAT_R8G8_UNORM:
120 case DXGI_FORMAT_R8G8_UINT: return CV_8UC2;
121 case DXGI_FORMAT_R8G8_SNORM:
122 case DXGI_FORMAT_R8G8_SINT: return CV_8SC2;
123 //case DXGI_FORMAT_R16_TYPELESS:
124 //case DXGI_FORMAT_R16_FLOAT:
125 case DXGI_FORMAT_D16_UNORM:
126 case DXGI_FORMAT_R16_UNORM:
127 case DXGI_FORMAT_R16_UINT: return CV_16UC1;
128 case DXGI_FORMAT_R16_SNORM:
129 case DXGI_FORMAT_R16_SINT: return CV_16SC1;
130 //case DXGI_FORMAT_R8_TYPELESS:
131 case DXGI_FORMAT_R8_UNORM:
132 case DXGI_FORMAT_R8_UINT: return CV_8UC1;
133 case DXGI_FORMAT_R8_SNORM:
134 case DXGI_FORMAT_R8_SINT: return CV_8SC1;
135 case DXGI_FORMAT_A8_UNORM: return CV_8UC1;
136 //case DXGI_FORMAT_R1_UNORM:
137 //case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
138 //case DXGI_FORMAT_R8G8_B8G8_UNORM:
139 //case DXGI_FORMAT_G8R8_G8B8_UNORM:
140 //case DXGI_FORMAT_BC1_TYPELESS:
141 //case DXGI_FORMAT_BC1_UNORM:
142 //case DXGI_FORMAT_BC1_UNORM_SRGB:
143 //case DXGI_FORMAT_BC2_TYPELESS:
144 //case DXGI_FORMAT_BC2_UNORM:
145 //case DXGI_FORMAT_BC2_UNORM_SRGB:
146 //case DXGI_FORMAT_BC3_TYPELESS:
147 //case DXGI_FORMAT_BC3_UNORM:
148 //case DXGI_FORMAT_BC3_UNORM_SRGB:
149 //case DXGI_FORMAT_BC4_TYPELESS:
150 //case DXGI_FORMAT_BC4_UNORM:
151 //case DXGI_FORMAT_BC4_SNORM:
152 //case DXGI_FORMAT_BC5_TYPELESS:
153 //case DXGI_FORMAT_BC5_UNORM:
154 //case DXGI_FORMAT_BC5_SNORM:
155 //case DXGI_FORMAT_B5G6R5_UNORM:
156 //case DXGI_FORMAT_B5G5R5A1_UNORM:
157 case DXGI_FORMAT_B8G8R8A8_UNORM:
158 case DXGI_FORMAT_B8G8R8X8_UNORM: return CV_8UC4;
159 //case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
160 //case DXGI_FORMAT_B8G8R8A8_TYPELESS:
161 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return CV_8UC4;
162 //case DXGI_FORMAT_B8G8R8X8_TYPELESS:
163 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return CV_8UC4;
164 //case DXGI_FORMAT_BC6H_TYPELESS:
165 //case DXGI_FORMAT_BC6H_UF16:
166 //case DXGI_FORMAT_BC6H_SF16:
167 //case DXGI_FORMAT_BC7_TYPELESS:
168 //case DXGI_FORMAT_BC7_UNORM:
169 //case DXGI_FORMAT_BC7_UNORM_SRGB:
170 default: break;
171 }
172 return errorType;
173 #endif
174 }
175
getTypeFromD3DFORMAT(const int iD3DFORMAT)176 int getTypeFromD3DFORMAT(const int iD3DFORMAT)
177 {
178 (void)iD3DFORMAT;
179 #if !defined(HAVE_DIRECTX)
180 NO_DIRECTX_SUPPORT_ERROR;
181 #else
182 const int errorType = -1;
183 switch ((enum _D3DFORMAT)iD3DFORMAT)
184 {
185 //case D3DFMT_UNKNOWN:
186 case D3DFMT_R8G8B8: return CV_8UC3;
187 case D3DFMT_A8R8G8B8:
188 case D3DFMT_X8R8G8B8: return CV_8UC4;
189 //case D3DFMT_R5G6B5:
190 //case D3DFMT_X1R5G5B5:
191 //case D3DFMT_A1R5G5B5:
192 //case D3DFMT_A4R4G4B4:
193 //case D3DFMT_R3G3B2:
194 case D3DFMT_A8: return CV_8UC1;
195 //case D3DFMT_A8R3G3B2:
196 //case D3DFMT_X4R4G4B4:
197 //case D3DFMT_A2B10G10R10:
198 case D3DFMT_A8B8G8R8:
199 case D3DFMT_X8B8G8R8: return CV_8UC4;
200 //case D3DFMT_G16R16:
201 //case D3DFMT_A2R10G10B10:
202 //case D3DFMT_A16B16G16R16:
203
204 case D3DFMT_A8P8: return CV_8UC2;
205 case D3DFMT_P8: return CV_8UC1;
206
207 case D3DFMT_L8: return CV_8UC1;
208 case D3DFMT_A8L8: return CV_8UC2;
209 //case D3DFMT_A4L4:
210
211 case D3DFMT_V8U8: return CV_8UC2;
212 //case D3DFMT_L6V5U5:
213 case D3DFMT_X8L8V8U8:
214 case D3DFMT_Q8W8V8U8: return CV_8UC4;
215 case D3DFMT_V16U16: return CV_16UC4; // TODO 16SC4 ?
216 //case D3DFMT_A2W10V10U10:
217
218 case D3DFMT_D16_LOCKABLE: return CV_16UC1;
219 case D3DFMT_D32: return CV_32SC1;
220 //case D3DFMT_D15S1:
221 //case D3DFMT_D24S8:
222 //case D3DFMT_D24X8:
223 //case D3DFMT_D24X4S4:
224 case D3DFMT_D16: return CV_16UC1;
225
226 case D3DFMT_D32F_LOCKABLE: return CV_32FC1;
227 default: break;
228 }
229 return errorType;
230 #endif
231 }
232
233 namespace ocl {
234
235 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
236 static bool g_isDirect3DDevice9Ex = false; // Direct3DDevice9Ex or Direct3DDevice9 was used
237 #endif
238
initializeContextFromD3D11Device(ID3D11Device * pD3D11Device)239 Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
240 {
241 (void)pD3D11Device;
242 #if !defined(HAVE_DIRECTX)
243 NO_DIRECTX_SUPPORT_ERROR;
244 #elif !defined(HAVE_OPENCL)
245 NO_OPENCL_SUPPORT_ERROR;
246 #else
247 cl_uint numPlatforms;
248 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
249 if (status != CL_SUCCESS)
250 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
251 if (numPlatforms == 0)
252 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
253
254 std::vector<cl_platform_id> platforms(numPlatforms);
255 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
256 if (status != CL_SUCCESS)
257 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
258
259 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
260
261 int found = -1;
262 cl_device_id device = NULL;
263 cl_uint numDevices = 0;
264 cl_context context = NULL;
265
266 // try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
267 for (int i = 0; i < (int)numPlatforms; i++)
268 {
269 clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
270 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
271 if (!clGetDeviceIDsFromD3D11KHR)
272 continue;
273
274 device = NULL;
275 numDevices = 0;
276 status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
277 CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
278 if (status != CL_SUCCESS)
279 continue;
280 if (numDevices > 0)
281 {
282 cl_context_properties properties[] = {
283 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
284 CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
285 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
286 NULL, NULL
287 };
288 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
289 if (status != CL_SUCCESS)
290 {
291 clReleaseDevice(device);
292 }
293 else
294 {
295 found = i;
296 break;
297 }
298 }
299 }
300 if (found < 0)
301 {
302 // try with CL_ALL_DEVICES_FOR_D3D11_KHR
303 for (int i = 0; i < (int)numPlatforms; i++)
304 {
305 clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
306 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
307 if (!clGetDeviceIDsFromD3D11KHR)
308 continue;
309
310 device = NULL;
311 numDevices = 0;
312 status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
313 CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
314 if (status != CL_SUCCESS)
315 continue;
316 if (numDevices > 0)
317 {
318 cl_context_properties properties[] = {
319 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
320 CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
321 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
322 NULL, NULL
323 };
324 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
325 if (status != CL_SUCCESS)
326 {
327 clReleaseDevice(device);
328 }
329 else
330 {
331 found = i;
332 break;
333 }
334 }
335 }
336 if (found < 0)
337 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
338 }
339
340
341 Context& ctx = Context::getDefault(false);
342 initializeContextFromHandle(ctx, platforms[found], context, device);
343 return ctx;
344 #endif
345 }
346
initializeContextFromD3D10Device(ID3D10Device * pD3D10Device)347 Context& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device)
348 {
349 (void)pD3D10Device;
350 #if !defined(HAVE_DIRECTX)
351 NO_DIRECTX_SUPPORT_ERROR;
352 #elif !defined(HAVE_OPENCL)
353 NO_OPENCL_SUPPORT_ERROR;
354 #else
355 cl_uint numPlatforms;
356 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
357 if (status != CL_SUCCESS)
358 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
359 if (numPlatforms == 0)
360 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
361
362 std::vector<cl_platform_id> platforms(numPlatforms);
363 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
364 if (status != CL_SUCCESS)
365 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
366
367 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
368
369 int found = -1;
370 cl_device_id device = NULL;
371 cl_uint numDevices = 0;
372 cl_context context = NULL;
373
374 // try with CL_PREFERRED_DEVICES_FOR_D3D10_KHR
375 for (int i = 0; i < (int)numPlatforms; i++)
376 {
377 clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
378 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
379 if (!clGetDeviceIDsFromD3D10KHR)
380 continue;
381
382 device = NULL;
383 numDevices = 0;
384 status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
385 CL_PREFERRED_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
386 if (status != CL_SUCCESS)
387 continue;
388 if (numDevices > 0)
389 {
390 cl_context_properties properties[] = {
391 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
392 CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
393 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
394 NULL, NULL
395 };
396 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
397 if (status != CL_SUCCESS)
398 {
399 clReleaseDevice(device);
400 }
401 else
402 {
403 found = i;
404 break;
405 }
406 }
407 }
408 if (found < 0)
409 {
410 // try with CL_ALL_DEVICES_FOR_D3D10_KHR
411 for (int i = 0; i < (int)numPlatforms; i++)
412 {
413 clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
414 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
415 if (!clGetDeviceIDsFromD3D10KHR)
416 continue;
417
418 device = NULL;
419 numDevices = 0;
420 status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
421 CL_ALL_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
422 if (status != CL_SUCCESS)
423 continue;
424 if (numDevices > 0)
425 {
426 cl_context_properties properties[] = {
427 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
428 CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
429 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
430 NULL, NULL
431 };
432 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
433 if (status != CL_SUCCESS)
434 {
435 clReleaseDevice(device);
436 }
437 else
438 {
439 found = i;
440 break;
441 }
442 }
443 }
444 if (found < 0)
445 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
446 }
447
448
449 Context& ctx = Context::getDefault(false);
450 initializeContextFromHandle(ctx, platforms[found], context, device);
451 return ctx;
452 #endif
453 }
454
initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex * pDirect3DDevice9Ex)455 Context& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex)
456 {
457 (void)pDirect3DDevice9Ex;
458 #if !defined(HAVE_DIRECTX)
459 NO_DIRECTX_SUPPORT_ERROR;
460 #elif !defined(HAVE_OPENCL)
461 NO_OPENCL_SUPPORT_ERROR;
462 #else
463 cl_uint numPlatforms;
464 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
465 if (status != CL_SUCCESS)
466 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
467 if (numPlatforms == 0)
468 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
469
470 std::vector<cl_platform_id> platforms(numPlatforms);
471 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
472 if (status != CL_SUCCESS)
473 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
474
475 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
476
477 int found = -1;
478 cl_device_id device = NULL;
479 cl_uint numDevices = 0;
480 cl_context context = NULL;
481
482 // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
483 for (int i = 0; i < (int)numPlatforms; i++)
484 {
485 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
486 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
487 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
488 continue;
489
490 device = NULL;
491 numDevices = 0;
492 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
493 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
494 CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
495 if (status != CL_SUCCESS)
496 continue;
497 if (numDevices > 0)
498 {
499 cl_context_properties properties[] = {
500 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
501 CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
502 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
503 NULL, NULL
504 };
505 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
506 if (status != CL_SUCCESS)
507 {
508 clReleaseDevice(device);
509 }
510 else
511 {
512 found = i;
513 break;
514 }
515 }
516 }
517 if (found < 0)
518 {
519 // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
520 for (int i = 0; i < (int)numPlatforms; i++)
521 {
522 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
523 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
524 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
525 continue;
526
527 device = NULL;
528 numDevices = 0;
529 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
530 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
531 CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
532 if (status != CL_SUCCESS)
533 continue;
534 if (numDevices > 0)
535 {
536 cl_context_properties properties[] = {
537 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
538 CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
539 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
540 NULL, NULL
541 };
542 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
543 if (status != CL_SUCCESS)
544 {
545 clReleaseDevice(device);
546 }
547 else
548 {
549 found = i;
550 break;
551 }
552 }
553 }
554 if (found < 0)
555 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
556 }
557
558 Context& ctx = Context::getDefault(false);
559 initializeContextFromHandle(ctx, platforms[found], context, device);
560 g_isDirect3DDevice9Ex = true;
561 return ctx;
562 #endif
563 }
564
initializeContextFromDirect3DDevice9(IDirect3DDevice9 * pDirect3DDevice9)565 Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9)
566 {
567 (void)pDirect3DDevice9;
568 #if !defined(HAVE_DIRECTX)
569 NO_DIRECTX_SUPPORT_ERROR;
570 #elif !defined(HAVE_OPENCL)
571 NO_OPENCL_SUPPORT_ERROR;
572 #else
573 cl_uint numPlatforms;
574 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
575 if (status != CL_SUCCESS)
576 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
577 if (numPlatforms == 0)
578 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
579
580 std::vector<cl_platform_id> platforms(numPlatforms);
581 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
582 if (status != CL_SUCCESS)
583 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
584
585 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
586
587 int found = -1;
588 cl_device_id device = NULL;
589 cl_uint numDevices = 0;
590 cl_context context = NULL;
591
592 // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
593 for (int i = 0; i < (int)numPlatforms; i++)
594 {
595 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
596 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
597 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
598 continue;
599
600 device = NULL;
601 numDevices = 0;
602 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
603 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
604 CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
605 if (status != CL_SUCCESS)
606 continue;
607 if (numDevices > 0)
608 {
609 cl_context_properties properties[] = {
610 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
611 CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
612 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
613 NULL, NULL
614 };
615 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
616 if (status != CL_SUCCESS)
617 {
618 clReleaseDevice(device);
619 }
620 else
621 {
622 found = i;
623 break;
624 }
625 }
626 }
627 if (found < 0)
628 {
629 // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
630 for (int i = 0; i < (int)numPlatforms; i++)
631 {
632 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
633 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
634 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
635 continue;
636
637 device = NULL;
638 numDevices = 0;
639 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
640 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
641 CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
642 if (status != CL_SUCCESS)
643 continue;
644 if (numDevices > 0)
645 {
646 cl_context_properties properties[] = {
647 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
648 CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
649 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
650 NULL, NULL
651 };
652 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
653 if (status != CL_SUCCESS)
654 {
655 clReleaseDevice(device);
656 }
657 else
658 {
659 found = i;
660 break;
661 }
662 }
663 }
664 if (found < 0)
665 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
666 }
667
668 Context& ctx = Context::getDefault(false);
669 initializeContextFromHandle(ctx, platforms[found], context, device);
670 g_isDirect3DDevice9Ex = false;
671 return ctx;
672 #endif
673 }
674
675 } // namespace cv::ocl
676
677 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
678 clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL;
679 clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL;
680 clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL;
681
__OpenCLinitializeD3D11()682 static void __OpenCLinitializeD3D11()
683 {
684 using namespace cv::ocl;
685 static cl_platform_id initializedPlatform = NULL;
686 cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
687 if (initializedPlatform != platform)
688 {
689 clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
690 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
691 clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
692 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
693 clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
694 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
695 initializedPlatform = platform;
696 }
697 if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
698 {
699 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
700 }
701 }
702 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
703
convertToD3D11Texture2D(InputArray src,ID3D11Texture2D * pD3D11Texture2D)704 void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
705 {
706 (void)src; (void)pD3D11Texture2D;
707 #if !defined(HAVE_DIRECTX)
708 NO_DIRECTX_SUPPORT_ERROR;
709 #elif defined(HAVE_OPENCL)
710 __OpenCLinitializeD3D11();
711
712 D3D11_TEXTURE2D_DESC desc = { 0 };
713 pD3D11Texture2D->GetDesc(&desc);
714
715 int srcType = src.type();
716 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
717 CV_Assert(textureType == srcType);
718
719 Size srcSize = src.size();
720 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
721
722 using namespace cv::ocl;
723 Context& ctx = Context::getDefault();
724 cl_context context = (cl_context)ctx.ptr();
725
726 UMat u = src.getUMat();
727
728 // TODO Add support for roi
729 CV_Assert(u.offset == 0);
730 CV_Assert(u.isContinuous());
731
732 cl_int status = 0;
733 cl_mem clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
734 if (status != CL_SUCCESS)
735 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
736
737 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
738
739 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
740 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
741 if (status != CL_SUCCESS)
742 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
743 size_t offset = 0; // TODO
744 size_t dst_origin[3] = {0, 0, 0};
745 size_t region[3] = {u.cols, u.rows, 1};
746 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
747 if (status != CL_SUCCESS)
748 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
749 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
750 if (status != CL_SUCCESS)
751 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
752
753 status = clFinish(q); // TODO Use events
754 if (status != CL_SUCCESS)
755 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
756
757 status = clReleaseMemObject(clImage); // TODO RAII
758 if (status != CL_SUCCESS)
759 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
760 #else
761 // TODO memcpy
762 NO_OPENCL_SUPPORT_ERROR;
763 #endif
764 }
convertFromD3D11Texture2D(ID3D11Texture2D * pD3D11Texture2D,OutputArray dst)765 void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
766 {
767 (void)pD3D11Texture2D; (void)dst;
768 #if !defined(HAVE_DIRECTX)
769 NO_DIRECTX_SUPPORT_ERROR;
770 #elif defined(HAVE_OPENCL)
771 __OpenCLinitializeD3D11();
772
773 D3D11_TEXTURE2D_DESC desc = { 0 };
774 pD3D11Texture2D->GetDesc(&desc);
775
776 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
777 CV_Assert(textureType >= 0);
778
779 using namespace cv::ocl;
780 Context& ctx = Context::getDefault();
781 cl_context context = (cl_context)ctx.ptr();
782
783 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
784 dst.create(Size(desc.Width, desc.Height), textureType);
785 UMat u = dst.getUMat();
786
787 // TODO Add support for roi
788 CV_Assert(u.offset == 0);
789 CV_Assert(u.isContinuous());
790
791 cl_int status = 0;
792 cl_mem clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
793 if (status != CL_SUCCESS)
794 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
795
796 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
797
798 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
799 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
800 if (status != CL_SUCCESS)
801 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
802 size_t offset = 0; // TODO
803 size_t src_origin[3] = {0, 0, 0};
804 size_t region[3] = {u.cols, u.rows, 1};
805 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
806 if (status != CL_SUCCESS)
807 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
808 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
809 if (status != CL_SUCCESS)
810 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
811
812 status = clFinish(q); // TODO Use events
813 if (status != CL_SUCCESS)
814 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
815
816 status = clReleaseMemObject(clImage); // TODO RAII
817 if (status != CL_SUCCESS)
818 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
819 #else
820 // TODO memcpy
821 NO_OPENCL_SUPPORT_ERROR;
822 #endif
823 }
824
825 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
826 clCreateFromD3D10Texture2DKHR_fn clCreateFromD3D10Texture2DKHR = NULL;
827 clEnqueueAcquireD3D10ObjectsKHR_fn clEnqueueAcquireD3D10ObjectsKHR = NULL;
828 clEnqueueReleaseD3D10ObjectsKHR_fn clEnqueueReleaseD3D10ObjectsKHR = NULL;
829
__OpenCLinitializeD3D10()830 static void __OpenCLinitializeD3D10()
831 {
832 using namespace cv::ocl;
833 static cl_platform_id initializedPlatform = NULL;
834 cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
835 if (initializedPlatform != platform)
836 {
837 clCreateFromD3D10Texture2DKHR = (clCreateFromD3D10Texture2DKHR_fn)
838 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D10Texture2DKHR");
839 clEnqueueAcquireD3D10ObjectsKHR = (clEnqueueAcquireD3D10ObjectsKHR_fn)
840 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D10ObjectsKHR");
841 clEnqueueReleaseD3D10ObjectsKHR = (clEnqueueReleaseD3D10ObjectsKHR_fn)
842 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D10ObjectsKHR");
843 initializedPlatform = platform;
844 }
845 if (!clCreateFromD3D10Texture2DKHR || !clEnqueueAcquireD3D10ObjectsKHR || !clEnqueueReleaseD3D10ObjectsKHR)
846 {
847 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D10");
848 }
849 }
850 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
851
convertToD3D10Texture2D(InputArray src,ID3D10Texture2D * pD3D10Texture2D)852 void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D)
853 {
854 (void)src; (void)pD3D10Texture2D;
855 #if !defined(HAVE_DIRECTX)
856 NO_DIRECTX_SUPPORT_ERROR;
857 #elif defined(HAVE_OPENCL)
858 __OpenCLinitializeD3D10();
859
860 D3D10_TEXTURE2D_DESC desc = { 0 };
861 pD3D10Texture2D->GetDesc(&desc);
862
863 int srcType = src.type();
864 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
865 CV_Assert(textureType == srcType);
866
867 Size srcSize = src.size();
868 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
869
870 using namespace cv::ocl;
871 Context& ctx = Context::getDefault();
872 cl_context context = (cl_context)ctx.ptr();
873
874 UMat u = src.getUMat();
875
876 // TODO Add support for roi
877 CV_Assert(u.offset == 0);
878 CV_Assert(u.isContinuous());
879
880 cl_int status = 0;
881 cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D10Texture2D, 0, &status);
882 if (status != CL_SUCCESS)
883 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
884
885 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
886
887 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
888 status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
889 if (status != CL_SUCCESS)
890 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
891 size_t offset = 0; // TODO
892 size_t dst_origin[3] = {0, 0, 0};
893 size_t region[3] = {u.cols, u.rows, 1};
894 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
895 if (status != CL_SUCCESS)
896 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
897 status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
898 if (status != CL_SUCCESS)
899 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
900
901 status = clFinish(q); // TODO Use events
902 if (status != CL_SUCCESS)
903 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
904
905 status = clReleaseMemObject(clImage); // TODO RAII
906 if (status != CL_SUCCESS)
907 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
908 #else
909 // TODO memcpy
910 NO_OPENCL_SUPPORT_ERROR;
911 #endif
912 }
convertFromD3D10Texture2D(ID3D10Texture2D * pD3D10Texture2D,OutputArray dst)913 void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst)
914 {
915 (void)pD3D10Texture2D; (void)dst;
916 #if !defined(HAVE_DIRECTX)
917 NO_DIRECTX_SUPPORT_ERROR;
918 #elif defined(HAVE_OPENCL)
919 __OpenCLinitializeD3D10();
920
921 D3D10_TEXTURE2D_DESC desc = { 0 };
922 pD3D10Texture2D->GetDesc(&desc);
923
924 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
925 CV_Assert(textureType >= 0);
926
927 using namespace cv::ocl;
928 Context& ctx = Context::getDefault();
929 cl_context context = (cl_context)ctx.ptr();
930
931 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
932 dst.create(Size(desc.Width, desc.Height), textureType);
933 UMat u = dst.getUMat();
934
935 // TODO Add support for roi
936 CV_Assert(u.offset == 0);
937 CV_Assert(u.isContinuous());
938
939 cl_int status = 0;
940 cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D10Texture2D, 0, &status);
941 if (status != CL_SUCCESS)
942 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
943
944 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
945
946 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
947 status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
948 if (status != CL_SUCCESS)
949 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
950 size_t offset = 0; // TODO
951 size_t src_origin[3] = {0, 0, 0};
952 size_t region[3] = {u.cols, u.rows, 1};
953 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
954 if (status != CL_SUCCESS)
955 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
956 status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
957 if (status != CL_SUCCESS)
958 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
959
960 status = clFinish(q); // TODO Use events
961 if (status != CL_SUCCESS)
962 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
963
964 status = clReleaseMemObject(clImage); // TODO RAII
965 if (status != CL_SUCCESS)
966 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
967 #else
968 // TODO memcpy
969 NO_OPENCL_SUPPORT_ERROR;
970 #endif
971 }
972
973 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
974 clCreateFromDX9MediaSurfaceKHR_fn clCreateFromDX9MediaSurfaceKHR = NULL;
975 clEnqueueAcquireDX9MediaSurfacesKHR_fn clEnqueueAcquireDX9MediaSurfacesKHR = NULL;
976 clEnqueueReleaseDX9MediaSurfacesKHR_fn clEnqueueReleaseDX9MediaSurfacesKHR = NULL;
977
__OpenCLinitializeD3D9()978 static void __OpenCLinitializeD3D9()
979 {
980 using namespace cv::ocl;
981 static cl_platform_id initializedPlatform = NULL;
982 cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
983 if (initializedPlatform != platform)
984 {
985 clCreateFromDX9MediaSurfaceKHR = (clCreateFromDX9MediaSurfaceKHR_fn)
986 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromDX9MediaSurfaceKHR");
987 clEnqueueAcquireDX9MediaSurfacesKHR = (clEnqueueAcquireDX9MediaSurfacesKHR_fn)
988 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireDX9MediaSurfacesKHR");
989 clEnqueueReleaseDX9MediaSurfacesKHR = (clEnqueueReleaseDX9MediaSurfacesKHR_fn)
990 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseDX9MediaSurfacesKHR");
991 initializedPlatform = platform;
992 }
993 if (!clCreateFromDX9MediaSurfaceKHR || !clEnqueueAcquireDX9MediaSurfacesKHR || !clEnqueueReleaseDX9MediaSurfacesKHR)
994 {
995 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D9");
996 }
997 }
998 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
999
convertToDirect3DSurface9(InputArray src,IDirect3DSurface9 * pDirect3DSurface9,void * surfaceSharedHandle)1000 void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle)
1001 {
1002 (void)src; (void)pDirect3DSurface9; (void)surfaceSharedHandle;
1003 #if !defined(HAVE_DIRECTX)
1004 NO_DIRECTX_SUPPORT_ERROR;
1005 #elif defined(HAVE_OPENCL)
1006 __OpenCLinitializeD3D9();
1007
1008 D3DSURFACE_DESC desc;
1009 if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1010 {
1011 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1012 }
1013
1014 int srcType = src.type();
1015 int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1016 CV_Assert(surfaceType == srcType);
1017
1018 Size srcSize = src.size();
1019 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
1020
1021 using namespace cv::ocl;
1022 Context& ctx = Context::getDefault();
1023 cl_context context = (cl_context)ctx.ptr();
1024
1025 UMat u = src.getUMat();
1026
1027 // TODO Add support for roi
1028 CV_Assert(u.offset == 0);
1029 CV_Assert(u.isContinuous());
1030
1031 cl_int status = 0;
1032 cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
1033 cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_WRITE_ONLY,
1034 ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
1035 &surfaceInfo, 0, &status);
1036 if (status != CL_SUCCESS)
1037 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
1038
1039 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1040
1041 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1042 status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1043 if (status != CL_SUCCESS)
1044 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
1045 size_t offset = 0; // TODO
1046 size_t dst_origin[3] = {0, 0, 0};
1047 size_t region[3] = {u.cols, u.rows, 1};
1048 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
1049 if (status != CL_SUCCESS)
1050 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
1051 status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1052 if (status != CL_SUCCESS)
1053 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
1054
1055 status = clFinish(q); // TODO Use events
1056 if (status != CL_SUCCESS)
1057 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1058
1059 status = clReleaseMemObject(clImage); // TODO RAII
1060 if (status != CL_SUCCESS)
1061 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1062 #else
1063 // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1064 NO_OPENCL_SUPPORT_ERROR;
1065 #endif
1066 }
1067
convertFromDirect3DSurface9(IDirect3DSurface9 * pDirect3DSurface9,OutputArray dst,void * surfaceSharedHandle)1068 void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle)
1069 {
1070 (void)pDirect3DSurface9; (void)dst; (void)surfaceSharedHandle;
1071 #if !defined(HAVE_DIRECTX)
1072 NO_DIRECTX_SUPPORT_ERROR;
1073 #elif defined(HAVE_OPENCL)
1074 __OpenCLinitializeD3D9();
1075
1076 D3DSURFACE_DESC desc;
1077 if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1078 {
1079 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1080 }
1081
1082 int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1083 CV_Assert(surfaceType >= 0);
1084
1085 using namespace cv::ocl;
1086 Context& ctx = Context::getDefault();
1087 cl_context context = (cl_context)ctx.ptr();
1088
1089 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
1090 dst.create(Size(desc.Width, desc.Height), surfaceType);
1091 UMat u = dst.getUMat();
1092
1093 // TODO Add support for roi
1094 CV_Assert(u.offset == 0);
1095 CV_Assert(u.isContinuous());
1096
1097 cl_int status = 0;
1098 cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
1099 cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_READ_ONLY,
1100 ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
1101 &surfaceInfo, 0, &status);
1102 if (status != CL_SUCCESS)
1103 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
1104
1105 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_WRITE);
1106
1107 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1108 status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1109 if (status != CL_SUCCESS)
1110 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
1111 size_t offset = 0; // TODO
1112 size_t src_origin[3] = {0, 0, 0};
1113 size_t region[3] = {u.cols, u.rows, 1};
1114 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
1115 if (status != CL_SUCCESS)
1116 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
1117 status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1118 if (status != CL_SUCCESS)
1119 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
1120
1121 status = clFinish(q); // TODO Use events
1122 if (status != CL_SUCCESS)
1123 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1124
1125 status = clReleaseMemObject(clImage); // TODO RAII
1126 if (status != CL_SUCCESS)
1127 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1128 #else
1129 // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1130 NO_OPENCL_SUPPORT_ERROR;
1131 #endif
1132 }
1133
1134 } } // namespace cv::directx
1135