--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of the copyright holders may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors as is and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the copyright holders or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#include "precomp.hpp"
+
+#include "opencv2/core.hpp"
+#include "opencv2/core/ocl.hpp"
+#include "opencv2/core/directx.hpp"
+
+#ifdef HAVE_DIRECTX
+#include <vector>
+# include "directx.inc.hpp"
+#else // HAVE_DIRECTX
+#define NO_DIRECTX_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
+#endif
+
+#ifndef HAVE_OPENCL
+# define NO_OPENCL_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
+#endif // HAVE_OPENCL
+
+namespace cv { namespace directx {
+
+int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
+{
+ (void)iDXGI_FORMAT;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#else
+ const int errorType = -1;
+ switch ((enum DXGI_FORMAT)iDXGI_FORMAT)
+ {
+ //case DXGI_FORMAT_UNKNOWN:
+ //case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32A32_FLOAT: return CV_32FC4;
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ case DXGI_FORMAT_R32G32B32A32_SINT: return CV_32SC4;
+ //case DXGI_FORMAT_R32G32B32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32_FLOAT: return CV_32FC3;
+ case DXGI_FORMAT_R32G32B32_UINT:
+ case DXGI_FORMAT_R32G32B32_SINT: return CV_32SC3;
+ //case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ //case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ case DXGI_FORMAT_R16G16B16A16_UINT: return CV_16UC4;
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ case DXGI_FORMAT_R16G16B16A16_SINT: return CV_16SC4;
+ //case DXGI_FORMAT_R32G32_TYPELESS:
+ //case DXGI_FORMAT_R32G32_FLOAT:
+ //case DXGI_FORMAT_R32G32_UINT:
+ //case DXGI_FORMAT_R32G32_SINT:
+ //case DXGI_FORMAT_R32G8X24_TYPELESS:
+ //case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ //case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ //case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ //case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ //case DXGI_FORMAT_R10G10B10A2_UNORM:
+ //case DXGI_FORMAT_R10G10B10A2_UINT:
+ //case DXGI_FORMAT_R11G11B10_FLOAT:
+ //case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ case DXGI_FORMAT_R8G8B8A8_UINT: return CV_8UC4;
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ case DXGI_FORMAT_R8G8B8A8_SINT: return CV_8SC4;
+ //case DXGI_FORMAT_R16G16_TYPELESS:
+ //case DXGI_FORMAT_R16G16_FLOAT:
+ case DXGI_FORMAT_R16G16_UNORM:
+ case DXGI_FORMAT_R16G16_UINT: return CV_16UC2;
+ case DXGI_FORMAT_R16G16_SNORM:
+ case DXGI_FORMAT_R16G16_SINT: return CV_16SC2;
+ //case DXGI_FORMAT_R32_TYPELESS:
+ //case DXGI_FORMAT_D32_FLOAT:
+ case DXGI_FORMAT_R32_FLOAT: return CV_32FC1;
+ case DXGI_FORMAT_R32_UINT:
+ case DXGI_FORMAT_R32_SINT: return CV_32SC1;
+ //case DXGI_FORMAT_R24G8_TYPELESS:
+ //case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ //case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ //case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ //case DXGI_FORMAT_R8G8_TYPELESS:
+ case DXGI_FORMAT_R8G8_UNORM:
+ case DXGI_FORMAT_R8G8_UINT: return CV_8UC2;
+ case DXGI_FORMAT_R8G8_SNORM:
+ case DXGI_FORMAT_R8G8_SINT: return CV_8SC2;
+ //case DXGI_FORMAT_R16_TYPELESS:
+ //case DXGI_FORMAT_R16_FLOAT:
+ case DXGI_FORMAT_D16_UNORM:
+ case DXGI_FORMAT_R16_UNORM:
+ case DXGI_FORMAT_R16_UINT: return CV_16UC1;
+ case DXGI_FORMAT_R16_SNORM:
+ case DXGI_FORMAT_R16_SINT: return CV_16SC1;
+ //case DXGI_FORMAT_R8_TYPELESS:
+ case DXGI_FORMAT_R8_UNORM:
+ case DXGI_FORMAT_R8_UINT: return CV_8UC1;
+ case DXGI_FORMAT_R8_SNORM:
+ case DXGI_FORMAT_R8_SINT: return CV_8SC1;
+ case DXGI_FORMAT_A8_UNORM: return CV_8UC1;
+ //case DXGI_FORMAT_R1_UNORM:
+ //case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ //case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ //case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ //case DXGI_FORMAT_BC1_TYPELESS:
+ //case DXGI_FORMAT_BC1_UNORM:
+ //case DXGI_FORMAT_BC1_UNORM_SRGB:
+ //case DXGI_FORMAT_BC2_TYPELESS:
+ //case DXGI_FORMAT_BC2_UNORM:
+ //case DXGI_FORMAT_BC2_UNORM_SRGB:
+ //case DXGI_FORMAT_BC3_TYPELESS:
+ //case DXGI_FORMAT_BC3_UNORM:
+ //case DXGI_FORMAT_BC3_UNORM_SRGB:
+ //case DXGI_FORMAT_BC4_TYPELESS:
+ //case DXGI_FORMAT_BC4_UNORM:
+ //case DXGI_FORMAT_BC4_SNORM:
+ //case DXGI_FORMAT_BC5_TYPELESS:
+ //case DXGI_FORMAT_BC5_UNORM:
+ //case DXGI_FORMAT_BC5_SNORM:
+ //case DXGI_FORMAT_B5G6R5_UNORM:
+ //case DXGI_FORMAT_B5G5R5A1_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8X8_UNORM: return CV_8UC4;
+ //case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ //case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return CV_8UC4;
+ //case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return CV_8UC4;
+ //case DXGI_FORMAT_BC6H_TYPELESS:
+ //case DXGI_FORMAT_BC6H_UF16:
+ //case DXGI_FORMAT_BC6H_SF16:
+ //case DXGI_FORMAT_BC7_TYPELESS:
+ //case DXGI_FORMAT_BC7_UNORM:
+ //case DXGI_FORMAT_BC7_UNORM_SRGB:
+ default: break;
+ }
+ return errorType;
+#endif
+}
+
+int getTypeFromD3DFORMAT(const int iD3DFORMAT)
+{
+ (void)iD3DFORMAT;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#else
+ const int errorType = -1;
+ switch ((enum _D3DFORMAT)iD3DFORMAT)
+ {
+ //case D3DFMT_UNKNOWN:
+ case D3DFMT_R8G8B8: return CV_8UC3;
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8: return CV_8UC4;
+ //case D3DFMT_R5G6B5:
+ //case D3DFMT_X1R5G5B5:
+ //case D3DFMT_A1R5G5B5:
+ //case D3DFMT_A4R4G4B4:
+ //case D3DFMT_R3G3B2:
+ case D3DFMT_A8: return CV_8UC1;
+ //case D3DFMT_A8R3G3B2:
+ //case D3DFMT_X4R4G4B4:
+ //case D3DFMT_A2B10G10R10:
+ case D3DFMT_A8B8G8R8:
+ case D3DFMT_X8B8G8R8: return CV_8UC4;
+ //case D3DFMT_G16R16:
+ //case D3DFMT_A2R10G10B10:
+ //case D3DFMT_A16B16G16R16:
+
+ case D3DFMT_A8P8: return CV_8UC2;
+ case D3DFMT_P8: return CV_8UC1;
+
+ case D3DFMT_L8: return CV_8UC1;
+ case D3DFMT_A8L8: return CV_8UC2;
+ //case D3DFMT_A4L4:
+
+ case D3DFMT_V8U8: return CV_8UC2;
+ //case D3DFMT_L6V5U5:
+ case D3DFMT_X8L8V8U8:
+ case D3DFMT_Q8W8V8U8: return CV_8UC4;
+ case D3DFMT_V16U16: return CV_16UC4; // TODO 16SC4 ?
+ //case D3DFMT_A2W10V10U10:
+
+ case D3DFMT_D16_LOCKABLE: return CV_16UC1;
+ case D3DFMT_D32: return CV_32SC1;
+ //case D3DFMT_D15S1:
+ //case D3DFMT_D24S8:
+ //case D3DFMT_D24X8:
+ //case D3DFMT_D24X4S4:
+ case D3DFMT_D16: return CV_16UC1;
+
+ case D3DFMT_D32F_LOCKABLE: return CV_32FC1;
+ default: break;
+ }
+ return errorType;
+#endif
+}
+
+namespace ocl {
+
+#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
+static bool g_isDirect3DDevice9Ex = false; // Direct3DDevice9Ex or Direct3DDevice9 was used
+#endif
+
+Context2& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
+{
+ (void)pD3D11Device;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif !defined(HAVE_OPENCL)
+ NO_OPENCL_SUPPORT_ERROR;
+#else
+ cl_uint numPlatforms;
+ cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
+ if (numPlatforms == 0)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
+
+ std::vector<cl_platform_id> platforms(numPlatforms);
+ status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
+
+ // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
+
+ int found = -1;
+ cl_device_id device = NULL;
+ cl_uint numDevices = 0;
+ cl_context context = NULL;
+
+ // try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
+ for (int i = 0; i < (int)numPlatforms; i++)
+ {
+ clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
+ if (!clGetDeviceIDsFromD3D11KHR)
+ continue;
+
+ device = NULL;
+ numDevices = 0;
+ status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
+ CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
+ if (status != CL_SUCCESS)
+ continue;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ break;
+ }
+ }
+ }
+ if (found < 0)
+ {
+ // try with CL_ALL_DEVICES_FOR_D3D11_KHR
+ for (int i = 0; i < (int)numPlatforms; i++)
+ {
+ clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
+ if (!clGetDeviceIDsFromD3D11KHR)
+ continue;
+
+ device = NULL;
+ numDevices = 0;
+ status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
+ CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
+ if (status != CL_SUCCESS)
+ continue;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ break;
+ }
+ }
+ }
+ if (found < 0)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
+ }
+
+
+ Context2& ctx = Context2::getDefault(false);
+ initializeContextFromHandle(ctx, platforms[found], context, device);
+ return ctx;
+#endif
+}
+
+Context2& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device)
+{
+ (void)pD3D10Device;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif !defined(HAVE_OPENCL)
+ NO_OPENCL_SUPPORT_ERROR;
+#else
+ cl_uint numPlatforms;
+ cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
+ if (numPlatforms == 0)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
+
+ std::vector<cl_platform_id> platforms(numPlatforms);
+ status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
+
+ // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
+
+ int found = -1;
+ cl_device_id device = NULL;
+ cl_uint numDevices = 0;
+ cl_context context = NULL;
+
+ // try with CL_PREFERRED_DEVICES_FOR_D3D10_KHR
+ for (int i = 0; i < (int)numPlatforms; i++)
+ {
+ clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
+ if (!clGetDeviceIDsFromD3D10KHR)
+ continue;
+
+ device = NULL;
+ numDevices = 0;
+ status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
+ CL_PREFERRED_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
+ if (status != CL_SUCCESS)
+ continue;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ break;
+ }
+ }
+ }
+ if (found < 0)
+ {
+ // try with CL_ALL_DEVICES_FOR_D3D10_KHR
+ for (int i = 0; i < (int)numPlatforms; i++)
+ {
+ clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
+ if (!clGetDeviceIDsFromD3D10KHR)
+ continue;
+
+ device = NULL;
+ numDevices = 0;
+ status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
+ CL_ALL_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
+ if (status != CL_SUCCESS)
+ continue;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ break;
+ }
+ }
+ }
+ if (found < 0)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
+ }
+
+
+ Context2& ctx = Context2::getDefault(false);
+ initializeContextFromHandle(ctx, platforms[found], context, device);
+ return ctx;
+#endif
+}
+
+Context2& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex)
+{
+ (void)pDirect3DDevice9Ex;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif !defined(HAVE_OPENCL)
+ NO_OPENCL_SUPPORT_ERROR;
+#else
+ cl_uint numPlatforms;
+ cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
+ if (numPlatforms == 0)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
+
+ std::vector<cl_platform_id> platforms(numPlatforms);
+ status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
+
+ // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
+
+ int found = -1;
+ cl_device_id device = NULL;
+ cl_uint numDevices = 0;
+ cl_context context = NULL;
+
+ // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
+ for (int i = 0; i < (int)numPlatforms; i++)
+ {
+ clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
+ if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
+ continue;
+
+ device = NULL;
+ numDevices = 0;
+ cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
+ status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
+ CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
+ if (status != CL_SUCCESS)
+ continue;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ break;
+ }
+ }
+ }
+ if (found < 0)
+ {
+ // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
+ for (int i = 0; i < (int)numPlatforms; i++)
+ {
+ clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
+ if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
+ continue;
+
+ device = NULL;
+ numDevices = 0;
+ cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
+ status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
+ CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
+ if (status != CL_SUCCESS)
+ continue;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ break;
+ }
+ }
+ }
+ if (found < 0)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
+ }
+
+ Context2& ctx = Context2::getDefault(false);
+ initializeContextFromHandle(ctx, platforms[found], context, device);
+ g_isDirect3DDevice9Ex = true;
+ return ctx;
+#endif
+}
+
+Context2& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9)
+{
+ (void)pDirect3DDevice9;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif !defined(HAVE_OPENCL)
+ NO_OPENCL_SUPPORT_ERROR;
+#else
+ cl_uint numPlatforms;
+ cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
+ if (numPlatforms == 0)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
+
+ std::vector<cl_platform_id> platforms(numPlatforms);
+ status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
+
+ // TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
+
+ int found = -1;
+ cl_device_id device = NULL;
+ cl_uint numDevices = 0;
+ cl_context context = NULL;
+
+ // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
+ for (int i = 0; i < (int)numPlatforms; i++)
+ {
+ clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
+ if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
+ continue;
+
+ device = NULL;
+ numDevices = 0;
+ cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
+ status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
+ CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
+ if (status != CL_SUCCESS)
+ continue;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ break;
+ }
+ }
+ }
+ if (found < 0)
+ {
+ // try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
+ for (int i = 0; i < (int)numPlatforms; i++)
+ {
+ clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
+ if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
+ continue;
+
+ device = NULL;
+ numDevices = 0;
+ cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
+ status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
+ CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
+ if (status != CL_SUCCESS)
+ continue;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ break;
+ }
+ }
+ }
+ if (found < 0)
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
+ }
+
+ Context2& ctx = Context2::getDefault(false);
+ initializeContextFromHandle(ctx, platforms[found], context, device);
+ g_isDirect3DDevice9Ex = false;
+ return ctx;
+#endif
+}
+
+} // namespace cv::ocl
+
+#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
+clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL;
+clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL;
+clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL;
+
+static void __OpenCLinitializeD3D11()
+{
+ using namespace cv::ocl;
+ static cl_platform_id initializedPlatform = NULL;
+ cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
+ if (initializedPlatform != platform)
+ {
+ clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
+ clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
+ clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
+ initializedPlatform = platform;
+ }
+ if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
+ {
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
+ }
+}
+#endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
+
+void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
+{
+ (void)src; (void)pD3D11Texture2D;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif defined(HAVE_OPENCL)
+ __OpenCLinitializeD3D11();
+
+ D3D11_TEXTURE2D_DESC desc = { 0 };
+ pD3D11Texture2D->GetDesc(&desc);
+
+ int srcType = src.type();
+ int textureType = getTypeFromDXGI_FORMAT(desc.Format);
+ CV_Assert(textureType == srcType);
+
+ Size srcSize = src.size();
+ CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
+
+ using namespace cv::ocl;
+ Context2& ctx = Context2::getDefault();
+ cl_context context = (cl_context)ctx.ptr();
+
+ UMat u = src.getUMat();
+
+ // TODO Add support for roi
+ CV_Assert(u.offset == 0);
+ CV_Assert(u.isContinuous());
+
+ cl_int status = 0;
+ cl_mem clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
+
+ cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
+
+ cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
+ status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
+ size_t offset = 0; // TODO
+ size_t dst_origin[3] = {0, 0, 0};
+ size_t region[3] = {u.cols, u.rows, 1};
+ status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
+ status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
+
+ status = clFinish(q); // TODO Use events
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
+
+ status = clReleaseMemObject(clImage); // TODO RAII
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
+#else
+ // TODO memcpy
+ NO_OPENCL_SUPPORT_ERROR;
+#endif
+}
+void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
+{
+ (void)pD3D11Texture2D; (void)dst;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif defined(HAVE_OPENCL)
+ __OpenCLinitializeD3D11();
+
+ D3D11_TEXTURE2D_DESC desc = { 0 };
+ pD3D11Texture2D->GetDesc(&desc);
+
+ int textureType = getTypeFromDXGI_FORMAT(desc.Format);
+ CV_Assert(textureType >= 0);
+
+ using namespace cv::ocl;
+ Context2& ctx = Context2::getDefault();
+ cl_context context = (cl_context)ctx.ptr();
+
+ // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
+ dst.create(Size(desc.Width, desc.Height), textureType);
+ UMat u = dst.getUMat();
+
+ // TODO Add support for roi
+ CV_Assert(u.offset == 0);
+ CV_Assert(u.isContinuous());
+
+ cl_int status = 0;
+ cl_mem clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
+
+ cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
+
+ cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
+ status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
+ size_t offset = 0; // TODO
+ size_t src_origin[3] = {0, 0, 0};
+ size_t region[3] = {u.cols, u.rows, 1};
+ status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
+ status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
+
+ status = clFinish(q); // TODO Use events
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
+
+ status = clReleaseMemObject(clImage); // TODO RAII
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
+#else
+ // TODO memcpy
+ NO_OPENCL_SUPPORT_ERROR;
+#endif
+}
+
+#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
+clCreateFromD3D10Texture2DKHR_fn clCreateFromD3D10Texture2DKHR = NULL;
+clEnqueueAcquireD3D10ObjectsKHR_fn clEnqueueAcquireD3D10ObjectsKHR = NULL;
+clEnqueueReleaseD3D10ObjectsKHR_fn clEnqueueReleaseD3D10ObjectsKHR = NULL;
+
+static void __OpenCLinitializeD3D10()
+{
+ using namespace cv::ocl;
+ static cl_platform_id initializedPlatform = NULL;
+ cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
+ if (initializedPlatform != platform)
+ {
+ clCreateFromD3D10Texture2DKHR = (clCreateFromD3D10Texture2DKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D10Texture2DKHR");
+ clEnqueueAcquireD3D10ObjectsKHR = (clEnqueueAcquireD3D10ObjectsKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D10ObjectsKHR");
+ clEnqueueReleaseD3D10ObjectsKHR = (clEnqueueReleaseD3D10ObjectsKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D10ObjectsKHR");
+ initializedPlatform = platform;
+ }
+ if (!clCreateFromD3D10Texture2DKHR || !clEnqueueAcquireD3D10ObjectsKHR || !clEnqueueReleaseD3D10ObjectsKHR)
+ {
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D10");
+ }
+}
+#endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
+
+void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D)
+{
+ (void)src; (void)pD3D10Texture2D;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif defined(HAVE_OPENCL)
+ __OpenCLinitializeD3D10();
+
+ D3D10_TEXTURE2D_DESC desc = { 0 };
+ pD3D10Texture2D->GetDesc(&desc);
+
+ int srcType = src.type();
+ int textureType = getTypeFromDXGI_FORMAT(desc.Format);
+ CV_Assert(textureType == srcType);
+
+ Size srcSize = src.size();
+ CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
+
+ using namespace cv::ocl;
+ Context2& ctx = Context2::getDefault();
+ cl_context context = (cl_context)ctx.ptr();
+
+ UMat u = src.getUMat();
+
+ // TODO Add support for roi
+ CV_Assert(u.offset == 0);
+ CV_Assert(u.isContinuous());
+
+ cl_int status = 0;
+ cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D10Texture2D, 0, &status);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
+
+ cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
+
+ cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
+ status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
+ size_t offset = 0; // TODO
+ size_t dst_origin[3] = {0, 0, 0};
+ size_t region[3] = {u.cols, u.rows, 1};
+ status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
+ status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
+
+ status = clFinish(q); // TODO Use events
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
+
+ status = clReleaseMemObject(clImage); // TODO RAII
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
+#else
+ // TODO memcpy
+ NO_OPENCL_SUPPORT_ERROR;
+#endif
+}
+void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst)
+{
+ (void)pD3D10Texture2D; (void)dst;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif defined(HAVE_OPENCL)
+ __OpenCLinitializeD3D10();
+
+ D3D10_TEXTURE2D_DESC desc = { 0 };
+ pD3D10Texture2D->GetDesc(&desc);
+
+ int textureType = getTypeFromDXGI_FORMAT(desc.Format);
+ CV_Assert(textureType >= 0);
+
+ using namespace cv::ocl;
+ Context2& ctx = Context2::getDefault();
+ cl_context context = (cl_context)ctx.ptr();
+
+ // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
+ dst.create(Size(desc.Width, desc.Height), textureType);
+ UMat u = dst.getUMat();
+
+ // TODO Add support for roi
+ CV_Assert(u.offset == 0);
+ CV_Assert(u.isContinuous());
+
+ cl_int status = 0;
+ cl_mem clImage = clCreateFromD3D10Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D10Texture2D, 0, &status);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
+
+ cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
+
+ cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
+ status = clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
+ size_t offset = 0; // TODO
+ size_t src_origin[3] = {0, 0, 0};
+ size_t region[3] = {u.cols, u.rows, 1};
+ status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
+ status = clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
+
+ status = clFinish(q); // TODO Use events
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
+
+ status = clReleaseMemObject(clImage); // TODO RAII
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
+#else
+ // TODO memcpy
+ NO_OPENCL_SUPPORT_ERROR;
+#endif
+}
+
+#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
+clCreateFromDX9MediaSurfaceKHR_fn clCreateFromDX9MediaSurfaceKHR = NULL;
+clEnqueueAcquireDX9MediaSurfacesKHR_fn clEnqueueAcquireDX9MediaSurfacesKHR = NULL;
+clEnqueueReleaseDX9MediaSurfacesKHR_fn clEnqueueReleaseDX9MediaSurfacesKHR = NULL;
+
+static void __OpenCLinitializeD3D9()
+{
+ using namespace cv::ocl;
+ static cl_platform_id initializedPlatform = NULL;
+ cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
+ if (initializedPlatform != platform)
+ {
+ clCreateFromDX9MediaSurfaceKHR = (clCreateFromDX9MediaSurfaceKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromDX9MediaSurfaceKHR");
+ clEnqueueAcquireDX9MediaSurfacesKHR = (clEnqueueAcquireDX9MediaSurfacesKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireDX9MediaSurfacesKHR");
+ clEnqueueReleaseDX9MediaSurfacesKHR = (clEnqueueReleaseDX9MediaSurfacesKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseDX9MediaSurfacesKHR");
+ initializedPlatform = platform;
+ }
+ if (!clCreateFromDX9MediaSurfaceKHR || !clEnqueueAcquireDX9MediaSurfacesKHR || !clEnqueueReleaseDX9MediaSurfacesKHR)
+ {
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D9");
+ }
+}
+#endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
+
+void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle)
+{
+ (void)src; (void)pDirect3DSurface9; (void)surfaceSharedHandle;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif defined(HAVE_OPENCL)
+ __OpenCLinitializeD3D9();
+
+ D3DSURFACE_DESC desc;
+ if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
+ {
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
+ }
+
+ int srcType = src.type();
+ int surfaceType = getTypeFromD3DFORMAT(desc.Format);
+ CV_Assert(surfaceType == srcType);
+
+ Size srcSize = src.size();
+ CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
+
+ using namespace cv::ocl;
+ Context2& ctx = Context2::getDefault();
+ cl_context context = (cl_context)ctx.ptr();
+
+ UMat u = src.getUMat();
+
+ // TODO Add support for roi
+ CV_Assert(u.offset == 0);
+ CV_Assert(u.isContinuous());
+
+ cl_int status = 0;
+ cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
+ cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_WRITE_ONLY,
+ ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
+ &surfaceInfo, 0, &status);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
+
+ cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
+
+ cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
+ status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
+ size_t offset = 0; // TODO
+ size_t dst_origin[3] = {0, 0, 0};
+ size_t region[3] = {u.cols, u.rows, 1};
+ status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
+ status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
+
+ status = clFinish(q); // TODO Use events
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
+
+ status = clReleaseMemObject(clImage); // TODO RAII
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
+#else
+ // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
+ NO_OPENCL_SUPPORT_ERROR;
+#endif
+}
+
+void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle)
+{
+ (void)pDirect3DSurface9; (void)dst; (void)surfaceSharedHandle;
+#if !defined(HAVE_DIRECTX)
+ NO_DIRECTX_SUPPORT_ERROR;
+#elif defined(HAVE_OPENCL)
+ __OpenCLinitializeD3D9();
+
+ D3DSURFACE_DESC desc;
+ if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
+ {
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Can't get D3D surface description");
+ }
+
+ int surfaceType = getTypeFromD3DFORMAT(desc.Format);
+ CV_Assert(surfaceType >= 0);
+
+ using namespace cv::ocl;
+ Context2& ctx = Context2::getDefault();
+ cl_context context = (cl_context)ctx.ptr();
+
+ // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
+ dst.create(Size(desc.Width, desc.Height), surfaceType);
+ UMat u = dst.getUMat();
+
+ // TODO Add support for roi
+ CV_Assert(u.offset == 0);
+ CV_Assert(u.isContinuous());
+
+ cl_int status = 0;
+ cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
+ cl_mem clImage = clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_READ_ONLY,
+ ocl::g_isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
+ &surfaceInfo, 0, &status);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
+
+ cl_mem clBuffer = (cl_mem)u.handle(ACCESS_WRITE);
+
+ cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
+ status = clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
+ size_t offset = 0; // TODO
+ size_t src_origin[3] = {0, 0, 0};
+ size_t region[3] = {u.cols, u.rows, 1};
+ status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
+ status = clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
+
+ status = clFinish(q); // TODO Use events
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
+
+ status = clReleaseMemObject(clImage); // TODO RAII
+ if (status != CL_SUCCESS)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
+#else
+ // TODO pDirect3DSurface9->LockRect() + memcpy + Unlock()
+ NO_OPENCL_SUPPORT_ERROR;
+#endif
+}
+
+} } // namespace cv::directx
--- /dev/null
+//
+// Don't use as a standalone file
+//
+
+#include "opencv2/core.hpp"
+#include "opencv2/core/utility.hpp" // cv::format
+#include "opencv2/imgproc.hpp" // cvtColor
+#include "opencv2/imgproc/types_c.h" // cvtColor
+#include "opencv2/highgui.hpp" // imread
+#include "opencv2/core/directx.hpp"
+
+#include <iostream>
+#include <queue>
+
+using namespace cv;
+using namespace cv::directx;
+static const int fontFace = cv::FONT_HERSHEY_DUPLEX;
+#if !defined(USE_D3D9) && !defined(USE_D3DEX)
+const cv::Scalar frameColor(255,128,0,255);
+#else
+const cv::Scalar frameColor(0,128,255,255); // BGRA for D3D9
+#endif
+
+#define SAFE_RELEASE(p) if (p) { p->Release(); p = NULL; }
+
+const int WIDTH = 1024;
+const int HEIGHT = 768;
+
+HINSTANCE hInstance;
+HWND hWnd;
+
+// external declaration
+bool initDirect3D(void);
+bool initDirect3DTextures(void);
+void render(void);
+void cleanUp (void);
+
+#define USAGE_DESCRIPTION_0 "1 - CPU write via LockRect/Map"
+#define USAGE_DESCRIPTION_1 "2* - Mat->D3D"
+#define USAGE_DESCRIPTION_2 "3* - D3D->UMat / change UMat / UMat->D3D"
+#define USAGE_DESCRIPTION_3 "0 - show input texture without any processing"
+#define USAGE_DESCRIPTION_SPACE "SPACE - toggle frame processing (only data transfers)"
+
+static int g_sampleType = 0;
+static int g_disableProcessing = false;
+
+// forward declaration
+static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+
+static bool initWindow()
+{
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInstance;
+ wcex.hIcon = LoadIcon(0, IDI_APPLICATION);
+ wcex.hCursor = LoadCursor(0, IDC_ARROW);
+ wcex.hbrBackground = 0;
+ wcex.lpszMenuName = 0L;
+ wcex.lpszClassName = "OpenCVDirectX";
+ wcex.hIconSm = 0;
+
+ RegisterClassEx(&wcex);
+
+ RECT rc = {0, 0, WIDTH, HEIGHT};
+ AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false);
+ hWnd = CreateWindow("OpenCVDirectX", WINDOW_NAME,
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
+
+ if (!hWnd)
+ return false;
+
+ ShowWindow(hWnd, SW_SHOW);
+ UpdateWindow(hWnd);
+
+ return true;
+}
+
+static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+
+ case WM_CHAR:
+ if (wParam >= '0' && wParam <= '3')
+ {
+ g_sampleType = (char)wParam - '0';
+ return 0;
+ }
+ else if (wParam == ' ')
+ {
+ g_disableProcessing = !g_disableProcessing;
+ return 0;
+ }
+ else if (wParam == VK_ESCAPE)
+ {
+ DestroyWindow(hWnd);
+ return 0;
+ }
+ break;
+ }
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+static float getFps()
+{
+ static std::queue<int64> time_queue;
+
+ int64 now = cv::getTickCount(), then = 0;
+ time_queue.push(now);
+
+ if (time_queue.size() >= 2)
+ then = time_queue.front();
+
+ if (time_queue.size() >= 25)
+ time_queue.pop();
+
+ return time_queue.size() * (float)cv::getTickFrequency() / (now - then);
+}
+
+static int bgColor[4] = {0, 0, 0, 0};
+static cv::Mat* inputMat = NULL;
+
+static void renderToD3DObject(void)
+{
+ static int frame = 0;
+
+ const float fps = getFps();
+
+ String deviceName = cv::ocl::useOpenCL() ? cv::ocl::Context2::getDefault().device(0).name() : "No OpenCL device";
+
+ if ((frame % std::max(1, (int)(fps / 25))) == 0)
+ {
+ String msg = format("%s%s: %s, Sample %d, Frame %d, fps %g (%g ms)",
+ g_disableProcessing ? "(FRAME PROCESSING DISABLED) " : "",
+ WINDOW_NAME, deviceName.c_str(), g_sampleType,
+ frame, fps, (int(10 * 1000.0 / fps)) * 0.1);
+ SetWindowText(hWnd, msg.c_str());
+ }
+
+ // 0..255
+ int c[4] =
+ {
+ std::abs((frame & 0x1ff) - 0x100),
+ std::abs(((frame * 2) & 0x1ff) - 0x100),
+ std::abs(((frame / 2) & 0x1ff) - 0x100),
+ 0
+ };
+
+ int c1 = c[0] / 2 - 0x40 - bgColor[0];
+ int c2 = c[1] / 2 - 0x40 - bgColor[1];
+ int c3 = c[2] / 2 - 0x40 - bgColor[2];
+
+ switch (g_sampleType)
+ {
+ case 0:
+#if defined(USE_D3D9) || defined (USE_D3DEX)
+ if (FAILED(dev->StretchRect(pReadOnlySurface, NULL, pBackBuffer, NULL, D3DTEXF_NONE)))
+ {
+ std::cerr << "Can't StretchRect()" << std::endl;
+ }
+#elif defined(USE_D3D10)
+ dev->CopyResource(pBackBufferTexture, pInputTexture);
+#elif defined(USE_D3D11)
+ devcon->CopyResource(pBackBufferTexture, pInputTexture);
+#else
+#error "Invalid USE_D3D value"
+#endif
+ break;
+
+ case 1:
+ {
+ int BOXSIZE = 50;
+ int x = std::abs(((frame * 1) % (2 * (WIDTH - BOXSIZE))) - (WIDTH - BOXSIZE));
+ int y = std::abs(((frame / 2) % (2 * (HEIGHT - BOXSIZE))) - (HEIGHT - BOXSIZE));
+ cv::Rect boxRect(x, y, BOXSIZE, BOXSIZE);
+#if defined(USE_D3D9) || defined (USE_D3DEX)
+ D3DLOCKED_RECT memDesc = {0, NULL};
+ RECT rc = {0, 0, WIDTH, HEIGHT};
+ if (SUCCEEDED(pCPUWriteSurface->LockRect(&memDesc, &rc, 0)))
+ {
+ if (!g_disableProcessing)
+ {
+ Mat m(Size(WIDTH, HEIGHT), CV_8UC4, memDesc.pBits, (int)memDesc.Pitch);
+ inputMat->copyTo(m);
+ m(boxRect).setTo(Scalar(c[0], c[1], c[2], 255));
+ }
+ pCPUWriteSurface->UnlockRect();
+ }
+ else
+ {
+ std::cerr << "Can't LockRect() on surface" << std::endl;
+ }
+#elif defined(USE_D3D10)
+ D3D10_MAPPED_TEXTURE2D mappedTex;
+ if (SUCCEEDED(pCPUWriteTexture->Map( D3D10CalcSubresource(0, 0, 1), D3D10_MAP_WRITE_DISCARD, 0, &mappedTex)))
+ {
+ if (!g_disableProcessing)
+ {
+ Mat m(Size(WIDTH, HEIGHT), CV_8UC4, mappedTex.pData, (int)mappedTex.RowPitch);
+ inputMat->copyTo(m);
+ m(boxRect).setTo(Scalar(c[0], c[1], c[2], 255));
+ }
+ pCPUWriteTexture->Unmap(D3D10CalcSubresource(0, 0, 1));
+ dev->CopyResource(pBackBufferTexture, pCPUWriteTexture);
+ }
+ else
+ {
+ std::cerr << "Can't Map() texture" << std::endl;
+ }
+#elif defined(USE_D3D11)
+ D3D11_MAPPED_SUBRESOURCE mappedTex;
+ if (SUCCEEDED(devcon->Map(pCPUWriteTexture, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_WRITE_DISCARD, 0, &mappedTex)))
+ {
+ if (!g_disableProcessing)
+ {
+ Mat m(Size(WIDTH, HEIGHT), CV_8UC4, mappedTex.pData, (int)mappedTex.RowPitch);
+ inputMat->copyTo(m);
+ m(boxRect).setTo(Scalar(c[0], c[1], c[2], 255));
+ }
+ devcon->Unmap(pCPUWriteTexture, D3D11CalcSubresource(0, 0, 1));
+ devcon->CopyResource(pBackBufferTexture, pCPUWriteTexture);
+ }
+ else
+ {
+ std::cerr << "Can't Map() texture" << std::endl;
+ }
+#else
+#error "Invalid USE_D3D value"
+#endif
+ break;
+ }
+ case 2:
+ {
+ static Mat m;
+ if (!g_disableProcessing)
+ {
+#if 1
+ cv::add(*inputMat, Scalar(c1, c2, c3, 255), m);
+#else
+ inputMat->copyTo(m);
+#endif
+ cv::putText(m,
+ cv::format("Frame %d, fps %g (%g ms)",
+ frame, fps, (int(10 * 1000.0 / fps)) * 0.1),
+ cv::Point(8, 80), fontFace, 1, frameColor, 2);
+ }
+ else
+ {
+ m.create(Size(WIDTH, HEIGHT), CV_8UC4);
+ }
+ try
+ {
+ #if defined(USE_D3D9) || defined (USE_D3DEX)
+ convertToDirect3DSurface9(m, pSurface, (void*)surfaceShared);
+ #elif defined(USE_D3D10)
+ convertToD3D10Texture2D(m, pBackBufferTexture);
+ #elif defined(USE_D3D11)
+ convertToD3D11Texture2D(m, pBackBufferTexture);
+ #else
+ #error "Invalid USE_D3D value"
+ #endif
+ }
+ catch (cv::Exception& e)
+ {
+ std::cerr << "Can't convert to D3D object: exception: " << e.what() << std::endl;
+ }
+ catch (...)
+ {
+ std::cerr << "Can't convert to D3D object" << std::endl;
+ }
+ break;
+ }
+ case 3:
+ {
+ static UMat tmp;
+ try
+ {
+#if defined(USE_D3D9) || defined (USE_D3DEX)
+ convertFromDirect3DSurface9(pReadOnlySurface, tmp, (void*)readOnlySurfaceShared);
+#elif defined(USE_D3D10)
+ convertFromD3D10Texture2D(pInputTexture, tmp);
+#elif defined(USE_D3D11)
+ convertFromD3D11Texture2D(pInputTexture, tmp);
+#else
+#error "Invalid USE_D3D value"
+#endif
+ }
+ catch (cv::Exception& e)
+ {
+ std::cerr << "Can't convert from D3D object: exception: " << e.what() << std::endl;
+ }
+ catch (...)
+ {
+ std::cerr << "Can't convert from D3D object" << std::endl;
+ }
+ static UMat res;
+ if (!g_disableProcessing)
+ {
+ cv::add(tmp, Scalar(c1, c2, c3, 255), res);
+ }
+ else
+ {
+ res = tmp;
+ }
+ try
+ {
+#if defined(USE_D3D9) || defined (USE_D3DEX)
+ convertToDirect3DSurface9(res, pSurface, (void*)surfaceShared);
+#elif defined(USE_D3D10)
+ convertToD3D10Texture2D(res, pBackBufferTexture);
+#elif defined(USE_D3D11)
+ convertToD3D11Texture2D(res, pBackBufferTexture);
+#else
+#error "Invalid USE_D3D value"
+#endif
+ }
+ catch (cv::Exception& e)
+ {
+ std::cerr << "Can't convert to D3D object: exception: " << e.what() << std::endl;
+ }
+ catch (...)
+ {
+ std::cerr << "Can't convert to D3D object" << std::endl;
+ }
+ break;
+ }
+ }
+ frame++;
+}
+
+
+static cv::Mat getInputTexture()
+{
+ cv::Mat inputMat = cv::imread("input.bmp", cv::IMREAD_COLOR);
+
+ if (inputMat.depth() != CV_8U)
+ {
+ inputMat.convertTo(inputMat, CV_8U);
+ }
+ if (inputMat.type() == CV_8UC3)
+ {
+ cv::cvtColor(inputMat, inputMat, CV_RGB2BGRA);
+ }
+ if (inputMat.type() != CV_8UC4 || inputMat.size().area() == 0)
+ {
+ std::cerr << "Invalid input image format. Generate other" << std::endl;
+ inputMat.create(cv::Size(WIDTH, HEIGHT), CV_8UC4);
+ inputMat.setTo(cv::Scalar(0, 0, 255, 255));
+ bgColor[0] = -128; bgColor[1] = -128; bgColor[2] = 127; bgColor[3] = -128;
+ }
+ if (inputMat.size().width != WIDTH || inputMat.size().height != HEIGHT)
+ {
+ cv::resize(inputMat, inputMat, cv::Size(WIDTH, HEIGHT));
+ }
+ String deviceName = cv::ocl::useOpenCL() ? cv::ocl::Context2::getDefault().device(0).name() : "No OpenCL device";
+ cv::Scalar color(64, 255, 64, 255);
+ cv::putText(inputMat,
+ cv::format("OpenCL Device name: %s", deviceName.c_str()),
+ cv::Point(8,32), fontFace, 1, color);
+ cv::putText(inputMat, WINDOW_NAME, cv::Point(50, HEIGHT - 32), fontFace, 1, color);
+ cv::putText(inputMat, USAGE_DESCRIPTION_0, cv::Point(30, 128), fontFace, 1, color);
+ cv::putText(inputMat, USAGE_DESCRIPTION_1, cv::Point(30, 192), fontFace, 1, color);
+ cv::putText(inputMat, USAGE_DESCRIPTION_2, cv::Point(30, 256), fontFace, 1, color);
+ cv::putText(inputMat, USAGE_DESCRIPTION_3, cv::Point(30, 320), fontFace, 1, color);
+ cv::putText(inputMat, USAGE_DESCRIPTION_SPACE, cv::Point(30, 448), fontFace, 1, color);
+
+#if defined(USE_D3D9) || defined (USE_D3DEX)
+ cv::cvtColor(inputMat, inputMat, CV_RGBA2BGRA);
+ std::swap(bgColor[0], bgColor[2]);
+#endif
+
+ // Make a global copy
+ ::inputMat = new cv::Mat(inputMat);
+
+ return inputMat;
+}
+
+static int mainLoop()
+{
+ hInstance = GetModuleHandle(NULL);
+
+ if (!initWindow())
+ CV_Error(cv::Error::StsError, "Can't create window");
+
+ if (!initDirect3D())
+ CV_Error(cv::Error::StsError, "Can't create D3D object");
+
+ if (cv::ocl::haveOpenCL())
+ {
+#if defined(USE_D3D9)
+ cv::ocl::Context2& ctx = cv::directx::ocl::initializeContextFromDirect3DDevice9(dev);
+#elif defined (USE_D3DEX)
+ cv::ocl::Context2& ctx = cv::directx::ocl::initializeContextFromDirect3DDevice9Ex(dev);
+#elif defined(USE_D3D10)
+ cv::ocl::Context2& ctx = cv::directx::ocl::initializeContextFromD3D10Device(dev);
+#elif defined(USE_D3D11)
+ cv::ocl::Context2& ctx = cv::directx::ocl::initializeContextFromD3D11Device(dev);
+#else
+#error "Invalid USE_D3D value"
+#endif
+ std::cout << "Selected device: " << ctx.device(0).name().c_str() << std::endl;
+ g_sampleType = 2;
+ }
+ else
+ {
+ std::cerr << "OpenCL is not available. DirectX - OpenCL interop will not work" << std::endl;
+ }
+
+ if (!initDirect3DTextures())
+ CV_Error(cv::Error::StsError, "Can't create D3D texture object");
+
+ MSG msg;
+ ZeroMemory(&msg, sizeof(msg));
+
+ while (msg.message != WM_QUIT)
+ {
+ if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ else
+ {
+ render();
+ }
+ }
+
+ cleanUp();
+
+ return static_cast<int>(msg.wParam);
+}
+
+int main(int /*argc*/, char ** /*argv*/)
+{
+ try
+ {
+ return mainLoop();
+ }
+ catch (cv::Exception& e)
+ {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ return 10;
+ }
+ catch (...)
+ {
+ std::cerr << "FATAL ERROR: Unknown exception" << std::endl;
+ return 11;
+ }
+}