|
|
|
@ -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 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|