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
This commit is contained in:
C. M. Barth 2021-03-08 15:13:04 -08:00 committed by GitHub
parent dc3a92ef99
commit f218d7ed13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 3 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
}