1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 07:43:03 +04:00

Copy mpashchenkov's changes

Minor refactoring

Partially address review comments

Move DX-related stuff from the sample to a default source

Simplify the default OneVPL config

Address minor review comments

Add class for the default VPL source

WIP: Add initial stub for tests with description

Removing default vpl source and minor refactoring

Refactor default files

Fix build and application crash

Address review comments

Add test on VPL + OCL interaction compared to CPU behavior

Fix test
This commit is contained in:
Alexey Smirnov
2022-09-23 12:08:29 +01:00
parent 2aad039b4f
commit 4c74e6d89d
16 changed files with 387 additions and 17 deletions
@@ -114,7 +114,8 @@ cv::GArg cv::gimpl::GOCLExecutable::packArg(const GArg &arg)
GAPI_Assert( arg.kind != cv::detail::ArgKind::GMAT
&& arg.kind != cv::detail::ArgKind::GSCALAR
&& arg.kind != cv::detail::ArgKind::GARRAY
&& arg.kind != cv::detail::ArgKind::GOPAQUE);
&& arg.kind != cv::detail::ArgKind::GOPAQUE
&& arg.kind != cv::detail::ArgKind::GFRAME);
if (arg.kind != cv::detail::ArgKind::GOBJREF)
{
@@ -136,6 +137,7 @@ cv::GArg cv::gimpl::GOCLExecutable::packArg(const GArg &arg)
// Note: .at() is intentional for GOpaque as object MUST be already there
// (and constructed by either bindIn/Out or resetInternal)
case GShape::GOPAQUE: return GArg(m_res.slot<cv::detail::OpaqueRef>().at(ref.id));
case GShape::GFRAME: return GArg(m_res.slot<cv::MediaFrame>().at(ref.id));
default:
util::throw_error(std::logic_error("Unsupported GShape type"));
break;
@@ -6,11 +6,32 @@
#include "precomp.hpp"
#include "logger.hpp"
#include <opencv2/gapi/core.hpp>
#include <opencv2/gapi/ocl/core.hpp>
#include <opencv2/gapi/util/throw.hpp>
#include "backends/ocl/goclcore.hpp"
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#pragma comment(lib,"d3d11.lib")
// get rid of generate macro max/min/etc from DX side
#define D3D11_NO_HELPERS
#define NOMINMAX
#include <d3d11.h>
#pragma comment(lib, "dxgi")
#undef NOMINMAX
#undef D3D11_NO_HELPERS
#include <opencv2/core/directx.hpp>
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
#include <opencv2/core/ocl.hpp>
#include "streaming/onevpl/accelerators/surface/dx11_frame_adapter.hpp"
GAPI_OCL_KERNEL(GOCLAdd, cv::gapi::core::GAdd)
{
static void run(const cv::UMat& a, const cv::UMat& b, int dtype, cv::UMat& out)
@@ -523,6 +544,79 @@ GAPI_OCL_KERNEL(GOCLTranspose, cv::gapi::core::GTranspose)
}
};
GAPI_OCL_KERNEL(GOCLBGR, cv::gapi::streaming::GBGR)
{
static void run(const cv::MediaFrame& in, cv::UMat& out)
{
cv::util::suppress_unused_warning(in);
cv::util::suppress_unused_warning(out);
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#ifdef HAVE_ONEVPL
auto d = in.desc();
if (d.fmt != cv::MediaFormat::NV12)
{
GAPI_LOG_FATAL(nullptr, "Unsupported format provided: " << static_cast<int>(d.fmt) <<
". Expected cv::MediaFormat::NV12.");
cv::util::throw_error(std::logic_error("Unsupported MediaFrame format provided"));
}
// FIXME: consider a better solution.
// Current approach cannot be easily extended for other adapters (getHandle).
auto adapterPtr = in.get<cv::gapi::wip::onevpl::VPLMediaFrameDX11Adapter>();
if (adapterPtr == nullptr)
{
GAPI_LOG_FATAL(nullptr, "Unsupported adapter type. Only VPLMediaFrameDX11Adapter is supported");
cv::util::throw_error(std::logic_error("Unsupported adapter type. Only VPLMediaFrameDX11Adapter is supported"));
}
auto params = adapterPtr->getHandle();
auto handle = cv::util::any_cast<mfxHDLPair>(params);
ID3D11Texture2D* texture = reinterpret_cast<ID3D11Texture2D*>(handle.first);
if (texture == nullptr)
{
GAPI_LOG_FATAL(nullptr, "mfxHDLPair contains ID3D11Texture2D that is nullptr. Handle address" <<
reinterpret_cast<uint64_t>(handle.first));
cv::util::throw_error(std::logic_error("mfxHDLPair contains ID3D11Texture2D that is nullptr"));
}
// FIXME: Assuming here that we only have 1 device
// TODO: Textures are reusable, so to improve the peroformance here
// consider creating a hash map texture <-> device/ctx
static thread_local ID3D11Device* pD3D11Device = nullptr;
if (pD3D11Device == nullptr)
{
texture->GetDevice(&pD3D11Device);
}
if (pD3D11Device == nullptr)
{
GAPI_LOG_FATAL(nullptr, "D3D11Texture2D::GetDevice returns pD3D11Device that is nullptr");
cv::util::throw_error(std::logic_error("D3D11Texture2D::GetDevice returns pD3D11Device that is nullptr"));
}
// FIXME: assuming here that the context is always the same
// TODO: Textures are reusable, so to improve the peroformance here
// consider creating a hash map texture <-> device/ctx
static thread_local cv::ocl::Context ctx = cv::directx::ocl::initializeContextFromD3D11Device(pD3D11Device);
if (ctx.ptr() == nullptr)
{
GAPI_LOG_FATAL(nullptr, "initializeContextFromD3D11Device returned null context");
cv::util::throw_error(std::logic_error("initializeContextFromD3D11Device returned null context"));
}
cv::directx::convertFromD3D11Texture2D(texture, out);
#else
GAPI_LOG_FATAL(nullptr, "HAVE_ONEVPL is not set. Please, check your cmake flags");
cv::util::throw_error(std::logic_error("HAVE_ONEVPL is not set. Please, check your cmake flags"));
#endif // HAVE_ONEVPL
#else
GAPI_LOG_FATAL(nullptr, "HAVE_D3D11 or HAVE_DIRECTX is not set. Please, check your cmake flags");
cv::util::throw_error(std::logic_error("HAVE_D3D11 or HAVE_DIRECTX is not set. Please, check your cmake flags"));
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
}
};
cv::GKernelPackage cv::gapi::core::ocl::kernels()
{
static auto pkg = cv::gapi::kernels
@@ -587,6 +681,7 @@ cv::GKernelPackage cv::gapi::core::ocl::kernels()
, GOCLLUT
, GOCLConvertTo
, GOCLTranspose
, GOCLBGR
>();
return pkg;
}