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