From a1184d53c5bd08c28197ae730f731e368bf0ae1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Fri, 3 Mar 2017 18:05:36 -0800 Subject: [PATCH] Invalidate occlusion queries in flight when new occlusion query with the same id is created. --- src/bgfx.cpp | 9 +++++++++ src/bgfx_p.h | 13 +++++++++++-- src/renderer_d3d11.cpp | 33 ++++++++++++++++++++++++++++----- src/renderer_d3d11.h | 1 + src/renderer_d3d12.cpp | 24 +++++++++++++++++++++++- src/renderer_d3d12.h | 1 + src/renderer_d3d9.cpp | 33 ++++++++++++++++++++++++++++----- src/renderer_d3d9.h | 1 + src/renderer_gl.cpp | 38 +++++++++++++++++++++++++++++++------- src/renderer_gl.h | 1 + src/renderer_mtl.h | 1 + src/renderer_mtl.mm | 28 +++++++++++++++++++++++++--- src/renderer_noop.cpp | 4 ++++ src/renderer_vk.cpp | 5 +++++ 14 files changed, 169 insertions(+), 23 deletions(-) diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 4c8577f70..f699076f2 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -2475,6 +2475,15 @@ namespace bgfx } break; + case CommandBuffer::InvalidateOcclusionQuery: + { + OcclusionQueryHandle handle; + _cmdbuf.read(handle); + + m_renderCtx->invalidateOcclusionQuery(handle); + } + break; + default: BX_CHECK(false, "Invalid command: %d", command); break; diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 2bf30be72..4bfbde421 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -633,6 +633,7 @@ namespace bgfx CreateFrameBuffer, CreateUniform, UpdateViewName, + InvalidateOcclusionQuery, End, RendererShutdownEnd, DestroyVertexDecl, @@ -2170,6 +2171,7 @@ namespace bgfx virtual void updateViewName(uint8_t _id, const char* _name) = 0; virtual void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) = 0; virtual void setMarker(const char* _marker, uint32_t _size) = 0; + virtual void invalidateOcclusionQuery(OcclusionQueryHandle _handle) = 0; virtual void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) = 0; virtual void blitSetup(TextVideoMemBlitter& _blitter) = 0; virtual void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) = 0; @@ -3600,7 +3602,11 @@ namespace bgfx if (isValid(handle) ) { m_submit->m_occlusion[handle.idx] = UINT8_MAX; + + CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::InvalidateOcclusionQuery); + cmdbuf.write(handle); } + return handle; } @@ -3632,8 +3638,11 @@ namespace bgfx if (isValid(_handle) ) { FrameBufferRef& ref = m_frameBufferRef[_handle.idx]; - BX_CHECK(ref.m_window, "requestScreenShot can be done only for window frame buffer handles (handle: %d).", _handle.idx); BX_UNUSED(ref); - return; + if (!ref.m_window) + { + BX_TRACE("requestScreenShot can be done only for window frame buffer handles (handle: %d).", _handle.idx); + return; + } } CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::RequestScreenShot); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 54ac9b951..5f19d7376 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -2081,6 +2081,11 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) BX_OVERRIDE + { + m_occlusionQuery.invalidate(_handle); + } + void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE; void blitSetup(TextVideoMemBlitter& _blitter) BX_OVERRIDE @@ -5220,18 +5225,36 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { Query& query = m_query[m_control.m_read]; - uint64_t result = 0; - HRESULT hr = deviceCtx->GetData(query.m_ptr, &result, sizeof(result), _wait ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH); - if (S_FALSE == hr) + if (isValid(query.m_handle) ) { - break; + uint64_t result = 0; + HRESULT hr = deviceCtx->GetData(query.m_ptr, &result, sizeof(result), _wait ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH); + if (S_FALSE == hr) + { + break; + } + + _render->m_occlusion[query.m_handle.idx] = 0 < result; } - _render->m_occlusion[query.m_handle.idx] = 0 < result; m_control.consume(1); } } + void OcclusionQueryD3D11::invalidate(OcclusionQueryHandle _handle) + { + const uint32_t size = m_control.m_size; + + for (uint32_t ii = 0, num = m_control.available(); ii < num; ++ii) + { + Query& query = m_query[(m_control.m_read + ii) % size]; + if (query.m_handle.idx == _handle.idx) + { + query.m_handle.idx = bgfx::invalidHandle; + } + } + } + void RendererContextD3D11::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) { if (updateResolution(_render->m_resolution) ) diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index 03a3a77e5..852a69e11 100644 --- a/src/renderer_d3d11.h +++ b/src/renderer_d3d11.h @@ -338,6 +338,7 @@ namespace bgfx { namespace d3d11 void begin(Frame* _render, OcclusionQueryHandle _handle); void end(); void resolve(Frame* _render, bool _wait = false); + void invalidate(OcclusionQueryHandle _handle); struct Query { diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 0936c0fa0..a8cff30b9 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -1639,6 +1639,11 @@ namespace bgfx { namespace d3d12 { } + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) BX_OVERRIDE + { + m_occlusionQuery.invalidate(_handle); + } + void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE; void blitSetup(TextVideoMemBlitter& _blitter) BX_OVERRIDE @@ -4718,7 +4723,10 @@ data.NumQualityLevels = 0; while (0 == m_control.reserve(1) ) { OcclusionQueryHandle handle = m_handle[m_control.m_read]; - _render->m_occlusion[handle.idx] = 0 < m_result[handle.idx]; + if (isValid(handle) ) + { + _render->m_occlusion[handle.idx] = 0 < m_result[handle.idx]; + } m_control.consume(1); } @@ -4746,6 +4754,20 @@ data.NumQualityLevels = 0; m_control.commit(1); } + void OcclusionQueryD3D12::invalidate(OcclusionQueryHandle _handle) + { + const uint32_t size = m_control.m_size; + + for (uint32_t ii = 0, num = m_control.available(); ii < num; ++ii) + { + OcclusionQueryHandle& handle = m_handle[(m_control.m_read + ii) % size]; + if (handle.idx == _handle.idx) + { + handle.idx = bgfx::invalidHandle; + } + } + } + struct Bind { D3D12_GPU_DESCRIPTOR_HANDLE m_srvHandle; diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h index 10dab997c..25de46c80 100644 --- a/src/renderer_d3d12.h +++ b/src/renderer_d3d12.h @@ -481,6 +481,7 @@ namespace bgfx { namespace d3d12 void shutdown(); void begin(ID3D12GraphicsCommandList* _commandList, Frame* _render, OcclusionQueryHandle _handle); void end(ID3D12GraphicsCommandList* _commandList); + void invalidate(OcclusionQueryHandle _handle); ID3D12Resource* m_readback; ID3D12QueryHeap* m_queryHeap; diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 7b084228c..2d77b19b7 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -1232,6 +1232,11 @@ namespace bgfx { namespace d3d9 BX_UNUSED(_marker, _size); } + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) BX_OVERRIDE + { + m_occlusionQuery.invalidate(_handle); + } + void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE; void blitSetup(TextVideoMemBlitter& _blitter) BX_OVERRIDE @@ -3569,18 +3574,36 @@ namespace bgfx { namespace d3d9 { Query& query = m_query[m_control.m_read]; - uint32_t result; - HRESULT hr = query.m_ptr->GetData(&result, sizeof(result), 0); - if (S_FALSE == hr) + if (isValid(query.m_handle) ) { - break; + uint32_t result; + HRESULT hr = query.m_ptr->GetData(&result, sizeof(result), 0); + if (S_FALSE == hr) + { + break; + } + + _render->m_occlusion[query.m_handle.idx] = 0 < result; } - _render->m_occlusion[query.m_handle.idx] = 0 < result; m_control.consume(1); } } + void OcclusionQueryD3D9::invalidate(OcclusionQueryHandle _handle) + { + const uint32_t size = m_control.m_size; + + for (uint32_t ii = 0, num = m_control.available(); ii < num; ++ii) + { + Query& query = m_query[(m_control.m_read + ii) % size]; + if (query.m_handle.idx == _handle.idx) + { + query.m_handle.idx = bgfx::invalidHandle; + } + } + } + void RendererContextD3D9::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) { IDirect3DDevice9* device = m_device; diff --git a/src/renderer_d3d9.h b/src/renderer_d3d9.h index f44fdd952..2aa9b64dc 100644 --- a/src/renderer_d3d9.h +++ b/src/renderer_d3d9.h @@ -468,6 +468,7 @@ namespace bgfx { namespace d3d9 void begin(Frame* _render, OcclusionQueryHandle _handle); void end(); void resolve(Frame* _render, bool _wait = false); + void invalidate(OcclusionQueryHandle _handle); struct Query { diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 6966367bd..350287d62 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -2584,6 +2584,11 @@ namespace bgfx { namespace gl GL_CHECK(glInsertEventMarker(_size, _marker) ); } + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) BX_OVERRIDE + { + m_occlusionQuery.invalidate(_handle); + } + void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE; void blitSetup(TextVideoMemBlitter& _blitter) BX_OVERRIDE @@ -6124,24 +6129,43 @@ namespace bgfx { namespace gl while (0 != m_control.available() ) { Query& query = m_query[m_control.m_read]; - int32_t result; - if (!_wait) + if (isValid(query.m_handle) ) { - GL_CHECK(glGetQueryObjectiv(query.m_id, GL_QUERY_RESULT_AVAILABLE, &result) ); + int32_t result; - if (!result) + if (!_wait) { - break; + GL_CHECK(glGetQueryObjectiv(query.m_id, GL_QUERY_RESULT_AVAILABLE, &result) ); + + if (!result) + { + break; + } } + + GL_CHECK(glGetQueryObjectiv(query.m_id, GL_QUERY_RESULT, &result) ); + _render->m_occlusion[query.m_handle.idx] = 0 < result; } - GL_CHECK(glGetQueryObjectiv(query.m_id, GL_QUERY_RESULT, &result) ); - _render->m_occlusion[query.m_handle.idx] = 0 < result; m_control.consume(1); } } + void OcclusionQueryGL::invalidate(OcclusionQueryHandle _handle) + { + const uint32_t size = m_control.m_size; + + for (uint32_t ii = 0, num = m_control.available(); ii < num; ++ii) + { + Query& query = m_query[(m_control.m_read + ii) % size]; + if (query.m_handle.idx == _handle.idx) + { + query.m_handle.idx = bgfx::invalidHandle; + } + } + } + void RendererContextGL::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) { BGFX_GPU_PROFILER_BEGIN_DYNAMIC("rendererSubmit"); diff --git a/src/renderer_gl.h b/src/renderer_gl.h index abb422480..4d9778a0c 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -1505,6 +1505,7 @@ namespace bgfx { namespace gl void begin(Frame* _render, OcclusionQueryHandle _handle); void end(); void resolve(Frame* _render, bool _wait = false); + void invalidate(OcclusionQueryHandle _handle); struct Query { diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h index 4aca08a02..86893f70e 100644 --- a/src/renderer_mtl.h +++ b/src/renderer_mtl.h @@ -896,6 +896,7 @@ namespace bgfx { namespace mtl void begin(RenderCommandEncoder& _rce, Frame* _render, OcclusionQueryHandle _handle); void end(RenderCommandEncoder& _rce); void resolve(Frame* _render, bool _wait = false); + void invalidate(OcclusionQueryHandle _handle); struct Query { diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index db45f468e..e45f544cc 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -970,6 +970,11 @@ namespace bgfx { namespace mtl } } + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) BX_OVERRIDE + { + m_occlusionQuery.invalidate(_handle); + } + void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE; void blitSetup(TextVideoMemBlitter& _blitter) BX_OVERRIDE @@ -1692,7 +1697,6 @@ namespace bgfx { namespace mtl return _visible == (0 != _render->m_occlusion[_handle.idx]); } - BlitCommandEncoder getBlitCommandEncoder() { if ( m_blitCommandEncoder == NULL) @@ -2932,12 +2936,30 @@ namespace bgfx { namespace mtl { Query& query = m_query[m_control.m_read]; - uint64_t result = ( (uint64_t*)m_buffer.contents() )[query.m_handle.idx]; - _render->m_occlusion[query.m_handle.idx] = 0 < result; + if (isValid(query.m_handle) ) + { + uint64_t result = ( (uint64_t*)m_buffer.contents() )[query.m_handle.idx]; + _render->m_occlusion[query.m_handle.idx] = 0 < result; + } + m_control.consume(1); } } + void OcclusionQueryMTL::invalidate(OcclusionQueryHandle _handle) + { + const uint32_t size = m_control.m_size; + + for (uint32_t ii = 0, num = m_control.available(); ii < num; ++ii) + { + Query& query = m_query[(m_control.m_read + ii) % size]; + if (query.m_handle.idx == _handle.idx) + { + query.m_handle.idx = bgfx::invalidHandle; + } + } + } + void RendererContextMtl::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE { m_cmd.finish(false); diff --git a/src/renderer_noop.cpp b/src/renderer_noop.cpp index 74edf5346..24fbfb485 100644 --- a/src/renderer_noop.cpp +++ b/src/renderer_noop.cpp @@ -193,6 +193,10 @@ namespace bgfx { namespace noop { } + void invalidateOcclusionQuery(OcclusionQueryHandle /*_handle*/) BX_OVERRIDE + { + } + void submit(Frame* /*_render*/, ClearQuad& /*_clearQuad*/, TextVideoMemBlitter& /*_textVideoMemBlitter*/) BX_OVERRIDE { } diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 91d7c48f6..f926fce3c 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -2118,6 +2118,11 @@ VK_IMPORT_DEVICE { } + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) BX_OVERRIDE + { + BX_UNUSED(_handle); + } + void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE; void blitSetup(TextVideoMemBlitter& /*_blitter*/) BX_OVERRIDE