Explorar el Código

Don't present backbuffer if it's not affected by rendering.

Branimir Karadžić hace 9 años
padre
commit
e86aee5f2e
Se han modificado 3 ficheros con 53 adiciones y 26 borrados
  1. 27 18
      src/renderer_d3d11.cpp
  2. 13 4
      src/renderer_d3d9.cpp
  3. 13 4
      src/renderer_gl.cpp

+ 27 - 18
src/renderer_d3d11.cpp

@@ -444,6 +444,17 @@ namespace bgfx { namespace d3d11
 		IID_IDXGIDevice0,
 		IID_IDXGIDevice0,
 	};
 	};
 
 
+	inline bool isLost(HRESULT _hr)
+	{
+		return false
+			|| _hr == DXGI_ERROR_DEVICE_REMOVED
+			|| _hr == DXGI_ERROR_DEVICE_HUNG
+			|| _hr == DXGI_ERROR_DEVICE_RESET
+			|| _hr == DXGI_ERROR_DRIVER_INTERNAL_ERROR
+			|| _hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
+			;
+	}
+
 	template <typename Ty>
 	template <typename Ty>
 	static BX_NO_INLINE void setDebugObjectName(Ty* _interface, const char* _format, ...)
 	static BX_NO_INLINE void setDebugObjectName(Ty* _interface, const char* _format, ...)
 	{
 	{
@@ -2075,7 +2086,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 			uint32_t height = getBufferHeight();
 			uint32_t height = getBufferHeight();
 
 
 			FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
 			FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
-			setFrameBuffer(fbh, false);
+			setFrameBuffer(fbh, false, false);
 
 
 			D3D11_VIEWPORT vp;
 			D3D11_VIEWPORT vp;
 			vp.TopLeftX = 0;
 			vp.TopLeftX = 0;
@@ -2141,6 +2152,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 
 
 		void preReset()
 		void preReset()
 		{
 		{
+			m_needPresent = false;
+
 			ovrPreReset();
 			ovrPreReset();
 
 
 			if (m_timerQuerySupport)
 			if (m_timerQuerySupport)
@@ -2233,16 +2246,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 			capturePostReset();
 			capturePostReset();
 		}
 		}
 
 
-		static bool isLost(HRESULT _hr)
-		{
-			return DXGI_ERROR_DEVICE_REMOVED == _hr
-				|| DXGI_ERROR_DEVICE_HUNG == _hr
-				|| DXGI_ERROR_DEVICE_RESET == _hr
-				|| DXGI_ERROR_DRIVER_INTERNAL_ERROR == _hr
-				|| DXGI_ERROR_NOT_CURRENTLY_AVAILABLE == _hr
-				;
-		}
-
 		void flip(HMD& _hmd) BX_OVERRIDE
 		void flip(HMD& _hmd) BX_OVERRIDE
 		{
 		{
 			if (NULL != m_swapChain)
 			if (NULL != m_swapChain)
@@ -2258,19 +2261,21 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 					hr = m_frameBuffers[m_windows[ii].idx].present(syncInterval);
 					hr = m_frameBuffers[m_windows[ii].idx].present(syncInterval);
 				}
 				}
 
 
-				if (SUCCEEDED(hr) )
+				if (SUCCEEDED(hr)
+				&&  m_needPresent)
 				{
 				{
 					m_ovr.flip();
 					m_ovr.flip();
 					m_ovr.swap(_hmd);
 					m_ovr.swap(_hmd);
 
 
-					if (!m_ovr.isEnabled())
+					if (!m_ovr.isEnabled() )
 					{
 					{
 						hr = m_swapChain->Present(syncInterval, 0);
 						hr = m_swapChain->Present(syncInterval, 0);
 					}
 					}
+
+					m_needPresent = false;
 				}
 				}
 
 
-				if (FAILED(hr)
-				&&  isLost(hr) )
+				if (isLost(hr) )
 				{
 				{
 					++m_lost;
 					++m_lost;
 					BGFX_FATAL(10 > m_lost, bgfx::Fatal::DeviceLost, "Device is lost. FAILED 0x%08x", hr);
 					BGFX_FATAL(10 > m_lost, bgfx::Fatal::DeviceLost, "Device is lost. FAILED 0x%08x", hr);
@@ -2552,7 +2557,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 			}
 			}
 		}
 		}
 
 
-		void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true)
+		void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true, bool _needPresent = true)
 		{
 		{
 			if (isValid(m_fbh)
 			if (isValid(m_fbh)
 			&&  m_fbh.idx != _fbh.idx
 			&&  m_fbh.idx != _fbh.idx
@@ -2566,6 +2571,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 			{
 			{
 				m_deviceCtx->OMSetRenderTargets(1, &m_backBufferColor, m_backBufferDepthStencil);
 				m_deviceCtx->OMSetRenderTargets(1, &m_backBufferColor, m_backBufferDepthStencil);
 
 
+				m_needPresent |= _needPresent;
 				m_currentColor = m_backBufferColor;
 				m_currentColor = m_backBufferColor;
 				m_currentDepthStencil = m_backBufferDepthStencil;
 				m_currentDepthStencil = m_backBufferDepthStencil;
 			}
 			}
@@ -3513,6 +3519,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		IDXGISwapChain1*  m_swapChain;
 		IDXGISwapChain1*  m_swapChain;
 #endif // BX_PLATFORM_WINDOWS
 #endif // BX_PLATFORM_WINDOWS
 
 
+		bool m_needPresent;
 		uint16_t m_lost;
 		uint16_t m_lost;
 		uint16_t m_numWindows;
 		uint16_t m_numWindows;
 		FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
 		FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
@@ -5030,6 +5037,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		if (m_needPresent)
 		if (m_needPresent)
 		{
 		{
 			HRESULT hr = m_swapChain->Present(_syncInterval, 0);
 			HRESULT hr = m_swapChain->Present(_syncInterval, 0);
+			hr = !isLost(hr) ? S_OK : hr;
 			m_needPresent = false;
 			m_needPresent = false;
 			return hr;
 			return hr;
 		}
 		}
@@ -5103,7 +5111,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 
 
 			uint64_t timeEnd;
 			uint64_t timeEnd;
 			HRESULT hr = deviceCtx->GetData(frame.m_end, &timeEnd, sizeof(timeEnd), D3D11_ASYNC_GETDATA_DONOTFLUSH);
 			HRESULT hr = deviceCtx->GetData(frame.m_end, &timeEnd, sizeof(timeEnd), D3D11_ASYNC_GETDATA_DONOTFLUSH);
-			if (S_OK == hr)
+			if (S_OK == hr
+			||  isLost(hr) )
 			{
 			{
 				m_control.consume(1);
 				m_control.consume(1);
 
 
@@ -5283,7 +5292,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 			// reset the framebuffer to be the backbuffer; depending on the swap effect,
 			// reset the framebuffer to be the backbuffer; depending on the swap effect,
 			// if we don't do this we'll only see one frame of output and then nothing
 			// if we don't do this we'll only see one frame of output and then nothing
 			FrameBufferHandle invalid = BGFX_INVALID_HANDLE;
 			FrameBufferHandle invalid = BGFX_INVALID_HANDLE;
-			setFrameBuffer(invalid);
+			setFrameBuffer(invalid, true, false);
 
 
 			bool viewRestart = false;
 			bool viewRestart = false;
 			uint8_t eye = 0;
 			uint8_t eye = 0;

+ 13 - 4
src/renderer_d3d9.cpp

@@ -1206,7 +1206,7 @@ namespace bgfx { namespace d3d9
 			uint32_t height = m_params.BackBufferHeight;
 			uint32_t height = m_params.BackBufferHeight;
 
 
 			FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
 			FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
-			setFrameBuffer(fbh, false);
+			setFrameBuffer(fbh, false, false);
 
 
 			D3DVIEWPORT9 vp;
 			D3DVIEWPORT9 vp;
 			vp.X = 0;
 			vp.X = 0;
@@ -1347,7 +1347,7 @@ namespace bgfx { namespace d3d9
 			}
 			}
 		}
 		}
 
 
-		void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true)
+		void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true, bool _needPresent = true)
 		{
 		{
 			if (isValid(m_fbh)
 			if (isValid(m_fbh)
 			&&  m_fbh.idx != _fbh.idx)
 			&&  m_fbh.idx != _fbh.idx)
@@ -1358,6 +1358,7 @@ namespace bgfx { namespace d3d9
 
 
 			if (!isValid(_fbh) )
 			if (!isValid(_fbh) )
 			{
 			{
+				m_needPresent |= _needPresent;
 				DX_CHECK(m_device->SetRenderTarget(0, m_backBufferColor) );
 				DX_CHECK(m_device->SetRenderTarget(0, m_backBufferColor) );
 				for (uint32_t ii = 1, num = g_caps.limits.maxFBAttachments; ii < num; ++ii)
 				for (uint32_t ii = 1, num = g_caps.limits.maxFBAttachments; ii < num; ++ii)
 				{
 				{
@@ -1434,10 +1435,14 @@ namespace bgfx { namespace d3d9
 
 
 				for (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii)
 				for (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii)
 				{
 				{
-					HRESULT hr;
+					HRESULT hr = S_OK;
 					if (0 == ii)
 					if (0 == ii)
 					{
 					{
-						hr = m_swapChain->Present(NULL, NULL, (HWND)g_platformData.nwh, NULL, 0);
+						if (m_needPresent)
+						{
+							hr = m_swapChain->Present(NULL, NULL, (HWND)g_platformData.nwh, NULL, 0);
+							m_needPresent = false;
+						}
 					}
 					}
 					else
 					else
 					{
 					{
@@ -1473,6 +1478,8 @@ namespace bgfx { namespace d3d9
 
 
 		void preReset()
 		void preReset()
 		{
 		{
+			m_needPresent = false;
+
 			invalidateSamplerState();
 			invalidateSamplerState();
 
 
 			for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage)
 			for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage)
@@ -2034,6 +2041,8 @@ namespace bgfx { namespace d3d9
 		D3DPOOL m_pool;
 		D3DPOOL m_pool;
 
 
 		IDirect3DSwapChain9* m_swapChain;
 		IDirect3DSwapChain9* m_swapChain;
+
+		bool m_needPresent;
 		uint16_t m_numWindows;
 		uint16_t m_numWindows;
 		FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
 		FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
 
 

+ 13 - 4
src/renderer_gl.cpp

@@ -2217,6 +2217,8 @@ namespace bgfx { namespace gl
 
 
 			ovrPostReset();
 			ovrPostReset();
 
 
+			m_needPresent = false;
+
 			BGFX_GPU_PROFILER_BIND();
 			BGFX_GPU_PROFILER_BIND();
 		}
 		}
 
 
@@ -2285,11 +2287,16 @@ namespace bgfx { namespace gl
 					}
 					}
 				}
 				}
 
 
-				m_ovr.flip();
-				m_ovr.swap(_hmd);
+				if (m_needPresent)
+				{
+					m_ovr.flip();
+					m_ovr.swap(_hmd);
 
 
-				// need to swap GL render context even if OVR is enabled to get the mirror texture in the output
-				m_glctx.swap();
+					// need to swap GL render context even if OVR is enabled to get
+					// the mirror texture in the output
+					m_glctx.swap();
+					m_needPresent = false;
+				}
 			}
 			}
 		}
 		}
 
 
@@ -2745,6 +2752,7 @@ namespace bgfx { namespace gl
 
 
 			if (!isValid(_fbh) )
 			if (!isValid(_fbh) )
 			{
 			{
+				m_needPresent |= true;
 				GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
 				GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
 
 
 				if (m_srgbWriteControlSupport)
 				if (m_srgbWriteControlSupport)
@@ -3457,6 +3465,7 @@ namespace bgfx { namespace gl
 		GLuint m_msaaBackBufferFbo;
 		GLuint m_msaaBackBufferFbo;
 		GLuint m_msaaBackBufferRbos[2];
 		GLuint m_msaaBackBufferRbos[2];
 		GlContext m_glctx;
 		GlContext m_glctx;
+		bool m_needPresent;
 
 
 		const char* m_vendor;
 		const char* m_vendor;
 		const char* m_renderer;
 		const char* m_renderer;