Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of gr-peach-opencv-project-sd-card by
directx.cpp
00001 /*M/////////////////////////////////////////////////////////////////////////////////////// 00002 // 00003 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 00004 // 00005 // By downloading, copying, installing or using the software you agree to this license. 00006 // If you do not agree to this license, do not download, install, 00007 // copy or use the software. 00008 // 00009 // 00010 // License Agreement 00011 // For Open Source Computer Vision Library 00012 // 00013 // Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. 00014 // Third party copyrights are property of their respective owners. 00015 // 00016 // Redistribution and use in source and binary forms, with or without modification, 00017 // are permitted provided that the following conditions are met: 00018 // 00019 // * Redistribution's of source code must retain the above copyright notice, 00020 // this list of conditions and the following disclaimer. 00021 // 00022 // * Redistribution's in binary form must reproduce the above copyright notice, 00023 // this list of conditions and the following disclaimer in the documentation 00024 // and/or other materials provided with the distribution. 00025 // 00026 // * The name of the copyright holders may not be used to endorse or promote products 00027 // derived from this software without specific prior written permission. 00028 // 00029 // This software is provided by the copyright holders and contributors as is and 00030 // any express or implied warranties, including, but not limited to, the implied 00031 // warranties of merchantability and fitness for a particular purpose are disclaimed. 00032 // In no event shall the copyright holders or contributors be liable for any direct, 00033 // indirect, incidental, special, exemplary, or consequential damages 00034 // (including, but not limited to, procurement of substitute goods or services; 00035 // loss of use, data, or profits; or business interruption) however caused 00036 // and on any theory of liability, whether in contract, strict liability, 00037 // or tort (including negligence or otherwise) arising in any way out of 00038 // the use of this software, even if advised of the possibility of such damage. 00039 // 00040 //M*/ 00041 00042 #include "precomp.hpp" 00043 00044 #include "opencv2/core.hpp" 00045 #include "opencv2/core/ocl.hpp" 00046 #include "opencv2/core/directx.hpp" 00047 #include "opencl_kernels_core.hpp" 00048 00049 #ifdef HAVE_DIRECTX 00050 #include <vector> 00051 # include "directx.inc.hpp" 00052 #else // HAVE_DIRECTX 00053 #define NO_DIRECTX_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without DirectX support") 00054 #endif 00055 00056 #ifndef HAVE_OPENCL 00057 # define NO_OPENCL_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support") 00058 #endif // HAVE_OPENCL 00059 00060 namespace cv { namespace directx { 00061 00062 int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT) 00063 { 00064 (void)iDXGI_FORMAT; 00065 #if !defined(HAVE_DIRECTX) 00066 NO_DIRECTX_SUPPORT_ERROR; 00067 #else 00068 const int errorType = -1; 00069 switch ((enum DXGI_FORMAT)iDXGI_FORMAT) 00070 { 00071 //case DXGI_FORMAT_UNKNOWN: 00072 //case DXGI_FORMAT_R32G32B32A32_TYPELESS: 00073 case DXGI_FORMAT_R32G32B32A32_FLOAT: return CV_32FC4; 00074 case DXGI_FORMAT_R32G32B32A32_UINT: 00075 case DXGI_FORMAT_R32G32B32A32_SINT: return CV_32SC4; 00076 //case DXGI_FORMAT_R32G32B32_TYPELESS: 00077 case DXGI_FORMAT_R32G32B32_FLOAT: return CV_32FC3; 00078 case DXGI_FORMAT_R32G32B32_UINT: 00079 case DXGI_FORMAT_R32G32B32_SINT: return CV_32SC3; 00080 //case DXGI_FORMAT_R16G16B16A16_TYPELESS: 00081 //case DXGI_FORMAT_R16G16B16A16_FLOAT: 00082 case DXGI_FORMAT_R16G16B16A16_UNORM: 00083 case DXGI_FORMAT_R16G16B16A16_UINT: return CV_16UC4; 00084 case DXGI_FORMAT_R16G16B16A16_SNORM: 00085 case DXGI_FORMAT_R16G16B16A16_SINT: return CV_16SC4; 00086 //case DXGI_FORMAT_R32G32_TYPELESS: 00087 //case DXGI_FORMAT_R32G32_FLOAT: 00088 //case DXGI_FORMAT_R32G32_UINT: 00089 //case DXGI_FORMAT_R32G32_SINT: 00090 //case DXGI_FORMAT_R32G8X24_TYPELESS: 00091 //case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: 00092 //case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: 00093 //case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: 00094 //case DXGI_FORMAT_R10G10B10A2_TYPELESS: 00095 //case DXGI_FORMAT_R10G10B10A2_UNORM: 00096 //case DXGI_FORMAT_R10G10B10A2_UINT: 00097 //case DXGI_FORMAT_R11G11B10_FLOAT: 00098 //case DXGI_FORMAT_R8G8B8A8_TYPELESS: 00099 case DXGI_FORMAT_R8G8B8A8_UNORM: 00100 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: 00101 case DXGI_FORMAT_R8G8B8A8_UINT: return CV_8UC4; 00102 case DXGI_FORMAT_R8G8B8A8_SNORM: 00103 case DXGI_FORMAT_R8G8B8A8_SINT: return CV_8SC4; 00104 //case DXGI_FORMAT_R16G16_TYPELESS: 00105 //case DXGI_FORMAT_R16G16_FLOAT: 00106 case DXGI_FORMAT_R16G16_UNORM: 00107 case DXGI_FORMAT_R16G16_UINT: return CV_16UC2; 00108 case DXGI_FORMAT_R16G16_SNORM: 00109 case DXGI_FORMAT_R16G16_SINT: return CV_16SC2; 00110 //case DXGI_FORMAT_R32_TYPELESS: 00111 //case DXGI_FORMAT_D32_FLOAT: 00112 case DXGI_FORMAT_R32_FLOAT: return CV_32FC1; 00113 case DXGI_FORMAT_R32_UINT: 00114 case DXGI_FORMAT_R32_SINT: return CV_32SC1; 00115 //case DXGI_FORMAT_R24G8_TYPELESS: 00116 //case DXGI_FORMAT_D24_UNORM_S8_UINT: 00117 //case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: 00118 //case DXGI_FORMAT_X24_TYPELESS_G8_UINT: 00119 //case DXGI_FORMAT_R8G8_TYPELESS: 00120 case DXGI_FORMAT_R8G8_UNORM: 00121 case DXGI_FORMAT_R8G8_UINT: return CV_8UC2; 00122 case DXGI_FORMAT_R8G8_SNORM: 00123 case DXGI_FORMAT_R8G8_SINT: return CV_8SC2; 00124 //case DXGI_FORMAT_R16_TYPELESS: 00125 //case DXGI_FORMAT_R16_FLOAT: 00126 case DXGI_FORMAT_D16_UNORM: 00127 case DXGI_FORMAT_R16_UNORM: 00128 case DXGI_FORMAT_R16_UINT: return CV_16UC1; 00129 case DXGI_FORMAT_R16_SNORM: 00130 case DXGI_FORMAT_R16_SINT: return CV_16SC1; 00131 //case DXGI_FORMAT_R8_TYPELESS: 00132 case DXGI_FORMAT_R8_UNORM: 00133 case DXGI_FORMAT_R8_UINT: return CV_8UC1; 00134 case DXGI_FORMAT_R8_SNORM: 00135 case DXGI_FORMAT_R8_SINT: return CV_8SC1; 00136 case DXGI_FORMAT_A8_UNORM: return CV_8UC1; 00137 //case DXGI_FORMAT_R1_UNORM: 00138 //case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: 00139 //case DXGI_FORMAT_R8G8_B8G8_UNORM: 00140 //case DXGI_FORMAT_G8R8_G8B8_UNORM: 00141 //case DXGI_FORMAT_BC1_TYPELESS: 00142 //case DXGI_FORMAT_BC1_UNORM: 00143 //case DXGI_FORMAT_BC1_UNORM_SRGB: 00144 //case DXGI_FORMAT_BC2_TYPELESS: 00145 //case DXGI_FORMAT_BC2_UNORM: 00146 //case DXGI_FORMAT_BC2_UNORM_SRGB: 00147 //case DXGI_FORMAT_BC3_TYPELESS: 00148 //case DXGI_FORMAT_BC3_UNORM: 00149 //case DXGI_FORMAT_BC3_UNORM_SRGB: 00150 //case DXGI_FORMAT_BC4_TYPELESS: 00151 //case DXGI_FORMAT_BC4_UNORM: 00152 //case DXGI_FORMAT_BC4_SNORM: 00153 //case DXGI_FORMAT_BC5_TYPELESS: 00154 //case DXGI_FORMAT_BC5_UNORM: 00155 //case DXGI_FORMAT_BC5_SNORM: 00156 //case DXGI_FORMAT_B5G6R5_UNORM: 00157 //case DXGI_FORMAT_B5G5R5A1_UNORM: 00158 case DXGI_FORMAT_B8G8R8A8_UNORM: 00159 case DXGI_FORMAT_B8G8R8X8_UNORM: return CV_8UC4; 00160 //case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: 00161 //case DXGI_FORMAT_B8G8R8A8_TYPELESS: 00162 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return CV_8UC4; 00163 //case DXGI_FORMAT_B8G8R8X8_TYPELESS: 00164 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return CV_8UC4; 00165 //case DXGI_FORMAT_BC6H_TYPELESS: 00166 //case DXGI_FORMAT_BC6H_UF16: 00167 //case DXGI_FORMAT_BC6H_SF16: 00168 //case DXGI_FORMAT_BC7_TYPELESS: 00169 //case DXGI_FORMAT_BC7_UNORM: 00170 //case DXGI_FORMAT_BC7_UNORM_SRGB: 00171 #ifdef HAVE_DIRECTX_NV12 00172 case DXGI_FORMAT_NV12: return CV_8UC3; 00173 #endif 00174 default: break; 00175 } 00176 return errorType; 00177 #endif 00178 } 00179 00180 int getTypeFromD3DFORMAT(const int iD3DFORMAT) 00181 { 00182 (void)iD3DFORMAT; 00183 #if !defined(HAVE_DIRECTX) 00184 NO_DIRECTX_SUPPORT_ERROR; 00185 #else 00186 const int errorType = -1; 00187 switch ((enum _D3DFORMAT)iD3DFORMAT) 00188 { 00189 //case D3DFMT_UNKNOWN: 00190 case D3DFMT_R8G8B8: return CV_8UC3; 00191 case D3DFMT_A8R8G8B8: 00192 case D3DFMT_X8R8G8B8: return CV_8UC4; 00193 //case D3DFMT_R5G6B5: 00194 //case D3DFMT_X1R5G5B5: 00195 //case D3DFMT_A1R5G5B5: 00196 //case D3DFMT_A4R4G4B4: 00197 //case D3DFMT_R3G3B2: 00198 case D3DFMT_A8: return CV_8UC1; 00199 //case D3DFMT_A8R3G3B2: 00200 //case D3DFMT_X4R4G4B4: 00201 //case D3DFMT_A2B10G10R10: 00202 case D3DFMT_A8B8G8R8: 00203 case D3DFMT_X8B8G8R8: return CV_8UC4; 00204 //case D3DFMT_G16R16: 00205 //case D3DFMT_A2R10G10B10: 00206 //case D3DFMT_A16B16G16R16: 00207 00208 case D3DFMT_A8P8: return CV_8UC2; 00209 case D3DFMT_P8: return CV_8UC1; 00210 00211 case D3DFMT_L8: return CV_8UC1; 00212 case D3DFMT_A8L8: return CV_8UC2; 00213 //case D3DFMT_A4L4: 00214 00215 case D3DFMT_V8U8: return CV_8UC2; 00216 //case D3DFMT_L6V5U5: 00217 case D3DFMT_X8L8V8U8: 00218 case D3DFMT_Q8W8V8U8: return CV_8UC4; 00219 case D3DFMT_V16U16: return CV_16UC4; // TODO 16SC4 ? 00220 //case D3DFMT_A2W10V10U10: 00221 00222 case D3DFMT_D16_LOCKABLE: return CV_16UC1; 00223 case D3DFMT_D32: return CV_32SC1; 00224 //case D3DFMT_D15S1: 00225 //case D3DFMT_D24S8: 00226 //case D3DFMT_D24X8: 00227 //case D3DFMT_D24X4S4: 00228 case D3DFMT_D16: return CV_16UC1; 00229 00230 case D3DFMT_D32F_LOCKABLE: return CV_32FC1; 00231 default: break; 00232 } 00233 return errorType; 00234 #endif 00235 } 00236 00237 namespace ocl { 00238 00239 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL) 00240 static bool g_isDirect3DDevice9Ex = false; // Direct3DDevice9Ex or Direct3DDevice9 was used 00241 #endif 00242 00243 cv::ocl::Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device) 00244 { 00245 (void)pD3D11Device; 00246 #if !defined(HAVE_DIRECTX) 00247 NO_DIRECTX_SUPPORT_ERROR; 00248 #elif !defined(HAVE_OPENCL) 00249 NO_OPENCL_SUPPORT_ERROR; 00250 #else 00251 cl_uint numPlatforms; 00252 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); 00253 if (status != CL_SUCCESS) 00254 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms"); 00255 if (numPlatforms == 0) 00256 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms"); 00257 00258 std::vector<cl_platform_id> platforms(numPlatforms); 00259 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL); 00260 if (status != CL_SUCCESS) 00261 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms"); 00262 00263 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE 00264 00265 int found = -1; 00266 cl_device_id device = NULL; 00267 cl_uint numDevices = 0; 00268 cl_context context = NULL; 00269 00270 // try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR 00271 for (int i = 0; i < (int)numPlatforms; i++) 00272 { 00273 clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn) 00274 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR"); 00275 if (!clGetDeviceIDsFromD3D11KHR) 00276 continue; 00277 00278 device = NULL; 00279 numDevices = 0; 00280 status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device, 00281 CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices); 00282 if (status != CL_SUCCESS) 00283 continue; 00284 if (numDevices > 0) 00285 { 00286 cl_context_properties properties[] = { 00287 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 00288 CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device), 00289 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, 00290 NULL, NULL 00291 }; 00292 context = clCreateContext(properties, 1, &device, NULL, NULL, &status); 00293 if (status != CL_SUCCESS) 00294 { 00295 clReleaseDevice(device); 00296 } 00297 else 00298 { 00299 found = i; 00300 break; 00301 } 00302 } 00303 } 00304 if (found < 0) 00305 { 00306 // try with CL_ALL_DEVICES_FOR_D3D11_KHR 00307 for (int i = 0; i < (int)numPlatforms; i++) 00308 { 00309 clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn) 00310 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR"); 00311 if (!clGetDeviceIDsFromD3D11KHR) 00312 continue; 00313 00314 device = NULL; 00315 numDevices = 0; 00316 status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device, 00317 CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices); 00318 if (status != CL_SUCCESS) 00319 continue; 00320 if (numDevices > 0) 00321 { 00322 cl_context_properties properties[] = { 00323 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 00324 CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device), 00325 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, 00326 NULL, NULL 00327 }; 00328 context = clCreateContext(properties, 1, &device, NULL, NULL, &status); 00329 if (status != CL_SUCCESS) 00330 { 00331 clReleaseDevice(device); 00332 } 00333 else 00334 { 00335 found = i; 00336 break; 00337 } 00338 } 00339 } 00340 if (found < 0) 00341 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop"); 00342 } 00343 00344 00345 Context& ctx = Context::getDefault(false); 00346 initializeContextFromHandle(ctx, platforms[found], context, device); 00347 return ctx; 00348 #endif 00349 } 00350 00351 cv::ocl::Context& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device) 00352 { 00353 (void)pD3D10Device; 00354 #if !defined(HAVE_DIRECTX) 00355 NO_DIRECTX_SUPPORT_ERROR; 00356 #elif !defined(HAVE_OPENCL) 00357 NO_OPENCL_SUPPORT_ERROR; 00358 #else 00359 cl_uint numPlatforms; 00360 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); 00361 if (status != CL_SUCCESS) 00362 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms"); 00363 if (numPlatforms == 0) 00364 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms"); 00365 00366 std::vector<cl_platform_id> platforms(numPlatforms); 00367 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL); 00368 if (status != CL_SUCCESS) 00369 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms"); 00370 00371 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE 00372 00373 int found = -1; 00374 cl_device_id device = NULL; 00375 cl_uint numDevices = 0; 00376 cl_context context = NULL; 00377 00378 // try with CL_PREFERRED_DEVICES_FOR_D3D10_KHR 00379 for (int i = 0; i < (int)numPlatforms; i++) 00380 { 00381 clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn) 00382 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR"); 00383 if (!clGetDeviceIDsFromD3D10KHR) 00384 continue; 00385 00386 device = NULL; 00387 numDevices = 0; 00388 status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device, 00389 CL_PREFERRED_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices); 00390 if (status != CL_SUCCESS) 00391 continue; 00392 if (numDevices > 0) 00393 { 00394 cl_context_properties properties[] = { 00395 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 00396 CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device), 00397 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, 00398 NULL, NULL 00399 }; 00400 context = clCreateContext(properties, 1, &device, NULL, NULL, &status); 00401 if (status != CL_SUCCESS) 00402 { 00403 clReleaseDevice(device); 00404 } 00405 else 00406 { 00407 found = i; 00408 break; 00409 } 00410 } 00411 } 00412 if (found < 0) 00413 { 00414 // try with CL_ALL_DEVICES_FOR_D3D10_KHR 00415 for (int i = 0; i < (int)numPlatforms; i++) 00416 { 00417 clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn) 00418 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR"); 00419 if (!clGetDeviceIDsFromD3D10KHR) 00420 continue; 00421 00422 device = NULL; 00423 numDevices = 0; 00424 status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device, 00425 CL_ALL_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices); 00426 if (status != CL_SUCCESS) 00427 continue; 00428 if (numDevices > 0) 00429 { 00430 cl_context_properties properties[] = { 00431 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 00432 CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device), 00433 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, 00434 NULL, NULL 00435 }; 00436 context = clCreateContext(properties, 1, &device, NULL, NULL, &status); 00437 if (status != CL_SUCCESS) 00438 { 00439 clReleaseDevice(device); 00440 } 00441 else 00442 { 00443 found = i; 00444 break; 00445 } 00446 } 00447 } 00448 if (found < 0) 00449 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop"); 00450 } 00451 00452 00453 Context& ctx = Context::getDefault(false); 00454 initializeContextFromHandle(ctx, platforms[found], context, device); 00455 return ctx; 00456 #endif 00457 } 00458 00459 cv::ocl::Context& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex) 00460 { 00461 (void)pDirect3DDevice9Ex; 00462 #if !defined(HAVE_DIRECTX) 00463 NO_DIRECTX_SUPPORT_ERROR; 00464 #elif !defined(HAVE_OPENCL) 00465 NO_OPENCL_SUPPORT_ERROR; 00466 #else 00467 cl_uint numPlatforms; 00468 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); 00469 if (status != CL_SUCCESS) 00470 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms"); 00471 if (numPlatforms == 0) 00472 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms"); 00473 00474 std::vector<cl_platform_id> platforms(numPlatforms); 00475 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL); 00476 if (status != CL_SUCCESS) 00477 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms"); 00478 00479 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE 00480 00481 int found = -1; 00482 cl_device_id device = NULL; 00483 cl_uint numDevices = 0; 00484 cl_context context = NULL; 00485 00486 // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 00487 for (int i = 0; i < (int)numPlatforms; i++) 00488 { 00489 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn) 00490 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR"); 00491 if (!clGetDeviceIDsFromDX9MediaAdapterKHR) 00492 continue; 00493 00494 device = NULL; 00495 numDevices = 0; 00496 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR; 00497 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex, 00498 CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices); 00499 if (status != CL_SUCCESS) 00500 continue; 00501 if (numDevices > 0) 00502 { 00503 cl_context_properties properties[] = { 00504 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 00505 CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex), 00506 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, 00507 NULL, NULL 00508 }; 00509 context = clCreateContext(properties, 1, &device, NULL, NULL, &status); 00510 if (status != CL_SUCCESS) 00511 { 00512 clReleaseDevice(device); 00513 } 00514 else 00515 { 00516 found = i; 00517 break; 00518 } 00519 } 00520 } 00521 if (found < 0) 00522 { 00523 // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 00524 for (int i = 0; i < (int)numPlatforms; i++) 00525 { 00526 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn) 00527 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR"); 00528 if (!clGetDeviceIDsFromDX9MediaAdapterKHR) 00529 continue; 00530 00531 device = NULL; 00532 numDevices = 0; 00533 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR; 00534 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex, 00535 CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices); 00536 if (status != CL_SUCCESS) 00537 continue; 00538 if (numDevices > 0) 00539 { 00540 cl_context_properties properties[] = { 00541 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 00542 CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex), 00543 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, 00544 NULL, NULL 00545 }; 00546 context = clCreateContext(properties, 1, &device, NULL, NULL, &status); 00547 if (status != CL_SUCCESS) 00548 { 00549 clReleaseDevice(device); 00550 } 00551 else 00552 { 00553 found = i; 00554 break; 00555 } 00556 } 00557 } 00558 if (found < 0) 00559 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop"); 00560 } 00561 00562 Context& ctx = Context::getDefault(false); 00563 initializeContextFromHandle(ctx, platforms[found], context, device); 00564 g_isDirect3DDevice9Ex = true; 00565 return ctx; 00566 #endif 00567 } 00568 00569 cv::ocl::Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9) 00570 { 00571 (void)pDirect3DDevice9; 00572 #if !defined(HAVE_DIRECTX) 00573 NO_DIRECTX_SUPPORT_ERROR; 00574 #elif !defined(HAVE_OPENCL) 00575 NO_OPENCL_SUPPORT_ERROR; 00576 #else 00577 cl_uint numPlatforms; 00578 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); 00579 if (status != CL_SUCCESS) 00580 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms"); 00581 if (numPlatforms == 0) 00582 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms"); 00583 00584 std::vector<cl_platform_id> platforms(numPlatforms); 00585 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL); 00586 if (status != CL_SUCCESS) 00587 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms"); 00588 00589 // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE 00590 00591 int found = -1; 00592 cl_device_id device = NULL; 00593 cl_uint numDevices = 0; 00594 cl_context context = NULL; 00595 00596 // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 00597 for (int i = 0; i < (int)numPlatforms; i++) 00598 { 00599 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn) 00600 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR"); 00601 if (!clGetDeviceIDsFromDX9MediaAdapterKHR) 00602 continue; 00603 00604 device = NULL; 00605 numDevices = 0; 00606 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR; 00607 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9, 00608 CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices); 00609 if (status != CL_SUCCESS) 00610 continue; 00611 if (numDevices > 0) 00612 { 00613 cl_context_properties properties[] = { 00614 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 00615 CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9), 00616 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, 00617 NULL, NULL 00618 }; 00619 context = clCreateContext(properties, 1, &device, NULL, NULL, &status); 00620 if (status != CL_SUCCESS) 00621 { 00622 clReleaseDevice(device); 00623 } 00624 else 00625 { 00626 found = i; 00627 break; 00628 } 00629 } 00630 } 00631 if (found < 0) 00632 { 00633 // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 00634 for (int i = 0; i < (int)numPlatforms; i++) 00635 { 00636 clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn) 00637 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR"); 00638 if (!clGetDeviceIDsFromDX9MediaAdapterKHR) 00639 continue; 00640 00641 device = NULL; 00642 numDevices = 0; 00643 cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR; 00644 status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9, 00645 CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices); 00646 if (status != CL_SUCCESS) 00647 continue; 00648 if (numDevices > 0) 00649 { 00650 cl_context_properties properties[] = { 00651 CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i], 00652 CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9), 00653 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, 00654 NULL, NULL 00655 }; 00656 context = clCreateContext(properties, 1, &device, NULL, NULL, &status); 00657 if (status != CL_SUCCESS) 00658 { 00659 clReleaseDevice(device); 00660 } 00661 else 00662 { 00663 found = i; 00664 break; 00665 } 00666 } 00667 } 00668 if (found < 0) 00669 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop"); 00670 } 00671 00672 Context& ctx = Context::getDefault(false); 00673 initializeContextFromHandle(ctx, platforms[found], context, device); 00674 g_isDirect3DDevice9Ex = false; 00675 return ctx; 00676 #endif 00677 } 00678 00679 } // namespace cv::ocl 00680 00681 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL) 00682 clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL; 00683 clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL; 00684 clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL; 00685 00686 static void __OpenCLinitializeD3D11() 00687 { 00688 using namespace cv::ocl; 00689 static cl_platform_id initializedPlatform = NULL; 00690 cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr(); 00691 if (initializedPlatform != platform) 00692 { 00693 clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn) 00694 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR"); 00695 clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn) 00696 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR"); 00697 clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn) 00698 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR"); 00699 initializedPlatform = platform; 00700 } 00701 if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR) 00702 { 00703 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11"); 00704 } 00705 } 00706 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL) 00707 00708 } // namespace directx 00709 00710 00711 namespace ocl { 00712 00713 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL) 00714 #ifdef HAVE_DIRECTX_NV12 00715 00716 static 00717 bool ocl_convert_nv12_to_bgr( 00718 cl_mem clImageY, 00719 cl_mem clImageUV, 00720 cl_mem clBuffer, 00721 int step, 00722 int cols, 00723 int rows) 00724 { 00725 ocl::Kernel k; 00726 k.create("YUV2BGR_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, ""); 00727 if (k.empty()) 00728 return false; 00729 00730 k.args(clImageY, clImageUV, clBuffer, step, cols, rows); 00731 00732 size_t globalsize[] = { (size_t)cols, (size_t)rows }; 00733 return k.run(2, globalsize, 0, false); 00734 } 00735 00736 00737 static 00738 bool ocl_convert_bgr_to_nv12( 00739 cl_mem clBuffer, 00740 int step, 00741 int cols, 00742 int rows, 00743 cl_mem clImageY, 00744 cl_mem clImageUV) 00745 { 00746 ocl::Kernel k; 00747 k.create("BGR2YUV_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, ""); 00748 if (k.empty()) 00749 return false; 00750 00751 k.args(clBuffer, step, cols, rows, clImageY, clImageUV); 00752 00753 size_t globalsize[] = { (size_t)cols, (size_t)rows }; 00754 return k.run(2, globalsize, 0, false); 00755 } 00756 00757 #endif // HAVE_DIRECTX_NV12 00758 #endif // HAVE_DIRECTX && HAVE_OPENCL 00759 00760 } // namespace ocl 00761 00762 00763 namespace directx { 00764 00765 void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D) 00766 { 00767 (void)src; (void)pD3D11Texture2D; 00768 #if !defined(HAVE_DIRECTX) 00769 NO_DIRECTX_SUPPORT_ERROR; 00770 #elif defined(HAVE_OPENCL) 00771 __OpenCLinitializeD3D11(); 00772 00773 D3D11_TEXTURE2D_DESC desc = { 0 }; 00774 pD3D11Texture2D->GetDesc(&desc); 00775 00776 int srcType = src.type(); 00777 int textureType = getTypeFromDXGI_FORMAT(desc.Format); 00778 CV_Assert(textureType == srcType); 00779 00780 Size srcSize = src.size(); 00781 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height); 00782 00783 UMat u = src.getUMat(); 00784 00785 // TODO Add support for roi 00786 CV_Assert(u.offset == 0); 00787 CV_Assert(u.isContinuous()); 00788 00789 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ); 00790 00791 using namespace cv::ocl; 00792 Context& ctx = Context::getDefault(); 00793 cl_context context = (cl_context)ctx.ptr(); 00794 00795 cl_int status = 0; 00796 cl_mem clImage = 0; 00797 cl_mem clImageUV = 0; 00798 00799 clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status); 00800 if (status != CL_SUCCESS) 00801 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed"); 00802 00803 #ifdef HAVE_DIRECTX_NV12 00804 if(DXGI_FORMAT_NV12 == desc.Format) 00805 { 00806 clImageUV = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status); 00807 if (status != CL_SUCCESS) 00808 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed"); 00809 } 00810 #endif 00811 00812 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr(); 00813 00814 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL); 00815 if (status != CL_SUCCESS) 00816 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed"); 00817 00818 #ifdef HAVE_DIRECTX_NV12 00819 if(DXGI_FORMAT_NV12 == desc.Format) 00820 { 00821 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL); 00822 if (status != CL_SUCCESS) 00823 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed"); 00824 00825 if(!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV)) 00826 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed"); 00827 00828 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL); 00829 if (status != CL_SUCCESS) 00830 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed"); 00831 } 00832 else 00833 #endif 00834 { 00835 size_t offset = 0; // TODO 00836 size_t origin[3] = { 0, 0, 0 }; 00837 size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 }; 00838 00839 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, origin, region, 0, NULL, NULL); 00840 if (status != CL_SUCCESS) 00841 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed"); 00842 } 00843 00844 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL); 00845 if (status != CL_SUCCESS) 00846 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed"); 00847 00848 status = clFinish(q); // TODO Use events 00849 if (status != CL_SUCCESS) 00850 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed"); 00851 00852 status = clReleaseMemObject(clImage); // TODO RAII 00853 if (status != CL_SUCCESS) 00854 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed"); 00855 00856 #ifdef HAVE_DIRECTX_NV12 00857 if(DXGI_FORMAT_NV12 == desc.Format) 00858 { 00859 status = clReleaseMemObject(clImageUV); 00860 if (status != CL_SUCCESS) 00861 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed"); 00862 } 00863 #endif 00864 00865 #else 00866 // TODO memcpy 00867 NO_OPENCL_SUPPORT_ERROR; 00868 #endif 00869 } 00870 00871 00872 void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst) 00873 { 00874 (void)pD3D11Texture2D; (void)dst; 00875 #if !defined(HAVE_DIRECTX) 00876 NO_DIRECTX_SUPPORT_ERROR; 00877 #elif defined(HAVE_OPENCL) 00878 __OpenCLinitializeD3D11(); 00879 00880 D3D11_TEXTURE2D_DESC desc = { 0 }; 00881 pD3D11Texture2D->GetDesc(&desc); 00882 00883 int textureType = getTypeFromDXGI_FORMAT(desc.Format); 00884 CV_Assert(textureType >= 0); 00885 00886 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying! 00887 dst.create(Size(desc.Width, desc.Height), textureType); 00888 UMat u = dst.getUMat(); 00889 00890 // TODO Add support for roi 00891 CV_Assert(u.offset == 0); 00892 CV_Assert(u.isContinuous()); 00893 00894 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ); 00895 00896 using namespace cv::ocl; 00897 Context& ctx = Context::getDefault(); 00898 cl_context context = (cl_context)ctx.ptr(); 00899 00900 cl_int status = 0; 00901 cl_mem clImage = 0; 00902 00903 clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status); 00904 if (status != CL_SUCCESS) 00905 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed"); 00906 00907 #ifdef HAVE_DIRECTX_NV12 00908 cl_mem clImageUV = 0; 00909 if(DXGI_FORMAT_NV12 == desc.Format) 00910 { 00911 clImageUV = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status); 00912 if (status != CL_SUCCESS) 00913 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed"); 00914 } 00915 #endif 00916 00917 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr(); 00918 00919 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL); 00920 if (status != CL_SUCCESS) 00921 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed"); 00922 00923 #ifdef HAVE_DIRECTX_NV12 00924 if(DXGI_FORMAT_NV12 == desc.Format) 00925 { 00926 status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL); 00927 if (status != CL_SUCCESS) 00928 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed"); 00929 00930 if(!ocl::ocl_convert_nv12_to_bgr(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows)) 00931 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed"); 00932 00933 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL); 00934 if (status != CL_SUCCESS) 00935 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed"); 00936 } 00937 else 00938 #endif 00939 { 00940 size_t offset = 0; // TODO 00941 size_t origin[3] = { 0, 0, 0 }; 00942 size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 }; 00943 00944 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, origin, region, offset, 0, NULL, NULL); 00945 if (status != CL_SUCCESS) 00946 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed"); 00947 } 00948 00949 status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL); 00950 if (status != CL_SUCCESS) 00951 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed"); 00952 00953 status = clFinish(q); // TODO Use events 00954 if (status != CL_SUCCESS) 00955 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed"); 00956 00957 status = clReleaseMemObject(clImage); // TODO RAII 00958 if (status != CL_SUCCESS) 00959 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed"); 00960 00961 #ifdef HAVE_DIRECTX_NV12 00962 if(DXGI_FORMAT_NV12 == desc.Format) 00963 { 00964 status = clReleaseMemObject(clImageUV); 00965 if (status != CL_SUCCESS) 00966 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed"); 00967 } 00968 #endif 00969 00970 #else 00971 // TODO memcpy 00972 NO_OPENCL_SUPPORT_ERROR; 00973 #endif 00974 } 00975 00976 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL) 00977 clCreateFromD3D10Texture2DKHR_fn clCreateFromD3D10Texture2DKHR = NULL; 00978 clEnqueueAcquireD3D10ObjectsKHR_fn clEnqueueAcquireD3D10ObjectsKHR = NULL; 00979 clEnqueueReleaseD3D10ObjectsKHR_fn clEnqueueReleaseD3D10ObjectsKHR = NULL; 00980 00981 static void __OpenCLinitializeD3D10() 00982 { 00983 using namespace cv::ocl; 00984 static cl_platform_id initializedPlatform = NULL; 00985 cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr(); 00986 if (initializedPlatform != platform) 00987 { 00988 clCreateFromD3D10Texture2DKHR = (clCreateFromD3D10Texture2DKHR_fn) 00989 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D10Texture2DKHR"); 00990 clEnqueueAcquireD3D10ObjectsKHR = (clEnqueueAcquireD3D10ObjectsKHR_fn) 00991 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D10ObjectsKHR"); 00992 clEnqueueReleaseD3D10ObjectsKHR = (clEnqueueReleaseD3D10ObjectsKHR_fn) 00993 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D10ObjectsKHR"); 00994 initializedPlatform = platform; 00995 } 00996 if (!clCreateFromD3D10Texture2DKHR || !clEnqueueAcquireD3D10ObjectsKHR || !clEnqueueReleaseD3D10ObjectsKHR) 00997 { 00998 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D10"); 00999 } 01000 } 01001 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL) 01002 01003 void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D) 01004 { 01005 (void)src; (void)pD3D10Texture2D; 01006 #if !defined(HAVE_DIRECTX) 01007 NO_DIRECTX_SUPPORT_ERROR; 01008 #elif defined(HAVE_OPENCL) 01009 __OpenCLinitializeD3D10(); 01010 01011 D3D10_TEXTURE2D_DESC desc = { 0 }; 01012 pD3D10Texture2D->GetDesc(&desc); 01013 01014 int srcType = src.type(); 01015 int textureType = getTypeFromDXGI_FORMAT(desc.Format); 01016 CV_Assert(textureType == srcType); 01017 01018 Size srcSize = src.size(); 01019 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height); 01020 01021 using namespace cv::ocl; 01022 Context& ctx = Context::getDefault(); 01023 cl_context context = (cl_context)ctx.ptr(); 01024 01025 UMat u = src.getUMat(); 01026 01027 // TODO Add support for roi 01028 CV_Assert(u.offset == 0); 01029 CV_Assert(u.isContinuous()); 01030 01031 cl_int status = 0; 01032 cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D10Texture2D, 0, &status); 01033 if (status != CL_SUCCESS) 01034 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed"); 01035 01036 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ); 01037 01038 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr(); 01039 status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL); 01040 if (status != CL_SUCCESS) 01041 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed"); 01042 size_t offset = 0; // TODO 01043 size_t dst_origin[3] = {0, 0, 0}; 01044 size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1}; 01045 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL); 01046 if (status != CL_SUCCESS) 01047 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed"); 01048 status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL); 01049 if (status != CL_SUCCESS) 01050 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed"); 01051 01052 status = clFinish(q); // TODO Use events 01053 if (status != CL_SUCCESS) 01054 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed"); 01055 01056 status = clReleaseMemObject(clImage); // TODO RAII 01057 if (status != CL_SUCCESS) 01058 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed"); 01059 #else 01060 // TODO memcpy 01061 NO_OPENCL_SUPPORT_ERROR; 01062 #endif 01063 } 01064 void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst) 01065 { 01066 (void)pD3D10Texture2D; (void)dst; 01067 #if !defined(HAVE_DIRECTX) 01068 NO_DIRECTX_SUPPORT_ERROR; 01069 #elif defined(HAVE_OPENCL) 01070 __OpenCLinitializeD3D10(); 01071 01072 D3D10_TEXTURE2D_DESC desc = { 0 }; 01073 pD3D10Texture2D->GetDesc(&desc); 01074 01075 int textureType = getTypeFromDXGI_FORMAT(desc.Format); 01076 CV_Assert(textureType >= 0); 01077 01078 using namespace cv::ocl; 01079 Context& ctx = Context::getDefault(); 01080 cl_context context = (cl_context)ctx.ptr(); 01081 01082 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying! 01083 dst.create(Size(desc.Width, desc.Height), textureType); 01084 UMat u = dst.getUMat(); 01085 01086 // TODO Add support for roi 01087 CV_Assert(u.offset == 0); 01088 CV_Assert(u.isContinuous()); 01089 01090 cl_int status = 0; 01091 cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D10Texture2D, 0, &status); 01092 if (status != CL_SUCCESS) 01093 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed"); 01094 01095 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ); 01096 01097 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr(); 01098 status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL); 01099 if (status != CL_SUCCESS) 01100 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed"); 01101 size_t offset = 0; // TODO 01102 size_t src_origin[3] = {0, 0, 0}; 01103 size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1}; 01104 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL); 01105 if (status != CL_SUCCESS) 01106 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed"); 01107 status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL); 01108 if (status != CL_SUCCESS) 01109 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed"); 01110 01111 status = clFinish(q); // TODO Use events 01112 if (status != CL_SUCCESS) 01113 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed"); 01114 01115 status = clReleaseMemObject(clImage); // TODO RAII 01116 if (status != CL_SUCCESS) 01117 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed"); 01118 #else 01119 // TODO memcpy 01120 NO_OPENCL_SUPPORT_ERROR; 01121 #endif 01122 } 01123 01124 #if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL) 01125 clCreateFromDX9MediaSurfaceKHR_fn clCreateFromDX9MediaSurfaceKHR = NULL; 01126 clEnqueueAcquireDX9MediaSurfacesKHR_fn clEnqueueAcquireDX9MediaSurfacesKHR = NULL; 01127 clEnqueueReleaseDX9MediaSurfacesKHR_fn clEnqueueReleaseDX9MediaSurfacesKHR = NULL; 01128 01129 static void __OpenCLinitializeD3D9() 01130 { 01131 using namespace cv::ocl; 01132 static cl_platform_id initializedPlatform = NULL; 01133 cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr(); 01134 if (initializedPlatform != platform) 01135 { 01136 clCreateFromDX9MediaSurfaceKHR = (clCreateFromDX9MediaSurfaceKHR_fn) 01137 clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromDX9MediaSurfaceKHR"); 01138 clEnqueueAcquireDX9MediaSurfacesKHR = (clEnqueueAcquireDX9MediaSurfacesKHR_fn) 01139 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireDX9MediaSurfacesKHR"); 01140 clEnqueueReleaseDX9MediaSurfacesKHR = (clEnqueueReleaseDX9MediaSurfacesKHR_fn) 01141 clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseDX9MediaSurfacesKHR"); 01142 initializedPlatform = platform; 01143 } 01144 if (!clCreateFromDX9MediaSurfaceKHR || !clEnqueueAcquireDX9MediaSurfacesKHR || !clEnqueueReleaseDX9MediaSurfacesKHR) 01145 { 01146 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D9"); 01147 } 01148 } 01149 #endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL) 01150 01151 void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle) 01152 { 01153 (void)src; (void)pDirect3DSurface9; (void)surfaceSharedHandle; 01154 #if !defined(HAVE_DIRECTX) 01155 NO_DIRECTX_SUPPORT_ERROR; 01156 #elif defined(HAVE_OPENCL) 01157 __OpenCLinitializeD3D9(); 01158 01159 D3DSURFACE_DESC desc; 01160 if (FAILED(pDirect3DSurface9->GetDesc(&desc))) 01161 { 01162 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description"); 01163 } 01164 01165 int srcType = src.type(); 01166 int surfaceType = getTypeFromD3DFORMAT(desc.Format); 01167 CV_Assert(surfaceType == srcType); 01168 01169 Size srcSize = src.size(); 01170 CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height); 01171 01172 using namespace cv::ocl; 01173 Context& ctx = Context::getDefault(); 01174 cl_context context = (cl_context)ctx.ptr(); 01175 01176 UMat u = src.getUMat(); 01177 01178 // TODO Add support for roi 01179 CV_Assert(u.offset == 0); 01180 CV_Assert(u.isContinuous()); 01181 01182 cl_int status = 0; 01183 cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle}; 01184 cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_WRITE_ONLY, 01185 ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR, 01186 &surfaceInfo, 0, &status); 01187 if (status != CL_SUCCESS) 01188 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed"); 01189 01190 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ); 01191 01192 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr(); 01193 status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL); 01194 if (status != CL_SUCCESS) 01195 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed"); 01196 size_t offset = 0; // TODO 01197 size_t dst_origin[3] = {0, 0, 0}; 01198 size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1}; 01199 status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL); 01200 if (status != CL_SUCCESS) 01201 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed"); 01202 status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL); 01203 if (status != CL_SUCCESS) 01204 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed"); 01205 01206 status = clFinish(q); // TODO Use events 01207 if (status != CL_SUCCESS) 01208 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed"); 01209 01210 status = clReleaseMemObject(clImage); // TODO RAII 01211 if (status != CL_SUCCESS) 01212 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed"); 01213 #else 01214 // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock() 01215 NO_OPENCL_SUPPORT_ERROR; 01216 #endif 01217 } 01218 01219 void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle) 01220 { 01221 (void)pDirect3DSurface9; (void)dst; (void)surfaceSharedHandle; 01222 #if !defined(HAVE_DIRECTX) 01223 NO_DIRECTX_SUPPORT_ERROR; 01224 #elif defined(HAVE_OPENCL) 01225 __OpenCLinitializeD3D9(); 01226 01227 D3DSURFACE_DESC desc; 01228 if (FAILED(pDirect3DSurface9->GetDesc(&desc))) 01229 { 01230 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description"); 01231 } 01232 01233 int surfaceType = getTypeFromD3DFORMAT(desc.Format); 01234 CV_Assert(surfaceType >= 0); 01235 01236 using namespace cv::ocl; 01237 Context& ctx = Context::getDefault(); 01238 cl_context context = (cl_context)ctx.ptr(); 01239 01240 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying! 01241 dst.create(Size(desc.Width, desc.Height), surfaceType); 01242 UMat u = dst.getUMat(); 01243 01244 // TODO Add support for roi 01245 CV_Assert(u.offset == 0); 01246 CV_Assert(u.isContinuous()); 01247 01248 cl_int status = 0; 01249 cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle}; 01250 cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_READ_ONLY, 01251 ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR, 01252 &surfaceInfo, 0, &status); 01253 if (status != CL_SUCCESS) 01254 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed"); 01255 01256 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_WRITE); 01257 01258 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr(); 01259 status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL); 01260 if (status != CL_SUCCESS) 01261 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed"); 01262 size_t offset = 0; // TODO 01263 size_t src_origin[3] = {0, 0, 0}; 01264 size_t region[3] = {(size_t)u.cols, (size_t)u.rows, 1}; 01265 status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL); 01266 if (status != CL_SUCCESS) 01267 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed"); 01268 status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL); 01269 if (status != CL_SUCCESS) 01270 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed"); 01271 01272 status = clFinish(q); // TODO Use events 01273 if (status != CL_SUCCESS) 01274 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed"); 01275 01276 status = clReleaseMemObject(clImage); // TODO RAII 01277 if (status != CL_SUCCESS) 01278 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed"); 01279 #else 01280 // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock() 01281 NO_OPENCL_SUPPORT_ERROR; 01282 #endif 01283 } 01284 01285 } } // namespace cv::directx 01286
Generated on Tue Jul 12 2022 14:46:33 by
