Don't present backbuffer if it's not affected by rendering.

This commit is contained in:
Branimir Karadžić 2016-11-13 20:59:41 -08:00
parent ff669aceab
commit e86aee5f2e
3 changed files with 53 additions and 26 deletions

View File

@ -444,6 +444,17 @@ namespace bgfx { namespace d3d11
IID_IDXGIDevice0,
};
inline bool isLost(HRESULT _hr)
{
return false
|| _hr == DXGI_ERROR_DEVICE_REMOVED
|| _hr == DXGI_ERROR_DEVICE_HUNG
|| _hr == DXGI_ERROR_DEVICE_RESET
|| _hr == DXGI_ERROR_DRIVER_INTERNAL_ERROR
|| _hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
;
}
template <typename Ty>
static BX_NO_INLINE void setDebugObjectName(Ty* _interface, const char* _format, ...)
{
@ -2075,7 +2086,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
uint32_t height = getBufferHeight();
FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
setFrameBuffer(fbh, false);
setFrameBuffer(fbh, false, false);
D3D11_VIEWPORT vp;
vp.TopLeftX = 0;
@ -2141,6 +2152,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();
void preReset()
{
m_needPresent = false;
ovrPreReset();
if (m_timerQuerySupport)
@ -2233,16 +2246,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
capturePostReset();
}
static bool isLost(HRESULT _hr)
{
return DXGI_ERROR_DEVICE_REMOVED == _hr
|| DXGI_ERROR_DEVICE_HUNG == _hr
|| DXGI_ERROR_DEVICE_RESET == _hr
|| DXGI_ERROR_DRIVER_INTERNAL_ERROR == _hr
|| DXGI_ERROR_NOT_CURRENTLY_AVAILABLE == _hr
;
}
void flip(HMD& _hmd) BX_OVERRIDE
{
if (NULL != m_swapChain)
@ -2258,19 +2261,21 @@ BX_PRAGMA_DIAGNOSTIC_POP();
hr = m_frameBuffers[m_windows[ii].idx].present(syncInterval);
}
if (SUCCEEDED(hr) )
if (SUCCEEDED(hr)
&& m_needPresent)
{
m_ovr.flip();
m_ovr.swap(_hmd);
if (!m_ovr.isEnabled())
if (!m_ovr.isEnabled() )
{
hr = m_swapChain->Present(syncInterval, 0);
}
m_needPresent = false;
}
if (FAILED(hr)
&& isLost(hr) )
if (isLost(hr) )
{
++m_lost;
BGFX_FATAL(10 > m_lost, bgfx::Fatal::DeviceLost, "Device is lost. FAILED 0x%08x", hr);
@ -2552,7 +2557,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
}
}
void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true)
void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true, bool _needPresent = true)
{
if (isValid(m_fbh)
&& m_fbh.idx != _fbh.idx
@ -2566,6 +2571,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
{
m_deviceCtx->OMSetRenderTargets(1, &m_backBufferColor, m_backBufferDepthStencil);
m_needPresent |= _needPresent;
m_currentColor = m_backBufferColor;
m_currentDepthStencil = m_backBufferDepthStencil;
}
@ -3513,6 +3519,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
IDXGISwapChain1* m_swapChain;
#endif // BX_PLATFORM_WINDOWS
bool m_needPresent;
uint16_t m_lost;
uint16_t m_numWindows;
FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];
@ -5030,6 +5037,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (m_needPresent)
{
HRESULT hr = m_swapChain->Present(_syncInterval, 0);
hr = !isLost(hr) ? S_OK : hr;
m_needPresent = false;
return hr;
}
@ -5103,7 +5111,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();
uint64_t timeEnd;
HRESULT hr = deviceCtx->GetData(frame.m_end, &timeEnd, sizeof(timeEnd), D3D11_ASYNC_GETDATA_DONOTFLUSH);
if (S_OK == hr)
if (S_OK == hr
|| isLost(hr) )
{
m_control.consume(1);
@ -5283,7 +5292,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
// reset the framebuffer to be the backbuffer; depending on the swap effect,
// if we don't do this we'll only see one frame of output and then nothing
FrameBufferHandle invalid = BGFX_INVALID_HANDLE;
setFrameBuffer(invalid);
setFrameBuffer(invalid, true, false);
bool viewRestart = false;
uint8_t eye = 0;

View File

@ -1206,7 +1206,7 @@ namespace bgfx { namespace d3d9
uint32_t height = m_params.BackBufferHeight;
FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
setFrameBuffer(fbh, false);
setFrameBuffer(fbh, false, false);
D3DVIEWPORT9 vp;
vp.X = 0;
@ -1347,7 +1347,7 @@ namespace bgfx { namespace d3d9
}
}
void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true)
void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true, bool _needPresent = true)
{
if (isValid(m_fbh)
&& m_fbh.idx != _fbh.idx)
@ -1358,6 +1358,7 @@ namespace bgfx { namespace d3d9
if (!isValid(_fbh) )
{
m_needPresent |= _needPresent;
DX_CHECK(m_device->SetRenderTarget(0, m_backBufferColor) );
for (uint32_t ii = 1, num = g_caps.limits.maxFBAttachments; ii < num; ++ii)
{
@ -1434,10 +1435,14 @@ namespace bgfx { namespace d3d9
for (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii)
{
HRESULT hr;
HRESULT hr = S_OK;
if (0 == ii)
{
hr = m_swapChain->Present(NULL, NULL, (HWND)g_platformData.nwh, NULL, 0);
if (m_needPresent)
{
hr = m_swapChain->Present(NULL, NULL, (HWND)g_platformData.nwh, NULL, 0);
m_needPresent = false;
}
}
else
{
@ -1473,6 +1478,8 @@ namespace bgfx { namespace d3d9
void preReset()
{
m_needPresent = false;
invalidateSamplerState();
for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage)
@ -2034,6 +2041,8 @@ namespace bgfx { namespace d3d9
D3DPOOL m_pool;
IDirect3DSwapChain9* m_swapChain;
bool m_needPresent;
uint16_t m_numWindows;
FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];

View File

@ -2217,6 +2217,8 @@ namespace bgfx { namespace gl
ovrPostReset();
m_needPresent = false;
BGFX_GPU_PROFILER_BIND();
}
@ -2285,11 +2287,16 @@ namespace bgfx { namespace gl
}
}
m_ovr.flip();
m_ovr.swap(_hmd);
if (m_needPresent)
{
m_ovr.flip();
m_ovr.swap(_hmd);
// need to swap GL render context even if OVR is enabled to get the mirror texture in the output
m_glctx.swap();
// need to swap GL render context even if OVR is enabled to get
// the mirror texture in the output
m_glctx.swap();
m_needPresent = false;
}
}
}
@ -2745,6 +2752,7 @@ namespace bgfx { namespace gl
if (!isValid(_fbh) )
{
m_needPresent |= true;
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
if (m_srgbWriteControlSupport)
@ -3457,6 +3465,7 @@ namespace bgfx { namespace gl
GLuint m_msaaBackBufferFbo;
GLuint m_msaaBackBufferRbos[2];
GlContext m_glctx;
bool m_needPresent;
const char* m_vendor;
const char* m_renderer;