1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-07 16:54:14 +01:00

[dxgi] Promote output stored in swap chain to IDXGIOutput1

This commit is contained in:
Philip Rebohle 2022-09-15 15:30:07 +02:00
parent 57af9e8760
commit faaa6bf1df
2 changed files with 58 additions and 45 deletions

View File

@ -94,12 +94,19 @@ namespace dxvk {
if (!wsi::isWindow(m_window)) if (!wsi::isWindow(m_window))
return DXGI_ERROR_INVALID_CALL; return DXGI_ERROR_INVALID_CALL;
if (m_target != nullptr) { Com<IDXGIOutput1> output;
*ppOutput = m_target.ref();
return S_OK; if (m_target == nullptr) {
HRESULT hr = GetOutputFromMonitor(wsi::getWindowMonitor(m_window), &output);
if (FAILED(hr))
return hr;
} else {
output = m_target;
} }
return GetOutputFromMonitor(wsi::getWindowMonitor(m_window), ppOutput); *ppOutput = output.ref();
return S_OK;
} }
@ -322,26 +329,35 @@ namespace dxvk {
HRESULT STDMETHODCALLTYPE DxgiSwapChain::ResizeTarget(const DXGI_MODE_DESC* pNewTargetParameters) { HRESULT STDMETHODCALLTYPE DxgiSwapChain::ResizeTarget(const DXGI_MODE_DESC* pNewTargetParameters) {
std::lock_guard<dxvk::recursive_mutex> lock(m_lockWindow); std::lock_guard<dxvk::recursive_mutex> lock(m_lockWindow);
if (pNewTargetParameters == nullptr) if (!pNewTargetParameters)
return DXGI_ERROR_INVALID_CALL; return DXGI_ERROR_INVALID_CALL;
if (!wsi::isWindow(m_window)) if (!wsi::isWindow(m_window))
return DXGI_ERROR_INVALID_CALL; return DXGI_ERROR_INVALID_CALL;
// Promote display mode
DXGI_MODE_DESC1 newDisplayMode = { };
newDisplayMode.Width = pNewTargetParameters->Width;
newDisplayMode.Height = pNewTargetParameters->Height;
newDisplayMode.RefreshRate = pNewTargetParameters->RefreshRate;
newDisplayMode.Format = pNewTargetParameters->Format;
newDisplayMode.ScanlineOrdering = pNewTargetParameters->ScanlineOrdering;
newDisplayMode.Scaling = pNewTargetParameters->Scaling;
// Update the swap chain description // Update the swap chain description
if (pNewTargetParameters->RefreshRate.Numerator != 0) if (newDisplayMode.RefreshRate.Numerator != 0)
m_descFs.RefreshRate = pNewTargetParameters->RefreshRate; m_descFs.RefreshRate = newDisplayMode.RefreshRate;
m_descFs.ScanlineOrdering = pNewTargetParameters->ScanlineOrdering; m_descFs.ScanlineOrdering = newDisplayMode.ScanlineOrdering;
m_descFs.Scaling = pNewTargetParameters->Scaling; m_descFs.Scaling = newDisplayMode.Scaling;
if (m_descFs.Windowed) { if (m_descFs.Windowed) {
wsi::resizeWindow( wsi::resizeWindow(
m_window, &m_windowState, m_window, &m_windowState,
pNewTargetParameters->Width, newDisplayMode.Width,
pNewTargetParameters->Height); newDisplayMode.Height);
} else { } else {
Com<IDXGIOutput> output; Com<IDXGIOutput1> output;
if (FAILED(GetOutputFromMonitor(m_monitor, &output))) { if (FAILED(GetOutputFromMonitor(m_monitor, &output))) {
Logger::err("DXGI: ResizeTarget: Failed to query containing output"); Logger::err("DXGI: ResizeTarget: Failed to query containing output");
@ -350,7 +366,7 @@ namespace dxvk {
// If the swap chain allows it, change the display mode // If the swap chain allows it, change the display mode
if (m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) { if (m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) {
ChangeDisplayMode(output.ptr(), pNewTargetParameters); ChangeDisplayMode(output.ptr(), &newDisplayMode);
NotifyModeChange(m_monitor, FALSE); NotifyModeChange(m_monitor, FALSE);
} }
@ -369,8 +385,13 @@ namespace dxvk {
if (!Fullscreen && pTarget) if (!Fullscreen && pTarget)
return DXGI_ERROR_INVALID_CALL; return DXGI_ERROR_INVALID_CALL;
Com<IDXGIOutput1> target;
if (pTarget)
pTarget->QueryInterface(IID_PPV_ARGS(&target));
if (m_descFs.Windowed && Fullscreen) if (m_descFs.Windowed && Fullscreen)
return this->EnterFullscreenMode(pTarget); return this->EnterFullscreenMode(target.ptr());
else if (!m_descFs.Windowed && !Fullscreen) else if (!m_descFs.Windowed && !Fullscreen)
return this->LeaveFullscreenMode(); return this->LeaveFullscreenMode();
@ -528,14 +549,14 @@ namespace dxvk {
} }
HRESULT DxgiSwapChain::EnterFullscreenMode(IDXGIOutput* pTarget) { HRESULT DxgiSwapChain::EnterFullscreenMode(IDXGIOutput1* pTarget) {
Com<IDXGIOutput> output = pTarget; Com<IDXGIOutput1> output = pTarget;
if (!wsi::isWindow(m_window)) if (!wsi::isWindow(m_window))
return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
if (output == nullptr) { if (output == nullptr) {
if (FAILED(GetContainingOutput(&output))) { if (FAILED(GetOutputFromMonitor(wsi::getWindowMonitor(m_window), &output))) {
Logger::err("DXGI: EnterFullscreenMode: Cannot query containing output"); Logger::err("DXGI: EnterFullscreenMode: Cannot query containing output");
return E_FAIL; return E_FAIL;
} }
@ -544,7 +565,7 @@ namespace dxvk {
const bool modeSwitch = m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; const bool modeSwitch = m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
if (modeSwitch) { if (modeSwitch) {
DXGI_MODE_DESC displayMode; DXGI_MODE_DESC1 displayMode = { };
displayMode.Width = m_desc.Width; displayMode.Width = m_desc.Width;
displayMode.Height = m_desc.Height; displayMode.Height = m_desc.Height;
displayMode.RefreshRate = m_descFs.RefreshRate; displayMode.RefreshRate = m_descFs.RefreshRate;
@ -627,8 +648,8 @@ namespace dxvk {
HRESULT DxgiSwapChain::ChangeDisplayMode( HRESULT DxgiSwapChain::ChangeDisplayMode(
IDXGIOutput* pOutput, IDXGIOutput1* pOutput,
const DXGI_MODE_DESC* pDisplayMode) { const DXGI_MODE_DESC1* pDisplayMode) {
if (!pOutput) if (!pOutput)
return DXGI_ERROR_INVALID_CALL; return DXGI_ERROR_INVALID_CALL;
@ -636,13 +657,13 @@ namespace dxvk {
DXGI_OUTPUT_DESC outputDesc; DXGI_OUTPUT_DESC outputDesc;
pOutput->GetDesc(&outputDesc); pOutput->GetDesc(&outputDesc);
DXGI_MODE_DESC preferredMode = *pDisplayMode; DXGI_MODE_DESC1 preferredMode = *pDisplayMode;
DXGI_MODE_DESC selectedMode; DXGI_MODE_DESC1 selectedMode;
if (preferredMode.Format == DXGI_FORMAT_UNKNOWN) if (preferredMode.Format == DXGI_FORMAT_UNKNOWN)
preferredMode.Format = m_desc.Format; preferredMode.Format = m_desc.Format;
HRESULT hr = pOutput->FindClosestMatchingMode( HRESULT hr = pOutput->FindClosestMatchingMode1(
&preferredMode, &selectedMode, nullptr); &preferredMode, &selectedMode, nullptr);
if (FAILED(hr)) { if (FAILED(hr)) {
@ -654,16 +675,7 @@ namespace dxvk {
return hr; return hr;
} }
DXGI_MODE_DESC1 selectedMode1; if (!wsi::setWindowMode(outputDesc.Monitor, m_window, ConvertDisplayMode(selectedMode)))
selectedMode1.Width = selectedMode.Width;
selectedMode1.Height = selectedMode.Height;
selectedMode1.RefreshRate = selectedMode.RefreshRate;
selectedMode1.Format = selectedMode.Format;
selectedMode1.ScanlineOrdering = selectedMode.ScanlineOrdering;
selectedMode1.Scaling = selectedMode.Scaling;
selectedMode1.Stereo = false;
if (!wsi::setWindowMode(outputDesc.Monitor, m_window, ConvertDisplayMode(selectedMode1)))
return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE;
return S_OK; return S_OK;
@ -696,19 +708,20 @@ namespace dxvk {
HRESULT DxgiSwapChain::GetOutputFromMonitor( HRESULT DxgiSwapChain::GetOutputFromMonitor(
HMONITOR Monitor, HMONITOR Monitor,
IDXGIOutput** ppOutput) { IDXGIOutput1** ppOutput) {
if (!ppOutput) if (!ppOutput)
return DXGI_ERROR_INVALID_CALL; return DXGI_ERROR_INVALID_CALL;
for (uint32_t i = 0; SUCCEEDED(m_adapter->EnumOutputs(i, ppOutput)); i++) { Com<IDXGIOutput> output;
for (uint32_t i = 0; SUCCEEDED(m_adapter->EnumOutputs(i, &output)); i++) {
DXGI_OUTPUT_DESC outputDesc; DXGI_OUTPUT_DESC outputDesc;
(*ppOutput)->GetDesc(&outputDesc); output->GetDesc(&outputDesc);
if (outputDesc.Monitor == Monitor) if (outputDesc.Monitor == Monitor)
return S_OK; return output->QueryInterface(IID_PPV_ARGS(ppOutput));
(*ppOutput)->Release(); output = nullptr;
(*ppOutput) = nullptr;
} }
return DXGI_ERROR_NOT_FOUND; return DXGI_ERROR_NOT_FOUND;

View File

@ -177,7 +177,7 @@ namespace dxvk {
Com<IDXGIFactory> m_factory; Com<IDXGIFactory> m_factory;
Com<IDXGIAdapter> m_adapter; Com<IDXGIAdapter> m_adapter;
Com<IDXGIOutput> m_target; Com<IDXGIOutput1> m_target;
Com<IDXGIVkMonitorInfo> m_monitorInfo; Com<IDXGIVkMonitorInfo> m_monitorInfo;
HWND m_window; HWND m_window;
@ -191,13 +191,13 @@ namespace dxvk {
wsi::DxvkWindowState m_windowState; wsi::DxvkWindowState m_windowState;
HRESULT EnterFullscreenMode( HRESULT EnterFullscreenMode(
IDXGIOutput *pTarget); IDXGIOutput1 *pTarget);
HRESULT LeaveFullscreenMode(); HRESULT LeaveFullscreenMode();
HRESULT ChangeDisplayMode( HRESULT ChangeDisplayMode(
IDXGIOutput* pOutput, IDXGIOutput1* pOutput,
const DXGI_MODE_DESC* pDisplayMode); const DXGI_MODE_DESC1* pDisplayMode);
HRESULT RestoreDisplayMode( HRESULT RestoreDisplayMode(
HMONITOR hMonitor); HMONITOR hMonitor);
@ -208,7 +208,7 @@ namespace dxvk {
HRESULT GetOutputFromMonitor( HRESULT GetOutputFromMonitor(
HMONITOR Monitor, HMONITOR Monitor,
IDXGIOutput** ppOutput); IDXGIOutput1** ppOutput);
HRESULT AcquireMonitorData( HRESULT AcquireMonitorData(
HMONITOR hMonitor, HMONITOR hMonitor,