1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
42 #include "precomp.hpp"
44 #include "opencv2/core.hpp"
45 #include "opencv2/core/ocl.hpp"
46 #include "opencv2/core/directx.hpp"
47 #include "opencl_kernels_core.hpp"
51 # include "directx.inc.hpp"
53 #define NO_DIRECTX_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
57 # define NO_OPENCL_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
60 namespace cv { namespace directx {
62 int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
65 #if !defined(HAVE_DIRECTX)
66 NO_DIRECTX_SUPPORT_ERROR;
68 const int errorType = -1;
69 switch ((enum DXGI_FORMAT)iDXGI_FORMAT)
71 //case DXGI_FORMAT_UNKNOWN:
72 //case DXGI_FORMAT_R32G32B32A32_TYPELESS:
73 case DXGI_FORMAT_R32G32B32A32_FLOAT: return CV_32FC4;
74 case DXGI_FORMAT_R32G32B32A32_UINT:
75 case DXGI_FORMAT_R32G32B32A32_SINT: return CV_32SC4;
76 //case DXGI_FORMAT_R32G32B32_TYPELESS:
77 case DXGI_FORMAT_R32G32B32_FLOAT: return CV_32FC3;
78 case DXGI_FORMAT_R32G32B32_UINT:
79 case DXGI_FORMAT_R32G32B32_SINT: return CV_32SC3;
80 //case DXGI_FORMAT_R16G16B16A16_TYPELESS:
81 //case DXGI_FORMAT_R16G16B16A16_FLOAT:
82 case DXGI_FORMAT_R16G16B16A16_UNORM:
83 case DXGI_FORMAT_R16G16B16A16_UINT: return CV_16UC4;
84 case DXGI_FORMAT_R16G16B16A16_SNORM:
85 case DXGI_FORMAT_R16G16B16A16_SINT: return CV_16SC4;
86 //case DXGI_FORMAT_R32G32_TYPELESS:
87 //case DXGI_FORMAT_R32G32_FLOAT:
88 //case DXGI_FORMAT_R32G32_UINT:
89 //case DXGI_FORMAT_R32G32_SINT:
90 //case DXGI_FORMAT_R32G8X24_TYPELESS:
91 //case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
92 //case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
93 //case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
94 //case DXGI_FORMAT_R10G10B10A2_TYPELESS:
95 //case DXGI_FORMAT_R10G10B10A2_UNORM:
96 //case DXGI_FORMAT_R10G10B10A2_UINT:
97 //case DXGI_FORMAT_R11G11B10_FLOAT:
98 //case DXGI_FORMAT_R8G8B8A8_TYPELESS:
99 case DXGI_FORMAT_R8G8B8A8_UNORM:
100 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
101 case DXGI_FORMAT_R8G8B8A8_UINT: return CV_8UC4;
102 case DXGI_FORMAT_R8G8B8A8_SNORM:
103 case DXGI_FORMAT_R8G8B8A8_SINT: return CV_8SC4;
104 //case DXGI_FORMAT_R16G16_TYPELESS:
105 //case DXGI_FORMAT_R16G16_FLOAT:
106 case DXGI_FORMAT_R16G16_UNORM:
107 case DXGI_FORMAT_R16G16_UINT: return CV_16UC2;
108 case DXGI_FORMAT_R16G16_SNORM:
109 case DXGI_FORMAT_R16G16_SINT: return CV_16SC2;
110 //case DXGI_FORMAT_R32_TYPELESS:
111 //case DXGI_FORMAT_D32_FLOAT:
112 case DXGI_FORMAT_R32_FLOAT: return CV_32FC1;
113 case DXGI_FORMAT_R32_UINT:
114 case DXGI_FORMAT_R32_SINT: return CV_32SC1;
115 //case DXGI_FORMAT_R24G8_TYPELESS:
116 //case DXGI_FORMAT_D24_UNORM_S8_UINT:
117 //case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
118 //case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
119 //case DXGI_FORMAT_R8G8_TYPELESS:
120 case DXGI_FORMAT_R8G8_UNORM:
121 case DXGI_FORMAT_R8G8_UINT: return CV_8UC2;
122 case DXGI_FORMAT_R8G8_SNORM:
123 case DXGI_FORMAT_R8G8_SINT: return CV_8SC2;
124 //case DXGI_FORMAT_R16_TYPELESS:
125 //case DXGI_FORMAT_R16_FLOAT:
126 case DXGI_FORMAT_D16_UNORM:
127 case DXGI_FORMAT_R16_UNORM:
128 case DXGI_FORMAT_R16_UINT: return CV_16UC1;
129 case DXGI_FORMAT_R16_SNORM:
130 case DXGI_FORMAT_R16_SINT: return CV_16SC1;
131 //case DXGI_FORMAT_R8_TYPELESS:
132 case DXGI_FORMAT_R8_UNORM:
133 case DXGI_FORMAT_R8_UINT: return CV_8UC1;
134 case DXGI_FORMAT_R8_SNORM:
135 case DXGI_FORMAT_R8_SINT: return CV_8SC1;
136 case DXGI_FORMAT_A8_UNORM: return CV_8UC1;
137 //case DXGI_FORMAT_R1_UNORM:
138 //case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
139 //case DXGI_FORMAT_R8G8_B8G8_UNORM:
140 //case DXGI_FORMAT_G8R8_G8B8_UNORM:
141 //case DXGI_FORMAT_BC1_TYPELESS:
142 //case DXGI_FORMAT_BC1_UNORM:
143 //case DXGI_FORMAT_BC1_UNORM_SRGB:
144 //case DXGI_FORMAT_BC2_TYPELESS:
145 //case DXGI_FORMAT_BC2_UNORM:
146 //case DXGI_FORMAT_BC2_UNORM_SRGB:
147 //case DXGI_FORMAT_BC3_TYPELESS:
148 //case DXGI_FORMAT_BC3_UNORM:
149 //case DXGI_FORMAT_BC3_UNORM_SRGB:
150 //case DXGI_FORMAT_BC4_TYPELESS:
151 //case DXGI_FORMAT_BC4_UNORM:
152 //case DXGI_FORMAT_BC4_SNORM:
153 //case DXGI_FORMAT_BC5_TYPELESS:
154 //case DXGI_FORMAT_BC5_UNORM:
155 //case DXGI_FORMAT_BC5_SNORM:
156 //case DXGI_FORMAT_B5G6R5_UNORM:
157 //case DXGI_FORMAT_B5G5R5A1_UNORM:
158 case DXGI_FORMAT_B8G8R8A8_UNORM:
159 case DXGI_FORMAT_B8G8R8X8_UNORM: return CV_8UC4;
160 //case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
161 //case DXGI_FORMAT_B8G8R8A8_TYPELESS:
162 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return CV_8UC4;
163 //case DXGI_FORMAT_B8G8R8X8_TYPELESS:
164 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return CV_8UC4;
165 //case DXGI_FORMAT_BC6H_TYPELESS:
166 //case DXGI_FORMAT_BC6H_UF16:
167 //case DXGI_FORMAT_BC6H_SF16:
168 //case DXGI_FORMAT_BC7_TYPELESS:
169 //case DXGI_FORMAT_BC7_UNORM:
170 //case DXGI_FORMAT_BC7_UNORM_SRGB:
171 #ifdef HAVE_DIRECTX_NV12
172 case DXGI_FORMAT_NV12: return CV_8UC3;
180 int getTypeFromD3DFORMAT(const int iD3DFORMAT)
183 #if !defined(HAVE_DIRECTX)
184 NO_DIRECTX_SUPPORT_ERROR;
186 const int errorType = -1;
187 switch ((enum _D3DFORMAT)iD3DFORMAT)
189 //case D3DFMT_UNKNOWN:
190 case D3DFMT_R8G8B8: return CV_8UC3;
191 case D3DFMT_A8R8G8B8:
192 case D3DFMT_X8R8G8B8: return CV_8UC4;
193 //case D3DFMT_R5G6B5:
194 //case D3DFMT_X1R5G5B5:
195 //case D3DFMT_A1R5G5B5:
196 //case D3DFMT_A4R4G4B4:
197 //case D3DFMT_R3G3B2:
198 case D3DFMT_A8: return CV_8UC1;
199 //case D3DFMT_A8R3G3B2:
200 //case D3DFMT_X4R4G4B4:
201 //case D3DFMT_A2B10G10R10:
202 case D3DFMT_A8B8G8R8:
203 case D3DFMT_X8B8G8R8: return CV_8UC4;
204 //case D3DFMT_G16R16:
205 //case D3DFMT_A2R10G10B10:
206 //case D3DFMT_A16B16G16R16:
208 case D3DFMT_A8P8: return CV_8UC2;
209 case D3DFMT_P8: return CV_8UC1;
211 case D3DFMT_L8: return CV_8UC1;
212 case D3DFMT_A8L8: return CV_8UC2;
215 case D3DFMT_V8U8: return CV_8UC2;
216 //case D3DFMT_L6V5U5:
217 case D3DFMT_X8L8V8U8:
218 case D3DFMT_Q8W8V8U8: return CV_8UC4;
219 case D3DFMT_V16U16: return CV_16UC4; // TODO 16SC4 ?
220 //case D3DFMT_A2W10V10U10:
222 case D3DFMT_D16_LOCKABLE: return CV_16UC1;
223 case D3DFMT_D32: return CV_32SC1;
227 //case D3DFMT_D24X4S4:
228 case D3DFMT_D16: return CV_16UC1;
230 case D3DFMT_D32F_LOCKABLE: return CV_32FC1;
239 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
240 static bool g_isDirect3DDevice9Ex = false; // Direct3DDevice9Ex or Direct3DDevice9 was used
243 Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
246 #if !defined(HAVE_DIRECTX)
247 NO_DIRECTX_SUPPORT_ERROR;
248 #elif !defined(HAVE_OPENCL)
249 NO_OPENCL_SUPPORT_ERROR;
251 cl_uint numPlatforms;
252 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
253 if (status != CL_SUCCESS)
254 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
255 if (numPlatforms == 0)
256 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
258 std::vector<cl_platform_id> platforms(numPlatforms);
259 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
260 if (status != CL_SUCCESS)
261 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
263 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
266 cl_device_id device = NULL;
267 cl_uint numDevices = 0;
268 cl_context context = NULL;
270 // try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
271 for (int i = 0; i < (int)numPlatforms; i++)
273 clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
274 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
275 if (!clGetDeviceIDsFromD3D11KHR)
280 status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
281 CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
282 if (status != CL_SUCCESS)
286 cl_context_properties properties[] = {
287 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
288 CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
289 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
292 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
293 if (status != CL_SUCCESS)
295 clReleaseDevice(device);
306 // try with CL_ALL_DEVICES_FOR_D3D11_KHR
307 for (int i = 0; i < (int)numPlatforms; i++)
309 clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
310 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
311 if (!clGetDeviceIDsFromD3D11KHR)
316 status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
317 CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
318 if (status != CL_SUCCESS)
322 cl_context_properties properties[] = {
323 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
324 CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
325 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
328 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
329 if (status != CL_SUCCESS)
331 clReleaseDevice(device);
341 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
345 Context& ctx = Context::getDefault(false);
346 initializeContextFromHandle(ctx, platforms[found], context, device);
351 Context& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device)
354 #if !defined(HAVE_DIRECTX)
355 NO_DIRECTX_SUPPORT_ERROR;
356 #elif !defined(HAVE_OPENCL)
357 NO_OPENCL_SUPPORT_ERROR;
359 cl_uint numPlatforms;
360 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
361 if (status != CL_SUCCESS)
362 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
363 if (numPlatforms == 0)
364 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
366 std::vector<cl_platform_id> platforms(numPlatforms);
367 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
368 if (status != CL_SUCCESS)
369 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
371 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
374 cl_device_id device = NULL;
375 cl_uint numDevices = 0;
376 cl_context context = NULL;
378 // try with CL_PREFERRED_DEVICES_FOR_D3D10_KHR
379 for (int i = 0; i < (int)numPlatforms; i++)
381 clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
382 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
383 if (!clGetDeviceIDsFromD3D10KHR)
388 status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
389 CL_PREFERRED_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
390 if (status != CL_SUCCESS)
394 cl_context_properties properties[] = {
395 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
396 CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
397 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
400 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
401 if (status != CL_SUCCESS)
403 clReleaseDevice(device);
414 // try with CL_ALL_DEVICES_FOR_D3D10_KHR
415 for (int i = 0; i < (int)numPlatforms; i++)
417 clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
418 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
419 if (!clGetDeviceIDsFromD3D10KHR)
424 status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
425 CL_ALL_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
426 if (status != CL_SUCCESS)
430 cl_context_properties properties[] = {
431 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
432 CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
433 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
436 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
437 if (status != CL_SUCCESS)
439 clReleaseDevice(device);
449 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
453 Context& ctx = Context::getDefault(false);
454 initializeContextFromHandle(ctx, platforms[found], context, device);
459 Context& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex)
461 (void)pDirect3DDevice9Ex;
462 #if !defined(HAVE_DIRECTX)
463 NO_DIRECTX_SUPPORT_ERROR;
464 #elif !defined(HAVE_OPENCL)
465 NO_OPENCL_SUPPORT_ERROR;
467 cl_uint numPlatforms;
468 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
469 if (status != CL_SUCCESS)
470 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
471 if (numPlatforms == 0)
472 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
474 std::vector<cl_platform_id> platforms(numPlatforms);
475 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
476 if (status != CL_SUCCESS)
477 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
479 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
482 cl_device_id device = NULL;
483 cl_uint numDevices = 0;
484 cl_context context = NULL;
486 // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
487 for (int i = 0; i < (int)numPlatforms; i++)
489 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
490 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
491 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
496 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
497 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
498 CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
499 if (status != CL_SUCCESS)
503 cl_context_properties properties[] = {
504 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
505 CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
506 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
509 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
510 if (status != CL_SUCCESS)
512 clReleaseDevice(device);
523 // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
524 for (int i = 0; i < (int)numPlatforms; i++)
526 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
527 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
528 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
533 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
534 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
535 CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
536 if (status != CL_SUCCESS)
540 cl_context_properties properties[] = {
541 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
542 CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
543 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
546 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
547 if (status != CL_SUCCESS)
549 clReleaseDevice(device);
559 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
562 Context& ctx = Context::getDefault(false);
563 initializeContextFromHandle(ctx, platforms[found], context, device);
564 g_isDirect3DDevice9Ex = true;
569 Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9)
571 (void)pDirect3DDevice9;
572 #if !defined(HAVE_DIRECTX)
573 NO_DIRECTX_SUPPORT_ERROR;
574 #elif !defined(HAVE_OPENCL)
575 NO_OPENCL_SUPPORT_ERROR;
577 cl_uint numPlatforms;
578 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
579 if (status != CL_SUCCESS)
580 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
581 if (numPlatforms == 0)
582 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
584 std::vector<cl_platform_id> platforms(numPlatforms);
585 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
586 if (status != CL_SUCCESS)
587 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
589 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
592 cl_device_id device = NULL;
593 cl_uint numDevices = 0;
594 cl_context context = NULL;
596 // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
597 for (int i = 0; i < (int)numPlatforms; i++)
599 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
600 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
601 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
606 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
607 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
608 CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
609 if (status != CL_SUCCESS)
613 cl_context_properties properties[] = {
614 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
615 CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
616 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
619 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
620 if (status != CL_SUCCESS)
622 clReleaseDevice(device);
633 // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
634 for (int i = 0; i < (int)numPlatforms; i++)
636 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
637 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
638 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
643 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
644 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
645 CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
646 if (status != CL_SUCCESS)
650 cl_context_properties properties[] = {
651 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
652 CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
653 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
656 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
657 if (status != CL_SUCCESS)
659 clReleaseDevice(device);
669 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
672 Context& ctx = Context::getDefault(false);
673 initializeContextFromHandle(ctx, platforms[found], context, device);
674 g_isDirect3DDevice9Ex = false;
679 } // namespace cv::ocl
681 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
682 clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL;
683 clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL;
684 clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL;
686 static void __OpenCLinitializeD3D11()
688 using namespace cv::ocl;
689 static cl_platform_id initializedPlatform = NULL;
690 cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
691 if (initializedPlatform != platform)
693 clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
694 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
695 clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
696 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
697 clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
698 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
699 initializedPlatform = platform;
701 if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
703 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
706 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
708 } // namespace directx
713 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
714 #ifdef HAVE_DIRECTX_NV12
717 bool ocl_convert_nv12_to_bgr(
726 k.create("YUV2BGR_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, "");
730 k.args(clImageY, clImageUV, clBuffer, step, cols, rows);
732 size_t globalsize[] = { cols, rows };
733 return k.run(2, globalsize, 0, false);
738 bool ocl_convert_bgr_to_nv12(
747 k.create("BGR2YUV_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, "");
751 k.args(clBuffer, step, cols, rows, clImageY, clImageUV);
753 size_t globalsize[] = { cols, rows };
754 return k.run(2, globalsize, 0, false);
757 #endif // HAVE_DIRECTX_NV12
758 #endif // HAVE_DIRECTX && HAVE_OPENCL
765 void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
767 (void)src; (void)pD3D11Texture2D;
768 #if !defined(HAVE_DIRECTX)
769 NO_DIRECTX_SUPPORT_ERROR;
770 #elif defined(HAVE_OPENCL)
771 __OpenCLinitializeD3D11();
773 D3D11_TEXTURE2D_DESC desc = { 0 };
774 pD3D11Texture2D->GetDesc(&desc);
776 int srcType = src.type();
777 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
778 CV_Assert(textureType == srcType);
780 Size srcSize = src.size();
781 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
783 UMat u = src.getUMat();
785 // TODO Add support for roi
786 CV_Assert(u.offset == 0);
787 CV_Assert(u.isContinuous());
789 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
791 using namespace cv::ocl;
792 Context& ctx = Context::getDefault();
793 cl_context context = (cl_context)ctx.ptr();
797 cl_mem clImageUV = 0;
799 clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
800 if (status != CL_SUCCESS)
801 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
803 #ifdef HAVE_DIRECTX_NV12
804 if(DXGI_FORMAT_NV12 == desc.Format)
806 clImageUV = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
807 if (status != CL_SUCCESS)
808 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
812 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
814 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
815 if (status != CL_SUCCESS)
816 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
818 #ifdef HAVE_DIRECTX_NV12
819 if(DXGI_FORMAT_NV12 == desc.Format)
821 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
822 if (status != CL_SUCCESS)
823 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
825 if(!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV))
826 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed");
828 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
829 if (status != CL_SUCCESS)
830 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
835 size_t offset = 0; // TODO
836 size_t origin[3] = { 0, 0, 0 };
837 size_t region[3] = { u.cols, u.rows, 1 };
839 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, origin, region, 0, NULL, NULL);
840 if (status != CL_SUCCESS)
841 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
844 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
845 if (status != CL_SUCCESS)
846 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
848 status = clFinish(q); // TODO Use events
849 if (status != CL_SUCCESS)
850 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
852 status = clReleaseMemObject(clImage); // TODO RAII
853 if (status != CL_SUCCESS)
854 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
856 #ifdef HAVE_DIRECTX_NV12
857 if(DXGI_FORMAT_NV12 == desc.Format)
859 status = clReleaseMemObject(clImageUV);
860 if (status != CL_SUCCESS)
861 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
867 NO_OPENCL_SUPPORT_ERROR;
872 void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
874 (void)pD3D11Texture2D; (void)dst;
875 #if !defined(HAVE_DIRECTX)
876 NO_DIRECTX_SUPPORT_ERROR;
877 #elif defined(HAVE_OPENCL)
878 __OpenCLinitializeD3D11();
880 D3D11_TEXTURE2D_DESC desc = { 0 };
881 pD3D11Texture2D->GetDesc(&desc);
883 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
884 CV_Assert(textureType >= 0);
886 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
887 dst.create(Size(desc.Width, desc.Height), textureType);
888 UMat u = dst.getUMat();
890 // TODO Add support for roi
891 CV_Assert(u.offset == 0);
892 CV_Assert(u.isContinuous());
894 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
896 using namespace cv::ocl;
897 Context& ctx = Context::getDefault();
898 cl_context context = (cl_context)ctx.ptr();
903 clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
904 if (status != CL_SUCCESS)
905 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
907 #ifdef HAVE_DIRECTX_NV12
908 cl_mem clImageUV = 0;
909 if(DXGI_FORMAT_NV12 == desc.Format)
911 clImageUV = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
912 if (status != CL_SUCCESS)
913 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
917 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
919 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
920 if (status != CL_SUCCESS)
921 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
923 #ifdef HAVE_DIRECTX_NV12
924 if(DXGI_FORMAT_NV12 == desc.Format)
926 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
927 if (status != CL_SUCCESS)
928 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
930 if(!ocl::ocl_convert_nv12_to_bgr(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows))
931 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed");
933 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
934 if (status != CL_SUCCESS)
935 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
940 size_t offset = 0; // TODO
941 size_t origin[3] = { 0, 0, 0 };
942 size_t region[3] = { u.cols, u.rows, 1 };
944 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, origin, region, offset, 0, NULL, NULL);
945 if (status != CL_SUCCESS)
946 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
949 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
950 if (status != CL_SUCCESS)
951 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
953 status = clFinish(q); // TODO Use events
954 if (status != CL_SUCCESS)
955 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
957 status = clReleaseMemObject(clImage); // TODO RAII
958 if (status != CL_SUCCESS)
959 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
961 #ifdef HAVE_DIRECTX_NV12
962 if(DXGI_FORMAT_NV12 == desc.Format)
964 status = clReleaseMemObject(clImageUV);
965 if (status != CL_SUCCESS)
966 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
972 NO_OPENCL_SUPPORT_ERROR;
976 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
977 clCreateFromD3D10Texture2DKHR_fn clCreateFromD3D10Texture2DKHR = NULL;
978 clEnqueueAcquireD3D10ObjectsKHR_fn clEnqueueAcquireD3D10ObjectsKHR = NULL;
979 clEnqueueReleaseD3D10ObjectsKHR_fn clEnqueueReleaseD3D10ObjectsKHR = NULL;
981 static void __OpenCLinitializeD3D10()
983 using namespace cv::ocl;
984 static cl_platform_id initializedPlatform = NULL;
985 cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
986 if (initializedPlatform != platform)
988 clCreateFromD3D10Texture2DKHR = (clCreateFromD3D10Texture2DKHR_fn)
989 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D10Texture2DKHR");
990 clEnqueueAcquireD3D10ObjectsKHR = (clEnqueueAcquireD3D10ObjectsKHR_fn)
991 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D10ObjectsKHR");
992 clEnqueueReleaseD3D10ObjectsKHR = (clEnqueueReleaseD3D10ObjectsKHR_fn)
993 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D10ObjectsKHR");
994 initializedPlatform = platform;
996 if (!clCreateFromD3D10Texture2DKHR || !clEnqueueAcquireD3D10ObjectsKHR || !clEnqueueReleaseD3D10ObjectsKHR)
998 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D10");
1001 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
1003 void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D)
1005 (void)src; (void)pD3D10Texture2D;
1006 #if !defined(HAVE_DIRECTX)
1007 NO_DIRECTX_SUPPORT_ERROR;
1008 #elif defined(HAVE_OPENCL)
1009 __OpenCLinitializeD3D10();
1011 D3D10_TEXTURE2D_DESC desc = { 0 };
1012 pD3D10Texture2D->GetDesc(&desc);
1014 int srcType = src.type();
1015 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1016 CV_Assert(textureType == srcType);
1018 Size srcSize = src.size();
1019 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
1021 using namespace cv::ocl;
1022 Context& ctx = Context::getDefault();
1023 cl_context context = (cl_context)ctx.ptr();
1025 UMat u = src.getUMat();
1027 // TODO Add support for roi
1028 CV_Assert(u.offset == 0);
1029 CV_Assert(u.isContinuous());
1032 cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D10Texture2D, 0, &status);
1033 if (status != CL_SUCCESS)
1034 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
1036 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1038 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1039 status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1040 if (status != CL_SUCCESS)
1041 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
1042 size_t offset = 0; // TODO
1043 size_t dst_origin[3] = {0, 0, 0};
1044 size_t region[3] = {u.cols, u.rows, 1};
1045 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
1046 if (status != CL_SUCCESS)
1047 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
1048 status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1049 if (status != CL_SUCCESS)
1050 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
1052 status = clFinish(q); // TODO Use events
1053 if (status != CL_SUCCESS)
1054 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1056 status = clReleaseMemObject(clImage); // TODO RAII
1057 if (status != CL_SUCCESS)
1058 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1061 NO_OPENCL_SUPPORT_ERROR;
1064 void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst)
1066 (void)pD3D10Texture2D; (void)dst;
1067 #if !defined(HAVE_DIRECTX)
1068 NO_DIRECTX_SUPPORT_ERROR;
1069 #elif defined(HAVE_OPENCL)
1070 __OpenCLinitializeD3D10();
1072 D3D10_TEXTURE2D_DESC desc = { 0 };
1073 pD3D10Texture2D->GetDesc(&desc);
1075 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1076 CV_Assert(textureType >= 0);
1078 using namespace cv::ocl;
1079 Context& ctx = Context::getDefault();
1080 cl_context context = (cl_context)ctx.ptr();
1082 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
1083 dst.create(Size(desc.Width, desc.Height), textureType);
1084 UMat u = dst.getUMat();
1086 // TODO Add support for roi
1087 CV_Assert(u.offset == 0);
1088 CV_Assert(u.isContinuous());
1091 cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D10Texture2D, 0, &status);
1092 if (status != CL_SUCCESS)
1093 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
1095 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1097 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1098 status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1099 if (status != CL_SUCCESS)
1100 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
1101 size_t offset = 0; // TODO
1102 size_t src_origin[3] = {0, 0, 0};
1103 size_t region[3] = {u.cols, u.rows, 1};
1104 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
1105 if (status != CL_SUCCESS)
1106 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
1107 status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1108 if (status != CL_SUCCESS)
1109 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
1111 status = clFinish(q); // TODO Use events
1112 if (status != CL_SUCCESS)
1113 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1115 status = clReleaseMemObject(clImage); // TODO RAII
1116 if (status != CL_SUCCESS)
1117 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1120 NO_OPENCL_SUPPORT_ERROR;
1124 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
1125 clCreateFromDX9MediaSurfaceKHR_fn clCreateFromDX9MediaSurfaceKHR = NULL;
1126 clEnqueueAcquireDX9MediaSurfacesKHR_fn clEnqueueAcquireDX9MediaSurfacesKHR = NULL;
1127 clEnqueueReleaseDX9MediaSurfacesKHR_fn clEnqueueReleaseDX9MediaSurfacesKHR = NULL;
1129 static void __OpenCLinitializeD3D9()
1131 using namespace cv::ocl;
1132 static cl_platform_id initializedPlatform = NULL;
1133 cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
1134 if (initializedPlatform != platform)
1136 clCreateFromDX9MediaSurfaceKHR = (clCreateFromDX9MediaSurfaceKHR_fn)
1137 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromDX9MediaSurfaceKHR");
1138 clEnqueueAcquireDX9MediaSurfacesKHR = (clEnqueueAcquireDX9MediaSurfacesKHR_fn)
1139 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireDX9MediaSurfacesKHR");
1140 clEnqueueReleaseDX9MediaSurfacesKHR = (clEnqueueReleaseDX9MediaSurfacesKHR_fn)
1141 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseDX9MediaSurfacesKHR");
1142 initializedPlatform = platform;
1144 if (!clCreateFromDX9MediaSurfaceKHR || !clEnqueueAcquireDX9MediaSurfacesKHR || !clEnqueueReleaseDX9MediaSurfacesKHR)
1146 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D9");
1149 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
1151 void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle)
1153 (void)src; (void)pDirect3DSurface9; (void)surfaceSharedHandle;
1154 #if !defined(HAVE_DIRECTX)
1155 NO_DIRECTX_SUPPORT_ERROR;
1156 #elif defined(HAVE_OPENCL)
1157 __OpenCLinitializeD3D9();
1159 D3DSURFACE_DESC desc;
1160 if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1162 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1165 int srcType = src.type();
1166 int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1167 CV_Assert(surfaceType == srcType);
1169 Size srcSize = src.size();
1170 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
1172 using namespace cv::ocl;
1173 Context& ctx = Context::getDefault();
1174 cl_context context = (cl_context)ctx.ptr();
1176 UMat u = src.getUMat();
1178 // TODO Add support for roi
1179 CV_Assert(u.offset == 0);
1180 CV_Assert(u.isContinuous());
1183 cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
1184 cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_WRITE_ONLY,
1185 ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
1186 &surfaceInfo, 0, &status);
1187 if (status != CL_SUCCESS)
1188 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
1190 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1192 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1193 status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1194 if (status != CL_SUCCESS)
1195 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
1196 size_t offset = 0; // TODO
1197 size_t dst_origin[3] = {0, 0, 0};
1198 size_t region[3] = {u.cols, u.rows, 1};
1199 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
1200 if (status != CL_SUCCESS)
1201 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
1202 status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1203 if (status != CL_SUCCESS)
1204 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
1206 status = clFinish(q); // TODO Use events
1207 if (status != CL_SUCCESS)
1208 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1210 status = clReleaseMemObject(clImage); // TODO RAII
1211 if (status != CL_SUCCESS)
1212 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1214 // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1215 NO_OPENCL_SUPPORT_ERROR;
1219 void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle)
1221 (void)pDirect3DSurface9; (void)dst; (void)surfaceSharedHandle;
1222 #if !defined(HAVE_DIRECTX)
1223 NO_DIRECTX_SUPPORT_ERROR;
1224 #elif defined(HAVE_OPENCL)
1225 __OpenCLinitializeD3D9();
1227 D3DSURFACE_DESC desc;
1228 if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1230 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1233 int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1234 CV_Assert(surfaceType >= 0);
1236 using namespace cv::ocl;
1237 Context& ctx = Context::getDefault();
1238 cl_context context = (cl_context)ctx.ptr();
1240 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
1241 dst.create(Size(desc.Width, desc.Height), surfaceType);
1242 UMat u = dst.getUMat();
1244 // TODO Add support for roi
1245 CV_Assert(u.offset == 0);
1246 CV_Assert(u.isContinuous());
1249 cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
1250 cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_READ_ONLY,
1251 ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
1252 &surfaceInfo, 0, &status);
1253 if (status != CL_SUCCESS)
1254 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
1256 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_WRITE);
1258 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1259 status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1260 if (status != CL_SUCCESS)
1261 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
1262 size_t offset = 0; // TODO
1263 size_t src_origin[3] = {0, 0, 0};
1264 size_t region[3] = {u.cols, u.rows, 1};
1265 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
1266 if (status != CL_SUCCESS)
1267 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
1268 status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1269 if (status != CL_SUCCESS)
1270 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
1272 status = clFinish(q); // TODO Use events
1273 if (status != CL_SUCCESS)
1274 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1276 status = clReleaseMemObject(clImage); // TODO RAII
1277 if (status != CL_SUCCESS)
1278 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1280 // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1281 NO_OPENCL_SUPPORT_ERROR;
1285 } } // namespace cv::directx