1
0
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:
Philip Rebohle 2018-12-11 15:32:06 +01:00
parent e30bb498b6
commit aa2ec3f998
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 88 additions and 54 deletions

View File

@ -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;
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "dxgi_monitor.h"
#include "dxgi_object.h"
namespace dxvk {

View File

@ -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;
}

View File

@ -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;