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:
Vladimir Dudnik
2015-07-29 19:52:03 +03:00
parent c0b544af70
commit d4774ead43
7 changed files with 646 additions and 139 deletions

View File

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