mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 10:24:12 +01:00
[dxgi] Port DxgiOutput and DxgiSwapChain to new monitor data API
This allows us to remove the dependency between DxgiSwapChain and DxgiVkAdapter without losing gamma control emulation.
This commit is contained in:
parent
e30bb498b6
commit
aa2ec3f998
@ -19,21 +19,19 @@ namespace dxvk {
|
||||
HMONITOR monitor)
|
||||
: m_adapter(adapter),
|
||||
m_monitor(monitor) {
|
||||
// Init output data if necessary
|
||||
if (FAILED(m_adapter->GetOutputData(m_monitor, nullptr))) {
|
||||
DXGI_VK_OUTPUT_DATA outputData;
|
||||
outputData.FrameStats = DXGI_FRAME_STATISTICS();
|
||||
outputData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f };
|
||||
outputData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) {
|
||||
const float value = GammaControlPointLocation(i);
|
||||
outputData.GammaCurve.GammaCurve[i] = { value, value, value };
|
||||
}
|
||||
|
||||
outputData.GammaDirty = FALSE;
|
||||
m_adapter->SetOutputData(m_monitor, &outputData);
|
||||
// Init monitor info if necessary
|
||||
DXGI_VK_MONITOR_DATA monitorData;
|
||||
monitorData.pSwapChain = nullptr;
|
||||
monitorData.FrameStats = DXGI_FRAME_STATISTICS();
|
||||
monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f };
|
||||
monitorData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) {
|
||||
const float value = GammaControlPointLocation(i);
|
||||
monitorData.GammaCurve.GammaCurve[i] = { value, value, value };
|
||||
}
|
||||
|
||||
InitMonitorData(monitor, &monitorData);
|
||||
}
|
||||
|
||||
|
||||
@ -330,27 +328,27 @@ namespace dxvk {
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DxgiOutput::GetFrameStatistics(DXGI_FRAME_STATISTICS* pStats) {
|
||||
DXGI_VK_OUTPUT_DATA outputData;
|
||||
DXGI_VK_MONITOR_DATA* monitorInfo = nullptr;
|
||||
HRESULT hr = AcquireMonitorData(m_monitor, &monitorInfo);
|
||||
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (FAILED(m_adapter->GetOutputData(m_monitor, &outputData))) {
|
||||
Logger::err("DXGI: Failed to query output data");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
*pStats = outputData.FrameStats;
|
||||
*pStats = monitorInfo->FrameStats;
|
||||
ReleaseMonitorData();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DxgiOutput::GetGammaControl(DXGI_GAMMA_CONTROL* pArray) {
|
||||
DXGI_VK_OUTPUT_DATA outputData;
|
||||
DXGI_VK_MONITOR_DATA* monitorInfo = nullptr;
|
||||
HRESULT hr = AcquireMonitorData(m_monitor, &monitorInfo);
|
||||
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (FAILED(m_adapter->GetOutputData(m_monitor, &outputData))) {
|
||||
Logger::err("DXGI: Failed to query output data");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
*pArray = outputData.GammaCurve;
|
||||
*pArray = monitorInfo->GammaCurve;
|
||||
ReleaseMonitorData();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -385,20 +383,21 @@ namespace dxvk {
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DxgiOutput::SetGammaControl(const DXGI_GAMMA_CONTROL* pArray) {
|
||||
DXGI_VK_OUTPUT_DATA outputData;
|
||||
DXGI_VK_MONITOR_DATA* monitorInfo = nullptr;
|
||||
HRESULT hr = AcquireMonitorData(m_monitor, &monitorInfo);
|
||||
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (FAILED(m_adapter->GetOutputData(m_monitor, &outputData))) {
|
||||
Logger::err("DXGI: Failed to query output data");
|
||||
return E_FAIL;
|
||||
monitorInfo->GammaCurve = *pArray;
|
||||
|
||||
if (monitorInfo->pSwapChain) {
|
||||
hr = monitorInfo->pSwapChain->SetGammaControl(
|
||||
DXGI_VK_GAMMA_CP_COUNT, pArray->GammaCurve);
|
||||
}
|
||||
|
||||
outputData.GammaCurve = *pArray;
|
||||
outputData.GammaDirty = TRUE;
|
||||
|
||||
if (FAILED(m_adapter->SetOutputData(m_monitor, &outputData))) {
|
||||
Logger::err("DXGI: Failed to update output data");
|
||||
return E_FAIL;
|
||||
} return S_OK;
|
||||
|
||||
ReleaseMonitorData();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "dxgi_monitor.h"
|
||||
#include "dxgi_object.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
@ -47,6 +47,16 @@ namespace dxvk {
|
||||
|
||||
if (SUCCEEDED(GetOutputFromMonitor(m_monitor, &output)))
|
||||
RestoreDisplayMode(output.ptr());
|
||||
|
||||
// Decouple swap chain from monitor if necessary
|
||||
DXGI_VK_MONITOR_DATA* monitorInfo = nullptr;
|
||||
|
||||
if (SUCCEEDED(AcquireMonitorData(m_monitor, &monitorInfo))) {
|
||||
if (monitorInfo->pSwapChain == this)
|
||||
monitorInfo->pSwapChain = nullptr;
|
||||
|
||||
ReleaseMonitorData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -263,17 +273,6 @@ namespace dxvk {
|
||||
SyncInterval = std::min<UINT>(SyncInterval, 4);
|
||||
|
||||
try {
|
||||
// If in fullscreen mode, apply any updated gamma curve
|
||||
// if it has been changed since the last present call.
|
||||
DXGI_VK_OUTPUT_DATA outputData;
|
||||
|
||||
if (SUCCEEDED(m_adapter->GetOutputData(m_monitor, &outputData)) && outputData.GammaDirty) {
|
||||
m_presenter->SetGammaControl(DXGI_VK_GAMMA_CP_COUNT, outputData.GammaCurve.GammaCurve);
|
||||
|
||||
outputData.GammaDirty = FALSE;
|
||||
m_adapter->SetOutputData(m_monitor, &outputData);
|
||||
}
|
||||
|
||||
return m_presenter->Present(SyncInterval, PresentFlags, nullptr);
|
||||
} catch (const DxvkError& err) {
|
||||
Logger::err(err.message());
|
||||
@ -481,10 +480,18 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
HRESULT DxgiSwapChain::SetColorSpace1(DXGI_COLOR_SPACE_TYPE ColorSpace) {
|
||||
HRESULT STDMETHODCALLTYPE DxgiSwapChain::SetColorSpace1(DXGI_COLOR_SPACE_TYPE ColorSpace) {
|
||||
Logger::err("DxgiSwapChain::SetColorSpace1: Not implemented");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DxgiSwapChain::SetGammaControl(
|
||||
UINT NumPoints,
|
||||
const DXGI_RGB* pGammaCurve) {
|
||||
std::lock_guard<std::mutex> lockBuf(m_lockBuffer);
|
||||
return m_presenter->SetGammaControl(NumPoints, pGammaCurve);
|
||||
}
|
||||
|
||||
|
||||
VkExtent2D DxgiSwapChain::GetWindowSize() const {
|
||||
@ -560,6 +567,18 @@ namespace dxvk {
|
||||
SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
|
||||
|
||||
m_monitor = desc.Monitor;
|
||||
|
||||
// Apply current gamma curve of the output
|
||||
DXGI_VK_MONITOR_DATA* monitorInfo = nullptr;
|
||||
|
||||
if (SUCCEEDED(AcquireMonitorData(m_monitor, &monitorInfo))) {
|
||||
if (!monitorInfo->pSwapChain)
|
||||
monitorInfo->pSwapChain = this;
|
||||
|
||||
SetGammaControl(DXGI_VK_GAMMA_CP_COUNT, monitorInfo->GammaCurve.GammaCurve);
|
||||
ReleaseMonitorData();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -574,6 +593,17 @@ namespace dxvk {
|
||||
|| FAILED(RestoreDisplayMode(output.ptr())))
|
||||
Logger::warn("DXGI: LeaveFullscreenMode: Failed to restore display mode");
|
||||
|
||||
// Reset gamma control and decouple swap chain from monitor
|
||||
DXGI_VK_MONITOR_DATA* monitorInfo = nullptr;
|
||||
|
||||
if (SUCCEEDED(AcquireMonitorData(m_monitor, &monitorInfo))) {
|
||||
if (monitorInfo->pSwapChain == this)
|
||||
monitorInfo->pSwapChain = nullptr;
|
||||
|
||||
SetGammaControl(0, nullptr);
|
||||
ReleaseMonitorData();
|
||||
}
|
||||
|
||||
// Restore internal state
|
||||
m_descFs.Windowed = TRUE;
|
||||
m_monitor = nullptr;
|
||||
@ -596,7 +626,7 @@ namespace dxvk {
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
return m_presenter->SetGammaControl(0, nullptr);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,6 +155,10 @@ namespace dxvk {
|
||||
HRESULT STDMETHODCALLTYPE SetColorSpace1(
|
||||
DXGI_COLOR_SPACE_TYPE ColorSpace) final;
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SetGammaControl(
|
||||
UINT NumPoints,
|
||||
const DXGI_RGB* pGammaCurve);
|
||||
|
||||
private:
|
||||
|
||||
struct WindowState {
|
||||
@ -167,7 +171,7 @@ namespace dxvk {
|
||||
std::mutex m_lockBuffer;
|
||||
|
||||
Com<IDXGIFactory> m_factory;
|
||||
Com<DxgiAdapter> m_adapter;
|
||||
Com<IDXGIAdapter> m_adapter;
|
||||
|
||||
HWND m_window;
|
||||
DXGI_SWAP_CHAIN_DESC1 m_desc;
|
||||
|
Loading…
Reference in New Issue
Block a user