Add support for Windows App SDK (WinUI 3) (#3044)

* Add support for Windows App SDK (WinUI 3)

* Update namespace
This commit is contained in:
Gary Hsu 2023-02-27 18:38:49 -08:00 committed by GitHub
parent 403c4da2e0
commit e0b5e0d67a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 91 additions and 118 deletions

View File

@ -17,6 +17,33 @@
# endif // BX_PLATFORM_WINRT # endif // BX_PLATFORM_WINRT
#endif // !BX_PLATFORM_WINDOWS #endif // !BX_PLATFORM_WINDOWS
#if BX_PLATFORM_WINRT
// Copied from <microsoft.ui.xaml.media.dxinterop.h> from Windows App SDK
// Put in a namespace to avoid conflict with <windows.ui.xaml.media.dxinterop.h>
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 namespace bgfx
{ {
BX_PRAGMA_DIAGNOSTIC_PUSH(); BX_PRAGMA_DIAGNOSTIC_PUSH();
@ -111,6 +138,54 @@ namespace bgfx
IID_IDXGISwapChain3, IID_IDXGISwapChain3,
}; };
#if BX_PLATFORM_WINRT
template<typename T>
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<ISwapChainPanelNative>(nativeWindow, swapChain, &hr)
|| trySetSwapChain<ISwapChainBackgroundPanelNative>(nativeWindow, swapChain, &hr)
|| trySetSwapChain<WinUI3::ISwapChainPanelNative>(nativeWindow, swapChain, &hr)
|| trySetSwapChain<WinUI3::ISwapChainBackgroundPanelNative>(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() DxgiSwapChain::DxgiSwapChain()
{ {
} }
@ -183,7 +258,7 @@ namespace bgfx
hr = CreateDXGIFactory(IID_IDXGIFactory, (void**)&m_factory); hr = CreateDXGIFactory(IID_IDXGIFactory, (void**)&m_factory);
#endif // BX_PLATFORM_* #endif // BX_PLATFORM_*
if (FAILED(hr) ) if (FAILED(hr))
{ {
BX_TRACE("Init error: Unable to create DXGI factory."); BX_TRACE("Init error: Unable to create DXGI factory.");
return false; return false;
@ -475,65 +550,17 @@ namespace bgfx
, NULL , NULL
, reinterpret_cast<IDXGISwapChain1**>(_swapChain) , reinterpret_cast<IDXGISwapChain1**>(_swapChain)
); );
if (FAILED(hr) ) if (FAILED(hr))
{ {
return hr; return hr;
} }
# if BX_PLATFORM_WINRT # if BX_PLATFORM_WINRT
IInspectable *nativeWindow = reinterpret_cast<IInspectable*>(_scd.nwh); IInspectable* nativeWindow = reinterpret_cast<IInspectable*>(_scd.nwh);
ISwapChainPanelNative* swapChainPanelNative; hr = setSwapChain(nativeWindow, *_swapChain);
if (FAILED(hr))
hr = nativeWindow->QueryInterface(
__uuidof(ISwapChainPanelNative)
, (void**)&swapChainPanelNative
);
if (!FAILED(hr) )
{ {
// Swap Chain Panel return hr;
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);
}
} }
# endif // BX_PLATFORM_WINRT # endif // BX_PLATFORM_WINRT
} }
@ -546,7 +573,7 @@ namespace bgfx
if (NULL != dxgiDevice1) if (NULL != dxgiDevice1)
{ {
hr = dxgiDevice1->SetMaximumFrameLatency(_scd.maxFrameLatency); hr = dxgiDevice1->SetMaximumFrameLatency(_scd.maxFrameLatency);
if (FAILED(hr) ) if (FAILED(hr))
{ {
BX_TRACE("Failed to set maximum frame latency, hr 0x%08x", hr); BX_TRACE("Failed to set maximum frame latency, hr 0x%08x", hr);
hr = S_OK; hr = S_OK;
@ -555,7 +582,7 @@ namespace bgfx
} }
} }
if (FAILED(hr) ) if (FAILED(hr))
{ {
BX_TRACE("Failed to create swap chain."); BX_TRACE("Failed to create swap chain.");
return hr; return hr;
@ -602,64 +629,10 @@ namespace bgfx
} }
#if BX_PLATFORM_WINRT #if BX_PLATFORM_WINRT
HRESULT Dxgi::removeSwapChain(const SwapChainDesc& _scd, SwapChainI** _swapChain) HRESULT Dxgi::removeSwapChain(const SwapChainDesc& _scd)
{ {
IInspectable *nativeWindow = reinterpret_cast<IInspectable*>(_scd.nwh); IInspectable* nativeWindow = reinterpret_cast<IInspectable*>(_scd.nwh);
ISwapChainPanelNative* swapChainPanelNative; return setSwapChain(nativeWindow, NULL);
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 #endif

View File

@ -90,7 +90,7 @@ namespace bgfx
#if BX_PLATFORM_WINRT #if BX_PLATFORM_WINRT
/// ///
HRESULT removeSwapChain(const SwapChainDesc& _scd, SwapChainI** _swapChain); HRESULT removeSwapChain(const SwapChainDesc& _scd);
#endif #endif
/// ///

View File

@ -1617,7 +1617,7 @@ namespace bgfx { namespace d3d11
DX_RELEASE(m_msaaRt, 0); DX_RELEASE(m_msaaRt, 0);
#if BX_PLATFORM_WINRT #if BX_PLATFORM_WINRT
// Remove swap chain from SwapChainPanel (nwh) if applicable // Remove swap chain from SwapChainPanel (nwh) if applicable
m_dxgi.removeSwapChain(m_scd, &m_swapChain); m_dxgi.removeSwapChain(m_scd);
#endif #endif
DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_swapChain, 0);
DX_RELEASE(m_deviceCtx, 0); DX_RELEASE(m_deviceCtx, 0);
@ -1708,7 +1708,7 @@ namespace bgfx { namespace d3d11
DX_RELEASE(m_msaaRt, 0); DX_RELEASE(m_msaaRt, 0);
#if BX_PLATFORM_WINRT #if BX_PLATFORM_WINRT
// Remove swap chain from SwapChainPanel (nwh) if applicable // Remove swap chain from SwapChainPanel (nwh) if applicable
m_dxgi.removeSwapChain(m_scd, &m_swapChain); m_dxgi.removeSwapChain(m_scd);
#endif #endif
DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_swapChain, 0);
DX_RELEASE(m_deviceCtx, 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)) && (m_scd.nwh != g_platformData.nwh || m_scd.ndt != g_platformData.ndt))
{ {
// Remove swap chain from SwapChainPanel (nwh) if applicable // 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 // Update nwh after removing swap chain
m_scd.nwh = g_platformData.nwh; m_scd.nwh = g_platformData.nwh;
m_scd.ndt = g_platformData.ndt; m_scd.ndt = g_platformData.ndt;
@ -2511,7 +2511,7 @@ namespace bgfx { namespace d3d11
#if BX_PLATFORM_WINRT #if BX_PLATFORM_WINRT
// Remove swap chain from SwapChainPanel (nwh) if applicable // Remove swap chain from SwapChainPanel (nwh) if applicable
m_dxgi.removeSwapChain(m_scd, &m_swapChain); m_dxgi.removeSwapChain(m_scd);
#endif #endif
DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_swapChain, 0);
HRESULT hr = m_dxgi.createSwapChain(m_device HRESULT hr = m_dxgi.createSwapChain(m_device