mirror of https://github.com/opencv/opencv.git
Merge pull request #20738 from sivanov-work:merge_master_vpl_dev_select
G-API: oneVPL - Implement IDeviceSelector & default cfg_param-based selector * Initial commit * Add MACRO undef * Change IDeviceSelector, Change Inf sample for choose external device * Fix compilation * Address some comments * Fix compilation * Add missing header * Add EXPORT to dev selector * Add guard * Remove enum type attr * Fix compilation without VPL * Add HAVE_INFER guard in sample * Remove unusable include from tests * Remove unusable include from sample * Remove cl_d3d11 header from unit testpull/20614/head
parent
d33a048d89
commit
1f9a7b8fd3
12 changed files with 1018 additions and 8 deletions
@ -0,0 +1,102 @@ |
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
|
||||
#ifndef GAPI_STREAMING_ONEVPL_DEVICE_SELECTOR_INTERFACE_HPP |
||||
#define GAPI_STREAMING_ONEVPL_DEVICE_SELECTOR_INTERFACE_HPP |
||||
|
||||
#include <limits> |
||||
#include <map> |
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
#include "opencv2/gapi/own/exports.hpp" // GAPI_EXPORTS |
||||
|
||||
namespace cv { |
||||
namespace gapi { |
||||
namespace wip { |
||||
namespace onevpl { |
||||
|
||||
enum class AccelType : uint8_t { |
||||
HOST, |
||||
DX11, |
||||
|
||||
LAST_VALUE = std::numeric_limits<uint8_t>::max() |
||||
}; |
||||
|
||||
GAPI_EXPORTS const char* to_cstring(AccelType type); |
||||
|
||||
struct IDeviceSelector; |
||||
struct GAPI_EXPORTS Device { |
||||
friend struct IDeviceSelector; |
||||
using Ptr = void*; |
||||
|
||||
~Device(); |
||||
const std::string& get_name() const; |
||||
Ptr get_ptr() const; |
||||
AccelType get_type() const; |
||||
private: |
||||
Device(Ptr device_ptr, const std::string& device_name, |
||||
AccelType device_type); |
||||
|
||||
std::string name; |
||||
Ptr ptr; |
||||
AccelType type; |
||||
}; |
||||
|
||||
struct GAPI_EXPORTS Context { |
||||
friend struct IDeviceSelector; |
||||
using Ptr = void*; |
||||
|
||||
~Context(); |
||||
Ptr get_ptr() const; |
||||
AccelType get_type() const; |
||||
private: |
||||
Context(Ptr ctx_ptr, AccelType ctx_type); |
||||
Ptr ptr; |
||||
AccelType type; |
||||
}; |
||||
|
||||
struct GAPI_EXPORTS IDeviceSelector { |
||||
using Ptr = std::shared_ptr<IDeviceSelector>; |
||||
|
||||
struct GAPI_EXPORTS Score { |
||||
friend struct IDeviceSelector; |
||||
using Type = int16_t; |
||||
static constexpr Type MaxActivePriority = std::numeric_limits<Type>::max(); |
||||
static constexpr Type MinActivePriority = 0; |
||||
static constexpr Type MaxPassivePriority = MinActivePriority - 1; |
||||
static constexpr Type MinPassivePriority = std::numeric_limits<Type>::min(); |
||||
|
||||
Score(Type val); |
||||
~Score(); |
||||
|
||||
operator Type () const; |
||||
Type get() const; |
||||
friend bool operator< (Score lhs, Score rhs) { |
||||
return lhs.get() < rhs.get(); |
||||
} |
||||
private: |
||||
Type value; |
||||
}; |
||||
|
||||
using DeviceScoreTable = std::map<Score, Device>; |
||||
using DeviceContexts = std::vector<Context>; |
||||
|
||||
virtual ~IDeviceSelector(); |
||||
virtual DeviceScoreTable select_devices() const = 0; |
||||
virtual DeviceContexts select_context() = 0; |
||||
protected: |
||||
template<typename Entity, typename ...Args> |
||||
static Entity create(Args &&...args) { |
||||
return Entity(std::forward<Args>(args)...); |
||||
} |
||||
}; |
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
|
||||
#endif // GAPI_STREAMING_ONEVPL_DEVICE_SELECTOR_INTERFACE_HPP
|
@ -0,0 +1,314 @@ |
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
|
||||
#ifdef HAVE_ONEVPL |
||||
#include <vpl/mfxvideo.h> |
||||
#include <opencv2/gapi/own/assert.hpp> |
||||
#include <opencv2/gapi/util/variant.hpp> |
||||
|
||||
#include "streaming/onevpl/cfg_param_device_selector.hpp" |
||||
#include "logger.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 <atlbase.h> |
||||
#include <d3d11.h> |
||||
#include <d3d11_4.h> |
||||
#pragma comment(lib, "dxgi") |
||||
#undef D3D11_NO_HELPERS |
||||
#undef NOMINMAX |
||||
|
||||
#include <codecvt> |
||||
#include "opencv2/core/directx.hpp" |
||||
#ifdef HAVE_OPENCL |
||||
#include <CL/cl_d3d11.h> |
||||
#endif |
||||
|
||||
namespace cv { |
||||
namespace gapi { |
||||
namespace wip { |
||||
namespace onevpl { |
||||
|
||||
// TODO Will be changed on generic function from `onevpl_param_parser` as soons as feature merges
|
||||
static mfxVariant cfg_param_to_mfx_variant(const CfgParam& accel_param) { |
||||
mfxVariant ret; |
||||
const CfgParam::value_t& accel_val = accel_param.get_value(); |
||||
if (!cv::util::holds_alternative<std::string>(accel_val)) { |
||||
// expected string or uint32_t as value
|
||||
if (!cv::util::holds_alternative<uint32_t>(accel_val)) { |
||||
throw std::logic_error("Incorrect value type of \"mfxImplDescription.AccelerationMode\" " |
||||
" std::string is expected" ); |
||||
} |
||||
ret.Type = MFX_VARIANT_TYPE_U32; |
||||
ret.Data.U32 = cv::util::get<uint32_t>(accel_val); |
||||
return ret; |
||||
} |
||||
|
||||
const std::string& accel_val_str = cv::util::get<std::string>(accel_val); |
||||
ret.Type = MFX_VARIANT_TYPE_U32; |
||||
if (accel_val_str == "MFX_ACCEL_MODE_NA") { |
||||
ret.Data.U32 = MFX_ACCEL_MODE_NA; |
||||
} else if (accel_val_str == "MFX_ACCEL_MODE_VIA_D3D9") { |
||||
ret.Data.U32 = MFX_ACCEL_MODE_VIA_D3D9; |
||||
} else if (accel_val_str == "MFX_ACCEL_MODE_VIA_D3D11") { |
||||
ret.Data.U32 = MFX_ACCEL_MODE_VIA_D3D11; |
||||
} else if (accel_val_str == "MFX_ACCEL_MODE_VIA_VAAPI") { |
||||
ret.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI; |
||||
} else if (accel_val_str == "MFX_ACCEL_MODE_VIA_VAAPI_DRM_MODESET") { |
||||
ret.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI_DRM_MODESET; |
||||
} else if (accel_val_str == "MFX_ACCEL_MODE_VIA_VAAPI_GLX") { |
||||
ret.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI_GLX; |
||||
} else if (accel_val_str == "MFX_ACCEL_MODE_VIA_VAAPI_X11") { |
||||
ret.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI_X11; |
||||
} else if (accel_val_str == "MFX_ACCEL_MODE_VIA_VAAPI_WAYLAND") { |
||||
ret.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI_WAYLAND; |
||||
} else if (accel_val_str == "MFX_ACCEL_MODE_VIA_HDDLUNITE") { |
||||
ret.Data.U32 = MFX_ACCEL_MODE_VIA_HDDLUNITE; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
CfgParamDeviceSelector::CfgParamDeviceSelector(const CfgParams& cfg_params) : |
||||
suggested_device(IDeviceSelector::create<Device>(nullptr, "CPU", AccelType::HOST)), |
||||
suggested_context(IDeviceSelector::create<Context>(nullptr, AccelType::HOST)) { |
||||
|
||||
auto accel_mode_it = |
||||
std::find_if(cfg_params.begin(), cfg_params.end(), [] (const CfgParam& value) { |
||||
return value.get_name() == "mfxImplDescription.AccelerationMode"; |
||||
}); |
||||
if (accel_mode_it == cfg_params.end()) |
||||
{ |
||||
GAPI_LOG_DEBUG(nullptr, "No HW Accel requested. Use default CPU"); |
||||
return; |
||||
} |
||||
|
||||
GAPI_LOG_DEBUG(nullptr, "Add HW acceleration support"); |
||||
mfxVariant accel_mode = cfg_param_to_mfx_variant(*accel_mode_it); |
||||
|
||||
switch(accel_mode.Data.U32) { |
||||
case MFX_ACCEL_MODE_VIA_D3D11: { |
||||
#ifdef HAVE_DIRECTX |
||||
#ifdef HAVE_D3D11 |
||||
ID3D11Device *hw_handle = nullptr; |
||||
ID3D11DeviceContext* device_context = nullptr; |
||||
|
||||
//Create device
|
||||
UINT creationFlags = 0;//D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
#if defined _DEBUG || defined CV_STATIC_ANALYSIS |
||||
// If the project is in a debug build, enable debugging via SDK Layers with this flag.
|
||||
creationFlags |= D3D11_CREATE_DEVICE_DEBUG; |
||||
#endif |
||||
|
||||
D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, |
||||
D3D_FEATURE_LEVEL_11_0, |
||||
}; |
||||
D3D_FEATURE_LEVEL featureLevel; |
||||
|
||||
CComPtr<IDXGIFactory> adapter_factory; |
||||
CComPtr<IDXGIAdapter> intel_adapters; |
||||
{ |
||||
IDXGIFactory* out_factory = nullptr; |
||||
HRESULT err = CreateDXGIFactory(__uuidof(IDXGIFactory), |
||||
reinterpret_cast<void**>(&out_factory)); |
||||
if (FAILED(err)) { |
||||
throw std::runtime_error("Cannot create CreateDXGIFactory, error: " + std::to_string(HRESULT_CODE(err))); |
||||
} |
||||
adapter_factory.Attach(out_factory); |
||||
} |
||||
|
||||
CComPtr<IDXGIAdapter> intel_adapter; |
||||
UINT adapter_index = 0; |
||||
const unsigned int refIntelVendorID = 0x8086; |
||||
IDXGIAdapter* out_adapter = nullptr; |
||||
|
||||
while (adapter_factory->EnumAdapters(adapter_index, &out_adapter) != DXGI_ERROR_NOT_FOUND) { |
||||
DXGI_ADAPTER_DESC desc{}; |
||||
out_adapter->GetDesc(&desc); |
||||
if (desc.VendorId == refIntelVendorID) { |
||||
intel_adapter.Attach(out_adapter); |
||||
break; |
||||
} |
||||
++adapter_index; |
||||
} |
||||
|
||||
if (!intel_adapter) { |
||||
throw std::runtime_error("No Intel GPU adapter on aboard"); |
||||
} |
||||
|
||||
// Create the Direct3D 11 API device object and a corresponding context.
|
||||
HRESULT err = D3D11CreateDevice(intel_adapter, |
||||
D3D_DRIVER_TYPE_UNKNOWN, |
||||
nullptr, creationFlags, |
||||
featureLevels, ARRAYSIZE(featureLevels), |
||||
D3D11_SDK_VERSION, |
||||
&hw_handle, &featureLevel, |
||||
&device_context); |
||||
if(FAILED(err)) { |
||||
throw std::logic_error("Cannot create D3D11CreateDevice, error: " + std::to_string(HRESULT_CODE(err))); |
||||
} |
||||
|
||||
// oneVPL recommendation
|
||||
{ |
||||
ID3D11Multithread *pD11Multithread = nullptr; |
||||
device_context->QueryInterface(IID_PPV_ARGS(&pD11Multithread)); |
||||
pD11Multithread->SetMultithreadProtected(true); |
||||
pD11Multithread->Release(); |
||||
} |
||||
|
||||
suggested_device = IDeviceSelector::create<Device>(hw_handle, "GPU", AccelType::DX11); |
||||
suggested_context = IDeviceSelector::create<Context>(device_context, AccelType::DX11); |
||||
#else |
||||
GAPI_LOG_WARNING(nullptr, "Unavailable \"mfxImplDescription.AccelerationMode: MFX_ACCEL_MODE_VIA_D3D11\"" |
||||
"was chosen for current project configuration"); |
||||
throw std::logic_error("Unsupported \"mfxImplDescription.AccelerationMode: MFX_ACCEL_MODE_VIA_D3D11\""); |
||||
#endif // HAVE_DIRECTX
|
||||
#endif // HAVE_D3D11
|
||||
break; |
||||
} |
||||
case MFX_ACCEL_MODE_NA: { |
||||
// nothing to do
|
||||
break; |
||||
} |
||||
default: |
||||
throw std::logic_error("Unsupported \"mfxImplDescription.AccelerationMode\" requested: " + |
||||
std::to_string(accel_mode.Data.U32)); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
CfgParamDeviceSelector::CfgParamDeviceSelector(Device::Ptr device_ptr, |
||||
const std::string& device_id, |
||||
Context::Ptr ctx_ptr, |
||||
const CfgParams& cfg_params) : |
||||
suggested_device(IDeviceSelector::create<Device>(nullptr, "CPU", AccelType::HOST)), |
||||
suggested_context(IDeviceSelector::create<Context>(nullptr, AccelType::HOST)) { |
||||
auto accel_mode_it = |
||||
std::find_if(cfg_params.begin(), cfg_params.end(), [] (const CfgParam& value) { |
||||
return value.get_name() == "mfxImplDescription.AccelerationMode"; |
||||
}); |
||||
if (accel_mode_it == cfg_params.end()) { |
||||
GAPI_LOG_WARNING(nullptr, "Cannot deternime \"device_ptr\" type. " |
||||
"Make sure a param \"mfxImplDescription.AccelerationMode\" " |
||||
"presents in configurations and has correct value according to " |
||||
"\"device_ptr\" type"); |
||||
throw std::logic_error("Missing \"mfxImplDescription.AccelerationMode\" param"); |
||||
} |
||||
|
||||
GAPI_LOG_DEBUG(nullptr, "Turn on HW acceleration support for device: " << |
||||
device_ptr << |
||||
", context: " << ctx_ptr); |
||||
if (!device_ptr) { |
||||
GAPI_LOG_WARNING(nullptr, "Empty \"device_ptr\" is not allowed when " |
||||
"param \"mfxImplDescription.AccelerationMode\" existed"); |
||||
throw std::logic_error("Invalid param: \"device_ptr\""); |
||||
} |
||||
|
||||
if (!ctx_ptr) { |
||||
GAPI_LOG_WARNING(nullptr, "Empty \"ctx_ptr\" is not allowed"); |
||||
throw std::logic_error("Invalid param: \"ctx_ptr\""); |
||||
} |
||||
mfxVariant accel_mode = cfg_param_to_mfx_variant(*accel_mode_it); |
||||
|
||||
switch(accel_mode.Data.U32) { |
||||
case MFX_ACCEL_MODE_VIA_D3D11: { |
||||
#ifdef HAVE_DIRECTX |
||||
#ifdef HAVE_D3D11 |
||||
suggested_device = IDeviceSelector::create<Device>(device_ptr, device_id, AccelType::DX11); |
||||
ID3D11Device* dx_device_ptr = |
||||
reinterpret_cast<ID3D11Device*>(suggested_device.get_ptr()); |
||||
dx_device_ptr->AddRef(); |
||||
|
||||
suggested_context = IDeviceSelector::create<Context>(ctx_ptr, AccelType::DX11); |
||||
ID3D11DeviceContext* dx_ctx_ptr = |
||||
reinterpret_cast<ID3D11DeviceContext*>(suggested_context.get_ptr()); |
||||
dx_ctx_ptr->AddRef(); |
||||
#else |
||||
GAPI_LOG_WARNING(nullptr, "Unavailable \"mfxImplDescription.AccelerationMode: MFX_ACCEL_MODE_VIA_D3D11\"" |
||||
"was chosen for current project configuration"); |
||||
throw std::logic_error("Unsupported \"mfxImplDescription.AccelerationMode: MFX_ACCEL_MODE_VIA_D3D11\""); |
||||
#endif // HAVE_DIRECTX
|
||||
#endif // HAVE_D3D11
|
||||
break; |
||||
} |
||||
case MFX_ACCEL_MODE_NA: { |
||||
GAPI_LOG_WARNING(nullptr, "Incompatible \"mfxImplDescription.AccelerationMode: MFX_ACCEL_MODE_NA\" with " |
||||
"\"device_ptr\" and \"ctx_ptr\" arguments. " |
||||
"You should not clarify these arguments with \"MFX_ACCEL_MODE_NA\" mode"); |
||||
throw std::logic_error("Incompatible param: MFX_ACCEL_MODE_NA"); |
||||
} |
||||
default: |
||||
throw std::logic_error("Unsupported \"mfxImplDescription.AccelerationMode\" requested: " + |
||||
std::to_string(accel_mode.Data.U32)); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
CfgParamDeviceSelector::~CfgParamDeviceSelector() { |
||||
GAPI_LOG_INFO(nullptr, "release context: " << suggested_context.get_ptr()); |
||||
AccelType ctype = suggested_context.get_type(); |
||||
switch(ctype) { |
||||
case AccelType::HOST: |
||||
//nothing to do
|
||||
break; |
||||
case AccelType::DX11: { |
||||
#ifdef HAVE_DIRECTX |
||||
#ifdef HAVE_D3D11 |
||||
ID3D11DeviceContext* device_ctx_ptr = |
||||
reinterpret_cast<ID3D11DeviceContext*>(suggested_context.get_ptr()); |
||||
device_ctx_ptr->Release(); |
||||
device_ctx_ptr = nullptr; |
||||
#endif // HAVE_DIRECTX
|
||||
#endif // HAVE_D3D11
|
||||
break; |
||||
} |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
GAPI_LOG_INFO(nullptr, "release device by name: " << |
||||
suggested_device.get_name() << |
||||
", ptr: " << suggested_device.get_ptr()); |
||||
AccelType dtype = suggested_device.get_type(); |
||||
switch(dtype) { |
||||
case AccelType::HOST: |
||||
//nothing to do
|
||||
break; |
||||
case AccelType::DX11: { |
||||
#ifdef HAVE_DIRECTX |
||||
#ifdef HAVE_D3D11 |
||||
ID3D11Device* device_ptr = reinterpret_cast<ID3D11Device*>(suggested_device.get_ptr()); |
||||
device_ptr->Release(); |
||||
device_ptr = nullptr; |
||||
#endif // HAVE_DIRECTX
|
||||
#endif // HAVE_D3D11
|
||||
break; |
||||
} |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
|
||||
CfgParamDeviceSelector::DeviceScoreTable CfgParamDeviceSelector::select_devices() const { |
||||
return {std::make_pair(Score::MaxActivePriority, suggested_device)}; |
||||
} |
||||
|
||||
CfgParamDeviceSelector::DeviceContexts CfgParamDeviceSelector::select_context() { |
||||
return {suggested_context}; |
||||
} |
||||
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
#endif // HAVE_D3D11
|
||||
#endif // HAVE_DIRECTX
|
||||
#endif // HAVE_ONEVPL
|
@ -0,0 +1,44 @@ |
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
|
||||
#ifndef GAPI_STREAMING_ONEVPL_CFG_PARAM_DEVICE_SELECTOR_HPP |
||||
#define GAPI_STREAMING_ONEVPL_CFG_PARAM_DEVICE_SELECTOR_HPP |
||||
|
||||
#ifdef HAVE_ONEVPL |
||||
|
||||
#include <opencv2/gapi/streaming/onevpl/device_selector_interface.hpp> |
||||
#include <opencv2/gapi/streaming/onevpl/cfg_params.hpp> |
||||
#include <opencv2/gapi/streaming/onevpl/source.hpp> |
||||
|
||||
#include "opencv2/gapi/own/exports.hpp" // GAPI_EXPORTS |
||||
|
||||
namespace cv { |
||||
namespace gapi { |
||||
namespace wip { |
||||
namespace onevpl { |
||||
|
||||
struct GAPI_EXPORTS CfgParamDeviceSelector final: public IDeviceSelector { |
||||
CfgParamDeviceSelector(const CfgParams& params = {}); |
||||
CfgParamDeviceSelector(Device::Ptr device_ptr, |
||||
const std::string& device_id, |
||||
Context::Ptr ctx_ptr, |
||||
const CfgParams& params); |
||||
~CfgParamDeviceSelector(); |
||||
|
||||
DeviceScoreTable select_devices() const override; |
||||
DeviceContexts select_context() override; |
||||
|
||||
private: |
||||
Device suggested_device; |
||||
Context suggested_context; |
||||
}; |
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
|
||||
#endif //HAVE_ONEVPL
|
||||
#endif // GAPI_STREAMING_ONEVPL_CFG_PARAM_DEVICE_SELECTOR_HPP
|
@ -0,0 +1,87 @@ |
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
|
||||
#include <stdexcept> |
||||
#include <opencv2/gapi/streaming/onevpl/device_selector_interface.hpp> |
||||
#include <opencv2/gapi/own/assert.hpp> |
||||
|
||||
namespace cv { |
||||
namespace gapi { |
||||
namespace wip { |
||||
namespace onevpl { |
||||
|
||||
const char* to_cstring(AccelType type) { |
||||
|
||||
switch(type) { |
||||
case AccelType::HOST: |
||||
return "HOST"; |
||||
case AccelType::DX11: |
||||
return "DX11"; |
||||
default: |
||||
GAPI_DbgAssert(false && "Unexpected AccelType"); |
||||
break; |
||||
} |
||||
return "UNKNOWN"; |
||||
} |
||||
|
||||
Device::Device(Ptr device_ptr, const std::string& device_name, AccelType device_type) : |
||||
name(device_name), |
||||
ptr(device_ptr), |
||||
type(device_type) { |
||||
} |
||||
|
||||
Device::~Device() { |
||||
} |
||||
|
||||
const std::string& Device::get_name() const { |
||||
return name; |
||||
} |
||||
|
||||
Device::Ptr Device::get_ptr() const { |
||||
return ptr; |
||||
} |
||||
|
||||
AccelType Device::get_type() const { |
||||
return type; |
||||
} |
||||
|
||||
Context::Context(Ptr ctx_ptr, AccelType ctx_type) : |
||||
ptr(ctx_ptr), |
||||
type(ctx_type) { |
||||
} |
||||
|
||||
Context::~Context() { |
||||
} |
||||
|
||||
Context::Ptr Context::get_ptr() const { |
||||
return ptr; |
||||
} |
||||
|
||||
AccelType Context::get_type() const { |
||||
return type; |
||||
} |
||||
|
||||
IDeviceSelector::Score::Score(Type val) : |
||||
value(val) { |
||||
} |
||||
|
||||
IDeviceSelector::Score::~Score() { |
||||
} |
||||
|
||||
IDeviceSelector::Score::operator Type () const { |
||||
return value; |
||||
} |
||||
IDeviceSelector::Score::Type IDeviceSelector::Score::get() const { |
||||
return value; |
||||
} |
||||
|
||||
IDeviceSelector::~IDeviceSelector() { |
||||
} |
||||
|
||||
} // namespace onevpl
|
||||
} // namespace wip
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
@ -0,0 +1,229 @@ |
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
|
||||
|
||||
#include "../test_precomp.hpp" |
||||
|
||||
#include "../common/gapi_tests_common.hpp" |
||||
|
||||
#include <opencv2/gapi/cpu/core.hpp> |
||||
#include <opencv2/gapi/ocl/core.hpp> |
||||
|
||||
#include <opencv2/gapi/streaming/onevpl/source.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> |
||||
#include <codecvt> |
||||
#include "opencv2/core/directx.hpp" |
||||
#undef D3D11_NO_HELPERS |
||||
#undef NOMINMAX |
||||
#endif // HAVE_D3D11
|
||||
#endif // HAVE_DIRECTX
|
||||
|
||||
#ifdef HAVE_ONEVPL |
||||
#include <vpl/mfxvideo.h> |
||||
#include "streaming/onevpl/cfg_param_device_selector.hpp" |
||||
|
||||
namespace opencv_test |
||||
{ |
||||
namespace |
||||
{ |
||||
|
||||
void test_dev_eq(const typename cv::gapi::wip::onevpl::IDeviceSelector::DeviceScoreTable::value_type &scored_device, |
||||
cv::gapi::wip::onevpl::IDeviceSelector::Score expected_score, |
||||
cv::gapi::wip::onevpl::AccelType expected_type, |
||||
cv::gapi::wip::onevpl::Device::Ptr expected_ptr) { |
||||
EXPECT_EQ(std::get<0>(scored_device), expected_score); |
||||
EXPECT_EQ(std::get<1>(scored_device).get_type(), expected_type); |
||||
EXPECT_EQ(std::get<1>(scored_device).get_ptr(), expected_ptr); |
||||
} |
||||
|
||||
void test_ctx_eq(const typename cv::gapi::wip::onevpl::IDeviceSelector::DeviceContexts::value_type &ctx, |
||||
cv::gapi::wip::onevpl::AccelType expected_type, |
||||
cv::gapi::wip::onevpl::Context::Ptr expected_ptr) { |
||||
EXPECT_EQ(ctx.get_type(), expected_type); |
||||
EXPECT_EQ(ctx.get_ptr(), expected_ptr); |
||||
} |
||||
|
||||
void test_host_dev_eq(const typename cv::gapi::wip::onevpl::IDeviceSelector::DeviceScoreTable::value_type &scored_device, |
||||
cv::gapi::wip::onevpl::IDeviceSelector::Score expected_score) { |
||||
test_dev_eq(scored_device, expected_score, |
||||
cv::gapi::wip::onevpl::AccelType::HOST, nullptr); |
||||
} |
||||
|
||||
void test_host_ctx_eq(const typename cv::gapi::wip::onevpl::IDeviceSelector::DeviceContexts::value_type &ctx) { |
||||
test_ctx_eq(ctx, cv::gapi::wip::onevpl::AccelType::HOST, nullptr); |
||||
} |
||||
|
||||
TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDevice) |
||||
{ |
||||
using namespace cv::gapi::wip::onevpl; |
||||
CfgParamDeviceSelector selector; |
||||
IDeviceSelector::DeviceScoreTable devs = selector.select_devices(); |
||||
EXPECT_EQ(devs.size(), 1); |
||||
test_host_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority); |
||||
|
||||
IDeviceSelector::DeviceContexts ctxs = selector.select_context(); |
||||
EXPECT_EQ(ctxs.size(), 1); |
||||
test_host_ctx_eq(*ctxs.begin()); |
||||
} |
||||
|
||||
TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDeviceWithEmptyCfgParam) |
||||
{ |
||||
using namespace cv::gapi::wip::onevpl; |
||||
std::vector<CfgParam> empty_params; |
||||
CfgParamDeviceSelector selector(empty_params); |
||||
IDeviceSelector::DeviceScoreTable devs = selector.select_devices(); |
||||
EXPECT_EQ(devs.size(), 1); |
||||
test_host_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority); |
||||
IDeviceSelector::DeviceContexts ctxs = selector.select_context(); |
||||
EXPECT_EQ(ctxs.size(), 1); |
||||
test_host_ctx_eq(*ctxs.begin()); |
||||
} |
||||
|
||||
TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDeviceWithAccelNACfgParam) |
||||
{ |
||||
using namespace cv::gapi::wip::onevpl; |
||||
std::vector<CfgParam> cfg_params_w_no_accel; |
||||
cfg_params_w_no_accel.push_back(CfgParam::create<uint32_t>("mfxImplDescription.AccelerationMode", |
||||
MFX_ACCEL_MODE_NA)); |
||||
CfgParamDeviceSelector selector(cfg_params_w_no_accel); |
||||
IDeviceSelector::DeviceScoreTable devs = selector.select_devices(); |
||||
EXPECT_EQ(devs.size(), 1); |
||||
test_host_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority); |
||||
|
||||
IDeviceSelector::DeviceContexts ctxs = selector.select_context(); |
||||
EXPECT_EQ(ctxs.size(), 1); |
||||
test_host_ctx_eq(*ctxs.begin()); |
||||
} |
||||
|
||||
#ifdef HAVE_DIRECTX |
||||
#ifdef HAVE_D3D11 |
||||
TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDeviceWithEmptyCfgParam_DX11_ENABLED) |
||||
{ |
||||
using namespace cv::gapi::wip::onevpl; |
||||
std::vector<CfgParam> empty_params; |
||||
CfgParamDeviceSelector selector(empty_params); |
||||
IDeviceSelector::DeviceScoreTable devs = selector.select_devices(); |
||||
EXPECT_EQ(devs.size(), 1); |
||||
test_host_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority); |
||||
|
||||
IDeviceSelector::DeviceContexts ctxs = selector.select_context(); |
||||
EXPECT_EQ(ctxs.size(), 1); |
||||
test_host_ctx_eq(*ctxs.begin()); |
||||
} |
||||
|
||||
TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDeviceWithDX11AccelCfgParam_DX11_ENABLED) |
||||
{ |
||||
using namespace cv::gapi::wip::onevpl; |
||||
std::vector<CfgParam> cfg_params_w_dx11; |
||||
cfg_params_w_dx11.push_back(CfgParam::create<uint32_t>("mfxImplDescription.AccelerationMode", |
||||
MFX_ACCEL_MODE_VIA_D3D11)); |
||||
std::unique_ptr<CfgParamDeviceSelector> selector_ptr; |
||||
EXPECT_NO_THROW(selector_ptr.reset(new CfgParamDeviceSelector(cfg_params_w_dx11))); |
||||
IDeviceSelector::DeviceScoreTable devs = selector_ptr->select_devices(); |
||||
|
||||
EXPECT_EQ(devs.size(), 1); |
||||
test_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority, |
||||
AccelType::DX11, |
||||
std::get<1>(*devs.begin()).get_ptr() /* compare just type */); |
||||
|
||||
IDeviceSelector::DeviceContexts ctxs = selector_ptr->select_context(); |
||||
EXPECT_EQ(ctxs.size(), 1); |
||||
EXPECT_TRUE(ctxs.begin()->get_ptr()); |
||||
} |
||||
|
||||
TEST(OneVPL_Source_Device_Selector_CfgParam, NULLDeviceWithDX11AccelCfgParam_DX11_ENABLED) |
||||
{ |
||||
using namespace cv::gapi::wip::onevpl; |
||||
std::vector<CfgParam> cfg_params_w_dx11; |
||||
cfg_params_w_dx11.push_back(CfgParam::create<uint32_t>("mfxImplDescription.AccelerationMode", |
||||
MFX_ACCEL_MODE_VIA_D3D11)); |
||||
Device::Ptr empty_device_ptr = nullptr; |
||||
Context::Ptr empty_ctx_ptr = nullptr; |
||||
EXPECT_THROW(CfgParamDeviceSelector sel(empty_device_ptr, "GPU", |
||||
empty_ctx_ptr, |
||||
cfg_params_w_dx11), |
||||
std::logic_error); // empty_device_ptr must be invalid
|
||||
} |
||||
|
||||
TEST(OneVPL_Source_Device_Selector_CfgParam, ExternalDeviceWithDX11AccelCfgParam_DX11_ENABLED) |
||||
{ |
||||
using namespace cv::gapi::wip::onevpl; |
||||
ID3D11Device *device = nullptr; |
||||
ID3D11DeviceContext* device_context = nullptr; |
||||
{ |
||||
UINT flags = 0; |
||||
D3D_FEATURE_LEVEL features[] = { D3D_FEATURE_LEVEL_11_1, |
||||
D3D_FEATURE_LEVEL_11_0, |
||||
}; |
||||
D3D_FEATURE_LEVEL feature_level; |
||||
|
||||
// Create the Direct3D 11 API device object and a corresponding context.
|
||||
HRESULT err = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, |
||||
nullptr, flags, |
||||
features, |
||||
ARRAYSIZE(features), D3D11_SDK_VERSION, |
||||
&device, &feature_level, &device_context); |
||||
EXPECT_FALSE(FAILED(err)); |
||||
} |
||||
|
||||
std::unique_ptr<CfgParamDeviceSelector> selector_ptr; |
||||
std::vector<CfgParam> cfg_params_w_dx11; |
||||
cfg_params_w_dx11.push_back(CfgParam::create<uint32_t>("mfxImplDescription.AccelerationMode", |
||||
MFX_ACCEL_MODE_VIA_D3D11)); |
||||
EXPECT_NO_THROW(selector_ptr.reset(new CfgParamDeviceSelector(device, "GPU", |
||||
device_context, |
||||
cfg_params_w_dx11))); |
||||
IDeviceSelector::DeviceScoreTable devs = selector_ptr->select_devices(); |
||||
|
||||
EXPECT_EQ(devs.size(), 1); |
||||
test_dev_eq(*devs.begin(), IDeviceSelector::Score::MaxActivePriority, |
||||
AccelType::DX11, device); |
||||
|
||||
IDeviceSelector::DeviceContexts ctxs = selector_ptr->select_context(); |
||||
EXPECT_EQ(ctxs.size(), 1); |
||||
EXPECT_EQ(reinterpret_cast<ID3D11DeviceContext*>(ctxs.begin()->get_ptr()), |
||||
device_context); |
||||
} |
||||
|
||||
#endif // HAVE_D3D11
|
||||
#endif // HAVE_DIRECTX
|
||||
|
||||
#ifndef HAVE_DIRECTX |
||||
#ifndef HAVE_D3D11 |
||||
TEST(OneVPL_Source_Device_Selector_CfgParam, DX11DeviceFromCfgParamWithDX11Disabled) |
||||
{ |
||||
using namespace cv::gapi::wip::onevpl; |
||||
std::vector<CfgParam> cfg_params_w_non_existed_dx11; |
||||
cfg_params_w_not_existed_dx11.push_back(CfgParam::create<uint32_t>("mfxImplDescription.AccelerationMode", |
||||
MFX_ACCEL_MODE_VIA_D3D11)); |
||||
EXPECT_THROW(CfgParamDeviceSelector{cfg_params_w_non_existed_dx11}, |
||||
std::logic_error); |
||||
} |
||||
#endif // HAVE_D3D11
|
||||
#endif // HAVE_DIRECTX
|
||||
|
||||
TEST(OneVPL_Source_Device_Selector_CfgParam, UnknownPtrDeviceFromCfgParam) |
||||
{ |
||||
using namespace cv::gapi::wip::onevpl; |
||||
std::vector<CfgParam> empty_params; |
||||
Device::Ptr empty_device_ptr = nullptr; |
||||
Context::Ptr empty_ctx_ptr = nullptr; |
||||
EXPECT_THROW(CfgParamDeviceSelector sel(empty_device_ptr, "", |
||||
empty_ctx_ptr, |
||||
empty_params), |
||||
std::logic_error); // params must describe device_ptr explicitly
|
||||
} |
||||
} |
||||
} // namespace opencv_test
|
||||
#endif // HAVE_ONEVPL
|
Loading…
Reference in new issue