Skip to content

Commit

Permalink
[dxgi] Cache display metadata + colorimetry in DXGI_VK_MONITOR_DATA
Browse files Browse the repository at this point in the history
  • Loading branch information
misyltoad authored and doitsujin committed Nov 21, 2022
1 parent fabe4a8 commit aa71e7e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 17 deletions.
3 changes: 3 additions & 0 deletions src/dxgi/dxgi_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "../dxvk/dxvk_include.h"

#include "../wsi/wsi_edid.h"

#include "../util/util_time.h"

#include "dxgi_format.h"
Expand All @@ -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;
};


Expand Down
67 changes: 50 additions & 17 deletions src/dxgi/dxgi_output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}


Expand Down Expand Up @@ -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);
}

}
4 changes: 4 additions & 0 deletions src/dxgi/dxgi_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

};

}

0 comments on commit aa71e7e

Please sign in to comment.