소스 검색

Support dynamic SwapChainPanel changes for DirectX11 UWP scenarios (#2422)

* remove swap chain from consumer

* fix swap chain cleanup

* renderer workaround

* cleanup changes around platform data

* only update swapchainpanels

* revert spacing

* favor NULL over nullptr
C. M. Barth 4 년 전
부모
커밋
f218d7ed13
3개의 변경된 파일102개의 추가작업 그리고 3개의 파일을 삭제
  1. 62 0
      src/dxgi.cpp
  2. 5 0
      src/dxgi.h
  3. 35 3
      src/renderer_d3d11.cpp

+ 62 - 0
src/dxgi.cpp

@@ -572,6 +572,68 @@ namespace bgfx
 		return S_OK;
 	}
 
+#if BX_PLATFORM_WINRT
+	HRESULT Dxgi::removeSwapChain(const SwapChainDesc& _scd, SwapChainI** _swapChain)
+	{
+		IInspectable *nativeWindow = reinterpret_cast<IInspectable*>(_scd.nwh);
+		ISwapChainPanelNative* swapChainPanelNative;
+
+		HRESULT hr = nativeWindow->QueryInterface(
+			  __uuidof(ISwapChainPanelNative)
+			, (void**)&swapChainPanelNative
+			);
+
+		if (SUCCEEDED(hr))
+		{
+			// Swap Chain Panel
+			if (NULL != swapChainPanelNative)
+			{
+				// Remove swap chain
+				hr = swapChainPanelNative->SetSwapChain(NULL);
+
+				if (FAILED(hr))
+				{
+					DX_RELEASE(swapChainPanelNative, 0);
+					BX_TRACE("Failed to SetSwapChain, hr %x.");
+					return hr;
+				}
+
+				DX_RELEASE_I(swapChainPanelNative);
+			}
+		}
+		else
+		{
+			// Swap Chain Background Panel
+			ISwapChainBackgroundPanelNative* swapChainBackgroundPanelNative = NULL;
+
+			hr = nativeWindow->QueryInterface(
+				__uuidof(ISwapChainBackgroundPanelNative)
+				, (void**)&swapChainBackgroundPanelNative
+			);
+
+			if (FAILED(hr))
+			{
+				return hr;
+			}
+
+			if (NULL != swapChainBackgroundPanelNative)
+			{
+				// Remove swap chain
+				hr = swapChainBackgroundPanelNative->SetSwapChain(NULL);
+
+				if (FAILED(hr))
+				{
+					DX_RELEASE(swapChainBackgroundPanelNative, 0);
+					BX_TRACE("Failed to SetSwapChain, hr %x.");
+					return hr;
+				}
+
+				DX_RELEASE_I(swapChainBackgroundPanelNative);
+			}
+		}
+	}
+#endif
+
 	void Dxgi::updateHdr10(SwapChainI* _swapChain, const SwapChainDesc& _scd)
 	{
 #if BX_PLATFORM_WINDOWS

+ 5 - 0
src/dxgi.h

@@ -85,6 +85,11 @@ namespace bgfx
 		///
 		HRESULT createSwapChain(IUnknown* _device, const SwapChainDesc& _scd, SwapChainI** _swapChain);
 
+#if BX_PLATFORM_WINRT
+		///
+		HRESULT removeSwapChain(const SwapChainDesc& _scd, SwapChainI** _swapChain);
+#endif
+
 		///
 		void updateHdr10(SwapChainI* _swapChain, const SwapChainDesc& _scd);
 

+ 35 - 3
src/renderer_d3d11.cpp

@@ -1594,6 +1594,10 @@ namespace bgfx { namespace d3d11
 				DX_RELEASE(m_annotation, 1);
 				DX_RELEASE_W(m_infoQueue, 0);
 				DX_RELEASE(m_msaaRt, 0);
+#if BX_PLATFORM_WINRT
+				// Remove swap chain from SwapChainPanel (nwh) if applicable
+				m_dxgi.removeSwapChain(m_scd, &m_swapChain);
+#endif
 				DX_RELEASE(m_swapChain, 0);
 				DX_RELEASE(m_deviceCtx, 0);
 				DX_RELEASE(m_device, 0);
@@ -1681,6 +1685,10 @@ namespace bgfx { namespace d3d11
 			DX_RELEASE(m_annotation, 1);
 			DX_RELEASE_W(m_infoQueue, 0);
 			DX_RELEASE(m_msaaRt, 0);
+#if BX_PLATFORM_WINRT
+			// Remove swap chain from SwapChainPanel (nwh) if applicable
+			m_dxgi.removeSwapChain(m_scd, &m_swapChain);
+#endif
 			DX_RELEASE(m_swapChain, 0);
 			DX_RELEASE(m_deviceCtx, 0);
 			DX_RELEASE(m_device, 0);
@@ -2351,6 +2359,22 @@ namespace bgfx { namespace d3d11
 			}
 		}
 
+		void updateNativeWindow()
+		{
+#if BX_PLATFORM_WINRT
+			// SwapChainPanels can be dynamically updated
+			if (m_scd.ndt == reinterpret_cast<void*>(2)
+				&& (m_scd.nwh != g_platformData.nwh || m_scd.ndt != g_platformData.ndt))
+			{
+				// Remove swap chain from SwapChainPanel (nwh) if applicable
+				m_dxgi.removeSwapChain(m_scd, &m_swapChain);
+				// Update nwh after removing swap chain
+				m_scd.nwh = g_platformData.nwh;
+				m_scd.ndt = g_platformData.ndt;
+			}
+#endif
+		}
+
 		bool updateResolution(const Resolution& _resolution)
 		{
 			const bool suspended    = !!( _resolution.reset & BGFX_RESET_SUSPEND);
@@ -2456,8 +2480,11 @@ namespace bgfx { namespace d3d11
 						updateMsaa(m_scd.format);
 						m_scd.sampleDesc = s_msaa[(m_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
 
+#if BX_PLATFORM_WINRT
+						// Remove swap chain from SwapChainPanel (nwh) if applicable
+						m_dxgi.removeSwapChain(m_scd, &m_swapChain);
+#endif
 						DX_RELEASE(m_swapChain, 0);
-
 						HRESULT hr = m_dxgi.createSwapChain(m_device
 							, m_scd
 							, &m_swapChain
@@ -5483,8 +5510,13 @@ namespace bgfx { namespace d3d11
 
 	void RendererContextD3D11::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
 	{
-		if (m_lost
-		||  updateResolution(_render->m_resolution) )
+		if (m_lost)
+		{
+			return;
+		}
+
+		updateNativeWindow();
+		if (updateResolution(_render->m_resolution) )
 		{
 			return;
 		}