@ -48,13 +48,13 @@
# ifdef HAVE_DIRECTX
# include <vector>
# include "directx.inc.hpp"
# include "directx.inc.hpp"
# else // HAVE_DIRECTX
# define NO_DIRECTX_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
# endif
# ifndef HAVE_OPENCL
# define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
# define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
# endif // HAVE_OPENCL
namespace cv { namespace directx {
@ -168,7 +168,7 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
//case DXGI_FORMAT_BC7_TYPELESS:
//case DXGI_FORMAT_BC7_UNORM:
//case DXGI_FORMAT_BC7_UNORM_SRGB:
# ifdef HAVE_DIRECTX_NV12
# ifdef HAVE_DIRECTX_NV12 //D3DX11 should support DXGI_FORMAT_NV12.
case DXGI_FORMAT_NV12 : return CV_8UC3 ;
# endif
default : break ;
@ -256,75 +256,70 @@ Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
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
size_t exts_len ;
cv : : AutoBuffer < char > extensions ;
bool is_support_cl_khr_d3d11_sharing = false ;
# ifdef HAVE_OPENCL_D3D11_NV
bool is_support_cl_nv_d3d11_sharing = false ;
# endif
for ( int i = 0 ; i < ( int ) numPlatforms ; i + + )
{
status = clGetPlatformIDs ( numPlatforms , & platforms [ i ] , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: Can't get number of platforms " ) ;
status = clGetPlatformInfo ( platforms [ i ] , CL_PLATFORM_EXTENSIONS , 0 , NULL , & exts_len ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: Can't get length of CL_PLATFORM_EXTENSIONS " ) ;
extensions . resize ( exts_len ) ;
status = clGetPlatformInfo ( platforms [ i ] , CL_PLATFORM_EXTENSIONS , exts_len , static_cast < void * > ( extensions . data ( ) ) , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: No available CL_PLATFORM_EXTENSIONS " ) ;
if ( strstr ( extensions . data ( ) , " cl_khr_d3d11_sharing " ) )
is_support_cl_khr_d3d11_sharing = true ;
# ifdef HAVE_OPENCL_D3D11_NV
if ( strstr ( extensions . data ( ) , " cl_nv_d3d11_sharing " ) )
is_support_cl_nv_d3d11_sharing = true ;
# endif
}
# ifdef HAVE_OPENCL_D3D11_NV
if ( ! is_support_cl_nv_d3d11_sharing & & ! is_support_cl_khr_d3d11_sharing )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: No supported extensions " ) ;
# else
if ( ! is_support_cl_khr_d3d11_sharing )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: No supported extensions " ) ;
# endif
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 )
# ifdef HAVE_OPENCL_D3D11_NV
if ( is_support_cl_nv_d3d11_sharing )
{
// try with CL_ALL_DEVICES_FOR_D3D11_KHR
// try with CL_PREFERRED_DEVICES_FOR_D3D11_NV
for ( int i = 0 ; i < ( int ) numPlatforms ; i + + )
{
clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = ( clGetDeviceIDsFromD3D11KHR _fn )
clGetExtensionFunctionAddressForPlatform ( platforms [ i ] , " clGetDeviceIDsFromD3D11KHR " ) ;
if ( ! clGetDeviceIDsFromD3D11KHR )
clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = ( clGetDeviceIDsFromD3D11NV_fn )
clGetExtensionFunctionAddressForPlatform ( platforms [ i ] , " clGetDeviceIDsFromD3D11NV " ) ;
if ( ! clGetDeviceIDsFromD3D11NV )
continue ;
device = NULL ;
numDevices = 0 ;
status = clGetDeviceIDsFromD3D11KHR ( platforms [ i ] , CL_D3D11_DEVICE_KHR , pD3D11Device ,
CL_ALL_DEVICES_FOR_D3D11_KHR , 1 , & device , & numDevices ) ;
status = clGetDeviceIDsFromD3D11NV ( platforms [ i ] , CL_D3D11_DEVICE_NV , pD3D11Device ,
CL_PREFERRED_DEVICES_FOR_D3D11_NV , 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
CL_CONTEXT_D3D11_DEVICE_NV , ( cl_context_properties ) ( pD3D11Device ) ,
//CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
0
} ;
context = clCreateContext ( properties , 1 , & device , NULL , NULL , & status ) ;
if ( status ! = CL_SUCCESS )
{
@ -338,9 +333,127 @@ Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
}
}
if ( found < 0 )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: Can't create context for DirectX interop " ) ;
{
// try with CL_ALL_DEVICES_FOR_D3D11_NV
for ( int i = 0 ; i < ( int ) numPlatforms ; i + + )
{
clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = ( clGetDeviceIDsFromD3D11NV_fn )
clGetExtensionFunctionAddressForPlatform ( platforms [ i ] , " clGetDeviceIDsFromD3D11NV " ) ;
if ( ! clGetDeviceIDsFromD3D11NV )
continue ;
device = NULL ;
numDevices = 0 ;
status = clGetDeviceIDsFromD3D11NV ( platforms [ i ] , CL_D3D11_DEVICE_NV , pD3D11Device ,
CL_ALL_DEVICES_FOR_D3D11_NV , 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_NV , ( cl_context_properties ) ( pD3D11Device ) ,
//CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
0
} ;
context = clCreateContext ( properties , 1 , & device , NULL , NULL , & status ) ;
if ( status ! = CL_SUCCESS )
{
clReleaseDevice ( device ) ;
}
else
{
found = i ;
break ;
}
}
}
}
}
# endif
if ( is_support_cl_khr_d3d11_sharing )
{
if ( found < 0 )
{
// 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 " ) ;
}
Context & ctx = Context : : getDefault ( false ) ;
initializeContextFromHandle ( ctx , platforms [ found ] , context , device ) ;
@ -679,29 +792,85 @@ Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9
} // namespace cv::ocl
# if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
# ifdef HAVE_OPENCL_D3D11_NV
clCreateFromD3D11Texture2DNV_fn clCreateFromD3D11Texture2DNV = NULL ;
clEnqueueAcquireD3D11ObjectsNV_fn clEnqueueAcquireD3D11ObjectsNV = NULL ;
clEnqueueReleaseD3D11ObjectsNV_fn clEnqueueReleaseD3D11ObjectsNV = NULL ;
# endif
clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL ;
clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL ;
clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL ;
static void __OpenCLinitializeD3D11 ( )
static bool __OpenCLinitializeD3D11 ( )
{
using namespace cv : : ocl ;
static cl_platform_id initializedPlatform = NULL ;
cl_platform_id platform = ( cl_platform_id ) Platform : : getDefault ( ) . ptr ( ) ;
if ( initializedPlatform ! = platform )
bool useCLNVEXT = false ;
size_t exts_len ;
cl_int status = clGetPlatformInfo ( platform , CL_PLATFORM_EXTENSIONS , 0 , NULL , & exts_len ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: Can't get length of CL_PLATFORM_EXTENSIONS " ) ;
cv : : AutoBuffer < char > extensions ( exts_len ) ;
status = clGetPlatformInfo ( platform , CL_PLATFORM_EXTENSIONS , exts_len , static_cast < void * > ( extensions . data ( ) ) , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: No available CL_PLATFORM_EXTENSIONS " ) ;
bool is_support_cl_khr_d3d11_sharing = false ;
if ( strstr ( extensions . data ( ) , " cl_khr_d3d11_sharing " ) )
is_support_cl_khr_d3d11_sharing = true ;
# ifdef HAVE_OPENCL_D3D11_NV
bool is_support_cl_nv_d3d11_sharing = false ;
if ( strstr ( extensions . data ( ) , " cl_nv_d3d11_sharing " ) )
is_support_cl_nv_d3d11_sharing = true ;
if ( ! is_support_cl_nv_d3d11_sharing & & ! is_support_cl_khr_d3d11_sharing )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: No supported extensions " ) ;
# else
if ( ! is_support_cl_khr_d3d11_sharing )
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: No supported extensions " ) ;
# endif
# ifdef HAVE_OPENCL_D3D11_NV
if ( is_support_cl_nv_d3d11_sharing )
{
clCreateFromD3D11Texture2DKHR = ( clCreateFromD3D11Texture2DKHR_fn )
clGetExtensionFunctionAddressForPlatform ( platform , " clCreateFromD3D11Texture2DKHR " ) ;
clEnqueueAcquireD3D11ObjectsKHR = ( clEnqueueAcquireD3D11ObjectsKHR_fn )
clGetExtensionFunctionAddressForPlatform ( platform , " clEnqueueAcquireD3D11ObjectsKHR " ) ;
clEnqueueReleaseD3D11ObjectsKHR = ( clEnqueueReleaseD3D11ObjectsKHR_fn )
clGetExtensionFunctionAddressForPlatform ( platform , " clEnqueueReleaseD3D11ObjectsKHR " ) ;
initializedPlatform = platform ;
if ( initializedPlatform ! = platform )
{
clCreateFromD3D11Texture2DNV = ( clCreateFromD3D11Texture2DNV_fn )
clGetExtensionFunctionAddressForPlatform ( platform , " clCreateFromD3D11Texture2DNV " ) ;
clEnqueueAcquireD3D11ObjectsNV = ( clEnqueueAcquireD3D11ObjectsNV_fn )
clGetExtensionFunctionAddressForPlatform ( platform , " clEnqueueAcquireD3D11ObjectsNV " ) ;
clEnqueueReleaseD3D11ObjectsNV = ( clEnqueueReleaseD3D11ObjectsNV_fn )
clGetExtensionFunctionAddressForPlatform ( platform , " clEnqueueReleaseD3D11ObjectsNV " ) ;
initializedPlatform = platform ;
}
if ( clCreateFromD3D11Texture2DNV & & clEnqueueAcquireD3D11ObjectsNV & & clEnqueueReleaseD3D11ObjectsNV )
{
useCLNVEXT = true ;
}
}
if ( ! clCreateFromD3D11Texture2DKHR | | ! clEnqueueAcquireD3D11ObjectsKHR | | ! clEnqueueReleaseD3D11ObjectsKHR )
else
# endif
{
CV_Error ( cv : : Error : : OpenCLInitError , " OpenCL: Can't find functions for D3D11 " ) ;
if ( is_support_cl_khr_d3d11_sharing )
{
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 " ) ;
}
}
}
return useCLNVEXT ;
}
# endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
@ -762,14 +931,9 @@ bool ocl_convert_bgr_to_nv12(
namespace directx {
void convertToD3D11Texture2D ( InputArray src , ID3D11Texture2D * pD3D11Texture2D )
# if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
static void __convertToD3D11Texture2DKHR ( InputArray src , ID3D11Texture2D * pD3D11Texture2D )
{
CV_UNUSED ( src ) ; CV_UNUSED ( pD3D11Texture2D ) ;
# if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR ;
# elif defined(HAVE_OPENCL)
__OpenCLinitializeD3D11 ( ) ;
D3D11_TEXTURE2D_DESC desc = { 0 } ;
pD3D11Texture2D - > GetDesc ( & desc ) ;
@ -797,7 +961,6 @@ void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
# ifdef HAVE_DIRECTX_NV12
cl_mem clImageUV = 0 ;
# endif
clImage = clCreateFromD3D11Texture2DKHR ( context , CL_MEM_WRITE_ONLY , pD3D11Texture2D , 0 , & status ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clCreateFromD3D11Texture2DKHR failed " ) ;
@ -863,22 +1026,108 @@ void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clReleaseMem failed " ) ;
}
# endif
}
# endif
# else
// TODO memcpy
NO_OPENCL_SUPPORT_ERROR ;
# if defined(HAVE_OPENCL_D3D11_NV)
static void __convertToD3D11Texture2DNV ( InputArray src , ID3D11Texture2D * pD3D11Texture2D )
{
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 ) ;
UMat u = src . getUMat ( ) ;
// TODO Add support for roi
CV_Assert ( u . offset = = 0 ) ;
CV_Assert ( u . isContinuous ( ) ) ;
cl_mem clBuffer = ( cl_mem ) u . handle ( ACCESS_READ ) ;
using namespace cv : : ocl ;
Context & ctx = Context : : getDefault ( ) ;
cl_context context = ( cl_context ) ctx . ptr ( ) ;
cl_int status = 0 ;
cl_mem clImage = 0 ;
# ifdef HAVE_DIRECTX_NV12
cl_mem clImageUV = 0 ;
# endif
}
clImage = clCreateFromD3D11Texture2DNV ( context , CL_MEM_WRITE_ONLY , pD3D11Texture2D , 0 , & status ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clCreateFromD3D11Texture2DNV failed " ) ;
# ifdef HAVE_DIRECTX_NV12
if ( DXGI_FORMAT_NV12 = = desc . Format )
{
clImageUV = clCreateFromD3D11Texture2DNV ( context , CL_MEM_WRITE_ONLY , pD3D11Texture2D , 1 , & status ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clCreateFromD3D11Texture2DNV failed " ) ;
}
# endif
cl_command_queue q = ( cl_command_queue ) Queue : : getDefault ( ) . ptr ( ) ;
status = clEnqueueAcquireD3D11ObjectsNV ( q , 1 , & clImage , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueAcquireD3D11ObjectsNV failed " ) ;
void convertFromD3D11Texture2D ( ID3D11Texture2D * pD3D11Texture2D , OutputArray dst )
{
CV_UNUSED ( pD3D11Texture2D ) ; CV_UNUSED ( dst ) ;
# if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR ;
# elif defined(HAVE_OPENCL)
__OpenCLinitializeD3D11 ( ) ;
# ifdef HAVE_DIRECTX_NV12
if ( DXGI_FORMAT_NV12 = = desc . Format )
{
status = clEnqueueAcquireD3D11ObjectsNV ( q , 1 , & clImageUV , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueAcquireD3D11ObjectsNV failed " ) ;
if ( ! ocl : : ocl_convert_bgr_to_nv12 ( clBuffer , ( int ) u . step [ 0 ] , u . cols , u . rows , clImage , clImageUV ) )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: ocl_convert_bgr_to_nv12 failed " ) ;
status = clEnqueueReleaseD3D11ObjectsNV ( q , 1 , & clImageUV , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueReleaseD3D11ObjectsNV failed " ) ;
}
else
# endif
{
size_t offset = 0 ; // TODO
size_t origin [ 3 ] = { 0 , 0 , 0 } ;
size_t region [ 3 ] = { ( size_t ) u . cols , ( size_t ) u . rows , 1 } ;
status = clEnqueueCopyBufferToImage ( q , clBuffer , clImage , offset , origin , region , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueCopyBufferToImage failed " ) ;
}
status = clEnqueueReleaseD3D11ObjectsNV ( q , 1 , & clImage , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueReleaseD3D11ObjectsNV 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 " ) ;
# ifdef HAVE_DIRECTX_NV12
if ( DXGI_FORMAT_NV12 = = desc . Format )
{
status = clReleaseMemObject ( clImageUV ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clReleaseMem failed " ) ;
}
# endif
}
# endif
# if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
static void __convertFromD3D11Texture2DKHR ( ID3D11Texture2D * pD3D11Texture2D , OutputArray dst )
{
D3D11_TEXTURE2D_DESC desc = { 0 } ;
pD3D11Texture2D - > GetDesc ( & desc ) ;
@ -968,10 +1217,144 @@ void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clReleaseMem failed " ) ;
}
# endif
}
# endif
# if defined(HAVE_OPENCL_D3D11_NV)
static void __convertFromD3D11Texture2DNV ( ID3D11Texture2D * pD3D11Texture2D , OutputArray dst )
{
D3D11_TEXTURE2D_DESC desc = { 0 } ;
pD3D11Texture2D - > GetDesc ( & desc ) ;
int textureType = getTypeFromDXGI_FORMAT ( desc . Format ) ;
CV_Assert ( textureType > = 0 ) ;
// 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_mem clBuffer = ( cl_mem ) u . handle ( ACCESS_READ ) ;
using namespace cv : : ocl ;
Context & ctx = Context : : getDefault ( ) ;
cl_context context = ( cl_context ) ctx . ptr ( ) ;
cl_int status = 0 ;
cl_mem clImage = 0 ;
clImage = clCreateFromD3D11Texture2DNV ( context , CL_MEM_READ_ONLY , pD3D11Texture2D , 0 , & status ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clCreateFromD3D11Texture2DNV failed " ) ;
# ifdef HAVE_DIRECTX_NV12
cl_mem clImageUV = 0 ;
if ( DXGI_FORMAT_NV12 = = desc . Format )
{
clImageUV = clCreateFromD3D11Texture2DNV ( context , CL_MEM_READ_ONLY , pD3D11Texture2D , 1 , & status ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clCreateFromD3D11Texture2DNV failed " ) ;
}
# endif
cl_command_queue q = ( cl_command_queue ) Queue : : getDefault ( ) . ptr ( ) ;
status = clEnqueueAcquireD3D11ObjectsNV ( q , 1 , & clImage , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueAcquireD3D11ObjectsNV failed " ) ;
# ifdef HAVE_DIRECTX_NV12
if ( DXGI_FORMAT : : DXGI_FORMAT_NV12 = = desc . Format )
{
status = clEnqueueAcquireD3D11ObjectsNV ( q , 1 , & clImageUV , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueAcquireD3D11ObjectsNV failed " ) ;
if ( ! ocl : : ocl_convert_nv12_to_bgr ( clImage , clImageUV , clBuffer , ( int ) u . step [ 0 ] , u . cols , u . rows ) )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: ocl_convert_nv12_to_bgr failed " ) ;
status = clEnqueueReleaseD3D11ObjectsNV ( q , 1 , & clImageUV , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueReleaseD3D11ObjectsNV failed " ) ;
}
else
# endif
{
size_t offset = 0 ; // TODO
size_t origin [ 3 ] = { 0 , 0 , 0 } ;
size_t region [ 3 ] = { ( size_t ) u . cols , ( size_t ) u . rows , 1 } ;
status = clEnqueueCopyImageToBuffer ( q , clImage , clBuffer , origin , region , offset , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueCopyImageToBuffer failed " ) ;
}
status = clEnqueueReleaseD3D11ObjectsNV ( q , 1 , & clImage , 0 , NULL , NULL ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clEnqueueReleaseD3D11ObjectsNV 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 " ) ;
# ifdef HAVE_DIRECTX_NV12
if ( DXGI_FORMAT_NV12 = = desc . Format )
{
status = clReleaseMemObject ( clImageUV ) ;
if ( status ! = CL_SUCCESS )
CV_Error ( cv : : Error : : OpenCLApiCallError , " OpenCL: clReleaseMem failed " ) ;
}
# endif
}
# endif
void convertToD3D11Texture2D ( InputArray src , ID3D11Texture2D * pD3D11Texture2D )
{
CV_UNUSED ( src ) ; CV_UNUSED ( pD3D11Texture2D ) ;
# if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR ;
# elif !defined(HAVE_OPENCL)
NO_OPENCL_SUPPORT_ERROR ;
# else
// TODO memcpy
bool useCLNVEXT = __OpenCLinitializeD3D11 ( ) ;
if ( ! useCLNVEXT ) {
__convertToD3D11Texture2DKHR ( src , pD3D11Texture2D ) ;
}
# ifdef HAVE_OPENCL_D3D11_NV
else
{
__convertToD3D11Texture2DNV ( src , pD3D11Texture2D ) ;
}
# endif
# endif
}
void convertFromD3D11Texture2D ( ID3D11Texture2D * pD3D11Texture2D , OutputArray dst )
{
CV_UNUSED ( pD3D11Texture2D ) ; CV_UNUSED ( dst ) ;
# if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR ;
# elif !defined(HAVE_OPENCL)
NO_OPENCL_SUPPORT_ERROR ;
# else
bool useCLNVEXT = __OpenCLinitializeD3D11 ( ) ;
if ( ! useCLNVEXT ) {
__convertFromD3D11Texture2DKHR ( pD3D11Texture2D , dst ) ;
}
# ifdef HAVE_OPENCL_D3D11_NV
else
{
__convertFromD3D11Texture2DNV ( pD3D11Texture2D , dst ) ;
}
# endif
# endif
}