diff --git a/include/bgfx/bgfxdefines.h b/include/bgfx/bgfxdefines.h index 0fa429c87..6dbd9bae6 100644 --- a/include/bgfx/bgfxdefines.h +++ b/include/bgfx/bgfxdefines.h @@ -355,6 +355,7 @@ #define BGFX_RESET_SRGB_BACKBUFFER UINT32_C(0x00008000) //!< Enable sRGB backbuffer. #define BGFX_RESET_HIDPI UINT32_C(0x00010000) //!< Enable HiDPI rendering. #define BGFX_RESET_DEPTH_CLAMP UINT32_C(0x00020000) //!< Enable depth clamp. +#define BGFX_RESET_SUSPEND UINT32_C(0x00040000) //!< Suspend rendering. #define BGFX_RESET_RESERVED_SHIFT 31 //!< Internal bits shift. #define BGFX_RESET_RESERVED_MASK UINT32_C(0x80000000) //!< Internal bits mask. diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 27f1681a0..a9c84571e 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -493,6 +493,27 @@ namespace bgfx { namespace d3d11 return false; }; + void resume(ID3D11Device* _device) + { + BX_UNUSED(_device); + } + + void suspend(ID3D11Device* _device) + { + BX_UNUSED(_device); + } + + void trim(ID3D11Device* _device) + { + IDXGIDevice3* device; + HRESULT hr = _device->QueryInterface(IID_IDXGIDevice3, (void**)&device); + if (SUCCEEDED(hr) ) + { + device->Trim(); + DX_RELEASE(device, 1); + } + } + // Reference: // https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK enum AGS_RETURN_CODE @@ -2206,9 +2227,30 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - void updateResolution(const Resolution& _resolution) + bool updateResolution(const Resolution& _resolution) { - bool recenter = !!(_resolution.m_flags & BGFX_RESET_HMD_RECENTER); + const bool suspended = !!( _resolution.m_flags & BGFX_RESET_SUSPEND); + const bool wasSuspended = !!(m_resolution.m_flags & BGFX_RESET_SUSPEND); + if (suspended && wasSuspended) + { + return true; + } + else if (suspended) + { + m_deviceCtx->Flush(); + m_deviceCtx->ClearState(); + trim(m_device); + suspend(m_device); + m_resolution.m_flags |= BGFX_RESET_SUSPEND; + return true; + } + else if (wasSuspended) + { + resume(m_device); + m_resolution.m_flags &= ~BGFX_RESET_SUSPEND; + } + + bool recenter = !!(_resolution.m_flags & BGFX_RESET_HMD_RECENTER); uint32_t maxAnisotropy = 1; if (!!(_resolution.m_flags & BGFX_RESET_MAXANISOTROPY) ) @@ -2236,7 +2278,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_rasterizerStateCache.invalidate(); } - uint32_t flags = _resolution.m_flags & ~(BGFX_RESET_HMD_RECENTER | BGFX_RESET_MAXANISOTROPY | BGFX_RESET_DEPTH_CLAMP); + uint32_t flags = _resolution.m_flags & ~(0 + | BGFX_RESET_HMD_RECENTER + | BGFX_RESET_MAXANISOTROPY + | BGFX_RESET_DEPTH_CLAMP + | BGFX_RESET_SUSPEND + ); if (m_resolution.m_width != _resolution.m_width || m_resolution.m_height != _resolution.m_height @@ -2259,6 +2306,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); preReset(); + m_deviceCtx->Flush(); + m_deviceCtx->ClearState(); + if (NULL == m_swapChain) { // Updated backbuffer if it changed in PlatformData. @@ -2267,9 +2317,6 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } else { - m_deviceCtx->ClearState(); - m_deviceCtx->Flush(); - if (resize) { m_deviceCtx->OMSetRenderTargets(1, s_zero.m_rtv, NULL); @@ -2353,6 +2400,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { m_ovr.recenter(); } + + return false; } void setShaderUniform(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs) @@ -3471,25 +3520,6 @@ BX_PRAGMA_DIAGNOSTIC_POP(); s_renderD3D11 = NULL; } - void trim() - { -#if BX_PLATFORM_WINRT - if (NULL != s_renderD3D11) - { - if (s_renderD3D11->m_device) - { - IDXGIDevice3* pDXGIDevice; - HRESULT hr = s_renderD3D11->m_device->QueryInterface(__uuidof(IDXGIDevice3),(void **)&pDXGIDevice); - if (SUCCEEDED(hr) ) - { - pDXGIDevice->Trim(); - pDXGIDevice->Release(); - } - } - } -#endif // BX_PLATFORM_WINRT - } - void stubMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride) { ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; @@ -4726,13 +4756,16 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void RendererContextD3D11::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) { + if (updateResolution(_render->m_resolution) ) + { + return; + } + PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), L"rendererSubmit"); BGFX_GPU_PROFILER_BEGIN_DYNAMIC("rendererSubmit"); ID3D11DeviceContext* deviceCtx = m_deviceCtx; - updateResolution(_render->m_resolution); - int64_t elapsed = -bx::getHPCounter(); int64_t captureElapsed = 0; diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index f4a92e4ab..0f3166127 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -21,6 +21,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4005) // warning C4005: '' : macro redefinitio #define D3D11_NO_HELPERS #if BX_PLATFORM_WINDOWS # include +# include #elif BX_PLATFORM_WINRT # include #else diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 06bc06325..1a5bef94b 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -1770,7 +1770,12 @@ data.NumQualityLevels = 0; m_pipelineStateCache.invalidate(); } - uint32_t flags = _resolution.m_flags & ~(BGFX_RESET_HMD_RECENTER | BGFX_RESET_MAXANISOTROPY | BGFX_RESET_DEPTH_CLAMP); + uint32_t flags = _resolution.m_flags & ~(0 + | BGFX_RESET_HMD_RECENTER + | BGFX_RESET_MAXANISOTROPY + | BGFX_RESET_DEPTH_CLAMP + | BGFX_RESET_SUSPEND + ); if (m_resolution.m_width != _resolution.m_width || m_resolution.m_height != _resolution.m_height diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 8b52ff2d6..43564c552 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -1260,7 +1260,12 @@ namespace bgfx { namespace d3d9 ? m_caps.MaxAnisotropy : 1 ; - uint32_t flags = _resolution.m_flags & ~(BGFX_RESET_HMD_RECENTER | BGFX_RESET_MAXANISOTROPY); + uint32_t flags = _resolution.m_flags & ~(0 + | BGFX_RESET_HMD_RECENTER + | BGFX_RESET_MAXANISOTROPY + | BGFX_RESET_DEPTH_CLAMP + | BGFX_RESET_SUSPEND + ); if (m_resolution.m_width != _resolution.m_width || m_resolution.m_height != _resolution.m_height diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 7fc65a3db..063285f19 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2456,7 +2456,12 @@ namespace bgfx { namespace gl } } - uint32_t flags = _resolution.m_flags & ~(BGFX_RESET_HMD_RECENTER | BGFX_RESET_MAXANISOTROPY | BGFX_RESET_DEPTH_CLAMP); + uint32_t flags = _resolution.m_flags & ~(0 + | BGFX_RESET_HMD_RECENTER + | BGFX_RESET_MAXANISOTROPY + | BGFX_RESET_DEPTH_CLAMP + | BGFX_RESET_SUSPEND + ); if (m_resolution.m_width != _resolution.m_width || m_resolution.m_height != _resolution.m_height