From 8a2ed7f126369b2d0f5974f3365a044b3489b948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Mon, 17 Sep 2018 17:19:03 -0700 Subject: [PATCH] Added init parameter for maximum allowed frame latency. --- include/bgfx/bgfx.h | 1 + include/bgfx/c99/bgfx.h | 1 + include/bgfx/defines.h | 2 +- src/bgfx.cpp | 1 + src/dxgi.cpp | 133 +++++++++++----------------------------- src/dxgi.h | 1 + src/renderer_d3d11.cpp | 14 +++-- src/renderer_d3d12.cpp | 8 ++- 8 files changed, 55 insertions(+), 106 deletions(-) diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index d7a4a304e..e9e364bf6 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -605,6 +605,7 @@ namespace bgfx uint32_t width; //!< Backbuffer width. uint32_t height; //!< Backbuffer height. uint32_t reset; //!< Reset parameters. + uint8_t maxFrameLatency; //!< Maximum frame latency. }; /// Initialization parameters used by `bgfx::init`. diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index cc39673f9..cbed3c6d1 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -603,6 +603,7 @@ typedef struct bgfx_resolution_s uint32_t width; uint32_t height; uint32_t reset; + uint8_t maxFrameLatency; } bgfx_resolution_t; diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index 614b39007..80fd25ac5 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -6,7 +6,7 @@ #ifndef BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD -#define BGFX_API_VERSION UINT32_C(81) +#define BGFX_API_VERSION UINT32_C(82) /// Color RGB/alpha/depth write. When it's not specified write will be disabled. #define BGFX_STATE_WRITE_R UINT64_C(0x0000000000000001) //!< Enable R write. diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 369ee9b5c..fa3f35f6b 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -2817,6 +2817,7 @@ namespace bgfx , width(1280) , height(720) , reset(BGFX_RESET_NONE) + , maxFrameLatency(0) { } diff --git a/src/dxgi.cpp b/src/dxgi.cpp index 036898fb9..a879496f9 100644 --- a/src/dxgi.cpp +++ b/src/dxgi.cpp @@ -319,38 +319,6 @@ namespace bgfx : (uint16_t)m_adapterDesc.VendorId ; _caps.deviceId = (uint16_t)m_adapterDesc.DeviceId; - - { - IDXGIDevice* dxgiDevice = NULL; - hr = E_FAIL; - for (uint32_t ii = 0; ii < BX_COUNTOF(s_dxgiDeviceIIDs) && FAILED(hr); ++ii) - { - hr = m_factory->QueryInterface(s_dxgiDeviceIIDs[ii], (void**)&dxgiDevice); - BX_TRACE("DXGI device 11.%d, hr %x", BX_COUNTOF(s_dxgiDeviceIIDs) - 1 - ii, hr); - - if (SUCCEEDED(hr)) - { -#if BX_COMPILER_MSVC - BX_PRAGMA_DIAGNOSTIC_PUSH(); - BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4530) // warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc - try - { - // QueryInterface above can succeed, but getting adapter call might crash on Win7. - hr = dxgiDevice->GetAdapter(reinterpret_cast(&adapter) ); - } - catch (...) - { - BX_TRACE("Failed to get adapter for IID_IDXGIDevice%d.", BX_COUNTOF(s_dxgiDeviceIIDs) - 1 - ii); - DX_RELEASE(dxgiDevice, 0); - hr = E_FAIL; - } - BX_PRAGMA_DIAGNOSTIC_POP(); -#else - hr = dxgiDevice->GetAdapter(reinterpret_cast(&adapter) ); -#endif // BX_COMPILER_MSVC - } - } - } } return true; @@ -371,64 +339,26 @@ namespace bgfx void Dxgi::update(IUnknown* _device) { + IDXGIDevice* dxgiDevice = NULL; + HRESULT hr = E_FAIL; + for (uint32_t ii = 0; ii < BX_COUNTOF(s_dxgiDeviceIIDs) && FAILED(hr); ++ii) + { + hr = _device->QueryInterface(s_dxgiDeviceIIDs[ii], (void**)&dxgiDevice); + BX_TRACE("DXGI device 11.%d, hr %x", BX_COUNTOF(s_dxgiDeviceIIDs) - 1 - ii, hr); + } + if (NULL == m_factory) { - IDXGIDevice* dxgiDevice = NULL; - HRESULT hr = E_FAIL; - for (uint32_t ii = 0; ii < BX_COUNTOF(s_dxgiDeviceIIDs) && FAILED(hr); ++ii) - { - hr = _device->QueryInterface(s_dxgiDeviceIIDs[ii], (void**)&dxgiDevice); - BX_TRACE("DXGI device 11.%d, hr %x", BX_COUNTOF(s_dxgiDeviceIIDs) - 1 - ii, hr); - - if (SUCCEEDED(hr) ) - { - DX_CHECK(dxgiDevice->GetAdapter(reinterpret_cast(&m_adapter) ) ); - DX_RELEASE(dxgiDevice, 1); - } - } + DX_CHECK(dxgiDevice->GetAdapter(reinterpret_cast(&m_adapter) ) ); bx::memSet(&m_adapterDesc, 0, sizeof(m_adapterDesc) ); hr = m_adapter->GetDesc(&m_adapterDesc); BX_WARN(SUCCEEDED(hr), "Adapter GetDesc failed 0x%08x.", hr); DX_CHECK(m_adapter->GetParent(IID_IDXGIFactory2, (void**)&m_factory) ); - -#if 0 - bx::memSet(&m_adapterDesc, 0, sizeof(m_adapterDesc) ); -// NOTICE: -// LUID STDMETHODCALLTYPE ID3D12Device::GetAdapterLuid() has a different behaviour in gcc , -// because gcc64 returns small struct in RAX, but the microsoft implemention of ID3D12Device::GetAdapterLuid() in d3d12.dll -// pass the struct LUID's address as the second parameter. - typedef void (STDMETHODCALLTYPE ID3D12Device::*ID3D12Device_GetAdapterLuid_f)(LUID *); - (m_device->*(ID3D12Device_GetAdapterLuid_f)(&ID3D12Device::GetAdapterLuid))(&luid); - AdapterI* adapter; - for (uint32_t ii = 0; DXGI_ERROR_NOT_FOUND != m_factory->EnumAdapters(ii, reinterpret_cast(&adapter) ); ++ii) - { - adapter->GetDesc(&m_adapterDesc); - if (m_adapterDesc.AdapterLuid.LowPart == luid.LowPart - && m_adapterDesc.AdapterLuid.HighPart == luid.HighPart) - { - if (NULL == m_adapter) - { - m_adapter = adapter; - } - else - { -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT - DX_RELEASE(adapter, 0); -#else - DX_RELEASE(adapter, 2); -#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT - } - break; - } - DX_RELEASE(adapter, 0); - } - - g_caps.vendorId = (uint16_t)m_adapterDesc.VendorId; - g_caps.deviceId = (uint16_t)m_adapterDesc.DeviceId; -#endif // 0 } + + DX_RELEASE(dxgiDevice, 1); } static const GUID IID_ID3D12CommandQueue = { 0x0ec870a6, 0x5d7e, 0x4c22, { 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed } }; @@ -469,10 +399,21 @@ namespace bgfx ; hr = m_factory->CreateSwapChain( - _device - , &scd - , reinterpret_cast(_swapChain) - ); + _device + , &scd + , reinterpret_cast(_swapChain) + ); + + if (SUCCEEDED(hr) ) + { + IDXGIDevice1* dxgiDevice1; + _device->QueryInterface(IID_IDXGIDevice1, (void**)&dxgiDevice1); + if (NULL != dxgiDevice1) + { + dxgiDevice1->SetMaximumFrameLatency(_scd.maxFrameLatency); + DX_RELEASE(dxgiDevice1, 1); + } + } #else DXGI_SWAP_CHAIN_DESC1 scd; scd.Width = _scd.width; @@ -491,12 +432,12 @@ namespace bgfx if (NULL == _scd.ndt) { hr = m_factory->CreateSwapChainForCoreWindow( - _device - , (::IUnknown*)_scd.nwh - , &scd - , NULL - , reinterpret_cast(_swapChain) - ); + _device + , (::IUnknown*)_scd.nwh + , &scd + , NULL + , reinterpret_cast(_swapChain) + ); } else if (reinterpret_cast(1) == _scd.ndt) { @@ -505,11 +446,11 @@ namespace bgfx else { hr = m_factory->CreateSwapChainForComposition( - _device - , &scd - , NULL - , reinterpret_cast(_swapChain) - ); + _device + , &scd + , NULL + , reinterpret_cast(_swapChain) + ); if (FAILED(hr) ) { return hr; diff --git a/src/dxgi.h b/src/dxgi.h index b9cf4b304..604a50eb9 100644 --- a/src/dxgi.h +++ b/src/dxgi.h @@ -38,6 +38,7 @@ namespace bgfx DXGI_SWAP_EFFECT swapEffect; DXGI_ALPHA_MODE alphaMode; uint32_t flags; + uint8_t maxFrameLatency; void* nwh; void* ndt; bool windowed; diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 11dd8eb09..ccd9160dc 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -989,12 +989,14 @@ namespace bgfx { namespace d3d11 ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH ; - m_scd.swapEffect = m_swapEffect; - m_scd.alphaMode = DXGI_ALPHA_MODE_IGNORE; - m_scd.flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - m_scd.nwh = g_platformData.nwh; - m_scd.ndt = g_platformData.ndt; - m_scd.windowed = true; + m_scd.swapEffect = m_swapEffect; + m_scd.alphaMode = DXGI_ALPHA_MODE_IGNORE; + m_scd.flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + m_scd.maxFrameLatency = bx::min(_init.resolution.maxFrameLatency, 3); + m_scd.nwh = g_platformData.nwh; + m_scd.ndt = g_platformData.ndt; + m_scd.windowed = true; m_msaaRt = NULL; diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 125d19242..faa417171 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -898,9 +898,11 @@ namespace bgfx { namespace d3d12 m_scd.swapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; m_scd.alphaMode = DXGI_ALPHA_MODE_IGNORE; m_scd.flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - m_scd.nwh = g_platformData.nwh; - m_scd.ndt = g_platformData.ndt; - m_scd.windowed = true; + + m_scd.maxFrameLatency = bx::min(_init.resolution.maxFrameLatency, 3); + m_scd.nwh = g_platformData.nwh; + m_scd.ndt = g_platformData.ndt; + m_scd.windowed = true; m_backBufferColorIdx = m_scd.bufferCount-1;