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:
parent
57af9e8760
commit
faaa6bf1df
@ -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;
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user