d3d11-nv12 interop
fixed issues with ocl nv12 cvt kernel finisged ocl nv12-to-rgba kernel, update dx-interop samples. (ocl rgba-to-nv12 kernel will be added later) an attempt to fix build issue fix for non opencl build issue fix typo fix compilation warnings fix compile issue for Mac (OpenCL) add convertion from rgba to nv12 (still need to debug kernel) remove empty line at the EOF fixed compilation warning
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
#include "opencv2/core/directx.hpp"
|
||||
#include "opencl_kernels_core.hpp"
|
||||
|
||||
#ifdef HAVE_DIRECTX
|
||||
#include <vector>
|
||||
@@ -167,6 +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:
|
||||
case DXGI_FORMAT_NV12: return CV_8UC4;
|
||||
default: break;
|
||||
}
|
||||
return errorType;
|
||||
@@ -701,6 +703,59 @@ static void __OpenCLinitializeD3D11()
|
||||
}
|
||||
#endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
|
||||
|
||||
} // namespace directx
|
||||
|
||||
|
||||
namespace ocl {
|
||||
|
||||
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
|
||||
static
|
||||
bool ocl_convert_nv12_to_rgba(
|
||||
cl_mem clImageY,
|
||||
cl_mem clImageUV,
|
||||
cl_mem clBuffer,
|
||||
int step,
|
||||
int cols,
|
||||
int rows)
|
||||
{
|
||||
ocl::Kernel k;
|
||||
k.create("YUV2RGBA_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, "");
|
||||
if (k.empty())
|
||||
return false;
|
||||
|
||||
k.args(clImageY, clImageUV, clBuffer, step, cols, rows);
|
||||
|
||||
size_t globalsize[] = { cols, rows };
|
||||
return k.run(2, globalsize, 0, false);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
bool ocl_convert_rgba_to_nv12(
|
||||
cl_mem clBuffer,
|
||||
int step,
|
||||
int cols,
|
||||
int rows,
|
||||
cl_mem clImageY,
|
||||
cl_mem clImageUV)
|
||||
{
|
||||
ocl::Kernel k;
|
||||
k.create("RGBA2YUV_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, "");
|
||||
if (k.empty())
|
||||
return false;
|
||||
|
||||
k.args(clBuffer, step, cols, rows, clImageY, clImageUV);
|
||||
|
||||
size_t globalsize[] = { cols, rows };
|
||||
return k.run(2, globalsize, 0, false);
|
||||
}
|
||||
#endif // HAVE_DIRECTX && HAVE_OPENCL
|
||||
|
||||
} // namespace ocl
|
||||
|
||||
|
||||
namespace directx {
|
||||
|
||||
void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
|
||||
{
|
||||
(void)src; (void)pD3D11Texture2D;
|
||||
@@ -719,33 +774,63 @@ void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
|
||||
Size srcSize = src.size();
|
||||
CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
|
||||
|
||||
using namespace cv::ocl;
|
||||
Context& ctx = Context::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_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 = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
|
||||
cl_mem clImage = 0;
|
||||
cl_mem clImageUV = 0;
|
||||
|
||||
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);
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
clImageUV = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
|
||||
|
||||
if(!ocl::ocl_convert_rgba_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV))
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_rgba_to_nv12 failed");
|
||||
|
||||
status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t offset = 0; // TODO
|
||||
size_t origin[3] = { 0, 0, 0 };
|
||||
size_t region[3] = { u.cols, 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 = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
|
||||
@@ -757,11 +842,20 @@ void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
|
||||
status = clReleaseMemObject(clImage); // TODO RAII
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
|
||||
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
status = clReleaseMemObject(clImageUV);
|
||||
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;
|
||||
@@ -776,10 +870,6 @@ void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst
|
||||
int textureType = getTypeFromDXGI_FORMAT(desc.Format);
|
||||
CV_Assert(textureType >= 0);
|
||||
|
||||
using namespace cv::ocl;
|
||||
Context& ctx = Context::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();
|
||||
@@ -788,23 +878,57 @@ void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst
|
||||
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 = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
|
||||
cl_mem clImage = 0;
|
||||
cl_mem clImageUV = 0;
|
||||
|
||||
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);
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
clImageUV = clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
status = clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
|
||||
|
||||
if(!ocl::ocl_convert_nv12_to_rgba(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows))
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_rgba failed");
|
||||
|
||||
status = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t offset = 0; // TODO
|
||||
size_t origin[3] = { 0, 0, 0 };
|
||||
size_t region[3] = { u.cols, 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 = clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
|
||||
@@ -816,6 +940,13 @@ void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst
|
||||
status = clReleaseMemObject(clImage); // TODO RAII
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
|
||||
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
status = clReleaseMemObject(clImageUV);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
|
||||
}
|
||||
#else
|
||||
// TODO memcpy
|
||||
NO_OPENCL_SUPPORT_ERROR;
|
||||
|
||||
Reference in New Issue
Block a user