Faster occlusion queries (take advantage of GL_ARB_occlusion_query2 where available and don't read back result if it will block).

meow-7.2.2
Dave Parks 2010-12-31 18:41:54 -06:00
parent 33d9b10fbb
commit 1e647e2cd2
3 changed files with 42 additions and 25 deletions

View File

@ -325,6 +325,7 @@ LLGLManager::LLGLManager() :
mHasVertexShader(FALSE),
mHasFragmentShader(FALSE),
mHasOcclusionQuery(FALSE),
mHasOcclusionQuery2(FALSE),
mHasPointParameters(FALSE),
mHasDrawBuffers(FALSE),
mHasTextureRectangle(FALSE),
@ -666,6 +667,7 @@ void LLGLManager::initExtensions()
mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
@ -782,6 +784,10 @@ void LLGLManager::initExtensions()
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL;
}
if (!mHasOcclusionQuery2)
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query2" << LL_ENDL;
}
if (!mHasPointParameters)
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL;

View File

@ -89,6 +89,7 @@ public:
BOOL mHasVertexShader;
BOOL mHasFragmentShader;
BOOL mHasOcclusionQuery;
BOOL mHasOcclusionQuery2;
BOOL mHasPointParameters;
BOOL mHasDrawBuffers;
BOOL mHasDepthClamp;

View File

@ -1516,31 +1516,37 @@ void LLSpatialGroup::checkOcclusion()
}
else if (isOcclusionState(QUERY_PENDING))
{ //otherwise, if a query is pending, read it back
GLuint res = 1;
if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);
}
if (isOcclusionState(DISCARD_QUERY))
{
res = 2;
}
GLuint available = 0;
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
if (available)
{ //result is available, read it back, otherwise wait until next frame
GLuint res = 1;
if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);
}
if (res > 0)
{
assert_states_valid(this);
clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
assert_states_valid(this);
}
else
{
assert_states_valid(this);
setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
assert_states_valid(this);
}
if (isOcclusionState(DISCARD_QUERY))
{
res = 2;
}
clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
if (res > 0)
{
assert_states_valid(this);
clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
assert_states_valid(this);
}
else
{
assert_states_valid(this);
setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
assert_states_valid(this);
}
clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
}
}
else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED))
{ //check occlusion has been issued for occluded node that has not had a query issued
@ -1566,7 +1572,8 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
}
else
{
{
if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY))
{ //no query pending, or previous query to be discarded
LLFastTimer t(FTM_RENDER_OCCLUSION);
if (!mOcclusionQuery[LLViewerCamera::sCurCameraID])
@ -1590,7 +1597,10 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
glEnable(GL_DEPTH_CLAMP);
}
glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
glVertexPointer(3, GL_FLOAT, 16, mOcclusionVerts);
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
@ -1604,7 +1614,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0]));
}
glEndQueryARB(GL_SAMPLES_PASSED_ARB);
glEndQueryARB(mode);
if (use_depth_clamp)
{