Explorar el Código

Present swap chain only when it's updated.

Branimir Karadžić hace 9 años
padre
commit
025d806c70
Se han modificado 6 ficheros con 96 adiciones y 40 borrados
  1. 25 6
      src/renderer_d3d11.cpp
  2. 4 0
      src/renderer_d3d11.h
  3. 46 30
      src/renderer_d3d9.cpp
  4. 5 2
      src/renderer_d3d9.h
  5. 14 2
      src/renderer_gl.cpp
  6. 2 0
      src/renderer_gl.h

+ 25 - 6
src/renderer_d3d11.cpp

@@ -2255,13 +2255,13 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 
 				for (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii)
 				{
-					hr = m_frameBuffers[m_windows[ii].idx].m_swapChain->Present(syncInterval, 0);
+					hr = m_frameBuffers[m_windows[ii].idx].present(syncInterval);
 				}
 
 				if (SUCCEEDED(hr) )
 				{
 					m_ovr.flip();
-					m_ovr.swap(_hmd); // TODO - move this out of end-of-frame
+					m_ovr.swap(_hmd);
 
 					if (!m_ovr.isEnabled())
 					{
@@ -2574,10 +2574,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 				invalidateTextureStage();
 
 				FrameBufferD3D11& frameBuffer = m_frameBuffers[_fbh.idx];
-				m_deviceCtx->OMSetRenderTargets(frameBuffer.m_num, frameBuffer.m_rtv, frameBuffer.m_dsv);
-
-				m_currentColor = frameBuffer.m_rtv[0];
-				m_currentDepthStencil = frameBuffer.m_dsv;
+				frameBuffer.set();
 			}
 
 			m_fbh = _fbh;
@@ -4712,6 +4709,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		m_swapChain = NULL;
 
 		m_numTh = _num;
+		m_needPresent = false;
 		memcpy(m_attachment, _attachment, _num*sizeof(Attachment) );
 
 		postReset();
@@ -4773,6 +4771,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 
 		m_num   = 0;
 		m_numTh = 0;
+		m_needPresent = false;
 
 		uint16_t denseIdx = m_denseIdx;
 		m_denseIdx = UINT16_MAX;
@@ -5018,6 +5017,26 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 		}
 	}
 
+	void FrameBufferD3D11::set()
+	{
+		s_renderD3D11->m_deviceCtx->OMSetRenderTargets(m_num, m_rtv, m_dsv);
+		m_needPresent = UINT16_MAX != m_denseIdx;
+		s_renderD3D11->m_currentColor        = m_rtv[0];
+		s_renderD3D11->m_currentDepthStencil = m_dsv;
+	}
+
+	HRESULT FrameBufferD3D11::present(uint32_t _syncInterval)
+	{
+		if (m_needPresent)
+		{
+			HRESULT hr = m_swapChain->Present(_syncInterval, 0);
+			m_needPresent = false;
+			return hr;
+		}
+
+		return S_OK;
+	}
+
 	void TimerQueryD3D11::postReset()
 	{
 		ID3D11Device* device = s_renderD3D11->m_device;

+ 4 - 0
src/renderer_d3d11.h

@@ -269,6 +269,7 @@ namespace bgfx { namespace d3d11
 			, m_denseIdx(UINT16_MAX)
 			, m_num(0)
 			, m_numTh(0)
+			, m_needPresent(false)
 		{
 		}
 
@@ -279,6 +280,8 @@ namespace bgfx { namespace d3d11
 		void postReset();
 		void resolve();
 		void clear(const Clear& _clear, const float _palette[][4]);
+		void set();
+		HRESULT present(uint32_t _syncInterval);
 
 		ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
 		ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
@@ -291,6 +294,7 @@ namespace bgfx { namespace d3d11
 		uint16_t m_denseIdx;
 		uint8_t m_num;
 		uint8_t m_numTh;
+		bool m_needPresent;
 	};
 
 	struct TimerQueryD3D11

+ 46 - 30
src/renderer_d3d9.cpp

@@ -1369,35 +1369,7 @@ namespace bgfx { namespace d3d9
 			}
 			else
 			{
-				const FrameBufferD3D9& frameBuffer = m_frameBuffers[_fbh.idx];
-
-				// If frame buffer has only depth attachment D3DFMT_NULL
-				// render target is created.
-				const uint32_t fbnum = bx::uint32_max(2, frameBuffer.m_numTh);
-				const uint8_t  dsIdx = frameBuffer.m_dsIdx;
-
-				DX_CHECK(m_device->SetDepthStencilSurface(UINT8_MAX == dsIdx
-						? m_backBufferDepthStencil
-						: frameBuffer.m_surface[dsIdx]
-						) );
-
-				uint32_t rtIdx = 0;
-				for (uint32_t ii = 0; ii < fbnum; ++ii)
-				{
-					IDirect3DSurface9* surface = frameBuffer.m_surface[ii];
-					if (ii != dsIdx)
-					{
-						DX_CHECK(m_device->SetRenderTarget(rtIdx, surface) );
-						++rtIdx;
-					}
-				}
-
-				for (uint32_t ii = rtIdx, num = g_caps.limits.maxFBAttachments; ii < num; ++ii)
-				{
-					DX_CHECK(m_device->SetRenderTarget(ii, NULL) );
-				}
-
-				DX_CHECK(m_device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE) );
+				m_frameBuffers[_fbh.idx].set();
 			}
 
 			m_fbh = _fbh;
@@ -3245,6 +3217,7 @@ namespace bgfx { namespace d3d9
 		m_denseIdx = _denseIdx;
 		m_num = 1;
 		m_needResolve = false;
+		m_needPresent = false;
 	}
 
 	uint16_t FrameBufferD3D9::destroy()
@@ -3274,6 +3247,7 @@ namespace bgfx { namespace d3d9
 		m_hwnd  = NULL;
 		m_num   = 0;
 		m_numTh = 0;
+		m_needPresent = false;
 
 		uint16_t denseIdx = m_denseIdx;
 		m_denseIdx = UINT16_MAX;
@@ -3283,7 +3257,14 @@ namespace bgfx { namespace d3d9
 
 	HRESULT FrameBufferD3D9::present()
 	{
-		return m_swapChain->Present(NULL, NULL, m_hwnd, NULL, 0);
+		if (m_needPresent)
+		{
+			HRESULT hr = m_swapChain->Present(NULL, NULL, m_hwnd, NULL, 0);
+			m_needPresent = false;
+			return hr;
+		}
+
+		return S_OK;
 	}
 
 	void FrameBufferD3D9::resolve() const
@@ -3382,6 +3363,41 @@ namespace bgfx { namespace d3d9
 			) );
 	}
 
+	void FrameBufferD3D9::set()
+	{
+		m_needPresent = UINT16_MAX != m_denseIdx;
+
+		// If frame buffer has only depth attachment D3DFMT_NULL
+		// render target is created.
+		const uint32_t fbnum = bx::uint32_max(2, m_numTh);
+		const uint8_t  dsIdx = m_dsIdx;
+
+		IDirect3DDevice9* device = s_renderD3D9->m_device;
+
+		DX_CHECK(device->SetDepthStencilSurface(UINT8_MAX == dsIdx
+			? s_renderD3D9->m_backBufferDepthStencil
+			: m_surface[dsIdx]
+			) );
+
+		uint32_t rtIdx = 0;
+		for (uint32_t ii = 0; ii < fbnum; ++ii)
+		{
+			IDirect3DSurface9* surface = m_surface[ii];
+			if (ii != dsIdx)
+			{
+				DX_CHECK(device->SetRenderTarget(rtIdx, surface) );
+				++rtIdx;
+			}
+		}
+
+		for (uint32_t ii = rtIdx, num = g_caps.limits.maxFBAttachments; ii < num; ++ii)
+		{
+			DX_CHECK(device->SetRenderTarget(ii, NULL) );
+		}
+
+		DX_CHECK(device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE) );
+	}
+
 	void TimerQueryD3D9::postReset()
 	{
 		IDirect3DDevice9* device = s_renderD3D9->m_device;

+ 5 - 2
src/renderer_d3d9.h

@@ -393,10 +393,11 @@ namespace bgfx { namespace d3d9
 		FrameBufferD3D9()
 			: m_hwnd(NULL)
 			, m_denseIdx(UINT16_MAX)
-			, m_needResolve(0)
 			, m_num(0)
 			, m_numTh(0)
 			, m_dsIdx(UINT8_MAX)
+			, m_needResolve(false)
+			, m_needPresent(false)
 		{
 		}
 
@@ -408,6 +409,7 @@ namespace bgfx { namespace d3d9
 		void preReset();
 		void postReset();
 		void createNullColorRT();
+		void set();
 
 		IDirect3DSurface9* m_surface[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
 		IDirect3DSwapChain9* m_swapChain;
@@ -417,10 +419,11 @@ namespace bgfx { namespace d3d9
 
 		Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
 		uint16_t m_denseIdx;
-		bool m_needResolve;
 		uint8_t m_num;
 		uint8_t m_numTh;
 		uint8_t m_dsIdx;
+		bool m_needResolve;
+		bool m_needPresent;
 	};
 
 	struct TimerQueryD3D9

+ 14 - 2
src/renderer_gl.cpp

@@ -2277,11 +2277,16 @@ namespace bgfx { namespace gl
 			{
 				for (uint32_t ii = 1, num = m_numWindows; ii < num; ++ii)
 				{
-					m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain);
+					FrameBufferGL& frameBuffer = m_frameBuffers[m_windows[ii].idx];
+					if (frameBuffer.m_needPresent)
+					{
+						m_glctx.swap(frameBuffer.m_swapChain);
+						frameBuffer.m_needPresent = false;
+					}
 				}
 
 				m_ovr.flip();
-				m_ovr.swap(_hmd); // TODO - move this out of end-of-frame
+				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();
@@ -2761,6 +2766,7 @@ namespace bgfx { namespace gl
 				if (UINT16_MAX != frameBuffer.m_denseIdx)
 				{
 					m_glctx.makeCurrent(frameBuffer.m_swapChain);
+					frameBuffer.m_needPresent = true;
 				}
 				else
 				{
@@ -5767,6 +5773,8 @@ namespace bgfx { namespace gl
 		m_numTh = _num;
 		memcpy(m_attachment, _attachment, _num*sizeof(Attachment) );
 
+		m_needPresent = false;
+
 		postReset();
 	}
 
@@ -5918,7 +5926,9 @@ namespace bgfx { namespace gl
 		m_swapChain = s_renderGL->m_glctx.createSwapChain(_nwh);
 		m_width     = _width;
 		m_height    = _height;
+		m_numTh     = 0;
 		m_denseIdx  = _denseIdx;
+		m_needPresent = false;
 	}
 
 	uint16_t FrameBufferGL::destroy()
@@ -5938,6 +5948,8 @@ namespace bgfx { namespace gl
 		memset(m_fbo, 0, sizeof(m_fbo) );
 		uint16_t denseIdx = m_denseIdx;
 		m_denseIdx = UINT16_MAX;
+		m_needPresent = false;
+		m_numTh = 0;
 
 		return denseIdx;
 	}

+ 2 - 0
src/renderer_gl.h

@@ -1308,6 +1308,7 @@ namespace bgfx { namespace gl
 			: m_swapChain(NULL)
 			, m_denseIdx(UINT16_MAX)
 			, m_num(0)
+			, m_needPresent(false)
 		{
 			memset(m_fbo, 0, sizeof(m_fbo) );
 		}
@@ -1326,6 +1327,7 @@ namespace bgfx { namespace gl
 		uint16_t m_denseIdx;
 		uint8_t  m_num;
 		uint8_t  m_numTh;
+		bool     m_needPresent;
 		Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
 	};