From 8244fdf54d549ce48f9d634f39de7b4189086893 Mon Sep 17 00:00:00 2001 From: Elliot Cuzzillo Date: Thu, 13 Aug 2020 15:45:45 -0700 Subject: [PATCH] only use srgb views into non-srgb backbuffers to enable flip presentation model (#2229) --- src/dxgi.cpp | 14 ++++++++++++-- src/renderer_d3d11.cpp | 35 +++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/dxgi.cpp b/src/dxgi.cpp index fa465370d..8bf4315de 100644 --- a/src/dxgi.cpp +++ b/src/dxgi.cpp @@ -381,7 +381,13 @@ namespace bgfx 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 | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT : 0; + scdFlags |= allowTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0; + scdFlags |= + (_scd.swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL + || _scd.swapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD) + ? DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT + : 0; + DX_RELEASE_I(factory5); } @@ -658,7 +664,11 @@ namespace bgfx 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 | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT : 0; + scdFlags |= allowTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0; + scdFlags |= (_scd.swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL + || _scd.swapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD) + ? DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT + : 0; DX_RELEASE_I(factory5); } diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 8e82412a1..b799cf4b0 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1009,10 +1009,20 @@ namespace bgfx { namespace d3d11 bx::memSet(&m_scd, 0, sizeof(m_scd) ); m_scd.width = _init.resolution.width; m_scd.height = _init.resolution.height; - m_scd.format = (_init.resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) - ? s_textureFormat[_init.resolution.format].m_fmtSrgb - : s_textureFormat[_init.resolution.format].m_fmt - ; + + /* + * Previously, this checked for BGFX_RESET_SRGB_BACKBUFFER and used m_fmtSrgb as the backbuffer format + * instead of m_fmt. + * + * However, according to https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/converting-data-color-space , + * this is not actually required, because you can create the render target view with m_fmtSrgb, and it will work + * identically. + * + * Moreover, it is actually not desirable to create the backbuffer with an _SRGB format, because that + * is incompatible with the flip presentation model, which is desirable for various reasons including + * player embedding. + */ + m_scd.format = s_textureFormat[_init.resolution.format].m_fmt; updateMsaa(m_scd.format); m_scd.sampleDesc = s_msaa[(_init.resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT]; @@ -1025,7 +1035,7 @@ namespace bgfx { namespace d3d11 ; m_scd.swapEffect = m_swapEffect; m_scd.alphaMode = DXGI_ALPHA_MODE_IGNORE; - m_scd.flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + 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; @@ -2192,10 +2202,12 @@ namespace bgfx { namespace d3d11 : D3D11_RTV_DIMENSION_TEXTURE2D ; desc.Texture2D.MipSlice = 0; - desc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) - ? m_scd.format == DXGI_FORMAT_R8G8B8A8_UNORM ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : m_scd.format - : m_scd.format - ; + + /* go find the srgb version of this format to make a render target view + * with the srgb version. this is OK because of this: + * https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/converting-data-color-space + */ + desc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) ? s_textureFormat[m_resolution.format].m_fmtSrgb : s_textureFormat[m_resolution.format].m_fmt; DX_CHECK(m_device->CreateRenderTargetView(NULL == m_msaaRt ? backBufferColor : m_msaaRt, &desc, &m_backBufferColor) ); DX_RELEASE(backBufferColor, 0); @@ -2405,9 +2417,8 @@ namespace bgfx { namespace d3d11 m_scd.width = _resolution.width; m_scd.height = _resolution.height; - m_scd.format = (_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) - ? s_textureFormat[_resolution.format].m_fmtSrgb - : s_textureFormat[_resolution.format].m_fmt + // see comment in init() about why we don't worry about BGFX_RESET_SRGB_BACKBUFFER here + m_scd.format = s_textureFormat[_resolution.format].m_fmt ; preReset();