diff --git a/modules/gapi/CMakeLists.txt b/modules/gapi/CMakeLists.txt index 6d47e909e0d8..a39b165b0873 100644 --- a/modules/gapi/CMakeLists.txt +++ b/modules/gapi/CMakeLists.txt @@ -167,6 +167,9 @@ set(gapi_srcs src/streaming/onevpl/onevpl_source.cpp src/streaming/onevpl/onevpl_source_priv.cpp + src/streaming/onevpl/cfg_param_device_selector.cpp + src/streaming/onevpl/device_selector_interface.cpp + # Utils (ITT tracing) src/utils/itt.cpp ) diff --git a/modules/gapi/include/opencv2/gapi/streaming/onevpl/device_selector_interface.hpp b/modules/gapi/include/opencv2/gapi/streaming/onevpl/device_selector_interface.hpp new file mode 100644 index 000000000000..bb49964538ba --- /dev/null +++ b/modules/gapi/include/opencv2/gapi/streaming/onevpl/device_selector_interface.hpp @@ -0,0 +1,93 @@ +// 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 +#include +#include +#include +#include +#include + +#include "opencv2/gapi/own/exports.hpp" // GAPI_EXPORTS + +namespace cv { +namespace gapi { +namespace wip { + +enum class AccelType : uint8_t { + HOST, + DX11 +}; + +struct IDeviceSelector; +struct GAPI_EXPORTS Device { + friend struct IDeviceSelector; + using Ptr = void*; + + ~Device(); + Ptr get_ptr() const; + AccelType get_type() const; +private: + Device(Ptr device_ptr, AccelType device_type); + 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; + + struct GAPI_EXPORTS Score { + friend struct IDeviceSelector; + using Type = uint16_t; + static constexpr Type Max = std::numeric_limits::max(); + static constexpr Type Min = std::numeric_limits::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; + + virtual ~IDeviceSelector(); + virtual DeviceScoreTable select_devices() const = 0; + virtual DeviceScoreTable select_spare_devices() const = 0; + virtual Context select_context(const DeviceScoreTable& selected_devices) = 0; + virtual Context get_last_context() const = 0; +protected: + template + static Entity create(Args &&...args) { + return Entity(std::forward(args)...); + } +}; +} // namespace wip +} // namespace gapi +} // namespace cv + +#endif // GAPI_STREAMING_ONEVPL_ONEVPL_DATA_PROVIDER_INTERFACE_HPP diff --git a/modules/gapi/src/streaming/onevpl/cfg_param_device_selector.cpp b/modules/gapi/src/streaming/onevpl/cfg_param_device_selector.cpp new file mode 100644 index 000000000000..98a666b2d9fd --- /dev/null +++ b/modules/gapi/src/streaming/onevpl/cfg_param_device_selector.cpp @@ -0,0 +1,251 @@ +// 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 + +#include "streaming/onevpl/cfg_param_device_selector.hpp" +#include "streaming/onevpl/onevpl_cfg_params_parser.hpp" +#include "logger.hpp" + +#ifdef HAVE_DIRECTX +#ifdef HAVE_D3D11 +#pragma comment(lib,"d3d11.lib") + +#define D3D11_NO_HELPERS +#include +#include +#include +#include "opencv2/core/directx.hpp" +#ifdef HAVE_OPENCL +#include +#endif + +namespace cv { +namespace gapi { +namespace wip { + +CfgParamDeviceSelector::CfgParamDeviceSelector(const onevpl_params_container_t& cfg_params) : + IDeviceSelector(), + suggested_device(IDeviceSelector::create(nullptr, AccelType::HOST)), + suggested_context(IDeviceSelector::create(nullptr, AccelType::HOST)) { + + auto accel_mode_it = + std::find_if(cfg_params.begin(), cfg_params.end(), [] (const oneVPL_cfg_param& 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; + + // Create the Direct3D 11 API device object and a corresponding context. + HRESULT err = D3D11CreateDevice( + nullptr, // Specify nullptr to use the default adapter. + D3D_DRIVER_TYPE_HARDWARE, + nullptr, + creationFlags, // Set set debug and Direct2D compatibility flags. + featureLevels, // List of feature levels this app can support. + ARRAYSIZE(featureLevels), + D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION. + &hw_handle, // Returns the Direct3D device created. + &featureLevel, // Returns feature level of device created. + &device_context // Returns the device immediate context. + ); + if(FAILED(err)) { + throw std::logic_error("Cannot create D3D11CreateDevice, error: " + std::to_string(HRESULT_CODE(err))); + } + + // oneVPL recommendation + { + ID3D11Multithread *pD11Multithread; + device_context->QueryInterface(IID_PPV_ARGS(&pD11Multithread)); + pD11Multithread->SetMultithreadProtected(true); + pD11Multithread->Release(); + } + + suggested_device = IDeviceSelector::create(hw_handle, AccelType::DX11); + suggested_context = IDeviceSelector::create(device_context, AccelType::DX11); +#else + GAPI_LOG_WARNING(nullptr, "Unavailable \"mfxImplDescription.AccelerationMode: MFX_ACCEL_MODE_VIA_D3D11\"" + "was choosed 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, + Context::Ptr ctx_ptr, + const onevpl_params_container_t& cfg_params) : + IDeviceSelector(), + suggested_device(IDeviceSelector::create(nullptr, AccelType::HOST)), + suggested_context(IDeviceSelector::create(nullptr, AccelType::HOST)) { + auto accel_mode_it = + std::find_if(cfg_params.begin(), cfg_params.end(), [] (const oneVPL_cfg_param& 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_ptr, AccelType::DX11); + ID3D11Device* dx_device_ptr = + reinterpret_cast(suggested_device.get_ptr()); + dx_device_ptr->AddRef(); + + suggested_context = IDeviceSelector::create(ctx_ptr, AccelType::DX11); + ID3D11DeviceContext* dx_ctx_ptr = + reinterpret_cast(suggested_context.get_ptr()); + dx_ctx_ptr->AddRef(); +#else + GAPI_LOG_WARNING(nullptr, "Unavailable \"mfxImplDescription.AccelerationMode: MFX_ACCEL_MODE_VIA_D3D11\"" + "was choosed 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(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: " << 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(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::Max, suggested_device)}; +} + +CfgParamDeviceSelector::DeviceScoreTable CfgParamDeviceSelector::select_spare_devices() const { + return {}; +} + +Context CfgParamDeviceSelector::select_context(const DeviceScoreTable& selected_devices) { + GAPI_Assert(selected_devices.size() == 1 && "Implementation must use only single device"); + GAPI_Assert(selected_devices.begin()->second.get_ptr() == suggested_device.get_ptr() && + "Implementation must use suggested device ptr"); + GAPI_Assert(selected_devices.begin()->second.get_type() == suggested_device.get_type() && + "Implementation must use suggested device type"); + return suggested_context; +} + +Context CfgParamDeviceSelector::get_last_context() const { + return suggested_context; +} +} // namespace wip +} // namespace gapi +} // namespace cv + +#endif // HAVE_D3D11 +#endif // HAVE_DIRECTX +#endif // HAVE_ONEVPL diff --git a/modules/gapi/src/streaming/onevpl/cfg_param_device_selector.hpp b/modules/gapi/src/streaming/onevpl/cfg_param_device_selector.hpp new file mode 100644 index 000000000000..44a16ac3f790 --- /dev/null +++ b/modules/gapi/src/streaming/onevpl/cfg_param_device_selector.hpp @@ -0,0 +1,39 @@ +// 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 +#include +#include +#include + +#include "opencv2/gapi/own/exports.hpp" // GAPI_EXPORTS + +namespace cv { +namespace gapi { +namespace wip { + + +struct GAPI_EXPORTS CfgParamDeviceSelector final: public IDeviceSelector { + CfgParamDeviceSelector(const onevpl_params_container_t& params = {}); + CfgParamDeviceSelector(Device::Ptr device_ptr, + Context::Ptr ctx_ptr, + const onevpl_params_container_t& params); + ~CfgParamDeviceSelector(); + + DeviceScoreTable select_devices() const override; + DeviceScoreTable select_spare_devices() const override; + Context select_context(const DeviceScoreTable& selected_devices) override; + Context get_last_context() const override; +private: + Device suggested_device; + Context suggested_context; +}; +} // namespace wip +} // namespace gapi +} // namespace cv + +#endif // GAPI_STREAMING_ONEVPL_ONEVPL_FILE_DATA_PROVIDER_HPP diff --git a/modules/gapi/src/streaming/onevpl/device_selector_interface.cpp b/modules/gapi/src/streaming/onevpl/device_selector_interface.cpp new file mode 100644 index 000000000000..6b108da6b58b --- /dev/null +++ b/modules/gapi/src/streaming/onevpl/device_selector_interface.cpp @@ -0,0 +1,68 @@ +// 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 + +namespace cv { +namespace gapi { +namespace wip { + +Device::Device(Ptr device_ptr, AccelType device_type) : + ptr(device_ptr), + type(device_type) { +} + +Device::~Device() { +} + +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 wip +} // namespace gapi +} // namespace cv diff --git a/modules/gapi/test/streaming/gapi_streaming_vpl_core_test.cpp b/modules/gapi/test/streaming/gapi_streaming_vpl_core_test.cpp index 3bc4dd8711ce..6841e2275dd1 100644 --- a/modules/gapi/test/streaming/gapi_streaming_vpl_core_test.cpp +++ b/modules/gapi/test/streaming/gapi_streaming_vpl_core_test.cpp @@ -35,6 +35,23 @@ #include #include "streaming/onevpl/engine/processing_engine_base.hpp" #include "streaming/onevpl/engine/engine_session.hpp" +#include "streaming/onevpl/cfg_param_device_selector.hpp" + +#ifdef HAVE_DIRECTX +#ifdef HAVE_D3D11 +#pragma comment(lib,"d3d11.lib") + +#define D3D11_NO_HELPERS +#include +#include +#include +#include "opencv2/core/directx.hpp" +#ifdef HAVE_OPENCL +#include +#endif + +#endif +#endif namespace opencv_test { @@ -107,6 +124,21 @@ struct TestProcessingEngine: public cv::gapi::wip::ProcessingEngineBase { } }; +void test_eq(const typename cv::gapi::wip::IDeviceSelector::DeviceScoreTable::value_type &scored_device, + cv::gapi::wip::IDeviceSelector::Score expected_score, + cv::gapi::wip::AccelType expected_type, + cv::gapi::wip::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_host_dev_eq(const typename cv::gapi::wip::IDeviceSelector::DeviceScoreTable::value_type &scored_device, + cv::gapi::wip::IDeviceSelector::Score expected_score) { + test_eq(scored_device, expected_score, + cv::gapi::wip::AccelType::HOST, nullptr); +} + TEST(OneVPL_Source_Surface, InitSurface) { using namespace cv::gapi::wip; @@ -527,6 +559,176 @@ TEST(OneVPL_Source_DX11_Accel, Init) MFXClose(mfx_session); MFXUnload(mfx_handle); } + +TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDevice) +{ + using namespace cv::gapi::wip; + CfgParamDeviceSelector selector; + IDeviceSelector::DeviceScoreTable devs = selector.select_devices(); + EXPECT_EQ(devs.size(), 1); + test_host_dev_eq(*devs.begin(), IDeviceSelector::Score::Max); + + Context ctx = selector.select_context(devs); + EXPECT_EQ(ctx.get_ptr(), nullptr); +} + +TEST(OneVPL_Source_Device_Selector_CfgParam, DefaultDeviceFromCfgParam) +{ + using namespace cv::gapi::wip; + + using cfg_param = cv::gapi::wip::oneVPL_cfg_param; + + { + std::vector 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::Max); + } + { + std::vector cfg_params_w_no_accel; + cfg_params_w_no_accel.push_back(cfg_param::create("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::Max); + } + + { +#ifdef HAVE_DIRECTX +#ifdef HAVE_D3D11 + std::vector 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::Max); +#endif // HAVE_D3D11 +#endif // HAVE_DIRECTX + } + + { +#ifndef HAVE_DIRECTX +#ifndef HAVE_D3D11 + std::vector cfg_params_w_non_existed_dx11; + cfg_params_w_not_existed_dx11.push_back(cfg_param::create("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 + } + + { +#ifdef HAVE_DIRECTX +#ifdef HAVE_D3D11 + std::vector cfg_params_w_dx11; + cfg_params_w_dx11.push_back(cfg_param::create("mfxImplDescription.AccelerationMode", + MFX_ACCEL_MODE_VIA_D3D11)); + std::unique_ptr 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_eq(*devs.begin(), IDeviceSelector::Score::Max, AccelType::DX11, + std::get<1>(*devs.begin()).get_ptr() /* compare just type */); + + Context ctx = selector_ptr->select_context(devs); + EXPECT_TRUE(ctx.get_ptr()); +#endif // HAVE_D3D11 +#endif // HAVE_DIRECTX + } +} + +TEST(OneVPL_Source_Device_Selector_CfgParam, PtrDeviceFromCfgParam) +{ + using namespace cv::gapi::wip; + + using cfg_param = cv::gapi::wip::oneVPL_cfg_param; + + { + std::vector 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 + } + + { +#ifndef HAVE_DIRECTX +#ifndef HAVE_D3D11 + std::vector cfg_params_w_non_existed_dx11; + cfg_params_w_not_existed_dx11.push_back(cfg_param::create("mfxImplDescription.AccelerationMode", + MFX_ACCEL_MODE_VIA_D3D11)); + EXPECT_THROW(CfgParamDeviceSelector{cfg_params_w_non_existed_dx11}, + std::logic_error); // the same as default dx11 +#endif // HAVE_D3D11 +#endif // HAVE_DIRECTX + } + + { +#ifdef HAVE_DIRECTX +#ifdef HAVE_D3D11 + std::vector cfg_params_w_dx11; + cfg_params_w_dx11.push_back(cfg_param::create("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, empty_ctx_ptr, + cfg_params_w_dx11), + std::logic_error); // empty_device_ptr must be valid +#endif // HAVE_D3D11 +#endif // HAVE_DIRECTX + } + + { +#ifdef HAVE_DIRECTX +#ifdef HAVE_D3D11 + ID3D11Device *device = nullptr; + ID3D11DeviceContext* device_context = nullptr; + { + //Create device + UINT creationFlags = 0;//D3D11_CREATE_DEVICE_BGRA_SUPPORT; + + D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + }; + D3D_FEATURE_LEVEL featureLevel; + + // Create the Direct3D 11 API device object and a corresponding context. + HRESULT err = D3D11CreateDevice( + nullptr, // Specify nullptr to use the default adapter. + D3D_DRIVER_TYPE_HARDWARE, + nullptr, + creationFlags, // Set set debug and Direct2D compatibility flags. + featureLevels, // List of feature levels this app can support. + ARRAYSIZE(featureLevels), + D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION. + &device, // Returns the Direct3D device created. + &featureLevel, // Returns feature level of device created. + &device_context // Returns the device immediate context. + ); + EXPECT_FALSE(FAILED(err)); + } + std::unique_ptr selector_ptr; + std::vector cfg_params_w_dx11; + cfg_params_w_dx11.push_back(cfg_param::create("mfxImplDescription.AccelerationMode", + MFX_ACCEL_MODE_VIA_D3D11)); + EXPECT_NO_THROW(selector_ptr.reset(new CfgParamDeviceSelector(device, device_context, + cfg_params_w_dx11))); + IDeviceSelector::DeviceScoreTable devs = selector_ptr->select_devices(); + + EXPECT_EQ(devs.size(), 1); + test_eq(*devs.begin(), IDeviceSelector::Score::Max, + AccelType::DX11, device); + + Context ctx = selector_ptr->select_context(devs); + EXPECT_EQ(ctx.get_ptr(), device_context); +#endif // HAVE_D3D11 +#endif // HAVE_DIRECTX + } +} } } // namespace opencv_test #endif // HAVE_ONEVPL