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