mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[dxgi] Leave fullscreen mode when window looses focus
This commit is contained in:
parent
758dc805bb
commit
ed9ffa6584
@ -302,7 +302,7 @@ namespace dxvk {
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
frontendSwapChain = new DxgiSwapChain(this, presenter.ptr(), hWnd, &desc, &fsDesc);
|
frontendSwapChain = new DxgiSwapChain(this, presenter.ptr(), hWnd, &desc, &fsDesc, pDevice);
|
||||||
} else {
|
} else {
|
||||||
Logger::err("DXGI: CreateSwapChainForHwnd: Unsupported device type");
|
Logger::err("DXGI: CreateSwapChainForHwnd: Unsupported device type");
|
||||||
return DXGI_ERROR_UNSUPPORTED;
|
return DXGI_ERROR_UNSUPPORTED;
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "../util/util_misc.h"
|
#include "../util/util_misc.h"
|
||||||
|
|
||||||
|
#include <d3d12.h>
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxgiSwapChain::DxgiSwapChain(
|
DxgiSwapChain::DxgiSwapChain(
|
||||||
@ -11,14 +13,17 @@ namespace dxvk {
|
|||||||
IDXGIVkSwapChain* pPresenter,
|
IDXGIVkSwapChain* pPresenter,
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
||||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc)
|
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc,
|
||||||
|
IUnknown* pDevice)
|
||||||
: m_factory (pFactory),
|
: m_factory (pFactory),
|
||||||
m_window (hWnd),
|
m_window (hWnd),
|
||||||
m_desc (*pDesc),
|
m_desc (*pDesc),
|
||||||
m_descFs (*pFullscreenDesc),
|
m_descFs (*pFullscreenDesc),
|
||||||
m_presentId (0u),
|
m_presentId (0u),
|
||||||
m_presenter (pPresenter),
|
m_presenter (pPresenter),
|
||||||
m_monitor (wsi::getWindowMonitor(m_window)) {
|
m_monitor (wsi::getWindowMonitor(m_window)),
|
||||||
|
m_is_d3d12(SUCCEEDED(pDevice->QueryInterface(__uuidof(ID3D12CommandQueue), reinterpret_cast<void**>(&Com<ID3D12CommandQueue>())))) {
|
||||||
|
|
||||||
if (FAILED(m_presenter->GetAdapter(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&m_adapter))))
|
if (FAILED(m_presenter->GetAdapter(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&m_adapter))))
|
||||||
throw DxvkError("DXGI: Failed to get adapter for present device");
|
throw DxvkError("DXGI: Failed to get adapter for present device");
|
||||||
|
|
||||||
@ -243,7 +248,9 @@ namespace dxvk {
|
|||||||
BOOL* pFullscreen,
|
BOOL* pFullscreen,
|
||||||
IDXGIOutput** ppTarget) {
|
IDXGIOutput** ppTarget) {
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if (!m_is_d3d12 && !m_descFs.Windowed && wsi::isOccluded(m_window))
|
||||||
|
SetFullscreenState(FALSE, nullptr);
|
||||||
if (pFullscreen != nullptr)
|
if (pFullscreen != nullptr)
|
||||||
*pFullscreen = !m_descFs.Windowed;
|
*pFullscreen = !m_descFs.Windowed;
|
||||||
|
|
||||||
@ -325,6 +332,10 @@ namespace dxvk {
|
|||||||
if (SyncInterval > 4)
|
if (SyncInterval > 4)
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
|
|
||||||
|
if ((m_desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD || m_desc.SwapEffect == DXGI_SWAP_EFFECT_SEQUENTIAL) && wsi::isMinimized(m_window))
|
||||||
|
return DXGI_STATUS_OCCLUDED;
|
||||||
|
bool occluded = !m_descFs.Windowed && wsi::isOccluded(m_window) && !wsi::isMinimized(m_window);
|
||||||
|
|
||||||
auto options = m_factory->GetOptions();
|
auto options = m_factory->GetOptions();
|
||||||
|
|
||||||
if (options->syncInterval >= 0)
|
if (options->syncInterval >= 0)
|
||||||
@ -342,7 +353,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (PresentFlags & DXGI_PRESENT_TEST)
|
if (PresentFlags & DXGI_PRESENT_TEST)
|
||||||
return hr;
|
return hr == S_OK && occluded ? DXGI_STATUS_OCCLUDED : hr;
|
||||||
|
|
||||||
if (hr == S_OK) {
|
if (hr == S_OK) {
|
||||||
|
|
||||||
@ -365,6 +376,11 @@ namespace dxvk {
|
|||||||
monitorData->FrameStats.PresentRefreshCount = monitorData->FrameStats.SyncRefreshCount + computeRefreshCount(t0, t1, refreshPeriod);
|
monitorData->FrameStats.PresentRefreshCount = monitorData->FrameStats.SyncRefreshCount + computeRefreshCount(t0, t1, refreshPeriod);
|
||||||
ReleaseMonitorData();
|
ReleaseMonitorData();
|
||||||
}
|
}
|
||||||
|
if (occluded) {
|
||||||
|
if (!(PresentFlags & DXGI_PRESENT_TEST))
|
||||||
|
SetFullscreenState(FALSE, nullptr);
|
||||||
|
hr = DXGI_STATUS_OCCLUDED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -31,7 +31,8 @@ namespace dxvk {
|
|||||||
IDXGIVkSwapChain* pPresenter,
|
IDXGIVkSwapChain* pPresenter,
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
const DXGI_SWAP_CHAIN_DESC1* pDesc,
|
||||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc);
|
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc,
|
||||||
|
IUnknown* pDevice);
|
||||||
|
|
||||||
~DxgiSwapChain();
|
~DxgiSwapChain();
|
||||||
|
|
||||||
@ -198,6 +199,7 @@ namespace dxvk {
|
|||||||
double m_frameRateOption = 0.0;
|
double m_frameRateOption = 0.0;
|
||||||
double m_frameRateRefresh = 0.0;
|
double m_frameRateRefresh = 0.0;
|
||||||
double m_frameRateLimit = 0.0;
|
double m_frameRateLimit = 0.0;
|
||||||
|
bool m_is_d3d12;
|
||||||
|
|
||||||
DXGI_COLOR_SPACE_TYPE m_colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
DXGI_COLOR_SPACE_TYPE m_colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
|
||||||
|
|
||||||
|
@ -95,6 +95,10 @@ namespace dxvk::wsi {
|
|||||||
|
|
||||||
virtual bool isWindow(HWND hWindow);
|
virtual bool isWindow(HWND hWindow);
|
||||||
|
|
||||||
|
virtual bool isMinimized(HWND hWindow);
|
||||||
|
|
||||||
|
virtual bool isOccluded(HWND hWindow);
|
||||||
|
|
||||||
virtual void updateFullscreenWindow(
|
virtual void updateFullscreenWindow(
|
||||||
HMONITOR hMonitor,
|
HMONITOR hMonitor,
|
||||||
HWND hWindow,
|
HWND hWindow,
|
||||||
|
@ -126,6 +126,18 @@ namespace dxvk::wsi {
|
|||||||
return window != nullptr;
|
return window != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GlfwWsiDriver::isMinimized(HWND hWindow) {
|
||||||
|
GLFWwindow* window = fromHwnd(hWindow);
|
||||||
|
return glfwGetWindowAttrib(window, GLFW_ICONIFIED) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GlfwWsiDriver::isOccluded(HWND hWindow) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GlfwWsiDriver::updateFullscreenWindow(
|
void GlfwWsiDriver::updateFullscreenWindow(
|
||||||
HMONITOR hMonitor,
|
HMONITOR hMonitor,
|
||||||
HWND hWindow,
|
HWND hWindow,
|
||||||
|
@ -93,6 +93,10 @@ namespace dxvk::wsi {
|
|||||||
|
|
||||||
virtual bool isWindow(HWND hWindow);
|
virtual bool isWindow(HWND hWindow);
|
||||||
|
|
||||||
|
virtual bool isMinimized(HWND hWindow);
|
||||||
|
|
||||||
|
virtual bool isOccluded(HWND hWindow);
|
||||||
|
|
||||||
virtual void updateFullscreenWindow(
|
virtual void updateFullscreenWindow(
|
||||||
HMONITOR hMonitor,
|
HMONITOR hMonitor,
|
||||||
HWND hWindow,
|
HWND hWindow,
|
||||||
|
@ -8,6 +8,7 @@ SDL_PROC(int, SDL_GetNumVideoDisplays, (void))
|
|||||||
SDL_PROC(int, SDL_GetWindowDisplayIndex, (SDL_Window*))
|
SDL_PROC(int, SDL_GetWindowDisplayIndex, (SDL_Window*))
|
||||||
SDL_PROC(int, SDL_SetWindowDisplayMode, (SDL_Window*, const SDL_DisplayMode*))
|
SDL_PROC(int, SDL_SetWindowDisplayMode, (SDL_Window*, const SDL_DisplayMode*))
|
||||||
SDL_PROC(int, SDL_SetWindowFullscreen, (SDL_Window*, Uint32))
|
SDL_PROC(int, SDL_SetWindowFullscreen, (SDL_Window*, Uint32))
|
||||||
|
SDL_PROC(SDL_WindowFlags, SDL_GetWindowFlags, (SDL_Window *))
|
||||||
SDL_PROC(void, SDL_GetWindowSize, (SDL_Window*, int*, int*))
|
SDL_PROC(void, SDL_GetWindowSize, (SDL_Window*, int*, int*))
|
||||||
SDL_PROC(void, SDL_SetWindowSize, (SDL_Window*, int, int))
|
SDL_PROC(void, SDL_SetWindowSize, (SDL_Window*, int, int))
|
||||||
SDL_PROC(SDL_bool, SDL_Vulkan_CreateSurface, (SDL_Window*, VkInstance, VkSurfaceKHR*))
|
SDL_PROC(SDL_bool, SDL_Vulkan_CreateSurface, (SDL_Window*, VkInstance, VkSurfaceKHR*))
|
||||||
|
@ -136,6 +136,17 @@ namespace dxvk::wsi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl2WsiDriver::isMinimized(HWND hWindow) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
return (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl2WsiDriver::isOccluded(HWND hWindow) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Sdl2WsiDriver::updateFullscreenWindow(
|
void Sdl2WsiDriver::updateFullscreenWindow(
|
||||||
HMONITOR hMonitor,
|
HMONITOR hMonitor,
|
||||||
HWND hWindow,
|
HWND hWindow,
|
||||||
|
@ -77,6 +77,10 @@ namespace dxvk::wsi {
|
|||||||
|
|
||||||
virtual bool isWindow(HWND hWindow);
|
virtual bool isWindow(HWND hWindow);
|
||||||
|
|
||||||
|
virtual bool isMinimized(HWND hWindow);
|
||||||
|
|
||||||
|
virtual bool isOccluded(HWND hWindow);
|
||||||
|
|
||||||
virtual void updateFullscreenWindow(
|
virtual void updateFullscreenWindow(
|
||||||
HMONITOR hMonitor,
|
HMONITOR hMonitor,
|
||||||
HWND hWindow,
|
HWND hWindow,
|
||||||
|
@ -254,6 +254,16 @@ namespace dxvk::wsi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Win32WsiDriver::isMinimized(HWND hWindow) {
|
||||||
|
return (::GetWindowLongW(hWindow, GWL_STYLE) & WS_MINIMIZE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Win32WsiDriver::isOccluded(HWND hWindow) {
|
||||||
|
return ::GetForegroundWindow() != hWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Win32WsiDriver::updateFullscreenWindow(
|
void Win32WsiDriver::updateFullscreenWindow(
|
||||||
HMONITOR hMonitor,
|
HMONITOR hMonitor,
|
||||||
HWND hWindow,
|
HWND hWindow,
|
||||||
|
@ -112,6 +112,14 @@ namespace dxvk::wsi {
|
|||||||
return s_driver->isWindow(hWindow);
|
return s_driver->isWindow(hWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isMinimized(HWND hWindow) {
|
||||||
|
return s_driver->isMinimized(hWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isOccluded(HWND hWindow) {
|
||||||
|
return s_driver->isOccluded(hWindow);
|
||||||
|
}
|
||||||
|
|
||||||
void updateFullscreenWindow(
|
void updateFullscreenWindow(
|
||||||
HMONITOR hMonitor,
|
HMONITOR hMonitor,
|
||||||
HWND hWindow,
|
HWND hWindow,
|
||||||
|
@ -80,6 +80,10 @@ namespace dxvk::wsi {
|
|||||||
|
|
||||||
virtual bool isWindow(HWND hWindow) = 0;
|
virtual bool isWindow(HWND hWindow) = 0;
|
||||||
|
|
||||||
|
virtual bool isMinimized(HWND hWindow) = 0;
|
||||||
|
|
||||||
|
virtual bool isOccluded(HWND hWindow) = 0;
|
||||||
|
|
||||||
virtual void updateFullscreenWindow(
|
virtual void updateFullscreenWindow(
|
||||||
HMONITOR hMonitor,
|
HMONITOR hMonitor,
|
||||||
HWND hWindow,
|
HWND hWindow,
|
||||||
|
@ -117,6 +117,22 @@ namespace dxvk::wsi {
|
|||||||
*/
|
*/
|
||||||
bool isWindow(HWND hWindow);
|
bool isWindow(HWND hWindow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Is window minimized?
|
||||||
|
*
|
||||||
|
* \param [in] hWindow The window
|
||||||
|
* \returns Is window minimized?
|
||||||
|
*/
|
||||||
|
bool isMinimized(HWND hWindow);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Is window occluded?
|
||||||
|
*
|
||||||
|
* \param [in] hWindow The window
|
||||||
|
* \returns Is window occluded?
|
||||||
|
*/
|
||||||
|
bool isOccluded(HWND hWindow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Update a fullscreen window's position/size
|
* \brief Update a fullscreen window's position/size
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user