mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-28 10:35:43 -05:00
Added ability to read occlusion query result on main thread.
This commit is contained in:
parent
a5bbb18a25
commit
ecf7eba043
11 changed files with 111 additions and 39 deletions
|
@ -212,6 +212,8 @@ class Occlusion : public entry::AppI
|
|||
bgfx::touch(0);
|
||||
bgfx::touch(2);
|
||||
|
||||
uint8_t img[CUBES_DIM*CUBES_DIM*2];
|
||||
|
||||
for (uint32_t yy = 0; yy < CUBES_DIM; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < CUBES_DIM; ++xx)
|
||||
|
@ -246,9 +248,14 @@ class Occlusion : public entry::AppI
|
|||
bgfx::setCondition(occlusionQuery, true);
|
||||
bgfx::setState(BGFX_STATE_DEFAULT);
|
||||
bgfx::submit(2, m_program);
|
||||
|
||||
img[(yy*CUBES_DIM+xx)*2+0] = " \xfex"[bgfx::getResult(occlusionQuery)];
|
||||
img[(yy*CUBES_DIM+xx)*2+1] = 0xf;
|
||||
}
|
||||
}
|
||||
|
||||
bgfx::dbgTextImage(5, 5, CUBES_DIM, CUBES_DIM, img, CUBES_DIM*2);
|
||||
|
||||
// Advance to next frame. Rendering thread will be kicked to
|
||||
// process submitted rendering primitives.
|
||||
bgfx::frame();
|
||||
|
|
|
@ -275,6 +275,18 @@ namespace bgfx
|
|||
};
|
||||
};
|
||||
|
||||
struct OcclusionQueryResult
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Invisible,
|
||||
Visible,
|
||||
NoResult,
|
||||
|
||||
Count
|
||||
};
|
||||
};
|
||||
|
||||
static const uint16_t invalidHandle = UINT16_MAX;
|
||||
|
||||
BGFX_HANDLE(DynamicIndexBufferHandle);
|
||||
|
@ -1538,6 +1550,14 @@ namespace bgfx
|
|||
///
|
||||
OcclusionQueryHandle createOcclusionQuery();
|
||||
|
||||
/// Retrieve occlusion query result.
|
||||
///
|
||||
/// @param[in] _handle Handle to occlusion query object.
|
||||
///
|
||||
/// @attention C99 equivalent is `bgfx_get_result`.
|
||||
///
|
||||
OcclusionQueryResult::Enum getResult(OcclusionQueryHandle _handle);
|
||||
|
||||
/// Destroy occlusion query.
|
||||
///
|
||||
/// @param[in] _handle Handle to occlusion query object.
|
||||
|
|
|
@ -184,6 +184,16 @@ typedef enum bgfx_backbuffer_ratio
|
|||
|
||||
} bgfx_backbuffer_ratio_t;
|
||||
|
||||
typedef enum bgfx_occlusion_query_result
|
||||
{
|
||||
BGFX_OCCLUSION_QUERY_RESULT_INVISIBLE,
|
||||
BGFX_OCCLUSION_QUERY_RESULT_VISIBLE,
|
||||
BGFX_OCCLUSION_QUERY_RESULT_NORESULT,
|
||||
|
||||
BGFX_OCCLUSION_QUERY_RESULT_COUNT
|
||||
|
||||
} bgfx_occlusion_query_result_t;
|
||||
|
||||
#define BGFX_HANDLE_T(_name) \
|
||||
typedef struct _name { uint16_t idx; } _name##_t
|
||||
|
||||
|
@ -642,6 +652,9 @@ BGFX_C_API void bgfx_destroy_uniform(bgfx_uniform_handle_t _handle);
|
|||
/**/
|
||||
BGFX_C_API bgfx_occlusion_query_handle_t bgfx_create_occlusion_query();
|
||||
|
||||
/**/
|
||||
BGFX_C_API bgfx_occlusion_query_result_t bgfx_get_result(bgfx_occlusion_query_handle_t _handle);
|
||||
|
||||
/**/
|
||||
BGFX_C_API void bgfx_destroy_occlusion_query(bgfx_occlusion_query_handle_t _handle);
|
||||
|
||||
|
|
15
src/bgfx.cpp
15
src/bgfx.cpp
|
@ -1372,6 +1372,8 @@ namespace bgfx
|
|||
|
||||
bx::xchg(m_render, m_submit);
|
||||
|
||||
memcpy(m_render->m_occlusion, m_submit->m_occlusion, sizeof(m_submit->m_occlusion) );
|
||||
|
||||
if (!BX_ENABLED(BGFX_CONFIG_MULTITHREADED)
|
||||
|| m_singleThreaded)
|
||||
{
|
||||
|
@ -3026,6 +3028,13 @@ again:
|
|||
return s_ctx->createOcclusionQuery();
|
||||
}
|
||||
|
||||
OcclusionQueryResult::Enum getResult(OcclusionQueryHandle _handle)
|
||||
{
|
||||
BGFX_CHECK_MAIN_THREAD();
|
||||
BGFX_CHECK_CAPS(BGFX_CAPS_OCCLUSION_QUERY, "Occlusion query is not supported!");
|
||||
return s_ctx->getResult(_handle);
|
||||
}
|
||||
|
||||
void destroyOcclusionQuery(OcclusionQueryHandle _handle)
|
||||
{
|
||||
BGFX_CHECK_MAIN_THREAD();
|
||||
|
@ -3991,6 +4000,12 @@ BGFX_C_API bgfx_occlusion_query_handle_t bgfx_create_occlusion_query()
|
|||
return handle.c;
|
||||
}
|
||||
|
||||
BGFX_C_API bgfx_occlusion_query_result_t bgfx_get_result(bgfx_occlusion_query_handle_t _handle)
|
||||
{
|
||||
union { bgfx_occlusion_query_handle_t c; bgfx::OcclusionQueryHandle cpp; } handle = { _handle };
|
||||
return bgfx_occlusion_query_result_t(bgfx::getResult(handle.cpp) );
|
||||
}
|
||||
|
||||
BGFX_C_API void bgfx_destroy_occlusion_query(bgfx_occlusion_query_handle_t _handle)
|
||||
{
|
||||
union { bgfx_occlusion_query_handle_t c; bgfx::OcclusionQueryHandle cpp; } handle = { _handle };
|
||||
|
|
20
src/bgfx_p.h
20
src/bgfx_p.h
|
@ -1292,6 +1292,7 @@ namespace bgfx
|
|||
term.m_program = invalidHandle;
|
||||
m_sortKeys[BGFX_CONFIG_MAX_DRAW_CALLS] = term.encodeDraw();
|
||||
m_sortValues[BGFX_CONFIG_MAX_DRAW_CALLS] = BGFX_CONFIG_MAX_DRAW_CALLS;
|
||||
memset(m_occlusion, 0xff, sizeof(m_occlusion) );
|
||||
}
|
||||
|
||||
~Frame()
|
||||
|
@ -1681,6 +1682,7 @@ namespace bgfx
|
|||
Matrix4 m_view[BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4 m_proj[2][BGFX_CONFIG_MAX_VIEWS];
|
||||
uint8_t m_viewFlags[BGFX_CONFIG_MAX_VIEWS];
|
||||
uint8_t m_occlusion[BGFX_CONFIG_MAX_OCCUSION_QUERIES];
|
||||
|
||||
uint64_t m_sortKeys[BGFX_CONFIG_MAX_DRAW_CALLS+1];
|
||||
RenderItemCount m_sortValues[BGFX_CONFIG_MAX_DRAW_CALLS+1];
|
||||
|
@ -3297,9 +3299,27 @@ namespace bgfx
|
|||
BGFX_API_FUNC(OcclusionQueryHandle createOcclusionQuery() )
|
||||
{
|
||||
OcclusionQueryHandle handle = { m_occlusionQueryHandle.alloc() };
|
||||
if (isValid(handle) )
|
||||
{
|
||||
m_submit->m_occlusion[handle.idx] = UINT8_MAX;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
BGFX_API_FUNC(OcclusionQueryResult::Enum getResult(OcclusionQueryHandle _handle) )
|
||||
{
|
||||
BGFX_CHECK_HANDLE("destroyOcclusionQuery", m_occlusionQueryHandle, _handle);
|
||||
|
||||
switch (m_submit->m_occlusion[_handle.idx])
|
||||
{
|
||||
case 0: return OcclusionQueryResult::Invisible;
|
||||
case UINT8_MAX: return OcclusionQueryResult::NoResult;
|
||||
default:;
|
||||
}
|
||||
|
||||
return OcclusionQueryResult::Visible;
|
||||
}
|
||||
|
||||
BGFX_API_FUNC(void destroyOcclusionQuery(OcclusionQueryHandle _handle) )
|
||||
{
|
||||
BGFX_CHECK_HANDLE("destroyOcclusionQuery", m_occlusionQueryHandle, _handle);
|
||||
|
|
|
@ -2729,10 +2729,10 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
return sampler;
|
||||
}
|
||||
|
||||
bool isVisible(OcclusionQueryHandle _handle, bool _visible)
|
||||
bool isVisible(Frame* _render, OcclusionQueryHandle _handle, bool _visible)
|
||||
{
|
||||
m_occlusionQuery.resolve();
|
||||
return _visible == m_occlusion[_handle.idx];
|
||||
m_occlusionQuery.resolve(_render);
|
||||
return _visible == 0 != _render->m_occlusion[_handle.idx];
|
||||
}
|
||||
|
||||
DXGI_FORMAT getBufferFormat()
|
||||
|
@ -3334,7 +3334,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
TextureD3D11 m_textures[BGFX_CONFIG_MAX_TEXTURES];
|
||||
VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
|
||||
FrameBufferD3D11 m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS];
|
||||
bool m_occlusion[BGFX_CONFIG_MAX_OCCUSION_QUERIES];
|
||||
void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
|
||||
Matrix4 m_predefinedUniforms[PredefinedUniform::Count];
|
||||
UniformRegistry m_uniformReg;
|
||||
|
@ -4577,11 +4576,11 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
}
|
||||
}
|
||||
|
||||
void OcclusionQueryD3D11::begin(OcclusionQueryHandle _handle)
|
||||
void OcclusionQueryD3D11::begin(Frame* _render, OcclusionQueryHandle _handle)
|
||||
{
|
||||
while (0 == m_control.reserve(1) )
|
||||
{
|
||||
resolve(true);
|
||||
resolve(_render, true);
|
||||
}
|
||||
|
||||
ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;
|
||||
|
@ -4598,7 +4597,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
m_control.commit(1);
|
||||
}
|
||||
|
||||
void OcclusionQueryD3D11::resolve(bool _wait)
|
||||
void OcclusionQueryD3D11::resolve(Frame* _render, bool _wait)
|
||||
{
|
||||
ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;
|
||||
|
||||
|
@ -4613,7 +4612,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
break;
|
||||
}
|
||||
|
||||
s_renderD3D11->m_occlusion[query.m_handle.idx] = 0 < result;
|
||||
_render->m_occlusion[query.m_handle.idx] = 0 < result;
|
||||
m_control.consume(1);
|
||||
}
|
||||
}
|
||||
|
@ -4687,7 +4686,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
uint32_t statsNumIndices = 0;
|
||||
uint32_t statsKeyType[2] = {};
|
||||
|
||||
m_occlusionQuery.resolve();
|
||||
m_occlusionQuery.resolve(_render);
|
||||
|
||||
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
||||
{
|
||||
|
@ -5053,7 +5052,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
const bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY);
|
||||
if (isValid(draw.m_occlusionQuery)
|
||||
&& !hasOcclusionQuery
|
||||
&& !isVisible(draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) ) )
|
||||
&& !isVisible(_render, draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -5348,7 +5347,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
|
|||
|
||||
if (hasOcclusionQuery)
|
||||
{
|
||||
m_occlusionQuery.begin(draw.m_occlusionQuery);
|
||||
m_occlusionQuery.begin(_render, draw.m_occlusionQuery);
|
||||
}
|
||||
|
||||
if (isValid(draw.m_indirectBuffer) )
|
||||
|
|
|
@ -316,9 +316,9 @@ namespace bgfx { namespace d3d11
|
|||
|
||||
void postReset();
|
||||
void preReset();
|
||||
void begin(OcclusionQueryHandle _handle);
|
||||
void begin(Frame* _render, OcclusionQueryHandle _handle);
|
||||
void end();
|
||||
void resolve(bool _wait = false);
|
||||
void resolve(Frame* _render, bool _wait = false);
|
||||
|
||||
struct Query
|
||||
{
|
||||
|
|
|
@ -1565,10 +1565,10 @@ namespace bgfx { namespace d3d9
|
|||
}
|
||||
}
|
||||
|
||||
bool isVisible(OcclusionQueryHandle _handle, bool _visible)
|
||||
bool isVisible(Frame* _render, OcclusionQueryHandle _handle, bool _visible)
|
||||
{
|
||||
m_occlusionQuery.resolve();
|
||||
return _visible == m_occlusion[_handle.idx];
|
||||
m_occlusionQuery.resolve(_render);
|
||||
return _visible == 0 != _render->m_occlusion[_handle.idx];
|
||||
}
|
||||
|
||||
void capturePreReset()
|
||||
|
@ -2007,7 +2007,6 @@ namespace bgfx { namespace d3d9
|
|||
TextureD3D9 m_textures[BGFX_CONFIG_MAX_TEXTURES];
|
||||
VertexDeclD3D9 m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
|
||||
FrameBufferD3D9 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];
|
||||
|
||||
|
@ -3410,11 +3409,11 @@ namespace bgfx { namespace d3d9
|
|||
}
|
||||
}
|
||||
|
||||
void OcclusionQueryD3D9::begin(OcclusionQueryHandle _handle)
|
||||
void OcclusionQueryD3D9::begin(Frame* _render, OcclusionQueryHandle _handle)
|
||||
{
|
||||
while (0 == m_control.reserve(1) )
|
||||
{
|
||||
resolve(true);
|
||||
resolve(_render, true);
|
||||
}
|
||||
|
||||
Query& query = m_query[m_control.m_current];
|
||||
|
@ -3429,7 +3428,7 @@ namespace bgfx { namespace d3d9
|
|||
m_control.commit(1);
|
||||
}
|
||||
|
||||
void OcclusionQueryD3D9::resolve(bool)
|
||||
void OcclusionQueryD3D9::resolve(Frame* _render, bool)
|
||||
{
|
||||
while (0 != m_control.available() )
|
||||
{
|
||||
|
@ -3442,7 +3441,7 @@ namespace bgfx { namespace d3d9
|
|||
break;
|
||||
}
|
||||
|
||||
s_renderD3D9->m_occlusion[query.m_handle.idx] = 0 < result;
|
||||
_render->m_occlusion[query.m_handle.idx] = 0 < result;
|
||||
m_control.consume(1);
|
||||
}
|
||||
}
|
||||
|
@ -3518,7 +3517,7 @@ namespace bgfx { namespace d3d9
|
|||
|
||||
if (m_occlusionQuerySupport)
|
||||
{
|
||||
m_occlusionQuery.resolve();
|
||||
m_occlusionQuery.resolve(_render);
|
||||
}
|
||||
|
||||
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
||||
|
@ -3539,7 +3538,7 @@ namespace bgfx { namespace d3d9
|
|||
const bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY);
|
||||
if (isValid(draw.m_occlusionQuery)
|
||||
&& !hasOcclusionQuery
|
||||
&& !isVisible(draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) ) )
|
||||
&& !isVisible(_render, draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -4003,7 +4002,7 @@ namespace bgfx { namespace d3d9
|
|||
|
||||
if (hasOcclusionQuery)
|
||||
{
|
||||
m_occlusionQuery.begin(draw.m_occlusionQuery);
|
||||
m_occlusionQuery.begin(_render, draw.m_occlusionQuery);
|
||||
}
|
||||
|
||||
if (isValid(draw.m_indexBuffer) )
|
||||
|
|
|
@ -439,9 +439,9 @@ namespace bgfx { namespace d3d9
|
|||
|
||||
void postReset();
|
||||
void preReset();
|
||||
void begin(OcclusionQueryHandle _handle);
|
||||
void begin(Frame* _render, OcclusionQueryHandle _handle);
|
||||
void end();
|
||||
void resolve(bool _wait = false);
|
||||
void resolve(Frame* _render, bool _wait = false);
|
||||
|
||||
struct Query
|
||||
{
|
||||
|
|
|
@ -2712,10 +2712,10 @@ namespace bgfx { namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
bool isVisible(OcclusionQueryHandle _handle, bool _visible)
|
||||
bool isVisible(Frame* _render, OcclusionQueryHandle _handle, bool _visible)
|
||||
{
|
||||
m_occlusionQuery.resolve();
|
||||
return _visible == m_occlusion[_handle.idx];
|
||||
m_occlusionQuery.resolve(_render);
|
||||
return _visible == 0 != _render->m_occlusion[_handle.idx];
|
||||
}
|
||||
|
||||
void ovrPostReset()
|
||||
|
@ -3156,7 +3156,6 @@ 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];
|
||||
|
||||
|
@ -5166,11 +5165,11 @@ namespace bgfx { namespace gl
|
|||
}
|
||||
}
|
||||
|
||||
void OcclusionQueryGL::begin(OcclusionQueryHandle _handle)
|
||||
void OcclusionQueryGL::begin(Frame* _render, OcclusionQueryHandle _handle)
|
||||
{
|
||||
while (0 == m_control.reserve(1) )
|
||||
{
|
||||
resolve(true);
|
||||
resolve(_render, true);
|
||||
}
|
||||
|
||||
Query& query = m_query[m_control.m_current];
|
||||
|
@ -5184,7 +5183,7 @@ namespace bgfx { namespace gl
|
|||
m_control.commit(1);
|
||||
}
|
||||
|
||||
void OcclusionQueryGL::resolve(bool _wait)
|
||||
void OcclusionQueryGL::resolve(Frame* _render, bool _wait)
|
||||
{
|
||||
while (0 != m_control.available() )
|
||||
{
|
||||
|
@ -5202,7 +5201,7 @@ namespace bgfx { namespace gl
|
|||
}
|
||||
|
||||
GL_CHECK(glGetQueryObjectiv(query.m_id, GL_QUERY_RESULT, &result) );
|
||||
s_renderGL->m_occlusion[query.m_handle.idx] = 0 < result;
|
||||
_render->m_occlusion[query.m_handle.idx] = 0 < result;
|
||||
m_control.consume(1);
|
||||
}
|
||||
}
|
||||
|
@ -5307,7 +5306,7 @@ namespace bgfx { namespace gl
|
|||
|
||||
if (m_occlusionQuerySupport)
|
||||
{
|
||||
m_occlusionQuery.resolve();
|
||||
m_occlusionQuery.resolve(_render);
|
||||
}
|
||||
|
||||
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
||||
|
@ -5605,7 +5604,7 @@ namespace bgfx { namespace gl
|
|||
const bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY);
|
||||
if (isValid(draw.m_occlusionQuery)
|
||||
&& !hasOcclusionQuery
|
||||
&& !isVisible(draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) ) )
|
||||
&& !isVisible(_render, draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -6124,7 +6123,7 @@ namespace bgfx { namespace gl
|
|||
|
||||
if (hasOcclusionQuery)
|
||||
{
|
||||
m_occlusionQuery.begin(draw.m_occlusionQuery);
|
||||
m_occlusionQuery.begin(_render, draw.m_occlusionQuery);
|
||||
}
|
||||
|
||||
if (isValid(draw.m_indirectBuffer) )
|
||||
|
|
|
@ -1270,9 +1270,9 @@ namespace bgfx { namespace gl
|
|||
|
||||
void create();
|
||||
void destroy();
|
||||
void begin(OcclusionQueryHandle _handle);
|
||||
void begin(Frame* _render, OcclusionQueryHandle _handle);
|
||||
void end();
|
||||
void resolve(bool _wait = false);
|
||||
void resolve(Frame* _render, bool _wait = false);
|
||||
|
||||
struct Query
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue