Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/core/src/directx.cpp
16337 views
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
namespace cv { namespace directx {
61
62
int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
63
{
64
CV_UNUSED(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
CV_UNUSED(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
CV_UNUSED(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
CV_UNUSED(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
CV_UNUSED(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
CV_UNUSED(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
CV_UNUSED(src); CV_UNUSED(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
#ifdef HAVE_DIRECTX_NV12
798
cl_mem clImageUV = 0;
799
#endif
800
801
clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
802
if (status != CL_SUCCESS)
803
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
804
805
#ifdef HAVE_DIRECTX_NV12
806
if(DXGI_FORMAT_NV12 == desc.Format)
807
{
808
clImageUV = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
809
if (status != CL_SUCCESS)
810
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
811
}
812
#endif
813
814
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
815
816
status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
817
if (status != CL_SUCCESS)
818
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
819
820
#ifdef HAVE_DIRECTX_NV12
821
if(DXGI_FORMAT_NV12 == desc.Format)
822
{
823
status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
824
if (status != CL_SUCCESS)
825
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
826
827
if(!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV))
828
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed");
829
830
status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
831
if (status != CL_SUCCESS)
832
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
833
}
834
else
835
#endif
836
{
837
size_t offset = 0; // TODO
838
size_t origin[3] = { 0, 0, 0 };
839
size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
840
841
status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, origin, region, 0, NULL, NULL);
842
if (status != CL_SUCCESS)
843
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
844
}
845
846
status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
847
if (status != CL_SUCCESS)
848
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
849
850
status = clFinish(q); // TODO Use events
851
if (status != CL_SUCCESS)
852
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
853
854
status = clReleaseMemObject(clImage); // TODO RAII
855
if (status != CL_SUCCESS)
856
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
857
858
#ifdef HAVE_DIRECTX_NV12
859
if(DXGI_FORMAT_NV12 == desc.Format)
860
{
861
status = clReleaseMemObject(clImageUV);
862
if (status != CL_SUCCESS)
863
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
864
}
865
#endif
866
867
#else
868
// TODO memcpy
869
NO_OPENCL_SUPPORT_ERROR;
870
#endif
871
}
872
873
874
void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
875
{
876
CV_UNUSED(pD3D11Texture2D); CV_UNUSED(dst);
877
#if !defined(HAVE_DIRECTX)
878
NO_DIRECTX_SUPPORT_ERROR;
879
#elif defined(HAVE_OPENCL)
880
__OpenCLinitializeD3D11();
881
882
D3D11_TEXTURE2D_DESC desc = { 0 };
883
pD3D11Texture2D->GetDesc(&desc);
884
885
int textureType = getTypeFromDXGI_FORMAT(desc.Format);
886
CV_Assert(textureType >= 0);
887
888
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
889
dst.create(Size(desc.Width, desc.Height), textureType);
890
UMat u = dst.getUMat();
891
892
// TODO Add support for roi
893
CV_Assert(u.offset == 0);
894
CV_Assert(u.isContinuous());
895
896
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
897
898
using namespace cv::ocl;
899
Context& ctx = Context::getDefault();
900
cl_context context = (cl_context)ctx.ptr();
901
902
cl_int status = 0;
903
cl_mem clImage = 0;
904
905
clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
906
if (status != CL_SUCCESS)
907
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
908
909
#ifdef HAVE_DIRECTX_NV12
910
cl_mem clImageUV = 0;
911
if(DXGI_FORMAT_NV12 == desc.Format)
912
{
913
clImageUV = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
914
if (status != CL_SUCCESS)
915
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
916
}
917
#endif
918
919
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
920
921
status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
922
if (status != CL_SUCCESS)
923
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
924
925
#ifdef HAVE_DIRECTX_NV12
926
if(DXGI_FORMAT_NV12 == desc.Format)
927
{
928
status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
929
if (status != CL_SUCCESS)
930
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
931
932
if(!ocl::ocl_convert_nv12_to_bgr(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows))
933
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed");
934
935
status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
936
if (status != CL_SUCCESS)
937
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
938
}
939
else
940
#endif
941
{
942
size_t offset = 0; // TODO
943
size_t origin[3] = { 0, 0, 0 };
944
size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
945
946
status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, origin, region, offset, 0, NULL, NULL);
947
if (status != CL_SUCCESS)
948
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
949
}
950
951
status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
952
if (status != CL_SUCCESS)
953
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
954
955
status = clFinish(q); // TODO Use events
956
if (status != CL_SUCCESS)
957
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
958
959
status = clReleaseMemObject(clImage); // TODO RAII
960
if (status != CL_SUCCESS)
961
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
962
963
#ifdef HAVE_DIRECTX_NV12
964
if(DXGI_FORMAT_NV12 == desc.Format)
965
{
966
status = clReleaseMemObject(clImageUV);
967
if (status != CL_SUCCESS)
968
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
969
}
970
#endif
971
972
#else
973
// TODO memcpy
974
NO_OPENCL_SUPPORT_ERROR;
975
#endif
976
}
977
978
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
979
clCreateFromD3D10Texture2DKHR_fn clCreateFromD3D10Texture2DKHR = NULL;
980
clEnqueueAcquireD3D10ObjectsKHR_fn clEnqueueAcquireD3D10ObjectsKHR = NULL;
981
clEnqueueReleaseD3D10ObjectsKHR_fn clEnqueueReleaseD3D10ObjectsKHR = NULL;
982
983
static void __OpenCLinitializeD3D10()
984
{
985
using namespace cv::ocl;
986
static cl_platform_id initializedPlatform = NULL;
987
cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
988
if (initializedPlatform != platform)
989
{
990
clCreateFromD3D10Texture2DKHR = (clCreateFromD3D10Texture2DKHR_fn)
991
clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D10Texture2DKHR");
992
clEnqueueAcquireD3D10ObjectsKHR = (clEnqueueAcquireD3D10ObjectsKHR_fn)
993
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D10ObjectsKHR");
994
clEnqueueReleaseD3D10ObjectsKHR = (clEnqueueReleaseD3D10ObjectsKHR_fn)
995
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D10ObjectsKHR");
996
initializedPlatform = platform;
997
}
998
if (!clCreateFromD3D10Texture2DKHR || !clEnqueueAcquireD3D10ObjectsKHR || !clEnqueueReleaseD3D10ObjectsKHR)
999
{
1000
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D10");
1001
}
1002
}
1003
#endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
1004
1005
void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D)
1006
{
1007
CV_UNUSED(src); CV_UNUSED(pD3D10Texture2D);
1008
#if !defined(HAVE_DIRECTX)
1009
NO_DIRECTX_SUPPORT_ERROR;
1010
#elif defined(HAVE_OPENCL)
1011
__OpenCLinitializeD3D10();
1012
1013
D3D10_TEXTURE2D_DESC desc = { 0 };
1014
pD3D10Texture2D->GetDesc(&desc);
1015
1016
int srcType = src.type();
1017
int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1018
CV_Assert(textureType == srcType);
1019
1020
Size srcSize = src.size();
1021
CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
1022
1023
using namespace cv::ocl;
1024
Context& ctx = Context::getDefault();
1025
cl_context context = (cl_context)ctx.ptr();
1026
1027
UMat u = src.getUMat();
1028
1029
// TODO Add support for roi
1030
CV_Assert(u.offset == 0);
1031
CV_Assert(u.isContinuous());
1032
1033
cl_int status = 0;
1034
cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D10Texture2D, 0, &status);
1035
if (status != CL_SUCCESS)
1036
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
1037
1038
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1039
1040
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1041
status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1042
if (status != CL_SUCCESS)
1043
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
1044
size_t offset = 0; // TODO
1045
size_t dst_origin[3] = {0, 0, 0};
1046
size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1};
1047
status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
1048
if (status != CL_SUCCESS)
1049
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
1050
status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1051
if (status != CL_SUCCESS)
1052
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
1053
1054
status = clFinish(q); // TODO Use events
1055
if (status != CL_SUCCESS)
1056
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1057
1058
status = clReleaseMemObject(clImage); // TODO RAII
1059
if (status != CL_SUCCESS)
1060
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1061
#else
1062
// TODO memcpy
1063
NO_OPENCL_SUPPORT_ERROR;
1064
#endif
1065
}
1066
void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst)
1067
{
1068
CV_UNUSED(pD3D10Texture2D); CV_UNUSED(dst);
1069
#if !defined(HAVE_DIRECTX)
1070
NO_DIRECTX_SUPPORT_ERROR;
1071
#elif defined(HAVE_OPENCL)
1072
__OpenCLinitializeD3D10();
1073
1074
D3D10_TEXTURE2D_DESC desc = { 0 };
1075
pD3D10Texture2D->GetDesc(&desc);
1076
1077
int textureType = getTypeFromDXGI_FORMAT(desc.Format);
1078
CV_Assert(textureType >= 0);
1079
1080
using namespace cv::ocl;
1081
Context& ctx = Context::getDefault();
1082
cl_context context = (cl_context)ctx.ptr();
1083
1084
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
1085
dst.create(Size(desc.Width, desc.Height), textureType);
1086
UMat u = dst.getUMat();
1087
1088
// TODO Add support for roi
1089
CV_Assert(u.offset == 0);
1090
CV_Assert(u.isContinuous());
1091
1092
cl_int status = 0;
1093
cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D10Texture2D, 0, &status);
1094
if (status != CL_SUCCESS)
1095
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
1096
1097
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1098
1099
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1100
status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1101
if (status != CL_SUCCESS)
1102
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
1103
size_t offset = 0; // TODO
1104
size_t src_origin[3] = {0, 0, 0};
1105
size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1};
1106
status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
1107
if (status != CL_SUCCESS)
1108
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
1109
status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
1110
if (status != CL_SUCCESS)
1111
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
1112
1113
status = clFinish(q); // TODO Use events
1114
if (status != CL_SUCCESS)
1115
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1116
1117
status = clReleaseMemObject(clImage); // TODO RAII
1118
if (status != CL_SUCCESS)
1119
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1120
#else
1121
// TODO memcpy
1122
NO_OPENCL_SUPPORT_ERROR;
1123
#endif
1124
}
1125
1126
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
1127
clCreateFromDX9MediaSurfaceKHR_fn clCreateFromDX9MediaSurfaceKHR = NULL;
1128
clEnqueueAcquireDX9MediaSurfacesKHR_fn clEnqueueAcquireDX9MediaSurfacesKHR = NULL;
1129
clEnqueueReleaseDX9MediaSurfacesKHR_fn clEnqueueReleaseDX9MediaSurfacesKHR = NULL;
1130
1131
static void __OpenCLinitializeD3D9()
1132
{
1133
using namespace cv::ocl;
1134
static cl_platform_id initializedPlatform = NULL;
1135
cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
1136
if (initializedPlatform != platform)
1137
{
1138
clCreateFromDX9MediaSurfaceKHR = (clCreateFromDX9MediaSurfaceKHR_fn)
1139
clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromDX9MediaSurfaceKHR");
1140
clEnqueueAcquireDX9MediaSurfacesKHR = (clEnqueueAcquireDX9MediaSurfacesKHR_fn)
1141
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireDX9MediaSurfacesKHR");
1142
clEnqueueReleaseDX9MediaSurfacesKHR = (clEnqueueReleaseDX9MediaSurfacesKHR_fn)
1143
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseDX9MediaSurfacesKHR");
1144
initializedPlatform = platform;
1145
}
1146
if (!clCreateFromDX9MediaSurfaceKHR || !clEnqueueAcquireDX9MediaSurfacesKHR || !clEnqueueReleaseDX9MediaSurfacesKHR)
1147
{
1148
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D9");
1149
}
1150
}
1151
#endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
1152
1153
void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle)
1154
{
1155
CV_UNUSED(src); CV_UNUSED(pDirect3DSurface9); CV_UNUSED(surfaceSharedHandle);
1156
#if !defined(HAVE_DIRECTX)
1157
NO_DIRECTX_SUPPORT_ERROR;
1158
#elif defined(HAVE_OPENCL)
1159
__OpenCLinitializeD3D9();
1160
1161
D3DSURFACE_DESC desc;
1162
if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1163
{
1164
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1165
}
1166
1167
int srcType = src.type();
1168
int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1169
CV_Assert(surfaceType == srcType);
1170
1171
Size srcSize = src.size();
1172
CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
1173
1174
using namespace cv::ocl;
1175
Context& ctx = Context::getDefault();
1176
cl_context context = (cl_context)ctx.ptr();
1177
1178
UMat u = src.getUMat();
1179
1180
// TODO Add support for roi
1181
CV_Assert(u.offset == 0);
1182
CV_Assert(u.isContinuous());
1183
1184
cl_int status = 0;
1185
cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
1186
cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_WRITE_ONLY,
1187
ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
1188
&surfaceInfo, 0, &status);
1189
if (status != CL_SUCCESS)
1190
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
1191
1192
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
1193
1194
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1195
status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1196
if (status != CL_SUCCESS)
1197
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
1198
size_t offset = 0; // TODO
1199
size_t dst_origin[3] = {0, 0, 0};
1200
size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1};
1201
status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
1202
if (status != CL_SUCCESS)
1203
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
1204
status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1205
if (status != CL_SUCCESS)
1206
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
1207
1208
status = clFinish(q); // TODO Use events
1209
if (status != CL_SUCCESS)
1210
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1211
1212
status = clReleaseMemObject(clImage); // TODO RAII
1213
if (status != CL_SUCCESS)
1214
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1215
#else
1216
// TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1217
NO_OPENCL_SUPPORT_ERROR;
1218
#endif
1219
}
1220
1221
void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle)
1222
{
1223
CV_UNUSED(pDirect3DSurface9); CV_UNUSED(dst); CV_UNUSED(surfaceSharedHandle);
1224
#if !defined(HAVE_DIRECTX)
1225
NO_DIRECTX_SUPPORT_ERROR;
1226
#elif defined(HAVE_OPENCL)
1227
__OpenCLinitializeD3D9();
1228
1229
D3DSURFACE_DESC desc;
1230
if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
1231
{
1232
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
1233
}
1234
1235
int surfaceType = getTypeFromD3DFORMAT(desc.Format);
1236
CV_Assert(surfaceType >= 0);
1237
1238
using namespace cv::ocl;
1239
Context& ctx = Context::getDefault();
1240
cl_context context = (cl_context)ctx.ptr();
1241
1242
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
1243
dst.create(Size(desc.Width, desc.Height), surfaceType);
1244
UMat u = dst.getUMat();
1245
1246
// TODO Add support for roi
1247
CV_Assert(u.offset == 0);
1248
CV_Assert(u.isContinuous());
1249
1250
cl_int status = 0;
1251
cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
1252
cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_READ_ONLY,
1253
ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
1254
&surfaceInfo, 0, &status);
1255
if (status != CL_SUCCESS)
1256
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
1257
1258
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_WRITE);
1259
1260
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
1261
status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1262
if (status != CL_SUCCESS)
1263
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
1264
size_t offset = 0; // TODO
1265
size_t src_origin[3] = {0, 0, 0};
1266
size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1};
1267
status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
1268
if (status != CL_SUCCESS)
1269
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
1270
status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
1271
if (status != CL_SUCCESS)
1272
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
1273
1274
status = clFinish(q); // TODO Use events
1275
if (status != CL_SUCCESS)
1276
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
1277
1278
status = clReleaseMemObject(clImage); // TODO RAII
1279
if (status != CL_SUCCESS)
1280
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
1281
#else
1282
// TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
1283
NO_OPENCL_SUPPORT_ERROR;
1284
#endif
1285
}
1286
1287
} } // namespace cv::directx
1288
1289