Merge pull request #6854 from sturkmen72:patch-8
[platform/upstream/opencv.git] / modules / core / src / directx.cpp
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 #include "opencl_kernels_core.hpp"
48
49 #ifdef HAVE_DIRECTX
50 #include <vector>
51 # include "directx.inc.hpp"
52 #else // HAVE_DIRECTX
53 #define NO_DIRECTX_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
54 #endif
55
56 #ifndef HAVE_OPENCL
57 # define NO_OPENCL_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
58 #endif // HAVE_OPENCL
59
60 namespace cv { namespace directx {
61
62 int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
63 {
64     (void)iDXGI_FORMAT;
65 #if !defined(HAVE_DIRECTX)
66     NO_DIRECTX_SUPPORT_ERROR;
67 #else
68     const int errorType = -1;
69     switch ((enum DXGI_FORMAT)iDXGI_FORMAT)
70     {
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;
173 #endif
174     default: break;
175     }
176     return errorType;
177 #endif
178 }
179
180 int getTypeFromD3DFORMAT(const int iD3DFORMAT)
181 {
182     (void)iD3DFORMAT;
183 #if !defined(HAVE_DIRECTX)
184     NO_DIRECTX_SUPPORT_ERROR;
185 #else
186     const int errorType = -1;
187     switch ((enum _D3DFORMAT)iD3DFORMAT)
188     {
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:
207
208     case D3DFMT_A8P8: return CV_8UC2;
209     case D3DFMT_P8: return CV_8UC1;
210
211     case D3DFMT_L8: return CV_8UC1;
212     case D3DFMT_A8L8: return CV_8UC2;
213     //case D3DFMT_A4L4:
214
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:
221
222     case D3DFMT_D16_LOCKABLE: return CV_16UC1;
223     case D3DFMT_D32: return CV_32SC1;
224     //case D3DFMT_D15S1:
225     //case D3DFMT_D24S8:
226     //case D3DFMT_D24X8:
227     //case D3DFMT_D24X4S4:
228     case D3DFMT_D16: return CV_16UC1;
229
230     case D3DFMT_D32F_LOCKABLE: return CV_32FC1;
231     default: break;
232     }
233     return errorType;
234 #endif
235 }
236
237 namespace ocl {
238
239 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
240 static bool g_isDirect3DDevice9Ex = false; // Direct3DDevice9Ex or Direct3DDevice9 was used
241 #endif
242
243 Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
244 {
245     (void)pD3D11Device;
246 #if !defined(HAVE_DIRECTX)
247     NO_DIRECTX_SUPPORT_ERROR;
248 #elif !defined(HAVE_OPENCL)
249     NO_OPENCL_SUPPORT_ERROR;
250 #else
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");
257
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");
262
263     // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
264
265     int found = -1;
266     cl_device_id device = NULL;
267     cl_uint numDevices = 0;
268     cl_context context = NULL;
269
270     // try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
271     for (int i = 0; i < (int)numPlatforms; i++)
272     {
273         clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
274                 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
275         if (!clGetDeviceIDsFromD3D11KHR)
276             continue;
277
278         device = NULL;
279         numDevices = 0;
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)
283             continue;
284         if (numDevices > 0)
285         {
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,
290                     NULL, NULL
291             };
292             context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
293             if (status != CL_SUCCESS)
294             {
295                 clReleaseDevice(device);
296             }
297             else
298             {
299                 found = i;
300                 break;
301             }
302         }
303     }
304     if (found < 0)
305     {
306         // try with CL_ALL_DEVICES_FOR_D3D11_KHR
307         for (int i = 0; i < (int)numPlatforms; i++)
308         {
309             clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
310                     clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
311             if (!clGetDeviceIDsFromD3D11KHR)
312                 continue;
313
314             device = NULL;
315             numDevices = 0;
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)
319                 continue;
320             if (numDevices > 0)
321             {
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,
326                         NULL, NULL
327                 };
328                 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
329                 if (status != CL_SUCCESS)
330                 {
331                     clReleaseDevice(device);
332                 }
333                 else
334                 {
335                     found = i;
336                     break;
337                 }
338             }
339         }
340         if (found < 0)
341             CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
342     }
343
344
345     Context& ctx = Context::getDefault(false);
346     initializeContextFromHandle(ctx, platforms[found], context, device);
347     return ctx;
348 #endif
349 }
350
351 Context& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device)
352 {
353     (void)pD3D10Device;
354 #if !defined(HAVE_DIRECTX)
355     NO_DIRECTX_SUPPORT_ERROR;
356 #elif !defined(HAVE_OPENCL)
357     NO_OPENCL_SUPPORT_ERROR;
358 #else
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");
365
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");
370
371     // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
372
373     int found = -1;
374     cl_device_id device = NULL;
375     cl_uint numDevices = 0;
376     cl_context context = NULL;
377
378     // try with CL_PREFERRED_DEVICES_FOR_D3D10_KHR
379     for (int i = 0; i < (int)numPlatforms; i++)
380     {
381         clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
382                 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
383         if (!clGetDeviceIDsFromD3D10KHR)
384             continue;
385
386         device = NULL;
387         numDevices = 0;
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)
391             continue;
392         if (numDevices > 0)
393         {
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,
398                     NULL, NULL
399             };
400             context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
401             if (status != CL_SUCCESS)
402             {
403                 clReleaseDevice(device);
404             }
405             else
406             {
407                 found = i;
408                 break;
409             }
410         }
411     }
412     if (found < 0)
413     {
414         // try with CL_ALL_DEVICES_FOR_D3D10_KHR
415         for (int i = 0; i < (int)numPlatforms; i++)
416         {
417             clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
418                     clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
419             if (!clGetDeviceIDsFromD3D10KHR)
420                 continue;
421
422             device = NULL;
423             numDevices = 0;
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)
427                 continue;
428             if (numDevices > 0)
429             {
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,
434                         NULL, NULL
435                 };
436                 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
437                 if (status != CL_SUCCESS)
438                 {
439                     clReleaseDevice(device);
440                 }
441                 else
442                 {
443                     found = i;
444                     break;
445                 }
446             }
447         }
448         if (found < 0)
449             CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
450     }
451
452
453     Context& ctx = Context::getDefault(false);
454     initializeContextFromHandle(ctx, platforms[found], context, device);
455     return ctx;
456 #endif
457 }
458
459 Context& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex)
460 {
461     (void)pDirect3DDevice9Ex;
462 #if !defined(HAVE_DIRECTX)
463     NO_DIRECTX_SUPPORT_ERROR;
464 #elif !defined(HAVE_OPENCL)
465     NO_OPENCL_SUPPORT_ERROR;
466 #else
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");
473
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");
478
479     // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
480
481     int found = -1;
482     cl_device_id device = NULL;
483     cl_uint numDevices = 0;
484     cl_context context = NULL;
485
486     // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
487     for (int i = 0; i < (int)numPlatforms; i++)
488     {
489         clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
490                 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
491         if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
492             continue;
493
494         device = NULL;
495         numDevices = 0;
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)
500             continue;
501         if (numDevices > 0)
502         {
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,
507                     NULL, NULL
508             };
509             context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
510             if (status != CL_SUCCESS)
511             {
512                 clReleaseDevice(device);
513             }
514             else
515             {
516                 found = i;
517                 break;
518             }
519         }
520     }
521     if (found < 0)
522     {
523         // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
524         for (int i = 0; i < (int)numPlatforms; i++)
525         {
526             clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
527                     clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
528             if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
529                 continue;
530
531             device = NULL;
532             numDevices = 0;
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)
537                 continue;
538             if (numDevices > 0)
539             {
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,
544                         NULL, NULL
545                 };
546                 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
547                 if (status != CL_SUCCESS)
548                 {
549                     clReleaseDevice(device);
550                 }
551                 else
552                 {
553                     found = i;
554                     break;
555                 }
556             }
557         }
558         if (found < 0)
559             CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
560     }
561
562     Context& ctx = Context::getDefault(false);
563     initializeContextFromHandle(ctx, platforms[found], context, device);
564     g_isDirect3DDevice9Ex = true;
565     return ctx;
566 #endif
567 }
568
569 Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9)
570 {
571     (void)pDirect3DDevice9;
572 #if !defined(HAVE_DIRECTX)
573     NO_DIRECTX_SUPPORT_ERROR;
574 #elif !defined(HAVE_OPENCL)
575     NO_OPENCL_SUPPORT_ERROR;
576 #else
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");
583
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");
588
589     // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
590
591     int found = -1;
592     cl_device_id device = NULL;
593     cl_uint numDevices = 0;
594     cl_context context = NULL;
595
596     // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
597     for (int i = 0; i < (int)numPlatforms; i++)
598     {
599         clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
600                 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
601         if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
602             continue;
603
604         device = NULL;
605         numDevices = 0;
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)
610             continue;
611         if (numDevices > 0)
612         {
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,
617                     NULL, NULL
618             };
619             context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
620             if (status != CL_SUCCESS)
621             {
622                 clReleaseDevice(device);
623             }
624             else
625             {
626                 found = i;
627                 break;
628             }
629         }
630     }
631     if (found < 0)
632     {
633         // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
634         for (int i = 0; i < (int)numPlatforms; i++)
635         {
636             clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
637                     clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
638             if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
639                 continue;
640
641             device = NULL;
642             numDevices = 0;
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)
647                 continue;
648             if (numDevices > 0)
649             {
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,
654                         NULL, NULL
655                 };
656                 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
657                 if (status != CL_SUCCESS)
658                 {
659                     clReleaseDevice(device);
660                 }
661                 else
662                 {
663                     found = i;
664                     break;
665                 }
666             }
667         }
668         if (found < 0)
669             CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
670     }
671
672     Context& ctx = Context::getDefault(false);
673     initializeContextFromHandle(ctx, platforms[found], context, device);
674     g_isDirect3DDevice9Ex = false;
675     return ctx;
676 #endif
677 }
678
679 } // namespace cv::ocl
680
681 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
682 clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL;
683 clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL;
684 clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL;
685
686 static void __OpenCLinitializeD3D11()
687 {
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)
692     {
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;
700     }
701     if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
702     {
703         CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
704     }
705 }
706 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
707
708 } // namespace directx
709
710
711 namespace ocl {
712
713 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
714 #ifdef HAVE_DIRECTX_NV12
715
716 static
717 bool ocl_convert_nv12_to_bgr(
718     cl_mem clImageY,
719     cl_mem clImageUV,
720     cl_mem clBuffer,
721     int step,
722     int cols,
723     int rows)
724 {
725     ocl::Kernel k;
726     k.create("YUV2BGR_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, "");
727     if (k.empty())
728         return false;
729
730     k.args(clImageY, clImageUV, clBuffer, step, cols, rows);
731
732     size_t globalsize[] = { (size_t)cols, (size_t)rows };
733     return k.run(2, globalsize, 0, false);
734 }
735
736
737 static
738 bool ocl_convert_bgr_to_nv12(
739     cl_mem clBuffer,
740     int step,
741     int cols,
742     int rows,
743     cl_mem clImageY,
744     cl_mem clImageUV)
745 {
746     ocl::Kernel k;
747     k.create("BGR2YUV_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, "");
748     if (k.empty())
749         return false;
750
751     k.args(clBuffer, step, cols, rows, clImageY, clImageUV);
752
753     size_t globalsize[] = { (size_t)cols, (size_t)rows };
754     return k.run(2, globalsize, 0, false);
755 }
756
757 #endif // HAVE_DIRECTX_NV12
758 #endif // HAVE_DIRECTX && HAVE_OPENCL
759
760 } // namespace ocl
761
762
763 namespace directx {
764
765 void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
766 {
767     (void)src; (void)pD3D11Texture2D;
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 srcType = src.type();
777     int textureType = getTypeFromDXGI_FORMAT(desc.Format);
778     CV_Assert(textureType == srcType);
779
780     Size srcSize = src.size();
781     CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
782
783     UMat u = src.getUMat();
784
785     // TODO Add support for roi
786     CV_Assert(u.offset == 0);
787     CV_Assert(u.isContinuous());
788
789     cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
790
791     using namespace cv::ocl;
792     Context& ctx = Context::getDefault();
793     cl_context context = (cl_context)ctx.ptr();
794
795     cl_int status = 0;
796     cl_mem clImage = 0;
797     cl_mem clImageUV = 0;
798
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");
802
803 #ifdef HAVE_DIRECTX_NV12
804     if(DXGI_FORMAT_NV12 == desc.Format)
805     {
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");
809     }
810 #endif
811
812     cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
813
814     status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
815     if (status != CL_SUCCESS)
816         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
817
818 #ifdef HAVE_DIRECTX_NV12
819     if(DXGI_FORMAT_NV12 == desc.Format)
820     {
821         status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
822         if (status != CL_SUCCESS)
823             CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
824
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");
827
828         status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
829         if (status != CL_SUCCESS)
830             CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
831     }
832     else
833 #endif
834     {
835         size_t offset = 0; // TODO
836         size_t origin[3] = { 0, 0, 0 };
837         size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
838
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");
842     }
843
844     status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
845     if (status != CL_SUCCESS)
846         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
847
848     status = clFinish(q); // TODO Use events
849     if (status != CL_SUCCESS)
850         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
851
852     status = clReleaseMemObject(clImage); // TODO RAII
853     if (status != CL_SUCCESS)
854         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
855
856 #ifdef HAVE_DIRECTX_NV12
857     if(DXGI_FORMAT_NV12 == desc.Format)
858     {
859         status = clReleaseMemObject(clImageUV);
860         if (status != CL_SUCCESS)
861             CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
862     }
863 #endif
864
865 #else
866     // TODO memcpy
867     NO_OPENCL_SUPPORT_ERROR;
868 #endif
869 }
870
871
872 void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
873 {
874     (void)pD3D11Texture2D; (void)dst;
875 #if !defined(HAVE_DIRECTX)
876     NO_DIRECTX_SUPPORT_ERROR;
877 #elif defined(HAVE_OPENCL)
878     __OpenCLinitializeD3D11();
879
880     D3D11_TEXTURE2D_DESC desc = { 0 };
881     pD3D11Texture2D->GetDesc(&desc);
882
883     int textureType = getTypeFromDXGI_FORMAT(desc.Format);
884     CV_Assert(textureType >= 0);
885
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();
889
890     // TODO Add support for roi
891     CV_Assert(u.offset == 0);
892     CV_Assert(u.isContinuous());
893
894     cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
895
896     using namespace cv::ocl;
897     Context& ctx = Context::getDefault();
898     cl_context context = (cl_context)ctx.ptr();
899
900     cl_int status = 0;
901     cl_mem clImage = 0;
902
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");
906
907 #ifdef HAVE_DIRECTX_NV12
908     cl_mem clImageUV = 0;
909     if(DXGI_FORMAT_NV12 == desc.Format)
910     {
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");
914     }
915 #endif
916
917     cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
918
919     status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
920     if (status != CL_SUCCESS)
921         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
922
923 #ifdef HAVE_DIRECTX_NV12
924     if(DXGI_FORMAT_NV12 == desc.Format)
925     {
926         status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
927         if (status != CL_SUCCESS)
928             CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
929
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");
932
933         status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
934         if (status != CL_SUCCESS)
935             CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
936     }
937     else
938 #endif
939     {
940         size_t offset = 0; // TODO
941         size_t origin[3] = { 0, 0, 0 };
942         size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
943
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");
947     }
948
949     status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
950     if (status != CL_SUCCESS)
951         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
952
953     status = clFinish(q); // TODO Use events
954     if (status != CL_SUCCESS)
955         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
956
957     status = clReleaseMemObject(clImage); // TODO RAII
958     if (status != CL_SUCCESS)
959         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
960
961 #ifdef HAVE_DIRECTX_NV12
962     if(DXGI_FORMAT_NV12 == desc.Format)
963     {
964         status = clReleaseMemObject(clImageUV);
965         if (status != CL_SUCCESS)
966             CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
967     }
968 #endif
969
970 #else
971     // TODO memcpy
972     NO_OPENCL_SUPPORT_ERROR;
973 #endif
974 }
975
976 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
977 clCreateFromD3D10Texture2DKHR_fn clCreateFromD3D10Texture2DKHR = NULL;
978 clEnqueueAcquireD3D10ObjectsKHR_fn clEnqueueAcquireD3D10ObjectsKHR = NULL;
979 clEnqueueReleaseD3D10ObjectsKHR_fn clEnqueueReleaseD3D10ObjectsKHR = NULL;
980
981 static void __OpenCLinitializeD3D10()
982 {
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)
987     {
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;
995     }
996     if (!clCreateFromD3D10Texture2DKHR || !clEnqueueAcquireD3D10ObjectsKHR || !clEnqueueReleaseD3D10ObjectsKHR)
997     {
998         CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D10");
999     }
1000 }
1001 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
1002
1003 void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D)
1004 {
1005     (void)src; (void)pD3D10Texture2D;
1006 #if !defined(HAVE_DIRECTX)
1007     NO_DIRECTX_SUPPORT_ERROR;
1008 #elif defined(HAVE_OPENCL)
1009     __OpenCLinitializeD3D10();
1010
1011     D3D10_TEXTURE2D_DESC desc = { 0 };
1012     pD3D10Texture2D->GetDesc(&desc);
1013
1014     int srcType = src.type();
1015     int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1016     CV_Assert(textureType == 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_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");
1035
1036     cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1037
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] = {(size_t)u.cols, (size_t)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");
1051
1052     status = clFinish(q); // TODO Use events
1053     if (status != CL_SUCCESS)
1054         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1055
1056     status = clReleaseMemObject(clImage); // TODO RAII
1057     if (status != CL_SUCCESS)
1058         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1059 #else
1060     // TODO memcpy
1061     NO_OPENCL_SUPPORT_ERROR;
1062 #endif
1063 }
1064 void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst)
1065 {
1066     (void)pD3D10Texture2D; (void)dst;
1067 #if !defined(HAVE_DIRECTX)
1068     NO_DIRECTX_SUPPORT_ERROR;
1069 #elif defined(HAVE_OPENCL)
1070     __OpenCLinitializeD3D10();
1071
1072     D3D10_TEXTURE2D_DESC desc = { 0 };
1073     pD3D10Texture2D->GetDesc(&desc);
1074
1075     int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1076     CV_Assert(textureType >= 0);
1077
1078     using namespace cv::ocl;
1079     Context& ctx = Context::getDefault();
1080     cl_context context = (cl_context)ctx.ptr();
1081
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();
1085
1086     // TODO Add support for roi
1087     CV_Assert(u.offset == 0);
1088     CV_Assert(u.isContinuous());
1089
1090     cl_int status = 0;
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");
1094
1095     cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1096
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] = {(size_t)u.cols, (size_t)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");
1110
1111     status = clFinish(q); // TODO Use events
1112     if (status != CL_SUCCESS)
1113         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1114
1115     status = clReleaseMemObject(clImage); // TODO RAII
1116     if (status != CL_SUCCESS)
1117         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1118 #else
1119     // TODO memcpy
1120     NO_OPENCL_SUPPORT_ERROR;
1121 #endif
1122 }
1123
1124 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
1125 clCreateFromDX9MediaSurfaceKHR_fn clCreateFromDX9MediaSurfaceKHR = NULL;
1126 clEnqueueAcquireDX9MediaSurfacesKHR_fn clEnqueueAcquireDX9MediaSurfacesKHR = NULL;
1127 clEnqueueReleaseDX9MediaSurfacesKHR_fn clEnqueueReleaseDX9MediaSurfacesKHR = NULL;
1128
1129 static void __OpenCLinitializeD3D9()
1130 {
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)
1135     {
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;
1143     }
1144     if (!clCreateFromDX9MediaSurfaceKHR || !clEnqueueAcquireDX9MediaSurfacesKHR || !clEnqueueReleaseDX9MediaSurfacesKHR)
1145     {
1146         CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D9");
1147     }
1148 }
1149 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
1150
1151 void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle)
1152 {
1153     (void)src; (void)pDirect3DSurface9; (void)surfaceSharedHandle;
1154 #if !defined(HAVE_DIRECTX)
1155     NO_DIRECTX_SUPPORT_ERROR;
1156 #elif defined(HAVE_OPENCL)
1157     __OpenCLinitializeD3D9();
1158
1159     D3DSURFACE_DESC desc;
1160     if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1161     {
1162         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1163     }
1164
1165     int srcType = src.type();
1166     int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1167     CV_Assert(surfaceType == srcType);
1168
1169     Size srcSize = src.size();
1170     CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
1171
1172     using namespace cv::ocl;
1173     Context& ctx = Context::getDefault();
1174     cl_context context = (cl_context)ctx.ptr();
1175
1176     UMat u = src.getUMat();
1177
1178     // TODO Add support for roi
1179     CV_Assert(u.offset == 0);
1180     CV_Assert(u.isContinuous());
1181
1182     cl_int status = 0;
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");
1189
1190     cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1191
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] = {(size_t)u.cols, (size_t)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");
1205
1206     status = clFinish(q); // TODO Use events
1207     if (status != CL_SUCCESS)
1208         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1209
1210     status = clReleaseMemObject(clImage); // TODO RAII
1211     if (status != CL_SUCCESS)
1212         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1213 #else
1214     // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1215     NO_OPENCL_SUPPORT_ERROR;
1216 #endif
1217 }
1218
1219 void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle)
1220 {
1221     (void)pDirect3DSurface9; (void)dst; (void)surfaceSharedHandle;
1222 #if !defined(HAVE_DIRECTX)
1223     NO_DIRECTX_SUPPORT_ERROR;
1224 #elif defined(HAVE_OPENCL)
1225     __OpenCLinitializeD3D9();
1226
1227     D3DSURFACE_DESC desc;
1228     if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1229     {
1230         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1231     }
1232
1233     int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1234     CV_Assert(surfaceType >= 0);
1235
1236     using namespace cv::ocl;
1237     Context& ctx = Context::getDefault();
1238     cl_context context = (cl_context)ctx.ptr();
1239
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();
1243
1244     // TODO Add support for roi
1245     CV_Assert(u.offset == 0);
1246     CV_Assert(u.isContinuous());
1247
1248     cl_int status = 0;
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");
1255
1256     cl_mem clBuffer = (cl_mem)u.handle(ACCESS_WRITE);
1257
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] = {(size_t)u.cols, (size_t)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");
1271
1272     status = clFinish(q); // TODO Use events
1273     if (status != CL_SUCCESS)
1274         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1275
1276     status = clReleaseMemObject(clImage); // TODO RAII
1277     if (status != CL_SUCCESS)
1278         CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1279 #else
1280     // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1281     NO_OPENCL_SUPPORT_ERROR;
1282 #endif
1283 }
1284
1285 } } // namespace cv::directx