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_Error(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
54 #endif
55
56 #ifndef HAVE_OPENCL
57 #define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
58 #endif // HAVE_OPENCL
59
60 using namespace cv::ocl;
61
62 namespace cv { namespace directx {
63
getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)64 int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
65 {
66 CV_UNUSED(iDXGI_FORMAT);
67 #if !defined(HAVE_DIRECTX)
68 NO_DIRECTX_SUPPORT_ERROR;
69 #else
70 const int errorType = -1;
71 switch ((enum DXGI_FORMAT)iDXGI_FORMAT)
72 {
73 //case DXGI_FORMAT_UNKNOWN:
74 //case DXGI_FORMAT_R32G32B32A32_TYPELESS:
75 case DXGI_FORMAT_R32G32B32A32_FLOAT: return CV_32FC4;
76 case DXGI_FORMAT_R32G32B32A32_UINT:
77 case DXGI_FORMAT_R32G32B32A32_SINT: return CV_32SC4;
78 //case DXGI_FORMAT_R32G32B32_TYPELESS:
79 case DXGI_FORMAT_R32G32B32_FLOAT: return CV_32FC3;
80 case DXGI_FORMAT_R32G32B32_UINT:
81 case DXGI_FORMAT_R32G32B32_SINT: return CV_32SC3;
82 //case DXGI_FORMAT_R16G16B16A16_TYPELESS:
83 case DXGI_FORMAT_R16G16B16A16_FLOAT: return CV_16FC4;
84 case DXGI_FORMAT_R16G16B16A16_UNORM:
85 case DXGI_FORMAT_R16G16B16A16_UINT: return CV_16UC4;
86 case DXGI_FORMAT_R16G16B16A16_SNORM:
87 case DXGI_FORMAT_R16G16B16A16_SINT: return CV_16SC4;
88 //case DXGI_FORMAT_R32G32_TYPELESS:
89 case DXGI_FORMAT_R32G32_FLOAT: return CV_32FC2;
90 case DXGI_FORMAT_R32G32_UINT:
91 case DXGI_FORMAT_R32G32_SINT: return CV_32SC2;
92 //case DXGI_FORMAT_R32G8X24_TYPELESS:
93 //case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
94 //case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
95 //case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
96 //case DXGI_FORMAT_R10G10B10A2_TYPELESS:
97 //case DXGI_FORMAT_R10G10B10A2_UNORM:
98 //case DXGI_FORMAT_R10G10B10A2_UINT:
99 //case DXGI_FORMAT_R11G11B10_FLOAT:
100 //case DXGI_FORMAT_R8G8B8A8_TYPELESS:
101 case DXGI_FORMAT_R8G8B8A8_UNORM:
102 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
103 case DXGI_FORMAT_R8G8B8A8_UINT: return CV_8UC4;
104 case DXGI_FORMAT_R8G8B8A8_SNORM:
105 case DXGI_FORMAT_R8G8B8A8_SINT: return CV_8SC4;
106 //case DXGI_FORMAT_R16G16_TYPELESS:
107 case DXGI_FORMAT_R16G16_FLOAT: return CV_16FC2;
108 case DXGI_FORMAT_R16G16_UNORM:
109 case DXGI_FORMAT_R16G16_UINT: return CV_16UC2;
110 case DXGI_FORMAT_R16G16_SNORM:
111 case DXGI_FORMAT_R16G16_SINT: return CV_16SC2;
112 //case DXGI_FORMAT_R32_TYPELESS:
113 case DXGI_FORMAT_D32_FLOAT:
114 case DXGI_FORMAT_R32_FLOAT: return CV_32FC1;
115 case DXGI_FORMAT_R32_UINT:
116 case DXGI_FORMAT_R32_SINT: return CV_32SC1;
117 //case DXGI_FORMAT_R24G8_TYPELESS:
118 //case DXGI_FORMAT_D24_UNORM_S8_UINT:
119 //case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
120 //case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
121 //case DXGI_FORMAT_R8G8_TYPELESS:
122 case DXGI_FORMAT_R8G8_UNORM:
123 case DXGI_FORMAT_R8G8_UINT: return CV_8UC2;
124 case DXGI_FORMAT_R8G8_SNORM:
125 case DXGI_FORMAT_R8G8_SINT: return CV_8SC2;
126 //case DXGI_FORMAT_R16_TYPELESS:
127 case DXGI_FORMAT_R16_FLOAT: return CV_16FC1;
128 case DXGI_FORMAT_D16_UNORM:
129 case DXGI_FORMAT_R16_UNORM:
130 case DXGI_FORMAT_R16_UINT: return CV_16UC1;
131 case DXGI_FORMAT_R16_SNORM:
132 case DXGI_FORMAT_R16_SINT: return CV_16SC1;
133 //case DXGI_FORMAT_R8_TYPELESS:
134 case DXGI_FORMAT_R8_UNORM:
135 case DXGI_FORMAT_R8_UINT: return CV_8UC1;
136 case DXGI_FORMAT_R8_SNORM:
137 case DXGI_FORMAT_R8_SINT: return CV_8SC1;
138 case DXGI_FORMAT_A8_UNORM: return CV_8UC1;
139 //case DXGI_FORMAT_R1_UNORM:
140 //case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
141 case DXGI_FORMAT_R8G8_B8G8_UNORM:
142 case DXGI_FORMAT_G8R8_G8B8_UNORM: return CV_8UC4;
143 //case DXGI_FORMAT_BC1_TYPELESS:
144 //case DXGI_FORMAT_BC1_UNORM:
145 //case DXGI_FORMAT_BC1_UNORM_SRGB:
146 //case DXGI_FORMAT_BC2_TYPELESS:
147 //case DXGI_FORMAT_BC2_UNORM:
148 //case DXGI_FORMAT_BC2_UNORM_SRGB:
149 //case DXGI_FORMAT_BC3_TYPELESS:
150 //case DXGI_FORMAT_BC3_UNORM:
151 //case DXGI_FORMAT_BC3_UNORM_SRGB:
152 //case DXGI_FORMAT_BC4_TYPELESS:
153 //case DXGI_FORMAT_BC4_UNORM:
154 //case DXGI_FORMAT_BC4_SNORM:
155 //case DXGI_FORMAT_BC5_TYPELESS:
156 //case DXGI_FORMAT_BC5_UNORM:
157 //case DXGI_FORMAT_BC5_SNORM:
158 //case DXGI_FORMAT_B5G6R5_UNORM:
159 //case DXGI_FORMAT_B5G5R5A1_UNORM:
160 case DXGI_FORMAT_B8G8R8A8_UNORM:
161 case DXGI_FORMAT_B8G8R8X8_UNORM: return CV_8UC4;
162 //case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
163 //case DXGI_FORMAT_B8G8R8A8_TYPELESS:
164 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return CV_8UC4;
165 //case DXGI_FORMAT_B8G8R8X8_TYPELESS:
166 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return CV_8UC4;
167 //case DXGI_FORMAT_BC6H_TYPELESS:
168 //case DXGI_FORMAT_BC6H_UF16:
169 //case DXGI_FORMAT_BC6H_SF16:
170 //case DXGI_FORMAT_BC7_TYPELESS:
171 //case DXGI_FORMAT_BC7_UNORM:
172 //case DXGI_FORMAT_BC7_UNORM_SRGB:
173 #ifdef HAVE_DIRECTX_NV12 //D3DX11 should support DXGI_FORMAT_NV12.
174 case DXGI_FORMAT_NV12: return CV_8UC3;
175 #endif
176 default: break;
177 }
178 return errorType;
179 #endif
180 }
181
getTypeFromD3DFORMAT(const int iD3DFORMAT)182 int getTypeFromD3DFORMAT(const int iD3DFORMAT)
183 {
184 CV_UNUSED(iD3DFORMAT);
185 #if !defined(HAVE_DIRECTX)
186 NO_DIRECTX_SUPPORT_ERROR;
187 #else
188 const int errorType = -1;
189 switch ((enum _D3DFORMAT)iD3DFORMAT)
190 {
191 //case D3DFMT_UNKNOWN:
192 case D3DFMT_R8G8B8: return CV_8UC3;
193 case D3DFMT_A8R8G8B8:
194 case D3DFMT_X8R8G8B8: return CV_8UC4;
195 //case D3DFMT_R5G6B5:
196 //case D3DFMT_X1R5G5B5:
197 //case D3DFMT_A1R5G5B5:
198 //case D3DFMT_A4R4G4B4:
199 //case D3DFMT_R3G3B2:
200 case D3DFMT_A8: return CV_8UC1;
201 //case D3DFMT_A8R3G3B2:
202 //case D3DFMT_X4R4G4B4:
203 //case D3DFMT_A2B10G10R10:
204 case D3DFMT_A8B8G8R8:
205 case D3DFMT_X8B8G8R8: return CV_8UC4;
206 //case D3DFMT_G16R16:
207 //case D3DFMT_A2R10G10B10:
208 //case D3DFMT_A16B16G16R16:
209
210 case D3DFMT_A8P8: return CV_8UC2;
211 case D3DFMT_P8: return CV_8UC1;
212
213 case D3DFMT_L8: return CV_8UC1;
214 case D3DFMT_A8L8: return CV_8UC2;
215 //case D3DFMT_A4L4:
216
217 case D3DFMT_V8U8: return CV_8UC2;
218 //case D3DFMT_L6V5U5:
219 case D3DFMT_X8L8V8U8:
220 case D3DFMT_Q8W8V8U8: return CV_8UC4;
221 case D3DFMT_V16U16: return CV_16UC4; // TODO 16SC4 ?
222 //case D3DFMT_A2W10V10U10:
223
224 case D3DFMT_D16_LOCKABLE: return CV_16UC1;
225 case D3DFMT_D32: return CV_32SC1;
226 //case D3DFMT_D15S1:
227 //case D3DFMT_D24S8:
228 //case D3DFMT_D24X8:
229 //case D3DFMT_D24X4S4:
230 case D3DFMT_D16: return CV_16UC1;
231
232 case D3DFMT_D32F_LOCKABLE: return CV_32FC1;
233 default: break;
234 }
235 return errorType;
236 #endif
237 }
238
239 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
240
241 #ifdef HAVE_OPENCL_D3D11_NV
242 class OpenCL_D3D11_NV : public ocl::Context::UserContext
243 {
244 public:
OpenCL_D3D11_NV(cl_platform_id platform,ID3D11Device * _device)245 OpenCL_D3D11_NV(cl_platform_id platform, ID3D11Device*_device) : device(_device)
246 {
247 clCreateFromD3D11Texture2DNV = (clCreateFromD3D11Texture2DNV_fn)
248 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DNV");
249 clEnqueueAcquireD3D11ObjectsNV = (clEnqueueAcquireD3D11ObjectsNV_fn)
250 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsNV");
251 clEnqueueReleaseD3D11ObjectsNV = (clEnqueueReleaseD3D11ObjectsNV_fn)
252 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsNV");
253 if (!clCreateFromD3D11Texture2DNV || !clEnqueueAcquireD3D11ObjectsNV || !clEnqueueReleaseD3D11ObjectsNV)
254 {
255 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11_NV");
256 }
257 device->AddRef();
258 }
~OpenCL_D3D11_NV()259 ~OpenCL_D3D11_NV() {
260 device->Release();
261 }
262 ID3D11Device* device;
263 clCreateFromD3D11Texture2DNV_fn clCreateFromD3D11Texture2DNV;
264 clEnqueueAcquireD3D11ObjectsNV_fn clEnqueueAcquireD3D11ObjectsNV;
265 clEnqueueReleaseD3D11ObjectsNV_fn clEnqueueReleaseD3D11ObjectsNV;
266 };
267 #endif
268
269 class OpenCL_D3D11 : public ocl::Context::UserContext
270 {
271 public:
OpenCL_D3D11(cl_platform_id platform,ID3D11Device * _device)272 OpenCL_D3D11(cl_platform_id platform, ID3D11Device* _device) : device(_device)
273 {
274 clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
275 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
276 clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
277 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
278 clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
279 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
280 if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
281 {
282 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
283 }
284 device->AddRef();
285 }
~OpenCL_D3D11()286 ~OpenCL_D3D11() {
287 device->Release();
288 }
289 ID3D11Device* device;
290 clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR;
291 clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR;
292 clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR;
293 };
294
295 class OpenCL_D3D9 : public ocl::Context::UserContext
296 {
297 public:
OpenCL_D3D9(cl_platform_id platform,IDirect3DDevice9 * _device,IDirect3DDevice9Ex * _deviceEx)298 OpenCL_D3D9(cl_platform_id platform, IDirect3DDevice9* _device, IDirect3DDevice9Ex* _deviceEx)
299 : device(_device)
300 , deviceEx(_deviceEx)
301 {
302 clCreateFromDX9MediaSurfaceKHR = (clCreateFromDX9MediaSurfaceKHR_fn)
303 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromDX9MediaSurfaceKHR");
304 clEnqueueAcquireDX9MediaSurfacesKHR = (clEnqueueAcquireDX9MediaSurfacesKHR_fn)
305 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireDX9MediaSurfacesKHR");
306 clEnqueueReleaseDX9MediaSurfacesKHR = (clEnqueueReleaseDX9MediaSurfacesKHR_fn)
307 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseDX9MediaSurfacesKHR");
308 if (!clCreateFromDX9MediaSurfaceKHR || !clEnqueueAcquireDX9MediaSurfacesKHR || !clEnqueueReleaseDX9MediaSurfacesKHR)
309 {
310 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D9");
311 }
312 if (device)
313 device->AddRef();
314 if (deviceEx)
315 deviceEx->AddRef();
316 }
~OpenCL_D3D9()317 ~OpenCL_D3D9() {
318 if (device)
319 device->Release();
320 if (deviceEx)
321 deviceEx->Release();
322 }
323 IDirect3DDevice9* device;
324 IDirect3DDevice9Ex* deviceEx;
325 clCreateFromDX9MediaSurfaceKHR_fn clCreateFromDX9MediaSurfaceKHR;
326 clEnqueueAcquireDX9MediaSurfacesKHR_fn clEnqueueAcquireDX9MediaSurfacesKHR;
327 clEnqueueReleaseDX9MediaSurfacesKHR_fn clEnqueueReleaseDX9MediaSurfacesKHR;
328 };
329
330 class OpenCL_D3D10 : public ocl::Context::UserContext
331 {
332 public:
OpenCL_D3D10(cl_platform_id platform,ID3D10Device * _device)333 OpenCL_D3D10(cl_platform_id platform, ID3D10Device* _device) : device(_device)
334 {
335 clCreateFromD3D10Texture2DKHR = (clCreateFromD3D10Texture2DKHR_fn)
336 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D10Texture2DKHR");
337 clEnqueueAcquireD3D10ObjectsKHR = (clEnqueueAcquireD3D10ObjectsKHR_fn)
338 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D10ObjectsKHR");
339 clEnqueueReleaseD3D10ObjectsKHR = (clEnqueueReleaseD3D10ObjectsKHR_fn)
340 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D10ObjectsKHR");
341 if (!clCreateFromD3D10Texture2DKHR || !clEnqueueAcquireD3D10ObjectsKHR || !clEnqueueReleaseD3D10ObjectsKHR)
342 {
343 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D10");
344 }
345 device->AddRef();
346 }
~OpenCL_D3D10()347 ~OpenCL_D3D10() {
348 device->Release();
349 }
350 ID3D10Device* device;
351 clCreateFromD3D10Texture2DKHR_fn clCreateFromD3D10Texture2DKHR;
352 clEnqueueAcquireD3D10ObjectsKHR_fn clEnqueueAcquireD3D10ObjectsKHR;
353 clEnqueueReleaseD3D10ObjectsKHR_fn clEnqueueReleaseD3D10ObjectsKHR;
354 };
355 #endif
356
357 namespace ocl {
358
initializeContextFromD3D11Device(ID3D11Device * pD3D11Device)359 Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
360 {
361 CV_UNUSED(pD3D11Device);
362 #if !defined(HAVE_DIRECTX)
363 NO_DIRECTX_SUPPORT_ERROR;
364 #elif !defined(HAVE_OPENCL)
365 NO_OPENCL_SUPPORT_ERROR;
366 #else
367 cl_uint numPlatforms;
368 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
369 if (status != CL_SUCCESS)
370 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
371 if (numPlatforms == 0)
372 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
373
374 std::vector<cl_platform_id> platforms(numPlatforms);
375 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
376 if (status != CL_SUCCESS)
377 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platforms");
378
379 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
380
381 for (int i = 0; i < (int)numPlatforms; i++)
382 {
383 cl_platform_id platform = platforms[i];
384 std::string platformName = PlatformInfo(&platform).name();
385
386 int found = -1;
387 cl_device_id device = NULL;
388 cl_uint numDevices = 0;
389 cl_context context = NULL;
390
391 #ifdef HAVE_OPENCL_D3D11_NV
392 // Get extension function "clGetDeviceIDsFromD3D11NV" (part of OpenCL extension "cl_nv_d3d11_sharing")
393 clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = (clGetDeviceIDsFromD3D11NV_fn)
394 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11NV");
395 if (clGetDeviceIDsFromD3D11NV) {
396 // try with CL_PREFERRED_DEVICES_FOR_D3D11_NV
397 do {
398 device = NULL;
399 numDevices = 0;
400 status = clGetDeviceIDsFromD3D11NV(platforms[i], CL_D3D11_DEVICE_NV, pD3D11Device,
401 CL_PREFERRED_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);
402 if (status != CL_SUCCESS)
403 break;
404 if (numDevices > 0)
405 {
406 cl_context_properties properties[] = {
407 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
408 CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)(pD3D11Device),
409 //CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
410 0
411 };
412
413 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
414 if (status != CL_SUCCESS)
415 {
416 clReleaseDevice(device);
417 }
418 else
419 {
420 found = i;
421 }
422 }
423 } while (0);
424 // try with CL_ALL_DEVICES_FOR_D3D11_NV
425 if (found < 0) do {
426 device = NULL;
427 numDevices = 0;
428 status = clGetDeviceIDsFromD3D11NV(platforms[i], CL_D3D11_DEVICE_NV, pD3D11Device,
429 CL_ALL_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);
430 if (status != CL_SUCCESS)
431 break;
432 if (numDevices > 0)
433 {
434 cl_context_properties properties[] = {
435 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
436 CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)(pD3D11Device),
437 //CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
438 0
439 };
440 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
441 if (status != CL_SUCCESS)
442 {
443 clReleaseDevice(device);
444 }
445 else
446 {
447 found = i;
448 }
449 }
450 } while (0);
451 if (found >= 0) {
452 OpenCLExecutionContext clExecCtx;
453 try
454 {
455 clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
456 clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D11_NV>(platform, pD3D11Device));
457 }
458 catch (...)
459 {
460 clReleaseDevice(device);
461 clReleaseContext(context);
462 throw;
463 }
464 clExecCtx.bind();
465 return const_cast<Context&>(clExecCtx.getContext());
466 }
467 }
468 #endif
469 // Get extension function "clGetDeviceIDsFromD3D11KHR" (part of OpenCL extension "cl_khr_d3d11_sharing")
470 clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
471 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
472 if (clGetDeviceIDsFromD3D11KHR)
473 {
474 // try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
475 do {
476
477 device = NULL;
478 numDevices = 0;
479
480 status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
481 CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
482
483 if (status != CL_SUCCESS)
484 break;
485 if (numDevices > 0)
486 {
487 cl_context_properties properties[] = {
488 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
489 CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
490 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
491 NULL, NULL
492 };
493 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
494 if (status != CL_SUCCESS)
495 {
496 clReleaseDevice(device);
497 }
498 else
499 {
500 found = i;
501 }
502 }
503 } while (0);
504 // try with CL_ALL_DEVICES_FOR_D3D11_KHR
505 if (found < 0) do {
506 device = NULL;
507 numDevices = 0;
508 status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
509 CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
510 if (status != CL_SUCCESS)
511 break;
512 if (numDevices > 0)
513 {
514 cl_context_properties properties[] = {
515 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
516 CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
517 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
518 NULL, NULL
519 };
520 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
521 if (status != CL_SUCCESS)
522 {
523 clReleaseDevice(device);
524 }
525 else
526 {
527 found = i;
528 }
529 }
530 } while (0);
531
532 if (found >= 0) {
533 OpenCLExecutionContext clExecCtx;
534 try
535 {
536 clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
537 clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D11>(platform, pD3D11Device));
538 }
539 catch (...)
540 {
541 clReleaseDevice(device);
542 clReleaseContext(context);
543 throw;
544 }
545 clExecCtx.bind();
546 return const_cast<Context&>(clExecCtx.getContext());
547 }
548 }
549 }
550
551 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
552 #endif
553 }
554
initializeContextFromD3D10Device(ID3D10Device * pD3D10Device)555 Context& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device)
556 {
557 CV_UNUSED(pD3D10Device);
558 #if !defined(HAVE_DIRECTX)
559 NO_DIRECTX_SUPPORT_ERROR;
560 #elif !defined(HAVE_OPENCL)
561 NO_OPENCL_SUPPORT_ERROR;
562 #else
563 cl_uint numPlatforms;
564 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
565 if (status != CL_SUCCESS)
566 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
567 if (numPlatforms == 0)
568 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
569
570 std::vector<cl_platform_id> platforms(numPlatforms);
571 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
572 if (status != CL_SUCCESS)
573 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platforms");
574
575 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
576 for (int i = 0; i < (int)numPlatforms; i++)
577 {
578 cl_platform_id platform = platforms[i];
579 std::string platformName = PlatformInfo(&platform).name();
580 int found = -1;
581 cl_device_id device = NULL;
582 cl_uint numDevices = 0;
583 cl_context context = NULL;
584
585 clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
586 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
587 if (!clGetDeviceIDsFromD3D10KHR)
588 continue;
589
590 // try with CL_PREFERRED_DEVICES_FOR_D3D10_KHR
591 do {
592 device = NULL;
593 numDevices = 0;
594 status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
595 CL_PREFERRED_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
596 if (status != CL_SUCCESS)
597 break;
598 if (numDevices > 0)
599 {
600 cl_context_properties properties[] = {
601 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
602 CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
603 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
604 NULL, NULL
605 };
606 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
607 if (status != CL_SUCCESS)
608 {
609 clReleaseDevice(device);
610 }
611 else
612 {
613 found = i;
614 }
615 }
616 } while (0);
617 // try with CL_ALL_DEVICES_FOR_D3D10_KHR
618 if (found < 0) do
619 {
620 device = NULL;
621 numDevices = 0;
622 status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
623 CL_ALL_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
624 if (status != CL_SUCCESS)
625 break;
626 if (numDevices > 0)
627 {
628 cl_context_properties properties[] = {
629 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
630 CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
631 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
632 NULL, NULL
633 };
634 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
635 if (status != CL_SUCCESS)
636 {
637 clReleaseDevice(device);
638 }
639 else
640 {
641 found = i;
642 }
643 }
644 } while (0);
645
646 if (found >= 0) {
647 OpenCLExecutionContext clExecCtx;
648 try
649 {
650 clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
651 clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D10>(platform, pD3D10Device));
652 }
653 catch (...)
654 {
655 clReleaseDevice(device);
656 clReleaseContext(context);
657 throw;
658 }
659 clExecCtx.bind();
660 return const_cast<Context&>(clExecCtx.getContext());
661 }
662 }
663 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
664 #endif
665 }
666
initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex * pDirect3DDevice9Ex)667 Context& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex)
668 {
669 CV_UNUSED(pDirect3DDevice9Ex);
670 #if !defined(HAVE_DIRECTX)
671 NO_DIRECTX_SUPPORT_ERROR;
672 #elif !defined(HAVE_OPENCL)
673 NO_OPENCL_SUPPORT_ERROR;
674 #else
675 cl_uint numPlatforms;
676 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
677 if (status != CL_SUCCESS)
678 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
679 if (numPlatforms == 0)
680 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
681
682 std::vector<cl_platform_id> platforms(numPlatforms);
683 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
684 if (status != CL_SUCCESS)
685 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platforms");
686
687 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
688 for (int i = 0; i < (int)numPlatforms; i++)
689 {
690 cl_platform_id platform = platforms[i];
691 std::string platformName = PlatformInfo(&platform).name();
692 int found = -1;
693 cl_device_id device = NULL;
694 cl_uint numDevices = 0;
695 cl_context context = NULL;
696
697 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
698 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
699 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
700 continue;
701
702 // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
703 do {
704 device = NULL;
705 numDevices = 0;
706 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
707 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
708 CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
709 if (status != CL_SUCCESS)
710 break;
711 if (numDevices > 0)
712 {
713 cl_context_properties properties[] = {
714 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
715 CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
716 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
717 NULL, NULL
718 };
719 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
720 if (status != CL_SUCCESS)
721 {
722 clReleaseDevice(device);
723 }
724 else
725 {
726 found = i;
727 }
728 }
729 } while (0);
730 // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
731 if (found < 0) do
732 {
733 device = NULL;
734 numDevices = 0;
735 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
736 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
737 CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
738 if (status != CL_SUCCESS)
739 break;
740 if (numDevices > 0)
741 {
742 cl_context_properties properties[] = {
743 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
744 CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
745 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
746 NULL, NULL
747 };
748 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
749 if (status != CL_SUCCESS)
750 {
751 clReleaseDevice(device);
752 }
753 else
754 {
755 found = i;
756 }
757 }
758 } while (0);
759
760 if (found >= 0) {
761 OpenCLExecutionContext clExecCtx;
762 try
763 {
764 clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
765 clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D9>(platform, nullptr, pDirect3DDevice9Ex));
766 }
767 catch (...)
768 {
769 clReleaseDevice(device);
770 clReleaseContext(context);
771 throw;
772 }
773 clExecCtx.bind();
774 return const_cast<Context&>(clExecCtx.getContext());
775 }
776 }
777 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
778 #endif
779 }
780
initializeContextFromDirect3DDevice9(IDirect3DDevice9 * pDirect3DDevice9)781 Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9)
782 {
783 CV_UNUSED(pDirect3DDevice9);
784 #if !defined(HAVE_DIRECTX)
785 NO_DIRECTX_SUPPORT_ERROR;
786 #elif !defined(HAVE_OPENCL)
787 NO_OPENCL_SUPPORT_ERROR;
788 #else
789 cl_uint numPlatforms;
790 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
791 if (status != CL_SUCCESS)
792 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
793 if (numPlatforms == 0)
794 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
795
796 std::vector<cl_platform_id> platforms(numPlatforms);
797 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
798 if (status != CL_SUCCESS)
799 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platforms");
800
801 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
802 for (int i = 0; i < (int)numPlatforms; i++)
803 {
804 cl_platform_id platform = platforms[i];
805 std::string platformName = PlatformInfo(&platform).name();
806 int found = -1;
807 cl_device_id device = NULL;
808 cl_uint numDevices = 0;
809 cl_context context = NULL;
810
811 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
812 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
813 if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
814 continue;
815
816 // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
817 do {
818 device = NULL;
819 numDevices = 0;
820 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
821 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
822 CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
823 if (status != CL_SUCCESS)
824 break;
825 if (numDevices > 0)
826 {
827 cl_context_properties properties[] = {
828 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
829 CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
830 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
831 NULL, NULL
832 };
833 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
834 if (status != CL_SUCCESS)
835 {
836 clReleaseDevice(device);
837 }
838 else
839 {
840 found = i;
841 break;
842 }
843 }
844 } while (0);
845 // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
846 if (found < 0) do
847 {
848 device = NULL;
849 numDevices = 0;
850 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
851 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
852 CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
853 if (status != CL_SUCCESS)
854 break;
855 if (numDevices > 0)
856 {
857 cl_context_properties properties[] = {
858 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
859 CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
860 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
861 NULL, NULL
862 };
863 context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
864 if (status != CL_SUCCESS)
865 {
866 clReleaseDevice(device);
867 }
868 else
869 {
870 found = i;
871 break;
872 }
873 }
874 } while (0);
875
876 if (found >= 0) {
877 OpenCLExecutionContext clExecCtx;
878 try
879 {
880 clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
881 clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D9>(platform, pDirect3DDevice9, nullptr));
882 }
883 catch (...)
884 {
885 clReleaseDevice(device);
886 clReleaseContext(context);
887 throw;
888 }
889 clExecCtx.bind();
890 return const_cast<Context&>(clExecCtx.getContext());
891 }
892 }
893 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
894 #endif
895 }
896
897 } // namespace cv::ocl
898
899 } // namespace directx
900
901
902 namespace ocl {
903
904 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
905 #ifdef HAVE_DIRECTX_NV12
906
907 static
ocl_convert_nv12_to_bgr(cl_mem clImageY,cl_mem clImageUV,cl_mem clBuffer,int step,int cols,int rows)908 bool ocl_convert_nv12_to_bgr(
909 cl_mem clImageY,
910 cl_mem clImageUV,
911 cl_mem clBuffer,
912 int step,
913 int cols,
914 int rows)
915 {
916 ocl::Kernel k;
917 k.create("YUV2BGR_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, "");
918 if (k.empty())
919 return false;
920
921 k.args(clImageY, clImageUV, clBuffer, step, cols, rows);
922
923 size_t globalsize[] = { (size_t)cols/2, (size_t)rows/2 };
924 return k.run(2, globalsize, 0, false);
925 }
926
927
928 static
ocl_convert_bgr_to_nv12(cl_mem clBuffer,int step,int cols,int rows,cl_mem clImageY,cl_mem clImageUV)929 bool ocl_convert_bgr_to_nv12(
930 cl_mem clBuffer,
931 int step,
932 int cols,
933 int rows,
934 cl_mem clImageY,
935 cl_mem clImageUV)
936 {
937 ocl::Kernel k;
938 k.create("BGR2YUV_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, "");
939 if (k.empty())
940 return false;
941
942 k.args(clBuffer, step, cols, rows, clImageY, clImageUV);
943
944 size_t globalsize[] = { (size_t)cols/2, (size_t)rows/2 };
945 return k.run(2, globalsize, 0, false);
946 }
947
948 #endif // HAVE_DIRECTX_NV12
949 #endif // HAVE_DIRECTX && HAVE_OPENCL
950
951 } // namespace ocl
952
953
954 namespace directx {
955
956 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
__convertToD3D11Texture2DKHR(InputArray src,ID3D11Texture2D * pD3D11Texture2D)957 static void __convertToD3D11Texture2DKHR(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
958 {
959 D3D11_TEXTURE2D_DESC desc = { 0 };
960 pD3D11Texture2D->GetDesc(&desc);
961
962 int srcType = src.type();
963 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
964 CV_Assert(textureType == srcType);
965
966 Size srcSize = src.size();
967 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
968
969 UMat u = src.getUMat();
970
971 // TODO Add support for roi
972 CV_Assert(u.offset == 0);
973 CV_Assert(u.isContinuous());
974
975 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
976
977 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
978 cl_context context = (cl_context)ctx.ptr();
979 OpenCL_D3D11* impl = ctx.getUserContext<OpenCL_D3D11>().get();
980 if (nullptr == impl)
981 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
982
983 cl_int status = 0;
984 cl_mem clImage = 0;
985 #ifdef HAVE_DIRECTX_NV12
986 cl_mem clImageUV = 0;
987 #endif
988 clImage = impl->clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
989 if (status != CL_SUCCESS)
990 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
991
992 #ifdef HAVE_DIRECTX_NV12
993 if(DXGI_FORMAT_NV12 == desc.Format)
994 {
995 clImageUV = impl->clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
996 if (status != CL_SUCCESS)
997 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
998 }
999 #endif
1000
1001 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1002
1003 status = impl->clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1004 if (status != CL_SUCCESS)
1005 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
1006
1007 #ifdef HAVE_DIRECTX_NV12
1008 if(DXGI_FORMAT_NV12 == desc.Format)
1009 {
1010 status = impl->clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
1011 if (status != CL_SUCCESS)
1012 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
1013
1014 if(!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV))
1015 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed");
1016
1017 status = impl->clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
1018 if (status != CL_SUCCESS)
1019 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
1020 }
1021 else
1022 #endif
1023 {
1024 size_t offset = 0; // TODO
1025 size_t origin[3] = { 0, 0, 0 };
1026 size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
1027
1028 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, origin, region, 0, NULL, NULL);
1029 if (status != CL_SUCCESS)
1030 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
1031 }
1032
1033 status = impl->clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1034 if (status != CL_SUCCESS)
1035 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
1036
1037 status = clFinish(q); // TODO Use events
1038 if (status != CL_SUCCESS)
1039 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1040
1041 status = clReleaseMemObject(clImage); // TODO RAII
1042 if (status != CL_SUCCESS)
1043 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1044
1045 #ifdef HAVE_DIRECTX_NV12
1046 if(DXGI_FORMAT_NV12 == desc.Format)
1047 {
1048 status = clReleaseMemObject(clImageUV);
1049 if (status != CL_SUCCESS)
1050 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1051 }
1052 #endif
1053 }
1054 #endif
1055
1056 #if defined(HAVE_OPENCL_D3D11_NV)
__convertToD3D11Texture2DNV(InputArray src,ID3D11Texture2D * pD3D11Texture2D)1057 static void __convertToD3D11Texture2DNV(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
1058 {
1059 D3D11_TEXTURE2D_DESC desc = { 0 };
1060 pD3D11Texture2D->GetDesc(&desc);
1061
1062 int srcType = src.type();
1063 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1064 CV_Assert(textureType == srcType);
1065
1066 Size srcSize = src.size();
1067 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
1068
1069 UMat u = src.getUMat();
1070
1071 // TODO Add support for roi
1072 CV_Assert(u.offset == 0);
1073 CV_Assert(u.isContinuous());
1074
1075 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1076
1077 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
1078 cl_context context = (cl_context)ctx.ptr();
1079 OpenCL_D3D11_NV* impl = ctx.getUserContext<OpenCL_D3D11_NV>().get();
1080 if (nullptr == impl)
1081 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
1082
1083 cl_int status = 0;
1084 cl_mem clImage = 0;
1085 #ifdef HAVE_DIRECTX_NV12
1086 cl_mem clImageUV = 0;
1087 #endif
1088 clImage = impl->clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
1089 if (status != CL_SUCCESS)
1090 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
1091
1092 #ifdef HAVE_DIRECTX_NV12
1093 if (DXGI_FORMAT_NV12 == desc.Format)
1094 {
1095 clImageUV = impl->clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
1096 if (status != CL_SUCCESS)
1097 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
1098 }
1099 #endif
1100 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1101 status = impl->clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
1102 if (status != CL_SUCCESS)
1103 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
1104
1105 #ifdef HAVE_DIRECTX_NV12
1106 if(DXGI_FORMAT_NV12 == desc.Format)
1107 {
1108 status = impl->clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
1109 if (status != CL_SUCCESS)
1110 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
1111
1112 if(!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV))
1113 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed");
1114
1115 status = impl->clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
1116 if (status != CL_SUCCESS)
1117 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
1118 }
1119 else
1120 #endif
1121 {
1122 size_t offset = 0; // TODO
1123 size_t origin[3] = { 0, 0, 0 };
1124 size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
1125
1126 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, origin, region, 0, NULL, NULL);
1127 if (status != CL_SUCCESS)
1128 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
1129 }
1130
1131 status = impl->clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
1132 if (status != CL_SUCCESS)
1133 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
1134
1135 status = clFinish(q); // TODO Use events
1136 if (status != CL_SUCCESS)
1137 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1138
1139 status = clReleaseMemObject(clImage); // TODO RAII
1140 if (status != CL_SUCCESS)
1141 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1142
1143 #ifdef HAVE_DIRECTX_NV12
1144 if(DXGI_FORMAT_NV12 == desc.Format)
1145 {
1146 status = clReleaseMemObject(clImageUV);
1147 if (status != CL_SUCCESS)
1148 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1149 }
1150 #endif
1151 }
1152 #endif
1153
1154 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
__convertFromD3D11Texture2DKHR(ID3D11Texture2D * pD3D11Texture2D,OutputArray dst)1155 static void __convertFromD3D11Texture2DKHR(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
1156 {
1157 D3D11_TEXTURE2D_DESC desc = { 0 };
1158 pD3D11Texture2D->GetDesc(&desc);
1159
1160 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1161 CV_Assert(textureType >= 0);
1162
1163 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
1164 dst.create(Size(desc.Width, desc.Height), textureType);
1165 UMat u = dst.getUMat();
1166
1167 // TODO Add support for roi
1168 CV_Assert(u.offset == 0);
1169 CV_Assert(u.isContinuous());
1170
1171 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1172
1173 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
1174 cl_context context = (cl_context)ctx.ptr();
1175 OpenCL_D3D11* impl = ctx.getUserContext<OpenCL_D3D11>().get();
1176 if (nullptr == impl)
1177 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
1178
1179 cl_int status = 0;
1180 cl_mem clImage = 0;
1181
1182 clImage = impl->clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
1183 if (status != CL_SUCCESS)
1184 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
1185
1186 #ifdef HAVE_DIRECTX_NV12
1187 cl_mem clImageUV = 0;
1188 if(DXGI_FORMAT_NV12 == desc.Format)
1189 {
1190 clImageUV = impl->clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
1191 if (status != CL_SUCCESS)
1192 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
1193 }
1194 #endif
1195
1196 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1197
1198 status = impl->clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1199 if (status != CL_SUCCESS)
1200 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
1201
1202 #ifdef HAVE_DIRECTX_NV12
1203 if(DXGI_FORMAT_NV12 == desc.Format)
1204 {
1205 status = impl->clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
1206 if (status != CL_SUCCESS)
1207 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
1208
1209 if(!ocl::ocl_convert_nv12_to_bgr(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows))
1210 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed");
1211
1212 status = impl->clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
1213 if (status != CL_SUCCESS)
1214 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
1215 }
1216 else
1217 #endif
1218 {
1219 size_t offset = 0; // TODO
1220 size_t origin[3] = { 0, 0, 0 };
1221 size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
1222
1223 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, origin, region, offset, 0, NULL, NULL);
1224 if (status != CL_SUCCESS)
1225 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
1226 }
1227
1228 status = impl->clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1229 if (status != CL_SUCCESS)
1230 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
1231
1232 status = clFinish(q); // TODO Use events
1233 if (status != CL_SUCCESS)
1234 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1235
1236 status = clReleaseMemObject(clImage); // TODO RAII
1237 if (status != CL_SUCCESS)
1238 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1239
1240 #ifdef HAVE_DIRECTX_NV12
1241 if(DXGI_FORMAT_NV12 == desc.Format)
1242 {
1243 status = clReleaseMemObject(clImageUV);
1244 if (status != CL_SUCCESS)
1245 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1246 }
1247 #endif
1248 }
1249 #endif
1250
1251 #if defined(HAVE_OPENCL_D3D11_NV)
__convertFromD3D11Texture2DNV(ID3D11Texture2D * pD3D11Texture2D,OutputArray dst)1252 static void __convertFromD3D11Texture2DNV(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
1253 {
1254 D3D11_TEXTURE2D_DESC desc = { 0 };
1255 pD3D11Texture2D->GetDesc(&desc);
1256
1257 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1258 CV_Assert(textureType >= 0);
1259
1260 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
1261 dst.create(Size(desc.Width, desc.Height), textureType);
1262 UMat u = dst.getUMat();
1263
1264 // TODO Add support for roi
1265 CV_Assert(u.offset == 0);
1266 CV_Assert(u.isContinuous());
1267
1268 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1269
1270 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
1271 cl_context context = (cl_context)ctx.ptr();
1272 OpenCL_D3D11_NV* impl = ctx.getUserContext<OpenCL_D3D11_NV>().get();
1273 if (nullptr == impl)
1274 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
1275
1276 cl_int status = 0;
1277 cl_mem clImage = 0;
1278
1279 clImage = impl->clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
1280 if (status != CL_SUCCESS)
1281 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
1282
1283 #ifdef HAVE_DIRECTX_NV12
1284 cl_mem clImageUV = 0;
1285 if(DXGI_FORMAT_NV12 == desc.Format)
1286 {
1287 clImageUV = impl->clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
1288 if (status != CL_SUCCESS)
1289 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
1290 }
1291 #endif
1292
1293 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1294 status = impl->clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
1295 if (status != CL_SUCCESS)
1296 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
1297
1298 #ifdef HAVE_DIRECTX_NV12
1299 if (DXGI_FORMAT::DXGI_FORMAT_NV12 == desc.Format)
1300 {
1301 status = impl->clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
1302 if (status != CL_SUCCESS)
1303 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
1304
1305 if (!ocl::ocl_convert_nv12_to_bgr(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows))
1306 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed");
1307
1308 status = impl->clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
1309 if (status != CL_SUCCESS)
1310 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
1311 }
1312 else
1313 #endif
1314 {
1315 size_t offset = 0; // TODO
1316 size_t origin[3] = { 0, 0, 0 };
1317 size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
1318
1319 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, origin, region, offset, 0, NULL, NULL);
1320 if (status != CL_SUCCESS)
1321 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
1322 }
1323
1324 status = impl->clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
1325 if (status != CL_SUCCESS)
1326 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
1327
1328 status = clFinish(q); // TODO Use events
1329 if (status != CL_SUCCESS)
1330 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1331
1332 status = clReleaseMemObject(clImage); // TODO RAII
1333 if (status != CL_SUCCESS)
1334 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1335
1336 #ifdef HAVE_DIRECTX_NV12
1337 if(DXGI_FORMAT_NV12 == desc.Format)
1338 {
1339 status = clReleaseMemObject(clImageUV);
1340 if (status != CL_SUCCESS)
1341 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1342 }
1343 #endif
1344 }
1345 #endif
1346
convertToD3D11Texture2D(InputArray src,ID3D11Texture2D * pD3D11Texture2D)1347 void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
1348 {
1349 CV_UNUSED(src); CV_UNUSED(pD3D11Texture2D);
1350 #if !defined(HAVE_DIRECTX)
1351 NO_DIRECTX_SUPPORT_ERROR;
1352 #elif !defined(HAVE_OPENCL)
1353 NO_OPENCL_SUPPORT_ERROR;
1354 #else
1355
1356 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
1357 #ifdef HAVE_OPENCL_D3D11_NV
1358 OpenCL_D3D11_NV* impl_nv = ctx.getUserContext<OpenCL_D3D11_NV>().get();
1359 if (impl_nv) {
1360 __convertToD3D11Texture2DNV(src,pD3D11Texture2D);
1361 return;
1362 }
1363 #endif
1364 OpenCL_D3D11* impl = ctx.getUserContext<OpenCL_D3D11>().get();
1365 if (impl) {
1366 __convertToD3D11Texture2DKHR(src, pD3D11Texture2D);
1367 }
1368 else {
1369 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
1370 }
1371 #endif
1372 }
1373
convertFromD3D11Texture2D(ID3D11Texture2D * pD3D11Texture2D,OutputArray dst)1374 void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
1375 {
1376 CV_UNUSED(pD3D11Texture2D); CV_UNUSED(dst);
1377 #if !defined(HAVE_DIRECTX)
1378 NO_DIRECTX_SUPPORT_ERROR;
1379 #elif !defined(HAVE_OPENCL)
1380 NO_OPENCL_SUPPORT_ERROR;
1381 #else
1382
1383 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
1384 #ifdef HAVE_OPENCL_D3D11_NV
1385 OpenCL_D3D11_NV* impl_nv = ctx.getUserContext<OpenCL_D3D11_NV>().get();
1386 if (impl_nv) {
1387 __convertFromD3D11Texture2DNV(pD3D11Texture2D,dst);
1388 }
1389 #endif
1390 OpenCL_D3D11* impl = ctx.getUserContext<OpenCL_D3D11>().get();
1391 if (impl) {
1392 __convertFromD3D11Texture2DKHR(pD3D11Texture2D, dst);
1393 }
1394 else {
1395 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
1396 }
1397 #endif
1398 }
1399
convertToD3D10Texture2D(InputArray src,ID3D10Texture2D * pD3D10Texture2D)1400 void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D)
1401 {
1402 CV_UNUSED(src); CV_UNUSED(pD3D10Texture2D);
1403 #if !defined(HAVE_DIRECTX)
1404 NO_DIRECTX_SUPPORT_ERROR;
1405 #elif defined(HAVE_OPENCL)
1406
1407 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
1408 OpenCL_D3D10* impl = ctx.getUserContext<OpenCL_D3D10>().get();
1409 if (nullptr == impl)
1410 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
1411
1412 D3D10_TEXTURE2D_DESC desc = { 0 };
1413 pD3D10Texture2D->GetDesc(&desc);
1414
1415 int srcType = src.type();
1416 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1417 CV_Assert(textureType == srcType);
1418
1419 Size srcSize = src.size();
1420 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
1421
1422 cl_context context = (cl_context)ctx.ptr();
1423
1424 UMat u = src.getUMat();
1425
1426 // TODO Add support for roi
1427 CV_Assert(u.offset == 0);
1428 CV_Assert(u.isContinuous());
1429
1430 cl_int status = 0;
1431 cl_mem clImage = impl->clCreateFromD3D10Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D10Texture2D, 0, &status);
1432 if (status != CL_SUCCESS)
1433 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
1434
1435 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1436
1437 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1438 status = impl->clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1439 if (status != CL_SUCCESS)
1440 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
1441 size_t offset = 0; // TODO
1442 size_t dst_origin[3] = {0, 0, 0};
1443 size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1};
1444 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
1445 if (status != CL_SUCCESS)
1446 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
1447 status = impl->clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1448 if (status != CL_SUCCESS)
1449 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
1450
1451 status = clFinish(q); // TODO Use events
1452 if (status != CL_SUCCESS)
1453 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1454
1455 status = clReleaseMemObject(clImage); // TODO RAII
1456 if (status != CL_SUCCESS)
1457 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1458 #else
1459 // TODO memcpy
1460 NO_OPENCL_SUPPORT_ERROR;
1461 #endif
1462 }
1463
convertFromD3D10Texture2D(ID3D10Texture2D * pD3D10Texture2D,OutputArray dst)1464 void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst)
1465 {
1466 CV_UNUSED(pD3D10Texture2D); CV_UNUSED(dst);
1467 #if !defined(HAVE_DIRECTX)
1468 NO_DIRECTX_SUPPORT_ERROR;
1469 #elif defined(HAVE_OPENCL)
1470 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
1471 OpenCL_D3D10* impl = ctx.getUserContext<OpenCL_D3D10>().get();
1472 if (nullptr == impl)
1473 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
1474
1475 D3D10_TEXTURE2D_DESC desc = { 0 };
1476 pD3D10Texture2D->GetDesc(&desc);
1477
1478 int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1479 CV_Assert(textureType >= 0);
1480
1481 cl_context context = (cl_context)ctx.ptr();
1482
1483 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
1484 dst.create(Size(desc.Width, desc.Height), textureType);
1485 UMat u = dst.getUMat();
1486
1487 // TODO Add support for roi
1488 CV_Assert(u.offset == 0);
1489 CV_Assert(u.isContinuous());
1490
1491 cl_int status = 0;
1492 cl_mem clImage = impl->clCreateFromD3D10Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D10Texture2D, 0, &status);
1493 if (status != CL_SUCCESS)
1494 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
1495
1496 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1497
1498 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1499 status = impl->clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1500 if (status != CL_SUCCESS)
1501 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
1502 size_t offset = 0; // TODO
1503 size_t src_origin[3] = {0, 0, 0};
1504 size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1};
1505 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
1506 if (status != CL_SUCCESS)
1507 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
1508 status = impl->clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1509 if (status != CL_SUCCESS)
1510 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
1511
1512 status = clFinish(q); // TODO Use events
1513 if (status != CL_SUCCESS)
1514 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1515
1516 status = clReleaseMemObject(clImage); // TODO RAII
1517 if (status != CL_SUCCESS)
1518 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1519 #else
1520 // TODO memcpy
1521 NO_OPENCL_SUPPORT_ERROR;
1522 #endif
1523 }
1524
convertToDirect3DSurface9(InputArray src,IDirect3DSurface9 * pDirect3DSurface9,void * surfaceSharedHandle)1525 void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle)
1526 {
1527 CV_UNUSED(src); CV_UNUSED(pDirect3DSurface9); CV_UNUSED(surfaceSharedHandle);
1528 #if !defined(HAVE_DIRECTX)
1529 NO_DIRECTX_SUPPORT_ERROR;
1530 #elif defined(HAVE_OPENCL)
1531
1532 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
1533 OpenCL_D3D9* impl = ctx.getUserContext<OpenCL_D3D9>().get();
1534 if (nullptr == impl)
1535 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
1536
1537 D3DSURFACE_DESC desc;
1538 if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1539 {
1540 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1541 }
1542
1543 int srcType = src.type();
1544 int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1545 CV_Assert(surfaceType == srcType);
1546
1547 Size srcSize = src.size();
1548 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
1549
1550 cl_context context = (cl_context)ctx.ptr();
1551
1552 UMat u = src.getUMat();
1553
1554 // TODO Add support for roi
1555 CV_Assert(u.offset == 0);
1556 CV_Assert(u.isContinuous());
1557
1558 cl_int status = 0;
1559 cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
1560 cl_mem clImage = impl->clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_WRITE_ONLY,
1561 impl->deviceEx ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
1562 &surfaceInfo, 0, &status);
1563 if (status != CL_SUCCESS)
1564 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
1565
1566 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1567
1568 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1569 status = impl->clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1570 if (status != CL_SUCCESS)
1571 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
1572 size_t offset = 0; // TODO
1573 size_t dst_origin[3] = {0, 0, 0};
1574 size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1};
1575 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
1576 if (status != CL_SUCCESS)
1577 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
1578 status = impl->clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1579 if (status != CL_SUCCESS)
1580 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
1581
1582 status = clFinish(q); // TODO Use events
1583 if (status != CL_SUCCESS)
1584 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1585
1586 status = clReleaseMemObject(clImage); // TODO RAII
1587 if (status != CL_SUCCESS)
1588 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1589 #else
1590 // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1591 NO_OPENCL_SUPPORT_ERROR;
1592 #endif
1593 }
1594
convertFromDirect3DSurface9(IDirect3DSurface9 * pDirect3DSurface9,OutputArray dst,void * surfaceSharedHandle)1595 void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle)
1596 {
1597 CV_UNUSED(pDirect3DSurface9); CV_UNUSED(dst); CV_UNUSED(surfaceSharedHandle);
1598 #if !defined(HAVE_DIRECTX)
1599 NO_DIRECTX_SUPPORT_ERROR;
1600 #elif defined(HAVE_OPENCL)
1601
1602 ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
1603 OpenCL_D3D9* impl = ctx.getUserContext<OpenCL_D3D9>().get();
1604 if (nullptr == impl)
1605 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
1606
1607 D3DSURFACE_DESC desc;
1608 if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1609 {
1610 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1611 }
1612
1613 int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1614 CV_Assert(surfaceType >= 0);
1615
1616 cl_context context = (cl_context)ctx.ptr();
1617
1618 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
1619 dst.create(Size(desc.Width, desc.Height), surfaceType);
1620 UMat u = dst.getUMat();
1621
1622 // TODO Add support for roi
1623 CV_Assert(u.offset == 0);
1624 CV_Assert(u.isContinuous());
1625
1626 cl_int status = 0;
1627 cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
1628 cl_mem clImage = impl->clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_READ_ONLY,
1629 impl->deviceEx ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
1630 &surfaceInfo, 0, &status);
1631 if (status != CL_SUCCESS)
1632 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
1633
1634 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_WRITE);
1635
1636 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1637 status = impl->clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1638 if (status != CL_SUCCESS)
1639 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
1640 size_t offset = 0; // TODO
1641 size_t src_origin[3] = {0, 0, 0};
1642 size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1};
1643 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
1644 if (status != CL_SUCCESS)
1645 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
1646 status = impl->clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1647 if (status != CL_SUCCESS)
1648 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
1649
1650 status = clFinish(q); // TODO Use events
1651 if (status != CL_SUCCESS)
1652 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1653
1654 status = clReleaseMemObject(clImage); // TODO RAII
1655 if (status != CL_SUCCESS)
1656 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1657 #else
1658 // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1659 NO_OPENCL_SUPPORT_ERROR;
1660 #endif
1661 }
1662
1663 } } // namespace cv::directx
1664