direct3d11: colour space is not properly set when rendering on a composition swapchain
A composition swap chain renders video on UWP applications. When used, the direct3d11 module fails to determine the screen colour space and may select the non-optimal colour space. This can lead to overexposed or oversaturated images when playing HDR content on an SDR screen.
For example, the screenshot below shows the difference between the correct colour space in VLC and the incorrect colour space in my UWP app.
More specifically, in the D3D11SetColorSpace
function, IDXGISwapChain_GetContainingOutput
does not work with a composition swapchain. (modules/video_output/win32/direct3d11.c)
As a workaround for my app, I created a patch for the direct3d11 module that finds the primary output (main screen) and gets Desc1 on that output to get the colour space info. I suspect this is not the complete solution as it does not handle cases where users have multiple screens with different colour capabilities.
static bool TryGetFirstOutputDesc(vout_display_t *vd, DXGI_OUTPUT_DESC1 *desc) {
vout_display_sys_t *sys = vd->sys;
IDXGIAdapter *dxgiadapter = D3D11DeviceAdapter(sys->d3d_dev.d3ddevice);
if (unlikely(dxgiadapter==NULL)) {
msg_Err(vd, "Could not get the DXGI Adapter");
return false;
}
// Get the first output (monitor)
IDXGIOutput *output = NULL;
if (SUCCEEDED(IDXGIAdapter1_EnumOutputs(dxgiadapter, 0, &output))) {
IDXGIOutput6 *output6 = NULL;
if (SUCCEEDED(IDXGIOutput_QueryInterface(output, &IID_IDXGIOutput6, (void **)&output6))) {
if (SUCCEEDED(IDXGIOutput6_GetDesc1(output6, desc))) {
IDXGIOutput6_Release(output6);
IDXGIOutput_Release(output);
IDXGIAdapter_Release(dxgiadapter);
return true;
}
IDXGIOutput6_Release(output6);
}
IDXGIOutput_Release(output);
}
IDXGIAdapter_Release(dxgiadapter);
return false;
}
cc @mfkl