AMD PowerXpress/Enduro switchable graphics DXGI issue

Yesterday I wrote about the NVIDIA Optimus problem with DXGI where Output Protection Manager API reported Intel certificate for NVIDIA DXGI adapter.

AMD hybrid graphics known as “PowerXpress” (and most recently as “Enduro”) exhibits the same behavior:

Adapters
 AMD Radeon HD 8850M
 Intel(R) HD Graphics Family 

Adapter: AMD Radeon HD 8850M
 Vendor Identifier: 0x1002
 [...]
 Output: \.\DISPLAY1
 [...]

Output Protection Manager (OPM Semantics)
 Certificate Subject: IntelVpgOpm2011
 OPM_GET_OUTPUT_ID: OutputId 0x0000000000040F04
 OPM_GET_ADAPTER_BUS_TYPE: ulInformation OPM_BUS_TYPE_OTHER | OPM_BUS_IMPLEMENTATION_MODIFIER_INSIDE_OF_CHIPSET | OPM_COPP_COMPATIBLE_BUS_TYPE_INTEGRATED
 OPM_GET_CONNECTOR_TYPE: ulInformation OPM_CONNECTOR_TYPE_DISPLAYPORT_EMBEDDED
 [...]

Output Duplication
 Exception: Указанный интерфейс устройства или уровень компонента не поддерживается в данной системе (0x887A0004; DXGI_ERROR_UNSUPPORTED); https://support.microsoft.com/en-ie/help/3019314/error-generated-when-desktop-duplication-api-capable-application-is-ru 

Interestingly, it seems that NVIDIA managed to resolve this problem in their most recent hybrid graphics solutions somehow (no suitable device handy), however AMD in turn seems to have this line of product discontinued at all (community forum questions look like desperate self-help service). Or I just failed to find accurate information on the topic.

MediaFoundationDxgiCapabilities: GPU preference & Hybrid GPU systems

I added a section that enumerates DXGI adapters with the help IDXGIFactory6::EnumAdapterByGpuPreference – this is included into the produced output.

Unfortunately the method does not distinguish between dual GPU systems, such as with discrete GPU and additional CPU integrated Intel GPU…

DXGI Capabilities
 NOTE: Baseline capabilities are corresponding to DXGI 1.1
 Windowed Stereo: 0
 DXGI_FEATURE_PRESENT_ALLOW_TEARING: 1
 Adapters by Preference:
 DXGI_GPU_PREFERENCE_UNSPECIFIED: Radeon RX 570 Series (0.0x0000D18A), Intel(R) UHD Graphics 630 (0.0x8E94827B), Microsoft Basic Render Driver (0.0x0000D163)
 DXGI_GPU_PREFERENCE_MINIMUM_POWER: Intel(R) UHD Graphics 630 (0.0x8E94827B), Radeon RX 570 Series (0.0x0000D18A), Microsoft Basic Render Driver (0.0x0000D163)
 DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE: Radeon RX 570 Series (0.0x0000D18A), Intel(R) UHD Graphics 630 (0.0x8E94827B), Microsoft Basic Render Driver (0.0x0000D163)
 Factory Interfaces: IDXGIObject, IDXGIFactory, IDXGIFactory1, IDXGIFactory2, IDXGIFactory3, IDXGIFactory4, IDXGIFactory5, IDXGIFactory6, IDXGIFactory7, IDXGIDisplayControl 

Adapters
 Radeon RX 570 Series
 Intel(R) UHD Graphics 630 

…and hybrid systems such as NVIDIA Optimus and AMD PowerXpress. Those from AMD seem to be discontinued and AMD is traditionally provides zero helpful feedback to developers (although NVIDIA is not any better).

However this time I might have spotted something interesting. On an NVIDIA hybrid system when an app is executed on iGPU, the output is this (expected):

DXGI Capabilities
 NOTE: Baseline capabilities are corresponding to DXGI 1.1
 Windowed Stereo: 0
 DXGI_FEATURE_PRESENT_ALLOW_TEARING: 1
 Adapters by Preference:
 DXGI_GPU_PREFERENCE_UNSPECIFIED: Intel(R) HD Graphics 520 (0.0x00010765), NVIDIA GeForce 940MX (0.0x00010A9D), Microsoft Basic Render Driver (0.0x00010A66)
 DXGI_GPU_PREFERENCE_MINIMUM_POWER: Intel(R) HD Graphics 520 (0.0x00010765), NVIDIA GeForce 940MX (0.0x00010A9D), Microsoft Basic Render Driver (0.0x00010A66)
 DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE: NVIDIA GeForce 940MX (0.0x00010A9D), Intel(R) HD Graphics 520 (0.0x00010765), Microsoft Basic Render Driver (0.0x00010A66)
 Factory Interfaces: IDXGIObject, IDXGIFactory, IDXGIFactory1, IDXGIFactory2, IDXGIFactory3, IDXGIFactory4, IDXGIFactory5, IDXGIFactory6, IDXGIFactory7, IDXGIDisplayControl 

Adapters
 Intel(R) HD Graphics 520
 NVIDIA GeForce 940MX 

[...]

Output Protection Manager (OPM Semantics)
 Certificate Subject: IntelVpgOpm2011
 OPM_GET_OUTPUT_ID: OutputId 0x0000000000040F04
 OPM_GET_ADAPTER_BUS_TYPE: ulInformation OPM_BUS_TYPE_OTHER | OPM_BUS_IMPLEMENTATION_MODIFIER_INSIDE_OF_CHIPSET | OPM_COPP_COMPATIBLE_BUS_TYPE_INTEGRATED
 OPM_GET_CONNECTOR_TYPE: ulInformation OPM_CONNECTOR_TYPE_DISPLAYPORT_EMBEDDED 

[...]
 
Output Duplication
 Direct3D 11 Feature Level: D3D_FEATURE_LEVEL_11_1; https://msdn.microsoft.com/en-us/library/windows/desktop/ff476876#Overview
 Mode Description:
 Width: 1 920
 Height: 1 080
 Refresh Rate: 138 500 000/2 310 880 (59,934)
 Format: DXGI_FORMAT_B8G8R8A8_UNORM
 Scanline Ordering: DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE
 Scaling: DXGI_MODE_SCALING_UNSPECIFIED
 Rotation: DXGI_MODE_ROTATION_IDENTITY
 Desktop Image In System Memory: 0 

However, when the app is started on dGPU, adapter enumeration order is expectedly changed, and also Desktop Duplication API is dysfunctional as documented here: Error generated when Desktop Duplication API-capable application is run against discrete GPU, but…

DXGI Capabilities
 NOTE: Baseline capabilities are corresponding to DXGI 1.1
 Windowed Stereo: 0
 DXGI_FEATURE_PRESENT_ALLOW_TEARING: 1
 Adapters by Preference:
 DXGI_GPU_PREFERENCE_UNSPECIFIED: NVIDIA GeForce 940MX (0.0x00010A9D), Intel(R) HD Graphics 520 (0.0x00010765), Microsoft Basic Render Driver (0.0x00010A66)
 DXGI_GPU_PREFERENCE_MINIMUM_POWER: Intel(R) HD Graphics 520 (0.0x00010765), NVIDIA GeForce 940MX (0.0x00010A9D), Microsoft Basic Render Driver (0.0x00010A66)
 DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE: NVIDIA GeForce 940MX (0.0x00010A9D), Intel(R) HD Graphics 520 (0.0x00010765), Microsoft Basic Render Driver (0.0x00010A66)
 Factory Interfaces: IDXGIObject, IDXGIFactory, IDXGIFactory1, IDXGIFactory2, IDXGIFactory3, IDXGIFactory4, IDXGIFactory5, IDXGIFactory6, IDXGIFactory7, IDXGIDisplayControl 

Adapters
 NVIDIA GeForce 940MX
 Intel(R) HD Graphics 520 

[...]

Output Protection Manager (OPM Semantics)
 Certificate Subject: IntelVpgOpm2011
 OPM_GET_OUTPUT_ID: OutputId 0x0000000000040F04
 OPM_GET_ADAPTER_BUS_TYPE: ulInformation OPM_BUS_TYPE_OTHER | OPM_BUS_IMPLEMENTATION_MODIFIER_INSIDE_OF_CHIPSET | OPM_COPP_COMPATIBLE_BUS_TYPE_INTEGRATED
 OPM_GET_CONNECTOR_TYPE: ulInformation OPM_CONNECTOR_TYPE_DISPLAYPORT_EMBEDDED

[...]
 
Output Duplication
 Exception: Указанный интерфейс устройства или уровень компонента не поддерживается в данной системе (0x887A0004; DXGI_ERROR_UNSUPPORTED); https://support.microsoft.com/en-ie/help/3019314/error-generated-when-desktop-duplication-api-capable-application-is-ru 

…here is the news: NVIDIA DXGI adapter is enumerated with Intel OPM certificate… What a find!

Download links

Low latency video streaming

Bits of Rainway Pulsar technology at work in this test run. The big monitor is a part of desktop system, by the way, not a high end one: Radeon RX 570 with two monitors, one of which is encoded into H.264 and streamed over network to two pieces of hardware:

  1. Intel NUC with a 2K monitor (small monitor on the left) connected to onboard Intel® Iris® Plus Graphics 640 & its HDMI connector
  2. Xbox One X (in the right bottom corner)

The high FPS 3D thing (by the way, it is “The Universe Within” by BigWIngs) is running on desktop PC and its image is being taken to the other two systems simultaneously via H.264 5 MBit/s encoding.

Ordinary hardware, yet streaming is made right and shows what can be squeezed out.

Will have to check faster hardware, and I think the latency can be cut twice. Interestingly, at some point it might be harder to remote audio at such low latency.

Media Foundation API primitive styling of WinRT windows.mediaCodec

An interesting Media Foundation question on StackOverflow: Weird connection between CoInitializeSecurity() and Media Foundation Encoders

A developer has reasons to discard standard COM security and go RPC_C_IMP_LEVEL_ANONYMOUS. Surprisingly this has effect on Windows Media Foundation API in the part of available codecs (Media Foundation Transforms).

Sample code:

#include <iostream>

#include <winrt\base.h>
#include <mfapi.h>
#include <mftransform.h>

#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mfuuid.lib")

int main()
{
	// https://stackoverflow.com/questions/59368680/weird-connection-between-coinitializesecurity-and-media-foundation-encoders
	WINRT_VERIFY(SUCCEEDED(MFStartup(MF_VERSION, MFSTARTUP_FULL)));
	WINRT_VERIFY(SUCCEEDED(CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_ANONYMOUS, nullptr, EOAC_NONE, nullptr)));
	//WINRT_VERIFY(SUCCEEDED(CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)));
	IMFActivate** Activates = nullptr;
	UINT32 ActivateCount = 0;
	WINRT_VERIFY(SUCCEEDED(MFTEnumEx(MFT_CATEGORY_VIDEO_ENCODER, MFT_ENUM_FLAG_ALL, nullptr, nullptr, &Activates, &ActivateCount)));
	WINRT_ASSERT(Activates || !ActivateCount);
	BOOL Found = FALSE;
	for(UINT32 Index = 0; Index < ActivateCount; Index++)
	{
		IMFActivate*& Activate = Activates[Index];
		WINRT_ASSERT(Activate);
		WCHAR* FriendlyName = nullptr;
		UINT32 FriendlyNameLength;
		WINRT_VERIFY(SUCCEEDED(Activate->GetAllocatedString(MFT_FRIENDLY_NAME_Attribute, &FriendlyName, &FriendlyNameLength)));
		std::wcout << FriendlyName << std::endl;
		if(wcscmp(FriendlyName, L"HEVCVideoExtensionEncoder") == 0)
			Found = TRUE;
		CoTaskMemFree(FriendlyName);
	}
	WINRT_ASSERT(Found);
	CoTaskMemFree(Activates);
	//CoUninitialize();
	WINRT_VERIFY(SUCCEEDED(MFShutdown()));
}

CoInitializeSecurity line in the code above removes the following from enumeration:

  • HEIFImageExtension
  • VP9VideoExtensionEncoder
  • HEVCVideoExtensionEncoder

See the pattern? Why?

Similarly to other and older APIs like DirectShow enumeration function combines uniformly interfaced primitives coming from multiple sources. In this case of Media Foundation, enumeration combines (and filters/orders when requested) traditional transforms registered with the API with information in system registry, limited scope transforms and also transforms coming from Windows Store.

For example, H.256/HEVC video decoder and encoder is added to the system as HEVC Video Extension Windows Store item.

<Identity ProcessorArchitecture="x64" Version="1.0.23254.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Name="Microsoft.HEVCVideoExtension"/>

Its video encoder, in turn, is:

        <uap4:Extension Category="windows.mediaCodec">
          <uap4:MediaCodec DisplayName="HEVCVideoExtensionEncoder" Description="This is a video codec" Category="videoEncoder" wincap3:ActivatableClassId="H265Encoder.CH265EncoderTransform" wincap3:Path="x86\mfh265enc.dll" wincap3:ProcessorArchitecture="x86">
            <uap4:MediaEncodingProperties>
              <uap4:InputTypes>
                <!-- NV12 -->
                <uap4:InputType SubType="3231564e-0000-0010-8000-00aa00389b71" />
                <!-- IYUV -->
                <uap4:InputType SubType="56555949-0000-0010-8000-00AA00389B71" />
                <!-- YV12 -->
                <uap4:InputType SubType="32315659-0000-0010-8000-00AA00389B71" />
                <!-- YUY2 -->
                <uap4:InputType SubType="32595559-0000-0010-8000-00AA00389B71" />
              </uap4:InputTypes>
              <uap4:OutputTypes>
                <!-- HEVC -->
                <uap4:OutputType SubType="43564548-0000-0010-8000-00AA00389B71" />
              </uap4:OutputTypes>
            </uap4:MediaEncodingProperties>
          </uap4:MediaCodec>
        </uap4:Extension>
      </Extensions>

Media Foundation API is capable to pick such mediaCodec from Windows Store applications and make it available to desktop applications. However, there in COM security in the middle of the glue layer. Media Foundation would create a special activation object (CMFWinrtInprocActivate) to implement IMFActivate for such WinRT codec and once activated, the transform acts as usual and as documented. These codecs are also dual interfaced and in addition to traditional Media Foundation interfaces like IMFTransform expose UWP interfaces like IMediaExtension and so they are consumable by UWP applications as well.

Cropped video with Xbox One XAML MediaPlayerElement control

XAML MediaPlayerElement control/class is exhibiting a ridiculous bug on Xbox One: once you are going fullscreen the control is not showing the video correctly. A texture is assumed to be rendered in full and it is cropped instead (left top quarter of actual video or alike).

I saw this before but at that time I had other reasons to not use built-in fullscreen mode. This time the reason is more straightforward – it simply does not work as expected.

Review your experience with Currenex

LinkedIn pulled a keyword and offered review option to wrong guy… But I have something to say about Currenex though.

Once in a while in past life I developed an automated trading application which run on Currenex FX trading platform. One of the most eye opening technologies implemented by the platform at that time was so called “last look“.

Long story short this thing was nothing but high level scam: privileged market participants had the right to take or reject a deal with a significant delay after trade time when profit from particular trade was obvious. Imagine you bought $1M on a price move and then your trade is put on hold. Someone else, unnamed, puts it under consideration: “Oh boy, your purchase from us was so profitable… It does not go along well with our bonuses, so canceling.”

Due to specificity of logic we implemented, the trading agent was hit hard by last look, and the unfairness was something absolutely and immediately clear.

Even though the end of this story was predictable…

(this screenshot and link are unrelated to Currenex)

…the interesting part comes from comparison with another screenshot:

2015-2009=?

What keeps me amazing is that FX trading is still popular at, well, low level. There are ads in subway how to get trained to earn on high frequency trading, “FX trading for dummies” with smiling well-dressed people on ad posters. Given that at every level of providers of such services there is a scam that shaves profits in unfair way, what crumbles get the lame ducks seduced by the advertisement? How many of them end up with positive bottom line, one of hundred just because of blind luck?

Media Foundation core deadlock around IMFPresentationClock::GetCorrelatedTime

It looks like as primitive call as IMFPresentationClock::GetCorrelatedTime can deadlock entire pipeline due to an issue in Media Foundation core. There are no symbols available for mfcore.dll so I would assume they have a global critical section there which is inaccurately used.

In any event the problem looks like an API bug, and severe one (given that it blows things up in UWP XAML MediaPlayerElement control and IMFMediaEngine::GetCurrentTime call!), because IMFPresentationClock::GetCorrelatedTime is too widely used to be banned even for RTWQ thread.

The two threads are locking two critical sections in the opposite order, a classic deadlock with two concurrent threads cross-locking one another. I would presume one of them is a global critical section – this would explain why such simple API participates in the deadlock.

Continue reading →