diff options
Diffstat (limited to '3rdparty/bgfx/src/dxgi.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/dxgi.cpp | 268 |
1 files changed, 216 insertions, 52 deletions
diff --git a/3rdparty/bgfx/src/dxgi.cpp b/3rdparty/bgfx/src/dxgi.cpp index 4f2bc7c0984..649de902190 100644 --- a/3rdparty/bgfx/src/dxgi.cpp +++ b/3rdparty/bgfx/src/dxgi.cpp @@ -1,16 +1,16 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + * Copyright 2011-2022 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE */ #include "bgfx_p.h" -#if BGFX_CONFIG_RENDERER_DIRECT3D11 || BGFX_CONFIG_RENDERER_DIRECT3D12 +#if BGFX_CONFIG_RENDERER_DIRECT3D11 || (BGFX_CONFIG_RENDERER_DIRECT3D12 && !BX_PLATFORM_LINUX) #include "dxgi.h" #include "renderer_d3d.h" -#if !BX_PLATFORM_WINDOWS +#if !BX_PLATFORM_WINDOWS && !BX_PLATFORM_LINUX # include <inspectable.h> # if BX_PLATFORM_WINRT # include <windows.ui.xaml.media.dxinterop.h> @@ -122,20 +122,32 @@ namespace bgfx , m_factory(NULL) , m_adapter(NULL) , m_output(NULL) + , m_tearingSupported(false) { } bool Dxgi::init(Caps& _caps) { -#if BX_PLATFORM_WINDOWS - m_dxgiDll = bx::dlopen("dxgi.dll"); +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS + + const char* dxgiDllName = +#if BX_PLATFORM_LINUX + "dxgi.so" +#else + "dxgi.dll" +#endif // BX_PLATFORM_LINUX + ; + m_dxgiDll = bx::dlopen(dxgiDllName); + if (NULL == m_dxgiDll) { - BX_TRACE("Init error: Failed to load dxgi.dll."); + BX_TRACE("Init error: Failed to load %s.", dxgiDllName); return false; } +# if BX_PLATFORM_WINDOWS m_dxgiDebugDll = bx::dlopen("dxgidebug.dll"); + if (NULL != m_dxgiDebugDll) { DXGIGetDebugInterface = (PFN_GET_DEBUG_INTERFACE )bx::dlsym(m_dxgiDebugDll, "DXGIGetDebugInterface"); @@ -160,6 +172,7 @@ namespace bgfx BX_TRACE("Init error: Function CreateDXGIFactory not found."); return false; } +# endif // BX_PLATFORM_WINDOWS #endif // BX_PLATFORM_WINDOWS HRESULT hr = S_OK; @@ -205,10 +218,20 @@ namespace bgfx , desc.SubSysId , desc.Revision ); - BX_TRACE("\tMemory: %" PRIi64 " (video), %" PRIi64 " (system), %" PRIi64 " (shared)" - , desc.DedicatedVideoMemory - , desc.DedicatedSystemMemory - , desc.SharedSystemMemory + + char dedicatedVideo[16]; + bx::prettify(dedicatedVideo, BX_COUNTOF(dedicatedVideo), desc.DedicatedVideoMemory); + + char dedicatedSystem[16]; + bx::prettify(dedicatedSystem, BX_COUNTOF(dedicatedSystem), desc.DedicatedSystemMemory); + + char sharedSystem[16]; + bx::prettify(sharedSystem, BX_COUNTOF(sharedSystem), desc.SharedSystemMemory); + + BX_TRACE("\tMemory: %s (video), %s (system), %s (shared)" + , dedicatedVideo + , dedicatedSystem + , sharedSystem ); _caps.gpu[ii].vendorId = (uint16_t)desc.VendorId; @@ -246,12 +269,12 @@ namespace bgfx { DXGI_OUTPUT_DESC outputDesc; hr = output->GetDesc(&outputDesc); - if (SUCCEEDED(hr)) + if (SUCCEEDED(hr) ) { BX_TRACE("\tOutput #%d", jj); char deviceName[BX_COUNTOF(outputDesc.DeviceName)]; - wcstombs(deviceName, outputDesc.DeviceName, BX_COUNTOF(outputDesc.DeviceName)); + wcstombs(deviceName, outputDesc.DeviceName, BX_COUNTOF(outputDesc.DeviceName) ); BX_TRACE("\t\t DeviceName: %s", deviceName); BX_TRACE("\t\t DesktopCoordinates: %d, %d, %d, %d" , outputDesc.DesktopCoordinates.left @@ -262,7 +285,7 @@ namespace bgfx BX_TRACE("\t\t AttachedToDesktop: %d", outputDesc.AttachedToDesktop); BX_TRACE("\t\t Rotation: %d", outputDesc.Rotation); -#if BX_PLATFORM_WINDOWS +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS IDXGIOutput6* output6; hr = output->QueryInterface(IID_IDXGIOutput6, (void**)&output6); if (SUCCEEDED(hr) ) @@ -297,6 +320,7 @@ namespace bgfx } _caps.supported |= hdr10 ? BGFX_CAPS_HDR10 : 0; + _caps.supported |= BX_ENABLED(BX_PLATFORM_WINRT) ? BGFX_CAPS_TRANSPARENT_BACKBUFFER : 0; DX_RELEASE(adapter, adapter == m_adapter ? 1 : 0); } @@ -361,21 +385,35 @@ namespace bgfx DX_RELEASE_I(dxgiDevice); } - static const GUID IID_ID3D12CommandQueue = { 0x0ec870a6, 0x5d7e, 0x4c22, { 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed } }; - HRESULT Dxgi::createSwapChain(IUnknown* _device, const SwapChainDesc& _scd, SwapChainI** _swapChain) { HRESULT hr = S_OK; - bool allowTearing = false; + uint32_t scdFlags = _scd.flags; -#if BX_PLATFORM_WINDOWS - if (windowsVersionIs(Condition::GreaterEqual, 0x0604) ) +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS + IDXGIFactory5* factory5; + hr = m_factory->QueryInterface(IID_IDXGIFactory5, (void**)&factory5); + + if (SUCCEEDED(hr) ) { + BOOL allowTearing = false; // BK - CheckFeatureSupport with DXGI_FEATURE_PRESENT_ALLOW_TEARING // will crash on pre Windows 8. Issue #1356. - hr = m_factory->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing) ); + hr = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing) ); BX_TRACE("Allow tearing is %ssupported.", allowTearing ? "" : "not "); + + scdFlags |= allowTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0; + scdFlags |= false + || _scd.swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL + || _scd.swapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD + ? 0 // DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT + : 0 + ; + + m_tearingSupported = allowTearing; + + DX_RELEASE_I(factory5); } DXGI_SWAP_CHAIN_DESC scd; @@ -393,27 +431,13 @@ namespace bgfx scd.OutputWindow = (HWND)_scd.nwh; scd.Windowed = _scd.windowed; scd.SwapEffect = _scd.swapEffect; - scd.Flags = 0 - | _scd.flags - | (allowTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0) - ; + scd.Flags = scdFlags; hr = m_factory->CreateSwapChain( _device , &scd , reinterpret_cast<IDXGISwapChain**>(_swapChain) ); - - if (SUCCEEDED(hr) ) - { - IDXGIDevice1* dxgiDevice1; - _device->QueryInterface(IID_IDXGIDevice1, (void**)&dxgiDevice1); - if (NULL != dxgiDevice1) - { - dxgiDevice1->SetMaximumFrameLatency(_scd.maxFrameLatency); - DX_RELEASE_I(dxgiDevice1); - } - } #else DXGI_SWAP_CHAIN_DESC1 scd; scd.Width = _scd.width; @@ -427,7 +451,7 @@ namespace bgfx scd.Scaling = _scd.scaling; scd.SwapEffect = _scd.swapEffect; scd.AlphaMode = _scd.alphaMode; - scd.Flags = _scd.flags; + scd.Flags = scdFlags; if (NULL == _scd.ndt) { @@ -457,38 +481,87 @@ namespace bgfx } # if BX_PLATFORM_WINRT - IInspectable *nativeWindow = reinterpret_cast<IInspectable *>(_scd.nwh); - ISwapChainBackgroundPanelNative* panel = NULL; + IInspectable *nativeWindow = reinterpret_cast<IInspectable*>(_scd.nwh); + ISwapChainPanelNative* swapChainPanelNative; + hr = nativeWindow->QueryInterface( - __uuidof(ISwapChainBackgroundPanelNative) - , (void **)&panel + __uuidof(ISwapChainPanelNative) + , (void**)&swapChainPanelNative ); - if (FAILED(hr) ) + + if (!FAILED(hr) ) { - return 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; + } - if (NULL != panel) + DX_RELEASE_I(swapChainPanelNative); + } + } + else { - hr = panel->SetSwapChain(*_swapChain); + // Swap Chain Background Panel + ISwapChainBackgroundPanelNative* swapChainBackgroundPanelNative = NULL; + + hr = nativeWindow->QueryInterface( + __uuidof(ISwapChainBackgroundPanelNative) + , (void**)&swapChainBackgroundPanelNative + ); + if (FAILED(hr) ) { return hr; } - panel->Release(); + 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_WINDOWS + if (SUCCEEDED(hr) ) + { + IDXGIDevice1* dxgiDevice1; + _device->QueryInterface(IID_IDXGIDevice1, (void**)&dxgiDevice1); + if (NULL != dxgiDevice1) + { + hr = dxgiDevice1->SetMaximumFrameLatency(_scd.maxFrameLatency); + if (FAILED(hr) ) + { + BX_TRACE("Failed to set maximum frame latency, hr 0x%08x", hr); + hr = S_OK; + } + DX_RELEASE_I(dxgiDevice1); + } + } + if (FAILED(hr) ) { BX_TRACE("Failed to create swap chain."); return hr; } -#if BX_PLATFORM_WINDOWS +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS if (SUCCEEDED(hr) ) { for (uint32_t ii = 0; ii < BX_COUNTOF(s_dxgiSwapChainIIDs); ++ii) @@ -521,13 +594,75 @@ namespace bgfx } } } -#endif // BX_PLATFORM_WINDOWS +#endif // BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS updateHdr10(*_swapChain, _scd); 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 @@ -559,7 +694,7 @@ namespace bgfx hr = output6->GetDesc1(&desc); if (SUCCEEDED(hr) ) { - BX_TRACE("Display specs:") + BX_TRACE("Display specs:"); BX_TRACE("\t BitsPerColor: %d", desc.BitsPerColor); BX_TRACE("\t Color space: %s (colorspace, range, gamma, sitting, primaries, transform)" , s_colorSpaceStr[bx::min<uint32_t>(desc.ColorSpace, kDxgiLastColorSpace+1)] @@ -606,7 +741,31 @@ namespace bgfx { HRESULT hr; -#if BX_PLATFORM_WINDOWS + uint32_t scdFlags = _scd.flags; + +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS + IDXGIFactory5* factory5; + hr = m_factory->QueryInterface(IID_IDXGIFactory5, (void**)&factory5); + + if (SUCCEEDED(hr)) + { + BOOL allowTearing = false; + // BK - CheckFeatureSupport with DXGI_FEATURE_PRESENT_ALLOW_TEARING + // will crash on pre Windows 8. Issue #1356. + hr = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing)); + BX_TRACE("Allow tearing is %ssupported.", allowTearing ? "" : "not "); + + scdFlags |= allowTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0; + scdFlags |= false + || _scd.swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL + || _scd.swapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD + ? 0 // DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT + : 0 + ; + + DX_RELEASE_I(factory5); + } + if (NULL != _nodeMask && NULL != _presentQueue) { @@ -615,7 +774,7 @@ namespace bgfx , _scd.width , _scd.height , _scd.format - , _scd.flags + , scdFlags , _nodeMask , _presentQueue ); @@ -630,7 +789,7 @@ namespace bgfx , _scd.width , _scd.height , _scd.format - , _scd.flags + , scdFlags ); } @@ -655,6 +814,11 @@ namespace bgfx #endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT } + bool Dxgi::tearingSupported() const + { + return m_tearingSupported; + } + } // namespace bgfx #endif // BGFX_CONFIG_RENDERER_DIRECT3D11 || BGFX_CONFIG_RENDERER_DIRECT3D12 |