mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2025-03-14 00:49:53 -04:00
GL: Occlusion query.
This commit is contained in:
parent
4eac3f398e
commit
7a8b3632b9
4 changed files with 151 additions and 37 deletions
|
@ -209,6 +209,9 @@ class Occlusion : public entry::AppI
|
|||
bgfx::setViewRect(2, 10, height - height/4 - 10, width/4, height/4);
|
||||
}
|
||||
|
||||
bgfx::touch(0);
|
||||
bgfx::touch(2);
|
||||
|
||||
for (uint32_t yy = 0; yy < CUBES_DIM; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < CUBES_DIM; ++xx)
|
||||
|
|
|
@ -3516,6 +3516,11 @@ namespace bgfx { namespace d3d9
|
|||
|
||||
invalidateSamplerState();
|
||||
|
||||
if (m_occlusionQuerySupport)
|
||||
{
|
||||
m_occlusionQuery.resolve();
|
||||
}
|
||||
|
||||
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
||||
{
|
||||
for (uint32_t item = 0, numItems = _render->m_num; item < numItems; ++item)
|
||||
|
|
|
@ -558,6 +558,7 @@ namespace bgfx { namespace gl
|
|||
|
||||
NV_copy_image,
|
||||
NV_draw_buffers,
|
||||
NV_occlusion_query,
|
||||
NV_texture_border_clamp,
|
||||
NVX_gpu_memory_info,
|
||||
|
||||
|
@ -716,7 +717,7 @@ namespace bgfx { namespace gl
|
|||
{ "EXT_framebuffer_object", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
|
||||
{ "EXT_framebuffer_sRGB", BGFX_CONFIG_RENDERER_OPENGL >= 30, true },
|
||||
{ "EXT_multi_draw_indirect", false, true }, // GLES3.1 extension.
|
||||
{ "EXT_occlusion_query_boolean", false, true },
|
||||
{ "EXT_occlusion_query_boolean", false, true }, // GLES2 extension.
|
||||
{ "EXT_packed_float", BGFX_CONFIG_RENDERER_OPENGL >= 33, true },
|
||||
{ "EXT_read_format_bgra", false, true },
|
||||
{ "EXT_shader_image_load_store", false, true },
|
||||
|
@ -761,6 +762,7 @@ namespace bgfx { namespace gl
|
|||
|
||||
{ "NV_copy_image", false, true },
|
||||
{ "NV_draw_buffers", false, true }, // GLES2 extension.
|
||||
{ "NV_occlusion_query", false, true },
|
||||
{ "NV_texture_border_clamp", false, true }, // GLES2 extension.
|
||||
{ "NVX_gpu_memory_info", false, true },
|
||||
|
||||
|
@ -1213,6 +1215,7 @@ namespace bgfx { namespace gl
|
|||
, m_textureSwizzleSupport(false)
|
||||
, m_depthTextureSupport(false)
|
||||
, m_timerQuerySupport(false)
|
||||
, m_occlusionQuerySupport(false)
|
||||
, m_flip(false)
|
||||
, m_hash( (BX_PLATFORM_WINDOWS<<1) | BX_ARCH_64BIT)
|
||||
, m_backBufferFbo(0)
|
||||
|
@ -1800,6 +1803,18 @@ namespace bgfx { namespace gl
|
|||
&& NULL != glGetQueryObjectui64v
|
||||
;
|
||||
|
||||
m_occlusionQuerySupport = false
|
||||
|| s_extension[Extension::ARB_occlusion_query ].m_supported
|
||||
|| s_extension[Extension::ARB_occlusion_query2 ].m_supported
|
||||
|| s_extension[Extension::EXT_occlusion_query_boolean].m_supported
|
||||
|| s_extension[Extension::NV_occlusion_query ].m_supported
|
||||
;
|
||||
|
||||
g_caps.supported |= m_occlusionQuerySupport
|
||||
? BGFX_CAPS_OCCLUSION_QUERY
|
||||
: 0
|
||||
;
|
||||
|
||||
g_caps.supported |= m_depthTextureSupport
|
||||
? BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
|
||||
: 0
|
||||
|
@ -1926,12 +1941,16 @@ namespace bgfx { namespace gl
|
|||
glInvalidateFramebuffer = stubInvalidateFramebuffer;
|
||||
}
|
||||
|
||||
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
|
||||
&& m_timerQuerySupport)
|
||||
if (m_timerQuerySupport)
|
||||
{
|
||||
m_gpuTimer.create();
|
||||
}
|
||||
|
||||
if (m_occlusionQuerySupport)
|
||||
{
|
||||
m_occlusionQuery.create();
|
||||
}
|
||||
|
||||
// Init reserved part of view name.
|
||||
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
|
||||
{
|
||||
|
@ -1957,12 +1976,16 @@ namespace bgfx { namespace gl
|
|||
|
||||
invalidateCache();
|
||||
|
||||
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
|
||||
&& m_timerQuerySupport)
|
||||
if (m_timerQuerySupport)
|
||||
{
|
||||
m_gpuTimer.destroy();
|
||||
}
|
||||
|
||||
if (m_occlusionQuerySupport)
|
||||
{
|
||||
m_occlusionQuery.destroy();
|
||||
}
|
||||
|
||||
destroyMsaaFbo();
|
||||
m_glctx.destroy();
|
||||
|
||||
|
@ -2689,6 +2712,12 @@ namespace bgfx { namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
bool isVisible(OcclusionQueryHandle _handle)
|
||||
{
|
||||
m_occlusionQuery.resolve();
|
||||
return m_occlusion[_handle.idx];
|
||||
}
|
||||
|
||||
void ovrPostReset()
|
||||
{
|
||||
#if BGFX_CONFIG_USE_OVR
|
||||
|
@ -3127,9 +3156,12 @@ namespace bgfx { namespace gl
|
|||
TextureGL m_textures[BGFX_CONFIG_MAX_TEXTURES];
|
||||
VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
|
||||
FrameBufferGL m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS];
|
||||
bool m_occlusion[BGFX_CONFIG_MAX_OCCUSION_QUERIES];
|
||||
UniformRegistry m_uniformReg;
|
||||
void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
|
||||
|
||||
TimerQueryGL m_gpuTimer;
|
||||
OcclusionQueryGL m_occlusionQuery;
|
||||
|
||||
VaoStateCache m_vaoStateCache;
|
||||
SamplerStateCache m_samplerStateCache;
|
||||
|
@ -3157,6 +3189,7 @@ namespace bgfx { namespace gl
|
|||
bool m_textureSwizzleSupport;
|
||||
bool m_depthTextureSupport;
|
||||
bool m_timerQuerySupport;
|
||||
bool m_occlusionQuerySupport;
|
||||
bool m_flip;
|
||||
|
||||
uint64_t m_hash;
|
||||
|
@ -5115,6 +5148,65 @@ namespace bgfx { namespace gl
|
|||
GL_CHECK(glInvalidateFramebuffer(GL_FRAMEBUFFER, idx, buffers) );
|
||||
}
|
||||
|
||||
void OcclusionQueryGL::create()
|
||||
{
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii)
|
||||
{
|
||||
Query& query = m_query[ii];
|
||||
GL_CHECK(glGenQueries(1, &query.m_id) );
|
||||
}
|
||||
}
|
||||
|
||||
void OcclusionQueryGL::destroy()
|
||||
{
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii)
|
||||
{
|
||||
Query& query = m_query[ii];
|
||||
GL_CHECK(glDeleteQueries(1, &query.m_id) );
|
||||
}
|
||||
}
|
||||
|
||||
void OcclusionQueryGL::begin(OcclusionQueryHandle _handle)
|
||||
{
|
||||
while (0 == m_control.reserve(1) )
|
||||
{
|
||||
resolve(true);
|
||||
}
|
||||
|
||||
Query& query = m_query[m_control.m_current];
|
||||
GL_CHECK(glBeginQuery(GL_SAMPLES_PASSED, query.m_id) );
|
||||
query.m_handle = _handle;
|
||||
}
|
||||
|
||||
void OcclusionQueryGL::end()
|
||||
{
|
||||
GL_CHECK(glEndQuery(GL_SAMPLES_PASSED) );
|
||||
m_control.commit(1);
|
||||
}
|
||||
|
||||
void OcclusionQueryGL::resolve(bool _wait)
|
||||
{
|
||||
while (0 != m_control.available() )
|
||||
{
|
||||
Query& query = m_query[m_control.m_read];
|
||||
int32_t result;
|
||||
|
||||
if (!_wait)
|
||||
{
|
||||
GL_CHECK(glGetQueryObjectiv(query.m_id, GL_QUERY_RESULT_AVAILABLE, &result) );
|
||||
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GL_CHECK(glGetQueryObjectiv(query.m_id, GL_QUERY_RESULT, &result) );
|
||||
s_renderGL->m_occlusion[query.m_handle.idx] = 0 < result;
|
||||
m_control.consume(1);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererContextGL::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
|
||||
{
|
||||
if (1 < m_numWindows
|
||||
|
@ -5213,6 +5305,11 @@ namespace bgfx { namespace gl
|
|||
uint32_t statsNumIndices = 0;
|
||||
uint32_t statsKeyType[2] = {};
|
||||
|
||||
if (m_occlusionQuerySupport)
|
||||
{
|
||||
m_occlusionQuery.resolve();
|
||||
}
|
||||
|
||||
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
||||
{
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
|
||||
|
@ -5505,6 +5602,14 @@ namespace bgfx { namespace gl
|
|||
|
||||
const RenderDraw& draw = renderItem.draw;
|
||||
|
||||
const bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY);
|
||||
if (isValid(draw.m_occlusionQuery)
|
||||
&& !hasOcclusionQuery
|
||||
&& !isVisible(draw.m_occlusionQuery) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint64_t newFlags = draw.m_stateFlags;
|
||||
uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags;
|
||||
currentState.m_stateFlags = newFlags;
|
||||
|
@ -6017,6 +6122,11 @@ namespace bgfx { namespace gl
|
|||
uint32_t numPrimsRendered = 0;
|
||||
uint32_t numDrawIndirect = 0;
|
||||
|
||||
if (hasOcclusionQuery)
|
||||
{
|
||||
m_occlusionQuery.begin(draw.m_occlusionQuery);
|
||||
}
|
||||
|
||||
if (isValid(draw.m_indirectBuffer) )
|
||||
{
|
||||
const VertexBufferGL& vb = m_vertexBuffers[draw.m_indirectBuffer.idx];
|
||||
|
@ -6123,6 +6233,11 @@ namespace bgfx { namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
if (hasOcclusionQuery)
|
||||
{
|
||||
m_occlusionQuery.end();
|
||||
}
|
||||
|
||||
statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
|
||||
statsNumPrimsRendered[primIndex] += numPrimsRendered;
|
||||
statsNumInstances[primIndex] += numInstances;
|
||||
|
|
|
@ -1188,38 +1188,6 @@ namespace bgfx { namespace gl
|
|||
VaoCacheRef m_vcref;
|
||||
};
|
||||
|
||||
struct QueriesGL
|
||||
{
|
||||
void create()
|
||||
{
|
||||
GL_CHECK(glGenQueries(BX_COUNTOF(m_queries), m_queries) );
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
GL_CHECK(glDeleteQueries(BX_COUNTOF(m_queries), m_queries) );
|
||||
}
|
||||
|
||||
void begin(uint16_t _id, GLenum _target) const
|
||||
{
|
||||
GL_CHECK(glBeginQuery(_target, m_queries[_id]) );
|
||||
}
|
||||
|
||||
void end(GLenum _target) const
|
||||
{
|
||||
GL_CHECK(glEndQuery(_target) );
|
||||
}
|
||||
|
||||
uint64_t getResult(uint16_t _id) const
|
||||
{
|
||||
uint64_t result;
|
||||
GL_CHECK(glGetQueryObjectui64v(m_queries[_id], GL_QUERY_RESULT, &result) );
|
||||
return result;
|
||||
}
|
||||
|
||||
GLuint m_queries[64];
|
||||
};
|
||||
|
||||
struct TimerQueryGL
|
||||
{
|
||||
TimerQueryGL()
|
||||
|
@ -1285,6 +1253,29 @@ namespace bgfx { namespace gl
|
|||
bx::RingBufferControl m_control;
|
||||
};
|
||||
|
||||
struct OcclusionQueryGL
|
||||
{
|
||||
OcclusionQueryGL()
|
||||
: m_control(BX_COUNTOF(m_query) )
|
||||
{
|
||||
}
|
||||
|
||||
void create();
|
||||
void destroy();
|
||||
void begin(OcclusionQueryHandle _handle);
|
||||
void end();
|
||||
void resolve(bool _wait = false);
|
||||
|
||||
struct Query
|
||||
{
|
||||
GLuint m_id;
|
||||
OcclusionQueryHandle m_handle;
|
||||
};
|
||||
|
||||
Query m_query[BGFX_CONFIG_MAX_OCCUSION_QUERIES];
|
||||
bx::RingBufferControl m_control;
|
||||
};
|
||||
|
||||
} /* namespace gl */ } // namespace bgfx
|
||||
|
||||
#endif // BGFX_RENDERER_GL_H_HEADER_GUARD
|
||||
|
|
Loading…
Reference in a new issue