summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/dxgi.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/dxgi.cpp')
-rw-r--r--3rdparty/bgfx/src/dxgi.cpp268
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