From e0b5e0d67ae819dabc0bfef6fdfb9d5fc5017e85 Mon Sep 17 00:00:00 2001 From: Gary Hsu Date: Mon, 27 Feb 2023 18:38:49 -0800 Subject: [PATCH] Add support for Windows App SDK (WinUI 3) (#3044) * Add support for Windows App SDK (WinUI 3) * Update namespace --- src/dxgi.cpp | 199 ++++++++++++++++++----------------------- src/dxgi.h | 2 +- src/renderer_d3d11.cpp | 8 +- 3 files changed, 91 insertions(+), 118 deletions(-) diff --git a/src/dxgi.cpp b/src/dxgi.cpp index 06ed02cf0..6871e1167 100644 --- a/src/dxgi.cpp +++ b/src/dxgi.cpp @@ -17,6 +17,33 @@ # endif // BX_PLATFORM_WINRT #endif // !BX_PLATFORM_WINDOWS +#if BX_PLATFORM_WINRT +// Copied from from Windows App SDK +// Put in a namespace to avoid conflict with +namespace WinUI3 +{ + // https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/win32/microsoft.ui.xaml.media.dxinterop/nn-microsoft-ui-xaml-media-dxinterop-iswapchainpanelnative + MIDL_INTERFACE("63aad0b8-7c24-40ff-85a8-640d944cc325") + ISwapChainPanelNative : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetSwapChain( + /* [annotation][in] */ + _In_ IDXGISwapChain *swapChain) = 0; + }; + + // https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/win32/microsoft.ui.xaml.media.dxinterop/nn-microsoft-ui-xaml-media-dxinterop-iswapchainbackgroundpanelnative + MIDL_INTERFACE("24d43d84-4246-4aa7-9774-8604cb73d90d") + ISwapChainBackgroundPanelNative : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE SetSwapChain( + /* [annotation][in] */ + _In_ IDXGISwapChain *swapChain) = 0; + }; +} +#endif // BX_PLATFORM_WINRT + namespace bgfx { BX_PRAGMA_DIAGNOSTIC_PUSH(); @@ -111,6 +138,54 @@ namespace bgfx IID_IDXGISwapChain3, }; +#if BX_PLATFORM_WINRT + template + static bool trySetSwapChain(IInspectable* nativeWindow, Dxgi::SwapChainI* swapChain, HRESULT* hr) + { + ISwapChainPanelNative* swapChainPanelNative; + + if (FAILED(nativeWindow->QueryInterface(__uuidof(T), (void**)&swapChainPanelNative)) + || NULL == swapChainPanelNative) + { + return false; + } + + *hr = swapChainPanelNative->SetSwapChain(swapChain); + if (SUCCEEDED(*hr)) + { + DX_RELEASE_I(swapChainPanelNative); + } + else + { + DX_RELEASE(swapChainPanelNative, 0); + } + + return true; + } + + static HRESULT setSwapChain(IInspectable* nativeWindow, Dxgi::SwapChainI* swapChain) + { + HRESULT hr = S_OK; + + if (trySetSwapChain(nativeWindow, swapChain, &hr) + || trySetSwapChain(nativeWindow, swapChain, &hr) + || trySetSwapChain(nativeWindow, swapChain, &hr) + || trySetSwapChain(nativeWindow, swapChain, &hr)) + { + if (FAILED(hr)) + { + BX_TRACE("Failed to SetSwapChain, hr %x."); + } + } + else + { + BX_TRACE("No available interface on native window to SetSwapChain."); + } + + return hr; + } +#endif // BX_PLATFORM_WINRT + DxgiSwapChain::DxgiSwapChain() { } @@ -183,7 +258,7 @@ namespace bgfx hr = CreateDXGIFactory(IID_IDXGIFactory, (void**)&m_factory); #endif // BX_PLATFORM_* - if (FAILED(hr) ) + if (FAILED(hr)) { BX_TRACE("Init error: Unable to create DXGI factory."); return false; @@ -475,65 +550,17 @@ namespace bgfx , NULL , reinterpret_cast(_swapChain) ); - if (FAILED(hr) ) + if (FAILED(hr)) { return hr; } # if BX_PLATFORM_WINRT - IInspectable *nativeWindow = reinterpret_cast(_scd.nwh); - ISwapChainPanelNative* swapChainPanelNative; - - hr = nativeWindow->QueryInterface( - __uuidof(ISwapChainPanelNative) - , (void**)&swapChainPanelNative - ); - - if (!FAILED(hr) ) + IInspectable* nativeWindow = reinterpret_cast(_scd.nwh); + hr = setSwapChain(nativeWindow, *_swapChain); + if (FAILED(hr)) { - // Swap Chain Panel - if (NULL != swapChainPanelNative) - { - hr = swapChainPanelNative->SetSwapChain(*_swapChain); - - 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) - { - hr = swapChainBackgroundPanelNative->SetSwapChain(*_swapChain); - - if (FAILED(hr) ) - { - DX_RELEASE(swapChainBackgroundPanelNative, 0); - BX_TRACE("Failed to SetSwapChain, hr %x."); - return hr; - } - - DX_RELEASE_I(swapChainBackgroundPanelNative); - } + return hr; } # endif // BX_PLATFORM_WINRT } @@ -546,7 +573,7 @@ namespace bgfx if (NULL != dxgiDevice1) { hr = dxgiDevice1->SetMaximumFrameLatency(_scd.maxFrameLatency); - if (FAILED(hr) ) + if (FAILED(hr)) { BX_TRACE("Failed to set maximum frame latency, hr 0x%08x", hr); hr = S_OK; @@ -555,7 +582,7 @@ namespace bgfx } } - if (FAILED(hr) ) + if (FAILED(hr)) { BX_TRACE("Failed to create swap chain."); return hr; @@ -602,64 +629,10 @@ namespace bgfx } #if BX_PLATFORM_WINRT - HRESULT Dxgi::removeSwapChain(const SwapChainDesc& _scd, SwapChainI** _swapChain) + HRESULT Dxgi::removeSwapChain(const SwapChainDesc& _scd) { - IInspectable *nativeWindow = reinterpret_cast(_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); - } - } + IInspectable* nativeWindow = reinterpret_cast(_scd.nwh); + return setSwapChain(nativeWindow, NULL); } #endif diff --git a/src/dxgi.h b/src/dxgi.h index 0a2623adb..e3a486d65 100644 --- a/src/dxgi.h +++ b/src/dxgi.h @@ -90,7 +90,7 @@ namespace bgfx #if BX_PLATFORM_WINRT /// - HRESULT removeSwapChain(const SwapChainDesc& _scd, SwapChainI** _swapChain); + HRESULT removeSwapChain(const SwapChainDesc& _scd); #endif /// diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index c4899f287..758db2f25 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1617,7 +1617,7 @@ namespace bgfx { namespace d3d11 DX_RELEASE(m_msaaRt, 0); #if BX_PLATFORM_WINRT // Remove swap chain from SwapChainPanel (nwh) if applicable - m_dxgi.removeSwapChain(m_scd, &m_swapChain); + m_dxgi.removeSwapChain(m_scd); #endif DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_deviceCtx, 0); @@ -1708,7 +1708,7 @@ namespace bgfx { namespace d3d11 DX_RELEASE(m_msaaRt, 0); #if BX_PLATFORM_WINRT // Remove swap chain from SwapChainPanel (nwh) if applicable - m_dxgi.removeSwapChain(m_scd, &m_swapChain); + m_dxgi.removeSwapChain(m_scd); #endif DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_deviceCtx, 0); @@ -2396,7 +2396,7 @@ namespace bgfx { namespace d3d11 && (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); + m_dxgi.removeSwapChain(m_scd); // Update nwh after removing swap chain m_scd.nwh = g_platformData.nwh; m_scd.ndt = g_platformData.ndt; @@ -2511,7 +2511,7 @@ namespace bgfx { namespace d3d11 #if BX_PLATFORM_WINRT // Remove swap chain from SwapChainPanel (nwh) if applicable - m_dxgi.removeSwapChain(m_scd, &m_swapChain); + m_dxgi.removeSwapChain(m_scd); #endif DX_RELEASE(m_swapChain, 0); HRESULT hr = m_dxgi.createSwapChain(m_device