2018-12-11 14:38:32 +01:00
|
|
|
#include "dxgi_monitor.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
2023-01-06 14:41:30 +00:00
|
|
|
DxgiMonitorInfo::DxgiMonitorInfo(IUnknown* pParent, const DxgiOptions& options)
|
2023-01-03 13:49:59 +00:00
|
|
|
: m_parent(pParent)
|
2023-01-06 14:41:30 +00:00
|
|
|
, m_options(options)
|
2023-01-03 13:49:59 +00:00
|
|
|
, m_globalColorSpace(DefaultColorSpace()) {
|
2019-03-14 15:28:05 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxgiMonitorInfo::~DxgiMonitorInfo() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE DxgiMonitorInfo::AddRef() {
|
|
|
|
return m_parent->AddRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE DxgiMonitorInfo::Release() {
|
|
|
|
return m_parent->Release();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiMonitorInfo::QueryInterface(
|
|
|
|
REFIID riid,
|
|
|
|
void** ppvObject) {
|
|
|
|
return m_parent->QueryInterface(riid, ppvObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiMonitorInfo::InitMonitorData(
|
|
|
|
HMONITOR hMonitor,
|
|
|
|
const DXGI_VK_MONITOR_DATA* pData) {
|
|
|
|
if (!hMonitor || !pData)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2021-06-28 19:19:29 +02:00
|
|
|
std::lock_guard<dxvk::mutex> lock(m_monitorMutex);
|
2019-03-14 15:28:05 +01:00
|
|
|
auto result = m_monitorData.insert({ hMonitor, *pData });
|
|
|
|
|
|
|
|
return result.second ? S_OK : E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE DxgiMonitorInfo::AcquireMonitorData(
|
|
|
|
HMONITOR hMonitor,
|
|
|
|
DXGI_VK_MONITOR_DATA** ppData) {
|
|
|
|
InitReturnPtr(ppData);
|
|
|
|
|
|
|
|
if (!hMonitor || !ppData)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
m_monitorMutex.lock();
|
|
|
|
|
|
|
|
auto entry = m_monitorData.find(hMonitor);
|
|
|
|
if (entry == m_monitorData.end()) {
|
|
|
|
m_monitorMutex.unlock();
|
|
|
|
return DXGI_ERROR_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
*ppData = &entry->second;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE DxgiMonitorInfo::ReleaseMonitorData() {
|
|
|
|
m_monitorMutex.unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-03 13:49:59 +00:00
|
|
|
void STDMETHODCALLTYPE DxgiMonitorInfo::PuntColorSpace(DXGI_COLOR_SPACE_TYPE ColorSpace) {
|
2023-01-16 02:47:48 +00:00
|
|
|
// Only allow punting if we started from sRGB.
|
|
|
|
// That way we can go from sRGB -> HDR10 or HDR10 -> sRGB if we started in sRGB.
|
|
|
|
// But if we started off by advertising HDR10 to the game, don't allow us to go back.
|
|
|
|
// This mirrors the behaviour of the global Windows HDR toggle more closely.
|
|
|
|
if (DefaultColorSpace() != DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709)
|
|
|
|
return;
|
|
|
|
|
2023-01-03 13:49:59 +00:00
|
|
|
m_globalColorSpace = ColorSpace;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DXGI_COLOR_SPACE_TYPE STDMETHODCALLTYPE DxgiMonitorInfo::CurrentColorSpace() const {
|
|
|
|
return m_globalColorSpace;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-06 14:41:30 +00:00
|
|
|
DXGI_COLOR_SPACE_TYPE DxgiMonitorInfo::DefaultColorSpace() const {
|
|
|
|
return m_options.enableHDR
|
2023-01-03 13:49:59 +00:00
|
|
|
? DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020
|
|
|
|
: DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-12-11 15:48:57 +01:00
|
|
|
uint32_t GetMonitorFormatBpp(DXGI_FORMAT Format) {
|
|
|
|
switch (Format) {
|
|
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
|
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM:
|
2020-09-04 17:54:01 +02:00
|
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM:
|
2018-12-11 15:48:57 +01:00
|
|
|
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
|
|
|
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
|
2020-09-04 17:54:01 +02:00
|
|
|
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
|
2018-12-11 15:48:57 +01:00
|
|
|
case DXGI_FORMAT_R10G10B10A2_UNORM:
|
|
|
|
return 32;
|
|
|
|
|
|
|
|
case DXGI_FORMAT_R16G16B16A16_FLOAT:
|
2023-10-29 01:57:13 +01:00
|
|
|
// Floating point output doesn't really make sense.
|
|
|
|
// This seemingly works on Windows, and based on FindClosestMode etc documentaton,
|
|
|
|
// this seems required to work for any format that scanout it supported for.
|
|
|
|
// Treat as 10-bit -> 32.
|
|
|
|
return 32;
|
2018-12-11 15:48:57 +01:00
|
|
|
|
|
|
|
default:
|
|
|
|
Logger::warn(str::format(
|
|
|
|
"GetMonitorFormatBpp: Unknown format: ",
|
|
|
|
Format));
|
|
|
|
return 32;
|
|
|
|
}
|
|
|
|
}
|
2018-12-21 15:14:07 +01:00
|
|
|
|
2018-12-11 14:38:32 +01:00
|
|
|
}
|