1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#include "dxgi_monitor.h"
namespace dxvk {
DxgiMonitorInfo::DxgiMonitorInfo(IUnknown* pParent, const DxgiOptions& options)
: m_parent(pParent)
, m_options(options)
, m_globalColorSpace(DefaultColorSpace()) {
}
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;
std::lock_guard<dxvk::mutex> lock(m_monitorMutex);
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();
}
void STDMETHODCALLTYPE DxgiMonitorInfo::PuntColorSpace(DXGI_COLOR_SPACE_TYPE ColorSpace) {
// 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;
m_globalColorSpace = ColorSpace;
}
DXGI_COLOR_SPACE_TYPE STDMETHODCALLTYPE DxgiMonitorInfo::CurrentColorSpace() const {
return m_globalColorSpace;
}
DXGI_COLOR_SPACE_TYPE DxgiMonitorInfo::DefaultColorSpace() const {
return m_options.enableHDR
? 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:
case DXGI_FORMAT_B8G8R8A8_UNORM:
case DXGI_FORMAT_B8G8R8X8_UNORM:
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
case DXGI_FORMAT_R10G10B10A2_UNORM:
return 32;
case DXGI_FORMAT_R16G16B16A16_FLOAT:
// 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;
default:
Logger::warn(str::format(
"GetMonitorFormatBpp: Unknown format: ",
Format));
return 32;
}
}
}
|