mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-05 01:24:14 +01:00
[dxgi] Implement DXGIOutput::GetDesc1's ColorSpace
Adds the ability to punt the global colorspace into HDR from SetColorSpace1. We have no way of checking the actual Windows colorspace as the only public method for this *is* DXGI which we are re-implementing. So we just pick our color space based on the DXVK_HDR env var and the punting from SetColorSpace1. We might expand on this in future, but this is good enough for an initial implementation.
This commit is contained in:
parent
dd660585c0
commit
f453d6ee2a
@ -200,6 +200,30 @@ IDXGIVkMonitorInfo : public IUnknown {
|
||||
*/
|
||||
virtual void STDMETHODCALLTYPE ReleaseMonitorData() = 0;
|
||||
|
||||
/**
|
||||
* \brief Punt global colorspace
|
||||
*
|
||||
* This exists to satiate a requirement for
|
||||
* IDXGISwapChain::SetColorSpace1 punting Windows into
|
||||
* the global "HDR mode".
|
||||
*
|
||||
* This operation is atomic and does not require
|
||||
* owning any monitor data.
|
||||
*
|
||||
* \param [in] ColorSpace The colorspace
|
||||
*/
|
||||
virtual void STDMETHODCALLTYPE PuntColorSpace(DXGI_COLOR_SPACE_TYPE ColorSpace) = 0;
|
||||
|
||||
/**
|
||||
* \brief Get current global colorspace
|
||||
*
|
||||
* This operation is atomic and does not require
|
||||
* owning any monitor data.
|
||||
*
|
||||
* \returns Current global colorspace
|
||||
*/
|
||||
virtual DXGI_COLOR_SPACE_TYPE STDMETHODCALLTYPE CurrentColorSpace() const = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
namespace dxvk {
|
||||
|
||||
DxgiMonitorInfo::DxgiMonitorInfo(IUnknown* pParent)
|
||||
: m_parent(pParent) {
|
||||
: m_parent(pParent)
|
||||
, m_globalColorSpace(DefaultColorSpace()) {
|
||||
|
||||
}
|
||||
|
||||
@ -69,6 +70,23 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void STDMETHODCALLTYPE DxgiMonitorInfo::PuntColorSpace(DXGI_COLOR_SPACE_TYPE ColorSpace) {
|
||||
m_globalColorSpace = ColorSpace;
|
||||
}
|
||||
|
||||
|
||||
DXGI_COLOR_SPACE_TYPE STDMETHODCALLTYPE DxgiMonitorInfo::CurrentColorSpace() const {
|
||||
return m_globalColorSpace;
|
||||
}
|
||||
|
||||
|
||||
DXGI_COLOR_SPACE_TYPE DxgiMonitorInfo::DefaultColorSpace() {
|
||||
return env::getEnvVar("DXVK_HDR") == "1"
|
||||
? DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
|
||||
: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||
}
|
||||
|
||||
|
||||
uint32_t GetMonitorFormatBpp(DXGI_FORMAT Format) {
|
||||
switch (Format) {
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
|
@ -37,6 +37,12 @@ namespace dxvk {
|
||||
|
||||
void STDMETHODCALLTYPE ReleaseMonitorData();
|
||||
|
||||
void STDMETHODCALLTYPE PuntColorSpace(DXGI_COLOR_SPACE_TYPE ColorSpace);
|
||||
|
||||
DXGI_COLOR_SPACE_TYPE STDMETHODCALLTYPE CurrentColorSpace() const;
|
||||
|
||||
static DXGI_COLOR_SPACE_TYPE DefaultColorSpace();
|
||||
|
||||
private:
|
||||
|
||||
IUnknown* m_parent;
|
||||
@ -44,6 +50,8 @@ namespace dxvk {
|
||||
dxvk::mutex m_monitorMutex;
|
||||
std::unordered_map<HMONITOR, DXGI_VK_MONITOR_DATA> m_monitorData;
|
||||
|
||||
std::atomic<DXGI_COLOR_SPACE_TYPE> m_globalColorSpace;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -218,21 +218,17 @@ namespace dxvk {
|
||||
pDesc->AttachedToDesktop = 1;
|
||||
pDesc->Rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
|
||||
pDesc->Monitor = m_monitor;
|
||||
// TODO: When in HDR, flip this to 10 to appease apps that the
|
||||
// transition has occured.
|
||||
// If we support more than HDR10 in future, then we may want
|
||||
// to visit that assumption.
|
||||
pDesc->BitsPerColor = 8;
|
||||
// This should only return DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
|
||||
// (HDR) if the user has the HDR setting enabled in Windows.
|
||||
// Games can still punt into HDR mode by using CheckColorSpaceSupport
|
||||
// and SetColorSpace1.
|
||||
//
|
||||
// TODO: When we have a swapchain using SetColorSpace1 to
|
||||
// DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, we should use our monitor
|
||||
// info to flip this over to that.
|
||||
// As on Windows this would automatically engage HDR mode.
|
||||
pDesc->ColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||
//
|
||||
// We have no way of checking the actual Windows colorspace as the
|
||||
// only public method for this *is* DXGI which we are re-implementing.
|
||||
// So we just pick our color space based on the DXVK_HDR env var
|
||||
// and the punting from SetColorSpace1.
|
||||
pDesc->ColorSpace = m_monitorInfo->CurrentColorSpace();
|
||||
pDesc->RedPrimary[0] = m_metadata.redPrimary[0];
|
||||
pDesc->RedPrimary[1] = m_metadata.redPrimary[1];
|
||||
pDesc->GreenPrimary[0] = m_metadata.greenPrimary[0];
|
||||
|
@ -536,7 +536,13 @@ namespace dxvk {
|
||||
return E_INVALIDARG;
|
||||
|
||||
std::lock_guard<dxvk::mutex> lock(m_lockBuffer);
|
||||
return m_presenter->SetColorSpace(ColorSpace);
|
||||
HRESULT hr = m_presenter->SetColorSpace(ColorSpace);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// If this was a colorspace other than our current one,
|
||||
// punt us into that one on the DXGI output.
|
||||
m_monitorInfo->PuntColorSpace(ColorSpace);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user