Comments (12)
Example Setup:
- AMD R9 285
- AMD RX 480 (Primary)
No matter what I do, I can't use the features of the R9 285. The R9 285 is capable of B-Pictures, but GetCaps() only reports the capabilities of the RX 480.
Edit: This is especially important for "AMD Hybrid" (Switchable GPU) systems, where GetCaps will report that encoding is not supported, but the GPU definitely can do encoding.
from amf.
You should be able to call DXGIFactory::EnumAdapters to enumerate all your adapters, then pass the selected one to D3D11CreateDevice to create a device that you can use to get the correct caps.
See:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb174538(v=vs.85).aspx
and
https://msdn.microsoft.com/en-us/library/windows/desktop/ff476082(v=vs.85).aspx
-Geoff
From: Michael Fabian Dirks [mailto:[email protected]]
Sent: Tuesday, November 15, 2016 8:46 AM
To: GPUOpen-LibrariesAndSDKs/AMF [email protected]
Subject: [GPUOpen-LibrariesAndSDKs/AMF] Video Encode API: Querying Capabilities for other Devices in the system? (#42)
I'm trying to add proper multi-GPU support to my plugin, but currently fail to actually do this. My attempt right now is to create a DirectX11/DirectX9/OpenGL device, initialize the amf::AMFContext with it (InitDX11/InitDX9/InitOpenGL) and then use CreateComponent and GetCaps to get the device capabilities.
This doesn't work as expected, as it will always output the capabilities of the primary GPU - which is not what I need or want.
Is there an example that shows how to do this properly? Or is this not yet possible?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHubhttps://github.com//issues/42, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AP4h_IgosAnIACdKGqHsItj_vlgqk4Ajks5q-bexgaJpZM4KyisX.
from amf.
That's what I am currently doing, however GetCaps still only reports capabilities for the primary GPU.
from amf.
Here is slightly modified CapabilityManager sample that goes through all GPUs. I inserted Fury and RX 480 in the same machine. The sample reported the correct B-frame support for both boards: one ON one OFF. Please try.
CapabilityManager.zip
from amf.
That one works, thanks. I'll have to see what is missing in my code to make it work.
from amf.
Perhaps you can see what I'm doing wrong, because I'm kinda stuck now. I create a Direct3D 11.1/11.0 instance on the necessary adapter, call InitDX11 with it, and then continue from there to query the device capabilities. This is the code:
amf::AMFContextPtr amfContext;
res = amfFactory->CreateContext(&amfContext);
if (res != AMF_OK) {
AMF_LOG_ERROR("Unable to gather capabilities for device '%s', error %ls (code %d).",
device.Name.c_str(), amfInstance->GetTrace()->GetResultText(res), res);
continue;
}
Plugin::API::BaseAPI apiDev = Plugin::API::BaseAPI::CreateBestAvailableAPIForDevice(device);
switch (apiDev.GetType()) {
case Plugin::API::APIType_Direct3D11:
res = amfContext->InitDX11(apiDev.GetContext());
break;
case Plugin::API::APIType_Direct3D9:
res = amfContext->InitDX9(apiDev.GetContext());
break;
case Plugin::API::APIType_OpenGL:
res = amfContext->InitOpenGL(apiDev.GetContext(), nullptr, nullptr);
break;
}
if (res != AMF_OK) {
AMF_LOG_ERROR("Unable to gather capabilities for device '%s' after initialization, error %ls (code %d).",
device.Name.c_str(), amfInstance->GetTrace()->GetResultText(res), res);
continue;
}
amf::AMFContextPtr amfContext;res = amfFactory->CreateContext(&amfContext);if (res != AMF_OK) {AMF_LOG_ERROR("Unable to gather capabilities for device '%s', error %ls (code %d).",device.Name.c_str(), amfInstance->GetTrace()->GetResultText(res), res);continue;}Plugin::API::BaseAPI apiDev = Plugin::API::BaseAPI::CreateBestAvailableAPIForDevice(device);switch (apiDev.GetType()) {case Plugin::API::APIType_Direct3D11:res = amfContext->InitDX11(apiDev.GetContext());break;case Plugin::API::APIType_Direct3D9:res = amfContext->InitDX9(apiDev.GetContext());break;case Plugin::API::APIType_OpenGL:res = amfContext->InitOpenGL(apiDev.GetContext(), nullptr, nullptr);break;}if (res != AMF_OK) {AMF_LOG_ERROR("Unable to gather capabilities for device '%s' after initialization, error %ls (code %d).",device.Name.c_str(), amfInstance->GetTrace()->GetResultText(res), res);continue;}
apiDev.GetContext() returns a IDirect3D11* pointer for the adapter. Does AMF expect something special here? I saw that the modified capability manager uses ATL::CComPtr instead.
This is the code that creates the IDirect3D11 pointer:
D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0
};
D3D_FEATURE_LEVEL featureLevel;
uint32_t flags =
D3D11_CREATE_DEVICE_BGRA_SUPPORT |
D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT |
D3D11_CREATE_DEVICE_VIDEO_SUPPORT;
auto singletonD3D11 = SingletonD3D11::GetInstance();
HRESULT hr = singletonD3D11->D3D11CreateDevice(
pAdapter, pAdapter == NULL ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN,
NULL, flags,
featureLevels, _countof(featureLevels),
D3D11_SDK_VERSION,
&pDevice, &featureLevel, &pDeviceContext);
if (FAILED(hr)) {
AMF_LOG_ERROR("Unable to create D3D11.1 device.");
hr = singletonD3D11->D3D11CreateDevice(
pAdapter, pAdapter == NULL ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN,
NULL, flags,
featureLevels + 1, _countof(featureLevels) - 1,
D3D11_SDK_VERSION,
&pDevice, &featureLevel, &pDeviceContext);
if (FAILED(hr)) {
throw new std::exception("Unable to create D3D11 device.");
}
}
from amf.
The calls to AMF look correct. I would verify adapter just before calling InitDX11() :
- Get pointer to ID3D11Device from appDev,
- Query for IDXGIDevice interface
- call dxgiDevice->GetAdapter()
- call adapter->GetDesc()
- trace DXGI_ADAPTER_DESC::AdapterLuid which is DWORD and LONG
- trace for different device and compare LUIDs
LUIDs is really unique adapter ID for current Windows session. It may give you Idea if you get the correct D3D11Device
from amf.
I've added that debug code, though it only revealed that the Direct3D11Device* is on the correct Adapter. Question remains why GetCaps only reports for the primary GPU in the plugin, but works fine in CapabilityManager. I hope this is not a limitation of it running in a dll.
Debug Output:
[AMF Encoder] Radeon (TM) RX 480 Graphics, 0:346269
[AMF Encoder] AMD Radeon R9 200 Series, 0:349276
[AMF Encoder] 0:346269 // pAdapter->GetDesc()->AdapterLuid
[AMF Encoder] 0:346269 // DXGIDevice->GetAdapter()->GetDesc()->AdapterLuid
[AMF Encoder] <Plugin::AMD::VCECapabilities::Refresh> Failed to gather capabilities for device 'Radeon (TM) RX 480 Graphics' with codec 'AMFVideoEncoderHW_HEVC', error AMF_NOT_SUPPORTED (code 10).
[AMF Encoder] 0:349276 // pAdapter->GetDesc()->AdapterLuid
[AMF Encoder] 0:349276 // DXGIDevice->GetAdapter()->GetDesc()->AdapterLuid
[AMF Encoder] <Plugin::AMD::VCECapabilities::Refresh> Failed to gather capabilities for device 'AMD Radeon R9 200 Series' with codec 'AMFVideoEncoderHW_HEVC', error AMF_NOT_SUPPORTED (code 10).
I've updated the master branch to include the new changes now: https://github.com/Xaymar/obs-studio_amf-encoder-plugin/tree/master
from amf.
I checked code in the plug-in master. The AMF CAPS are acquired in a different AMF context and different AMF component on default DX device: Plugin::AMD::VCECapabilities::RefreshCapabilities()
Am I missing something here?
from amf.
That's odd, RefreshCapabilities() only exists in stable and unstable, in master I've rewritten most of the code for multi GPU support. Make sure that when checking out the code that you tell git to pull the master branch. Here are the files and how they should look like:
- https://github.com/Xaymar/obs-studio_amf-encoder-plugin/blob/master/Source/amd-amf-vce-capabilities.cpp
- https://github.com/Xaymar/obs-studio_amf-encoder-plugin/blob/master/Source/api-d3d11.cpp
And the expected call structure:
- Plugin::AMD::VCECapabilities::VCECapabilities()
- Plugin::AMD::VCECapabilities*::Refresh()
- Plugin::API::Direct3D11::EnumerateDevices()
- (Retrieve amf::AMFFactory* instance and iterate over all enumerated devices)
(for each device do:)
- amf::AMFFactory*::CreateContext()
- Plugin::API::BaseAPI::CreateBestAvailableAPIForDevice(device)
- InitDX11, InitDX9, InitOpenGL - depending on device API type.
- Iterate over known Codecs (AVC, SVC, HEVC)
(for each codec do:)
from amf.
I debugged the plug-in and found the problem. Replace the line from commented out one to the next line:
// res = amfContext->InitDX11(apiDev.GetContext());
res = amfContext->InitDX11(apiDev.GetContext(), amf::AMF_DX11_1);
By default DX11_0 doesn't support video and DX11_1 does. For example allocation of NV12 surface is available in DX11_1 only. So the second parameter tells AMF which one to use. I will check if I could make AMF more flexible in the future.
from amf.
Found the actual cause, BaseAPI wasn't actually being overridden so GetContext() always returned nullptr. With that and your fix it works.
from amf.
Related Issues (20)
- [Investigation]: DX11 HW decode can cause image corruption on quick time skipping in some sources HOT 20
- [Question]: Using -rc for AV1_AMF HOT 1
- Need help for HEVC encoding GPU with AMF on FFMPEG HOT 4
- [Bug]: DX11 hardware accelerated transcode fails on FFMPEG v6 HOT 10
- [Bug]: Unable to produce scaled video with AMF specific methods HQScaler when preanalysis flag is enabled. HOT 2
- [Question]: How to use AMF with RADV driver? HOT 8
- [Bug]: AMF hangs on trying to decode video with momentary switch between progressive and interlaced fragment mid-stream
- [Question]: When AMD will use proper AI to replace programmers and produce a way better AMD AMF ? HOT 1
- [Bug]: <stream is not FLV 1.1 compatible> HOT 19
- [Question]: How to import AMF SDK into a QT project? HOT 2
- Missing documentation AMF_VE_FCR_RADIUS HOT 1
- [Bug]: Unable to make AMF encoder to follow specified CBR bitrate. Filler data parameter is ignored for CBR in some cases.
- [Question]: Every 4 seconds of recording gets blury HOT 19
- [Question]: (H)QVBR mode on Ryzen 5 8600G with AV1 HOT 6
- [Bug]: MJPEG decoder crashes with some JPEGs HOT 2
- Encoding from D3D RGBA/BGRA surfaces (encoder fails to init) HOT 3
- [Bug]: RX7600 AV1 Decoder crashes HOT 1
- Handling encoder output status after Flush() HOT 6
- AMF_VIDEO_ENCODER_OUTPUT_DATA_TYPE reports always frame type either 'NONE' or 'IDR' HOT 3
- [Bug]: AMD DX12 video encode driver bug?: Error using new FFMPEG HEVC D3D12 encoder support in Intel cartwheel repo.. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from amf.