Commit bd91b395 authored by Andrey Pavlenko's avatar Andrey Pavlenko Committed by OpenCV Buildbot

Merge pull request #1917 from alalek:ocl_d3d

parents 586a5cb6 11b9d5bf
...@@ -155,6 +155,7 @@ OCV_OPTION(WITH_CLP "Include Clp support (EPL)" OFF ...@@ -155,6 +155,7 @@ OCV_OPTION(WITH_CLP "Include Clp support (EPL)" OFF
OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" ON IF (NOT IOS) ) OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" ON IF (NOT IOS) )
OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" ON IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" ON IF (NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON IF (NOT ANDROID AND NOT IOS) )
OCV_OPTION(WITH_DIRECTX "Include DirectX support" ON IF WIN32 )
# OpenCV build components # OpenCV build components
...@@ -428,6 +429,11 @@ if(WITH_OPENCL) ...@@ -428,6 +429,11 @@ if(WITH_OPENCL)
include(cmake/OpenCVDetectOpenCL.cmake) include(cmake/OpenCVDetectOpenCL.cmake)
endif() endif()
# --- DirectX ---
if(WITH_DIRECTX)
include(cmake/OpenCVDetectDirectX.cmake)
endif()
# --- Matlab/Octave --- # --- Matlab/Octave ---
include(cmake/OpenCVFindMatlab.cmake) include(cmake/OpenCVFindMatlab.cmake)
......
if(WIN32)
try_compile(__VALID_DIRECTX
"${OpenCV_BINARY_DIR}"
"${OpenCV_SOURCE_DIR}/cmake/checks/directx.cpp"
OUTPUT_VARIABLE TRY_OUT
)
if(NOT __VALID_DIRECTX)
return()
endif()
set(HAVE_DIRECTX ON)
set(HAVE_D3D11 ON)
set(HAVE_D3D10 ON)
set(HAVE_D3D9 ON)
endif()
#include <windows.h>
#include <d3d11.h>
#pragma comment (lib, "d3d11.lib")
HINSTANCE g_hInst = NULL;
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device* g_pd3dDevice = NULL;
ID3D11DeviceContext* g_pImmediateContext = NULL;
IDXGISwapChain* g_pSwapChain = NULL;
static HRESULT InitDevice()
{
HRESULT hr = S_OK;
UINT width = 640;
UINT height = 480;
UINT createDeviceFlags = 0;
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory( &sd, sizeof( sd ) );
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = NULL; //g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
{
g_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext);
if (SUCCEEDED(hr))
break;
}
if (FAILED(hr))
return hr;
return S_OK;
}
int main(int /*argc*/, char** /*argv*/)
{
InitDevice();
return 0;
}
...@@ -55,6 +55,12 @@ ...@@ -55,6 +55,12 @@
/* IEEE1394 capturing support - libdc1394 v2.x */ /* IEEE1394 capturing support - libdc1394 v2.x */
#cmakedefine HAVE_DC1394_2 #cmakedefine HAVE_DC1394_2
/* DirectX */
#cmakedefine HAVE_DIRECTX
#cmakedefine HAVE_D3D11
#cmakedefine HAVE_D3D10
#cmakedefine HAVE_D3D9
/* DirectShow Video Capture library */ /* DirectShow Video Capture library */
#cmakedefine HAVE_DSHOW #cmakedefine HAVE_DSHOW
......
...@@ -1262,5 +1262,4 @@ template<> struct ParamType<uchar> ...@@ -1262,5 +1262,4 @@ template<> struct ParamType<uchar>
#include "opencv2/core/operations.hpp" #include "opencv2/core/operations.hpp"
#include "opencv2/core/cvstd.inl.hpp" #include "opencv2/core/cvstd.inl.hpp"
#endif /*__OPENCV_CORE_HPP__*/ #endif /*__OPENCV_CORE_HPP__*/
...@@ -231,6 +231,13 @@ CV_EXPORTS void error(int _code, const String& _err, const char* _func, const ch ...@@ -231,6 +231,13 @@ CV_EXPORTS void error(int _code, const String& _err, const char* _func, const ch
CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const char* _func, const char* _file, int _line) CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const char* _func, const char* _file, int _line)
{ {
error(_code, _err, _func, _file, _line); error(_code, _err, _func, _file, _line);
#ifdef __GNUC__
# if !defined __clang__ && !defined __APPLE__
// this suppresses this warning: "noreturn" function does return [enabled by default]
__builtin_trap();
// or use infinite loop: for (;;) {}
# endif
#endif
} }
#ifdef __GNUC__ #ifdef __GNUC__
# if defined __clang__ || defined __APPLE__ # if defined __clang__ || defined __APPLE__
......
/*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*/
#ifndef __OPENCV_CORE_DIRECTX_HPP__
#define __OPENCV_CORE_DIRECTX_HPP__
#include "mat.hpp"
#include "ocl.hpp"
#if !defined(__d3d11_h__)
struct ID3D11Device;
struct ID3D11Texture2D;
#endif
#if !defined(__d3d10_h__)
struct ID3D10Device;
struct ID3D10Texture2D;
#endif
#if !defined(_D3D9_H_)
struct IDirect3DDevice9;
struct IDirect3DDevice9Ex;
struct IDirect3DSurface9;
#endif
namespace cv { namespace directx {
namespace ocl {
using namespace cv::ocl;
// TODO static functions in the Context class
CV_EXPORTS Context2& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device);
CV_EXPORTS Context2& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device);
CV_EXPORTS Context2& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex);
CV_EXPORTS Context2& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9);
} // namespace cv::directx::ocl
CV_EXPORTS void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D);
CV_EXPORTS void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst);
CV_EXPORTS void convertToD3D10Texture2D(InputArray src, ID3D10Texture2D* pD3D10Texture2D);
CV_EXPORTS void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst);
CV_EXPORTS void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle = NULL);
CV_EXPORTS void convertFromDirect3DSurface9(IDirect3DSurface9* pDirect3DSurface9, OutputArray dst, void* surfaceSharedHandle = NULL);
// Get OpenCV type from DirectX type, return -1 if there is no equivalent
CV_EXPORTS int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT); // enum DXGI_FORMAT for D3D10/D3D11
// Get OpenCV type from DirectX type, return -1 if there is no equivalent
CV_EXPORTS int getTypeFromD3DFORMAT(const int iD3DFORMAT); // enum D3DTYPE for D3D9
} } // namespace cv::directx
#endif // __OPENCV_CORE_DIRECTX_HPP__
...@@ -215,10 +215,33 @@ public: ...@@ -215,10 +215,33 @@ public:
Program getProg(const ProgramSource2& prog, Program getProg(const ProgramSource2& prog,
const String& buildopt, String& errmsg); const String& buildopt, String& errmsg);
static Context2& getDefault(); static Context2& getDefault(bool initialize = true);
void* ptr() const; void* ptr() const;
struct Impl;
inline struct Impl* _getImpl() const { return p; };
protected: protected:
Impl* p;
};
// TODO Move to internal header
void initializeContextFromHandle(Context2& ctx, void* platform, void* context, void* device);
class CV_EXPORTS Platform
{
public:
Platform();
~Platform();
Platform(const Platform& p);
Platform& operator = (const Platform& p);
void* ptr() const;
static Platform& getDefault();
struct Impl; struct Impl;
inline struct Impl* _getImpl() const { return p; };
protected:
Impl* p; Impl* p;
}; };
......
/*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
/*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*/
#if defined(HAVE_DIRECTX)
#include <d3d11.h>
#include <d3d10.h>
#include <d3d9.h>
#ifdef HAVE_OPENCL
#include "opencv2/core/opencl/runtime/opencl_core.hpp"
#include <CL/cl_d3d11.h>
#include <CL/cl_d3d10.h>
#include <CL/cl_dx9_media_sharing.h>
#endif // HAVE_OPENCL
#endif // HAVE_DIRECTX
...@@ -1433,21 +1433,6 @@ void finish2() ...@@ -1433,21 +1433,6 @@ void finish2()
void release() { if( CV_XADD(&refcount, -1) == 1 ) delete this; } \ void release() { if( CV_XADD(&refcount, -1) == 1 ) delete this; } \
int refcount int refcount
class Platform
{
public:
Platform();
~Platform();
Platform(const Platform& p);
Platform& operator = (const Platform& p);
void* ptr() const;
static Platform& getDefault();
protected:
struct Impl;
Impl* p;
};
struct Platform::Impl struct Platform::Impl
{ {
Impl() Impl()
...@@ -1843,6 +1828,12 @@ const Device& Device::getDefault() ...@@ -1843,6 +1828,12 @@ const Device& Device::getDefault()
struct Context2::Impl struct Context2::Impl
{ {
Impl()
{
refcount = 1;
handle = 0;
}
Impl(int dtype0) Impl(int dtype0)
{ {
refcount = 1; refcount = 1;
...@@ -1925,7 +1916,6 @@ struct Context2::Impl ...@@ -1925,7 +1916,6 @@ struct Context2::Impl
cl_context handle; cl_context handle;
std::vector<Device> devices; std::vector<Device> devices;
bool initialized;
typedef ProgramSource2::hash_t hash_t; typedef ProgramSource2::hash_t hash_t;
...@@ -2007,10 +1997,12 @@ const Device& Context2::device(size_t idx) const ...@@ -2007,10 +1997,12 @@ const Device& Context2::device(size_t idx) const
return !p || idx >= p->devices.size() ? dummy : p->devices[idx]; return !p || idx >= p->devices.size() ? dummy : p->devices[idx];
} }
Context2& Context2::getDefault() Context2& Context2::getDefault(bool initialize)
{ {
static Context2 ctx; static Context2 ctx;
if( !ctx.p && haveOpenCL() ) if(!ctx.p && haveOpenCL())
{
if (initialize)
{ {
// do not create new Context2 right away. // do not create new Context2 right away.
// First, try to retrieve existing context of the same type. // First, try to retrieve existing context of the same type.
...@@ -2024,6 +2016,11 @@ Context2& Context2::getDefault() ...@@ -2024,6 +2016,11 @@ Context2& Context2::getDefault()
if(!ctx.p) if(!ctx.p)
ctx.create(Device::TYPE_CPU); ctx.create(Device::TYPE_CPU);
} }
else
{
ctx.p = new Impl();
}
}
return ctx; return ctx;
} }
...@@ -2034,6 +2031,30 @@ Program Context2::getProg(const ProgramSource2& prog, ...@@ -2034,6 +2031,30 @@ Program Context2::getProg(const ProgramSource2& prog,
return p ? p->getProg(prog, buildopts, errmsg) : Program(); return p ? p->getProg(prog, buildopts, errmsg) : Program();
} }
void initializeContextFromHandle(Context2& ctx, void* platform, void* _context, void* _device)
{
cl_context context = (cl_context)_context;
cl_device_id device = (cl_device_id)_device;
// cleanup old context
Context2::Impl* impl = ctx._getImpl();
if (impl->handle)
{
cl_int status = clReleaseContext(impl->handle);
(void)status;
}
impl->devices.clear();
impl->handle = context;
impl->devices.resize(1);
impl->devices[0].set(device);
Platform& p = Platform::getDefault();
Platform::Impl* pImpl = p._getImpl();
pImpl->handle = (cl_platform_id)platform;
}
struct Queue::Impl struct Queue::Impl
{ {
Impl(const Context2& c, const Device& d) Impl(const Context2& c, const Device& d)
......
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
#ifndef __OPENCV_PRECOMP_H__ #ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__ #define __OPENCV_PRECOMP_H__
#include "opencv2/opencv_modules.hpp"
#include "cvconfig.h"
#include "opencv2/core/utility.hpp" #include "opencv2/core/utility.hpp"
#include "opencv2/core/core_c.h" #include "opencv2/core/core_c.h"
#include "opencv2/core/cuda.hpp" #include "opencv2/core/cuda.hpp"
......
...@@ -15,6 +15,10 @@ add_subdirectory(cpp) ...@@ -15,6 +15,10 @@ add_subdirectory(cpp)
add_subdirectory(gpu) add_subdirectory(gpu)
add_subdirectory(ocl) add_subdirectory(ocl)
if(WIN32 AND HAVE_DIRECTX)
add_subdirectory(directx)
endif()
if(ANDROID AND BUILD_ANDROID_EXAMPLES) if(ANDROID AND BUILD_ANDROID_EXAMPLES)
add_subdirectory(android) add_subdirectory(android)
endif() endif()
...@@ -62,6 +66,10 @@ add_subdirectory(cpp) ...@@ -62,6 +66,10 @@ add_subdirectory(cpp)
add_subdirectory(ocl) add_subdirectory(ocl)
# FIXIT: can't use cvconfig.h in samples: add_subdirectory(gpu) # FIXIT: can't use cvconfig.h in samples: add_subdirectory(gpu)
if(WIN32)
add_subdirectory(directx)
endif()
# #
# END OF BUILD CASE 2: Build samples with library binaries # END OF BUILD CASE 2: Build samples with library binaries
# #
......
SET(OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS opencv_core opencv_imgproc opencv_highgui)
ocv_check_dependencies(${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS})
if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
set(project "directx")
string(TOUPPER "${project}" project_upper)
project("${project}_samples")
ocv_include_modules(${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS})
# ---------------------------------------------
# Define executable targets
# ---------------------------------------------
MACRO(OPENCV_DEFINE_DIRECTX_EXAMPLE name srcs)
set(the_target "example_${project}_${name}")
add_executable(${the_target} ${srcs})
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_DIRECTX_SAMPLES_REQUIRED_DEPS})
set_target_properties(${the_target} PROPERTIES
OUTPUT_NAME "${project}-example-${name}"
PROJECT_LABEL "(EXAMPLE_${project_upper}) ${name}")
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${the_target} PROPERTIES FOLDER "samples//${project}")
endif()
if(WIN32)
if(MSVC AND NOT BUILD_SHARED_LIBS)
set_target_properties(${the_target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /DEBUG")
endif()
install(TARGETS ${the_target} RUNTIME DESTINATION "${OPENCV_SAMPLES_BIN_INSTALL_PATH}/${project}" COMPONENT main)
endif()
ENDMACRO()
file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
foreach(sample_filename ${all_samples})
get_filename_component(sample ${sample_filename} NAME_WE)
file(GLOB sample_srcs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${sample}.*)
OPENCV_DEFINE_DIRECTX_EXAMPLE(${sample} ${sample_srcs})
endforeach()
endif()
#include <windows.h>
#include <d3d10.h>
#pragma comment (lib, "d3d10.lib")
#define USE_D3D10
#define WINDOW_NAME "OpenCV Direct3D 10 Sample"
IDXGISwapChain *swapchain = NULL;
ID3D10Device *dev = NULL;
ID3D10Texture2D *pBackBufferTexture = NULL;
ID3D10Texture2D *pCPUWriteTexture = NULL;
ID3D10Texture2D *pInputTexture = NULL;
ID3D10RenderTargetView *backbuffer = NULL;
#include "d3d_base.inl.hpp"
bool initDirect3D()
{
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
scd.BufferCount = 1; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
scd.BufferDesc.Width = WIDTH; // set the back buffer width
scd.BufferDesc.Height = HEIGHT; // set the back buffer height
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = hWnd; // the window to be used
scd.SampleDesc.Count = 1; // how many multisamples
scd.Windowed = TRUE; // windowed/full-screen mode
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // allow full-screen switching
if (FAILED(D3D10CreateDeviceAndSwapChain(
NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
0,
D3D10_SDK_VERSION,
&scd,
&swapchain,
&dev)))
{
return false;
}
if (FAILED(swapchain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBufferTexture)))
{
return false;
}
if (FAILED(dev->CreateRenderTargetView(pBackBufferTexture, NULL, &backbuffer)))
{
return false;
}
dev->OMSetRenderTargets(1, &backbuffer, NULL);
D3D10_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D10_VIEWPORT));
viewport.Width = WIDTH;
viewport.Height = HEIGHT;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 0.0f;
dev->RSSetViewports(1, &viewport);
return true;
}
bool initDirect3DTextures()
{
{ // Create texture for demo 0
D3D10_TEXTURE2D_DESC desc = { 0 };
desc.Width = WIDTH;
desc.Height = HEIGHT;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
desc.Usage = D3D10_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
if (FAILED(dev->CreateTexture2D(&desc, NULL, &pCPUWriteTexture)))
{
std::cerr << "Can't create texture for CPU write sample" << std::endl;
return false;
}
}
{ // Create Read-only texture
cv::Mat inputMat = getInputTexture();
D3D10_TEXTURE2D_DESC desc = { 0 };
desc.Width = inputMat.size().width;
desc.Height = inputMat.size().height;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
desc.Usage = D3D10_USAGE_IMMUTABLE;
desc.CPUAccessFlags = cv::ocl::useOpenCL() ? 0 : D3D10_CPU_ACCESS_READ;
D3D10_SUBRESOURCE_DATA srInitData;
srInitData.pSysMem = inputMat.data;
srInitData.SysMemPitch = (UINT)inputMat.step[0];
if (FAILED(dev->CreateTexture2D(&desc, &srInitData, &pInputTexture)))
{
std::cerr << "Can't create texture with input image" << std::endl;
return false;
}
}
return true;
}
void cleanUp(void)
{
if (swapchain) swapchain->SetFullscreenState(FALSE, NULL); // switch to windowed mode
SAFE_RELEASE(swapchain);
SAFE_RELEASE(pCPUWriteTexture);
SAFE_RELEASE(pInputTexture);
SAFE_RELEASE(pBackBufferTexture);
SAFE_RELEASE(backbuffer);
SAFE_RELEASE(dev);
}
void render(void)
{
// check to make sure you have a valid Direct3D device
CV_Assert(dev);
renderToD3DObject();
// switch the back buffer and the front buffer
swapchain->Present(0, 0);
}
#include <windows.h>
#include <d3d11.h>
#pragma comment (lib, "d3d11.lib")
#define USE_D3D11
#define WINDOW_NAME "OpenCV Direct3D 11 Sample"
IDXGISwapChain *swapchain = NULL;
ID3D11Device *dev = NULL;
ID3D11DeviceContext *devcon = NULL;
ID3D11Texture2D *pBackBufferTexture = NULL;
ID3D11Texture2D *pCPUWriteTexture = NULL;
ID3D11Texture2D *pInputTexture = NULL;
ID3D11RenderTargetView *backbuffer = NULL;
#include "d3d_base.inl.hpp"
bool initDirect3D()
{
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
scd.BufferCount = 1; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
scd.BufferDesc.Width = WIDTH; // set the back buffer width
scd.BufferDesc.Height = HEIGHT; // set the back buffer height
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = hWnd; // the window to be used
scd.SampleDesc.Count = 1; // how many multisamples
scd.Windowed = TRUE; // windowed/full-screen mode
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // allow full-screen switching
if (FAILED(D3D11CreateDeviceAndSwapChain(
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
0,
NULL,
0,
D3D11_SDK_VERSION,
&scd,
&swapchain,
&dev,
NULL,
&devcon)))
{
return false;
}
if (FAILED(swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBufferTexture)))
{
return false;
}
if (FAILED(dev->CreateRenderTargetView(pBackBufferTexture, NULL, &backbuffer)))
{
return false;
}
devcon->OMSetRenderTargets(1, &backbuffer, NULL);
D3D11_VIEWPORT viewport = { 0 };
viewport.Width = WIDTH;
viewport.Height = HEIGHT;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 0.0f;
devcon->RSSetViewports(1, &viewport);
return true;
}
bool initDirect3DTextures()
{
{ // Create texture for demo 0
D3D11_TEXTURE2D_DESC desc = { 0 };
desc.Width = WIDTH;
desc.Height = HEIGHT;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
if (FAILED(dev->CreateTexture2D(&desc, NULL, &pCPUWriteTexture)))
{
std::cerr << "Can't create texture for CPU write sample" << std::endl;
return false;
}
}
{ // Create Read-only texture
cv::Mat inputMat = getInputTexture();
D3D11_TEXTURE2D_DESC desc = { 0 };
desc.Width = inputMat.size().width;
desc.Height = inputMat.size().height;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.CPUAccessFlags = cv::ocl::useOpenCL() ? 0 : D3D11_CPU_ACCESS_READ;
D3D11_SUBRESOURCE_DATA srInitData;
srInitData.pSysMem = inputMat.data;
srInitData.SysMemPitch = (UINT)inputMat.step[0];
if (FAILED(dev->CreateTexture2D(&desc, &srInitData, &pInputTexture)))
{
std::cerr << "Can't create texture with input image" << std::endl;
return false;
}
}
return true;
}
void cleanUp(void)
{
if (swapchain) swapchain->SetFullscreenState(FALSE, NULL); // switch to windowed mode
SAFE_RELEASE(swapchain);
SAFE_RELEASE(pCPUWriteTexture);
SAFE_RELEASE(pInputTexture);
SAFE_RELEASE(pBackBufferTexture);
SAFE_RELEASE(backbuffer);
SAFE_RELEASE(dev);
SAFE_RELEASE(devcon);
}
void render(void)
{
// check to make sure you have a valid Direct3D device
CV_Assert(dev);
renderToD3DObject();
// switch the back buffer and the front buffer
swapchain->Present(0, 0);
}
#include <windows.h>
#include <d3d9.h>
#pragma comment (lib, "d3d9.lib")
#define USE_D3D9
#define WINDOW_NAME "OpenCV Direct3D 9 Sample"
IDirect3D9 *pD3D = NULL;
IDirect3DDevice9 *dev = NULL;
IDirect3DSurface9 *pBackBuffer = NULL;
IDirect3DSurface9 *pCPUWriteSurface = NULL; // required name
IDirect3DSurface9 *pReadOnlySurface = NULL; // required name
HANDLE readOnlySurfaceShared = 0; // required name
IDirect3DSurface9 *pSurface = NULL; // required name
HANDLE surfaceShared = 0; // required name
#include "d3d_base.inl.hpp"
bool initDirect3D(void)
{
if (NULL == (pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
{
return false;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));
DWORD flags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_NOWINDOWCHANGES
| D3DCREATE_MULTITHREADED;
d3dpp.Windowed = true;
d3dpp.Flags = 0;
d3dpp.BackBufferCount = 0;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferHeight = HEIGHT;
d3dpp.BackBufferWidth = WIDTH;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, flags, &d3dpp, &dev)))
{
return false;
}
if (FAILED(dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer)))
{
return false;
}
return true;
}
bool initDirect3DTextures()
{
// Note: sharing is not supported on some platforms
if (FAILED(dev->CreateOffscreenPlainSurface(WIDTH, HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface, NULL/*&surfaceShared*/)))
{
std::cerr << "Can't create surface for result" << std::endl;
return false;
}
// Note: sharing is not supported on some platforms
if (FAILED(dev->CreateOffscreenPlainSurface(WIDTH, HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pReadOnlySurface, NULL/*&readOnlySurfaceShared*/)))
{
std::cerr << "Can't create read only surface" << std::endl;
return false;
}
else
{
IDirect3DSurface9* pTmpSurface;
if (FAILED(dev->CreateOffscreenPlainSurface(WIDTH, HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTmpSurface, NULL)))
{
std::cerr << "Can't create temp surface for CPU write" << std::endl;
return false;
}
D3DLOCKED_RECT memDesc = {0, NULL};
RECT rc = {0, 0, WIDTH, HEIGHT};
if (SUCCEEDED(pTmpSurface->LockRect(&memDesc, &rc, 0)))
{
cv::Mat m(cv::Size(WIDTH, HEIGHT), CV_8UC4, memDesc.pBits, (int)memDesc.Pitch);
getInputTexture().copyTo(m);
pTmpSurface->UnlockRect();
dev->StretchRect(pTmpSurface, NULL, pReadOnlySurface, NULL, D3DTEXF_NONE);
}
else
{
std::cerr << "Can't LockRect() on surface" << std::endl;
}
pTmpSurface->Release();
}
if (FAILED(dev->CreateOffscreenPlainSurface(WIDTH, HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pCPUWriteSurface, NULL)))
{
std::cerr << "Can't create surface for CPU write" << std::endl;
return false;
}
return true;
}
void render(void)
{
// check to make sure you have a valid Direct3D device
CV_Assert(dev);
renderToD3DObject();
if (g_sampleType == 0)
{
// nothing
}
else if (g_sampleType == 1)
{
if (FAILED(dev->StretchRect(pCPUWriteSurface, NULL, pBackBuffer, NULL, D3DTEXF_NONE)))
{
std::cerr << "Can't StretchRect()" << std::endl;
}
}
else
{
if (FAILED(dev->StretchRect(pSurface, NULL, pBackBuffer, NULL, D3DTEXF_NONE)))
{
std::cerr << "Can't StretchRect()" << std::endl;
}
}
if (SUCCEEDED(dev -> BeginScene()))
{
// end the scene
dev -> EndScene();
}
// present the back buffer contents to the display
dev->Present(NULL, NULL, NULL, NULL);
}
void cleanUp (void)
{
SAFE_RELEASE(pCPUWriteSurface);
SAFE_RELEASE(pReadOnlySurface);
SAFE_RELEASE(pSurface);
SAFE_RELEASE(pBackBuffer);
SAFE_RELEASE(dev);
SAFE_RELEASE(pD3D);}
#include <windows.h>
#include <d3d9.h>
#pragma comment (lib, "d3d9.lib")
#define USE_D3DEX
#define WINDOW_NAME "OpenCV Direct3D 9 Ex Sample"
IDirect3D9Ex *pD3D = NULL;
IDirect3DDevice9Ex *dev = NULL;
IDirect3DSurface9 *pBackBuffer = NULL;
IDirect3DSurface9 *pCPUWriteSurface = NULL; // required name
IDirect3DSurface9 *pReadOnlySurface = NULL; // required name
HANDLE readOnlySurfaceShared = 0; // required name
IDirect3DSurface9 *pSurface = NULL; // required name
HANDLE surfaceShared = 0; // required name
#include "d3d_base.inl.hpp"
bool initDirect3D(void)
{
if (FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D)))
{
return false;
}
D3DDISPLAYMODEEX ddm;
ZeroMemory(&ddm, sizeof(ddm));
ddm.Size = sizeof(D3DDISPLAYMODEEX);
D3DDISPLAYROTATION rotation;
if (FAILED(pD3D->GetAdapterDisplayModeEx(D3DADAPTER_DEFAULT, &ddm, &rotation)))
{
return false;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));
DWORD flags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_NOWINDOWCHANGES
| D3DCREATE_MULTITHREADED;
d3dpp.Windowed = true;
d3dpp.Flags = 0;
d3dpp.BackBufferCount = 0;
d3dpp.BackBufferFormat = ddm.Format;
d3dpp.BackBufferHeight = HEIGHT;
d3dpp.BackBufferWidth = WIDTH;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
if (FAILED(pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, flags, &d3dpp, NULL, &dev)))
{
return false;
}
if (FAILED(dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer)))
{
return false;
}
return true;
}
bool initDirect3DTextures()
{
if (FAILED(dev->CreateOffscreenPlainSurface(WIDTH, HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pSurface, &surfaceShared)))
{
std::cerr << "Can't create surface for result" << std::endl;
return false;
}
if (FAILED(dev->CreateOffscreenPlainSurface(WIDTH, HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pReadOnlySurface, &readOnlySurfaceShared)))
{
std::cerr << "Can't create read only surface" << std::endl;
return false;
}
else
{
IDirect3DSurface9* pTmpSurface;
if (FAILED(dev->CreateOffscreenPlainSurface(WIDTH, HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTmpSurface, NULL)))
{
std::cerr << "Can't create temp surface for CPU write" << std::endl;
return false;
}
D3DLOCKED_RECT memDesc = {0, NULL};
RECT rc = {0, 0, WIDTH, HEIGHT};
if (SUCCEEDED(pTmpSurface->LockRect(&memDesc, &rc, 0)))
{
cv::Mat m(cv::Size(WIDTH, HEIGHT), CV_8UC4, memDesc.pBits, (int)memDesc.Pitch);
getInputTexture().copyTo(m);
pTmpSurface->UnlockRect();
dev->StretchRect(pTmpSurface, NULL, pReadOnlySurface, NULL, D3DTEXF_NONE);
}
else
{
std::cerr << "Can't LockRect() on surface" << std::endl;
}
pTmpSurface->Release();
}
if (FAILED(dev->CreateOffscreenPlainSurface(WIDTH, HEIGHT, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pCPUWriteSurface, NULL)))
{
std::cerr << "Can't create surface for CPU write" << std::endl;
return false;
}
return true;
}
void render(void)
{
// check to make sure you have a valid Direct3D device
CV_Assert(dev);
renderToD3DObject();
if (g_sampleType == 0)
{
// nothing
}
else if (g_sampleType == 1)
{
if (FAILED(dev->StretchRect(pCPUWriteSurface, NULL, pBackBuffer, NULL, D3DTEXF_NONE)))
{
std::cerr << "Can't StretchRect()" << std::endl;
}
}
else
{
if (FAILED(dev->StretchRect(pSurface, NULL, pBackBuffer, NULL, D3DTEXF_NONE)))
{
std::cerr << "Can't StretchRect()" << std::endl;
}
}
if (SUCCEEDED(dev -> BeginScene()))
{
// end the scene
dev -> EndScene();
}
// present the back buffer contents to the display
dev->Present(NULL, NULL, NULL, NULL);
}
void cleanUp (void)
{
SAFE_RELEASE(pCPUWriteSurface);
SAFE_RELEASE(pReadOnlySurface);
SAFE_RELEASE(pSurface);
SAFE_RELEASE(pBackBuffer);
SAFE_RELEASE(dev);
SAFE_RELEASE(pD3D);
}
//
// 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;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment