1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-13 19:29:14 +01:00

[dxgi] Cache display metadata + colorimetry in DXGI_VK_MONITOR_DATA

This commit is contained in:
Joshua Ashton 2022-11-17 17:21:38 +00:00 committed by Philip Rebohle
parent fabe4a85e3
commit aa71e7e323
3 changed files with 57 additions and 17 deletions

View File

@ -2,6 +2,8 @@
#include "../dxvk/dxvk_include.h"
#include "../wsi/wsi_edid.h"
#include "../util/util_time.h"
#include "dxgi_format.h"
@ -27,6 +29,7 @@ struct DXGI_VK_MONITOR_DATA {
DXGI_FRAME_STATISTICS FrameStats;
DXGI_GAMMA_CONTROL GammaCurve;
DXGI_MODE_DESC1 LastMode;
dxvk::wsi::WsiDisplayMetadata DisplayMetadata;
};

View File

@ -27,23 +27,7 @@ namespace dxvk {
: m_monitorInfo(factory->GetMonitorInfo()),
m_adapter(adapter),
m_monitor(monitor) {
// Query current display mode
wsi::WsiMode activeWsiMode = { };
wsi::getCurrentDisplayMode(m_monitor, &activeWsiMode);
// Init monitor info if necessary
DXGI_VK_MONITOR_DATA monitorData = { };
monitorData.FrameStats.SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter();
monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f };
monitorData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f };
monitorData.LastMode = ConvertDisplayMode(activeWsiMode);
for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) {
const float value = GammaControlPointLocation(i);
monitorData.GammaCurve.GammaCurve[i] = { value, value, value };
}
m_monitorInfo->InitMonitorData(monitor, &monitorData);
CacheMonitorData();
}
@ -637,4 +621,53 @@ namespace dxvk {
}
}
void DxgiOutput::CacheMonitorData() {
// Try and find an existing monitor info.
DXGI_VK_MONITOR_DATA* pMonitorData;
if (SUCCEEDED(m_monitorInfo->AcquireMonitorData(m_monitor, &pMonitorData))) {
m_metadata = pMonitorData->DisplayMetadata;
return;
}
// Init monitor info ourselves.
//
// If some other thread ends up beating us to it
// by another InitMonitorData, it doesn't really matter.
//
// The only thing we cache from this is the m_metadata which
// should be exactly the same.
// We don't store any pointers from the DXGI_VK_MONITOR_DATA
// sturcture, etc.
DXGI_VK_MONITOR_DATA monitorData = {};
// Query current display mode
wsi::WsiMode activeWsiMode = { };
wsi::getCurrentDisplayMode(m_monitor, &activeWsiMode);
// Get the display metadata + colorimetry
wsi::WsiEdidData edidData = wsi::getMonitorEdid(m_monitor);
std::optional<wsi::WsiDisplayMetadata> metadata = std::nullopt;
if (!edidData.empty())
metadata = wsi::parseColorimetryInfo(edidData);
if (metadata)
m_metadata = metadata.value();
else
Logger::err("DXGI: Failed to parse display metadata + colorimetry info, using blank.");
monitorData.FrameStats.SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter();
monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f };
monitorData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f };
monitorData.LastMode = ConvertDisplayMode(activeWsiMode);
monitorData.DisplayMetadata = m_metadata;
for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) {
const float value = GammaControlPointLocation(i);
monitorData.GammaCurve.GammaCurve[i] = { value, value, value };
}
m_monitorInfo->InitMonitorData(m_monitor, &monitorData);
}
}

View File

@ -133,10 +133,14 @@ namespace dxvk {
Com<DxgiAdapter> m_adapter = nullptr;
HMONITOR m_monitor = nullptr;
wsi::WsiDisplayMetadata m_metadata = {};
static void FilterModesByDesc(
std::vector<DXGI_MODE_DESC1>& Modes,
const DXGI_MODE_DESC1& TargetMode);
void CacheMonitorData();
};
}