Present swap chain only when it's updated.

This commit is contained in:
Branimir Karadžić 2016-11-09 14:29:37 -08:00
parent 616472b742
commit 025d806c70
6 changed files with 96 additions and 40 deletions

View File

@ -2255,13 +2255,13 @@ BX_PRAGMA_DIAGNOSTIC_POP();
for (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii) for (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii)
{ {
hr = m_frameBuffers[m_windows[ii].idx].m_swapChain->Present(syncInterval, 0); hr = m_frameBuffers[m_windows[ii].idx].present(syncInterval);
} }
if (SUCCEEDED(hr) ) if (SUCCEEDED(hr) )
{ {
m_ovr.flip(); m_ovr.flip();
m_ovr.swap(_hmd); // TODO - move this out of end-of-frame m_ovr.swap(_hmd);
if (!m_ovr.isEnabled()) if (!m_ovr.isEnabled())
{ {
@ -2574,10 +2574,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
invalidateTextureStage(); invalidateTextureStage();
FrameBufferD3D11& frameBuffer = m_frameBuffers[_fbh.idx]; FrameBufferD3D11& frameBuffer = m_frameBuffers[_fbh.idx];
m_deviceCtx->OMSetRenderTargets(frameBuffer.m_num, frameBuffer.m_rtv, frameBuffer.m_dsv); frameBuffer.set();
m_currentColor = frameBuffer.m_rtv[0];
m_currentDepthStencil = frameBuffer.m_dsv;
} }
m_fbh = _fbh; m_fbh = _fbh;
@ -4712,6 +4709,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
m_swapChain = NULL; m_swapChain = NULL;
m_numTh = _num; m_numTh = _num;
m_needPresent = false;
memcpy(m_attachment, _attachment, _num*sizeof(Attachment) ); memcpy(m_attachment, _attachment, _num*sizeof(Attachment) );
postReset(); postReset();
@ -4773,6 +4771,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
m_num = 0; m_num = 0;
m_numTh = 0; m_numTh = 0;
m_needPresent = false;
uint16_t denseIdx = m_denseIdx; uint16_t denseIdx = m_denseIdx;
m_denseIdx = UINT16_MAX; m_denseIdx = UINT16_MAX;
@ -5018,6 +5017,26 @@ BX_PRAGMA_DIAGNOSTIC_POP();
} }
} }
void FrameBufferD3D11::set()
{
s_renderD3D11->m_deviceCtx->OMSetRenderTargets(m_num, m_rtv, m_dsv);
m_needPresent = UINT16_MAX != m_denseIdx;
s_renderD3D11->m_currentColor = m_rtv[0];
s_renderD3D11->m_currentDepthStencil = m_dsv;
}
HRESULT FrameBufferD3D11::present(uint32_t _syncInterval)
{
if (m_needPresent)
{
HRESULT hr = m_swapChain->Present(_syncInterval, 0);
m_needPresent = false;
return hr;
}
return S_OK;
}
void TimerQueryD3D11::postReset() void TimerQueryD3D11::postReset()
{ {
ID3D11Device* device = s_renderD3D11->m_device; ID3D11Device* device = s_renderD3D11->m_device;

View File

@ -269,6 +269,7 @@ namespace bgfx { namespace d3d11
, m_denseIdx(UINT16_MAX) , m_denseIdx(UINT16_MAX)
, m_num(0) , m_num(0)
, m_numTh(0) , m_numTh(0)
, m_needPresent(false)
{ {
} }
@ -279,6 +280,8 @@ namespace bgfx { namespace d3d11
void postReset(); void postReset();
void resolve(); void resolve();
void clear(const Clear& _clear, const float _palette[][4]); void clear(const Clear& _clear, const float _palette[][4]);
void set();
HRESULT present(uint32_t _syncInterval);
ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
@ -291,6 +294,7 @@ namespace bgfx { namespace d3d11
uint16_t m_denseIdx; uint16_t m_denseIdx;
uint8_t m_num; uint8_t m_num;
uint8_t m_numTh; uint8_t m_numTh;
bool m_needPresent;
}; };
struct TimerQueryD3D11 struct TimerQueryD3D11

View File

@ -1369,35 +1369,7 @@ namespace bgfx { namespace d3d9
} }
else else
{ {
const FrameBufferD3D9& frameBuffer = m_frameBuffers[_fbh.idx]; m_frameBuffers[_fbh.idx].set();
// If frame buffer has only depth attachment D3DFMT_NULL
// render target is created.
const uint32_t fbnum = bx::uint32_max(2, frameBuffer.m_numTh);
const uint8_t dsIdx = frameBuffer.m_dsIdx;
DX_CHECK(m_device->SetDepthStencilSurface(UINT8_MAX == dsIdx
? m_backBufferDepthStencil
: frameBuffer.m_surface[dsIdx]
) );
uint32_t rtIdx = 0;
for (uint32_t ii = 0; ii < fbnum; ++ii)
{
IDirect3DSurface9* surface = frameBuffer.m_surface[ii];
if (ii != dsIdx)
{
DX_CHECK(m_device->SetRenderTarget(rtIdx, surface) );
++rtIdx;
}
}
for (uint32_t ii = rtIdx, num = g_caps.limits.maxFBAttachments; ii < num; ++ii)
{
DX_CHECK(m_device->SetRenderTarget(ii, NULL) );
}
DX_CHECK(m_device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE) );
} }
m_fbh = _fbh; m_fbh = _fbh;
@ -3245,6 +3217,7 @@ namespace bgfx { namespace d3d9
m_denseIdx = _denseIdx; m_denseIdx = _denseIdx;
m_num = 1; m_num = 1;
m_needResolve = false; m_needResolve = false;
m_needPresent = false;
} }
uint16_t FrameBufferD3D9::destroy() uint16_t FrameBufferD3D9::destroy()
@ -3274,6 +3247,7 @@ namespace bgfx { namespace d3d9
m_hwnd = NULL; m_hwnd = NULL;
m_num = 0; m_num = 0;
m_numTh = 0; m_numTh = 0;
m_needPresent = false;
uint16_t denseIdx = m_denseIdx; uint16_t denseIdx = m_denseIdx;
m_denseIdx = UINT16_MAX; m_denseIdx = UINT16_MAX;
@ -3283,7 +3257,14 @@ namespace bgfx { namespace d3d9
HRESULT FrameBufferD3D9::present() HRESULT FrameBufferD3D9::present()
{ {
return m_swapChain->Present(NULL, NULL, m_hwnd, NULL, 0); if (m_needPresent)
{
HRESULT hr = m_swapChain->Present(NULL, NULL, m_hwnd, NULL, 0);
m_needPresent = false;
return hr;
}
return S_OK;
} }
void FrameBufferD3D9::resolve() const void FrameBufferD3D9::resolve() const
@ -3382,6 +3363,41 @@ namespace bgfx { namespace d3d9
) ); ) );
} }
void FrameBufferD3D9::set()
{
m_needPresent = UINT16_MAX != m_denseIdx;
// If frame buffer has only depth attachment D3DFMT_NULL
// render target is created.
const uint32_t fbnum = bx::uint32_max(2, m_numTh);
const uint8_t dsIdx = m_dsIdx;
IDirect3DDevice9* device = s_renderD3D9->m_device;
DX_CHECK(device->SetDepthStencilSurface(UINT8_MAX == dsIdx
? s_renderD3D9->m_backBufferDepthStencil
: m_surface[dsIdx]
) );
uint32_t rtIdx = 0;
for (uint32_t ii = 0; ii < fbnum; ++ii)
{
IDirect3DSurface9* surface = m_surface[ii];
if (ii != dsIdx)
{
DX_CHECK(device->SetRenderTarget(rtIdx, surface) );
++rtIdx;
}
}
for (uint32_t ii = rtIdx, num = g_caps.limits.maxFBAttachments; ii < num; ++ii)
{
DX_CHECK(device->SetRenderTarget(ii, NULL) );
}
DX_CHECK(device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE) );
}
void TimerQueryD3D9::postReset() void TimerQueryD3D9::postReset()
{ {
IDirect3DDevice9* device = s_renderD3D9->m_device; IDirect3DDevice9* device = s_renderD3D9->m_device;

View File

@ -393,10 +393,11 @@ namespace bgfx { namespace d3d9
FrameBufferD3D9() FrameBufferD3D9()
: m_hwnd(NULL) : m_hwnd(NULL)
, m_denseIdx(UINT16_MAX) , m_denseIdx(UINT16_MAX)
, m_needResolve(0)
, m_num(0) , m_num(0)
, m_numTh(0) , m_numTh(0)
, m_dsIdx(UINT8_MAX) , m_dsIdx(UINT8_MAX)
, m_needResolve(false)
, m_needPresent(false)
{ {
} }
@ -408,6 +409,7 @@ namespace bgfx { namespace d3d9
void preReset(); void preReset();
void postReset(); void postReset();
void createNullColorRT(); void createNullColorRT();
void set();
IDirect3DSurface9* m_surface[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; IDirect3DSurface9* m_surface[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
IDirect3DSwapChain9* m_swapChain; IDirect3DSwapChain9* m_swapChain;
@ -417,10 +419,11 @@ namespace bgfx { namespace d3d9
Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
uint16_t m_denseIdx; uint16_t m_denseIdx;
bool m_needResolve;
uint8_t m_num; uint8_t m_num;
uint8_t m_numTh; uint8_t m_numTh;
uint8_t m_dsIdx; uint8_t m_dsIdx;
bool m_needResolve;
bool m_needPresent;
}; };
struct TimerQueryD3D9 struct TimerQueryD3D9

View File

@ -2277,11 +2277,16 @@ namespace bgfx { namespace gl
{ {
for (uint32_t ii = 1, num = m_numWindows; ii < num; ++ii) for (uint32_t ii = 1, num = m_numWindows; ii < num; ++ii)
{ {
m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain); FrameBufferGL& frameBuffer = m_frameBuffers[m_windows[ii].idx];
if (frameBuffer.m_needPresent)
{
m_glctx.swap(frameBuffer.m_swapChain);
frameBuffer.m_needPresent = false;
}
} }
m_ovr.flip(); m_ovr.flip();
m_ovr.swap(_hmd); // TODO - move this out of end-of-frame m_ovr.swap(_hmd);
// need to swap GL render context even if OVR is enabled to get the mirror texture in the output // need to swap GL render context even if OVR is enabled to get the mirror texture in the output
m_glctx.swap(); m_glctx.swap();
@ -2761,6 +2766,7 @@ namespace bgfx { namespace gl
if (UINT16_MAX != frameBuffer.m_denseIdx) if (UINT16_MAX != frameBuffer.m_denseIdx)
{ {
m_glctx.makeCurrent(frameBuffer.m_swapChain); m_glctx.makeCurrent(frameBuffer.m_swapChain);
frameBuffer.m_needPresent = true;
} }
else else
{ {
@ -5767,6 +5773,8 @@ namespace bgfx { namespace gl
m_numTh = _num; m_numTh = _num;
memcpy(m_attachment, _attachment, _num*sizeof(Attachment) ); memcpy(m_attachment, _attachment, _num*sizeof(Attachment) );
m_needPresent = false;
postReset(); postReset();
} }
@ -5918,7 +5926,9 @@ namespace bgfx { namespace gl
m_swapChain = s_renderGL->m_glctx.createSwapChain(_nwh); m_swapChain = s_renderGL->m_glctx.createSwapChain(_nwh);
m_width = _width; m_width = _width;
m_height = _height; m_height = _height;
m_numTh = 0;
m_denseIdx = _denseIdx; m_denseIdx = _denseIdx;
m_needPresent = false;
} }
uint16_t FrameBufferGL::destroy() uint16_t FrameBufferGL::destroy()
@ -5938,6 +5948,8 @@ namespace bgfx { namespace gl
memset(m_fbo, 0, sizeof(m_fbo) ); memset(m_fbo, 0, sizeof(m_fbo) );
uint16_t denseIdx = m_denseIdx; uint16_t denseIdx = m_denseIdx;
m_denseIdx = UINT16_MAX; m_denseIdx = UINT16_MAX;
m_needPresent = false;
m_numTh = 0;
return denseIdx; return denseIdx;
} }

View File

@ -1308,6 +1308,7 @@ namespace bgfx { namespace gl
: m_swapChain(NULL) : m_swapChain(NULL)
, m_denseIdx(UINT16_MAX) , m_denseIdx(UINT16_MAX)
, m_num(0) , m_num(0)
, m_needPresent(false)
{ {
memset(m_fbo, 0, sizeof(m_fbo) ); memset(m_fbo, 0, sizeof(m_fbo) );
} }
@ -1326,6 +1327,7 @@ namespace bgfx { namespace gl
uint16_t m_denseIdx; uint16_t m_denseIdx;
uint8_t m_num; uint8_t m_num;
uint8_t m_numTh; uint8_t m_numTh;
bool m_needPresent;
Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS]; Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
}; };