Reputation: 4357
Been trying to figure this out for a while and according to the docs, this should "just work".
The setup is:
We have a video swapchain at the bottom:
winrt::com_ptr<IMFMediaEngineEx> mediaEngineEx = m_mediaEngine.as<IMFMediaEngineEx>();
THROW_IF_FAILED(mediaEngineEx->EnableWindowlessSwapchainMode(true));
THROW_IF_FAILED(mediaEngineEx->GetVideoSwapchainHandle(&m_dcompSurfaceHandle));
This video can display both SDR and HDR video.
If the device and screen can support HDR, we change the display setting to HDR at startup.
Then we want to render some info on top of the video (subtitles, UI etc). Our vertex data has premultiplied alpha (this might be the issue since I haven't seen this being used in examples).
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
swapChainDesc.Width = lround(m_d3dRenderTargetSize.Width);
swapChainDesc.Height = lround(m_d3dRenderTargetSize.Height);
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc.Stereo = false;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
swapChainDesc.Flags = 0;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
ComPtr<IDXGISwapChain3> spSwapChain3;
m_swapChain.As<IDXGISwapChain3>(&spSwapChain3);
if( FAILED(spSwapChain3->SetColorSpace1(DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709)) )
{
FATAL("Could not set the correct color space\n");
}
Blending is:
D3D11_BLEND_DESC blendDesc = {};
blendDesc.AlphaToCoverageEnable = false;
blendDesc.IndependentBlendEnable = false;
blendDesc.RenderTarget[0].BlendEnable = true;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_DEST_ALPHA;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
DX_CHECK(s_device->CreateBlendState(&blendDesc, &m_blendSrcOverState));
The issue is when a semi-transparent gradient or box is shown over the video. The gradient gets a lot of banding and is a lot brighter than it should be. If the device is not in HDR more, it looks normal.
What am I missing here? I'm happy to provide more data. Cheers!
Upvotes: 0
Views: 134
Reputation: 4357
Hopefully this can help someone else, but what solved it in the end was something very unrelated.
MFARGB borderColor{ 0, 0, 0, 0 };
mediaEngineEx->UpdateVideoStream(nullptr, &destRect, &borderColor);
We are using the IMFMediaEngineEx
for our HDR video, and when we set the border color, the blending seems to look more accurate.
Still trying to look into why this fixed it, because it makes no sense.
Upvotes: 0