Renesas GR-PEACH OpenCV Development / gr-peach-opencv-project-sd-card_update

Fork of gr-peach-opencv-project-sd-card by the do

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers directx.cpp Source File

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