From Doug McCorkle, via Paul Martz who writes : "Summary: Some platforms/configurations cause application crashes if the
occlusion query result is not ready for retrieval when the app tries to retrieve it. This fix adds an application-level wait loop to ensure the result is ready for retrieval. This code is not compiled by default; add "-D FORCE_QUERY_RESULT_AVAILABLE_BEFORE_RETRIEVAL" to get this code. Full, gory details, to the best of my recollection: The conditions under which we encountered this issue are as follows: 64-bit processor, Mac/Linux OS, multiple NVIDIA GPUs, multiple concurrent draw threads, VRJuggler/SceneView-based viewer, and a scene graph containing OcclusionQueryNodes. Todd wrote a small test program that produces an almost instant crash in this environment. We verified the crash does not occur in a similar environment with a 32-bit processor, but we have not yet tested on Windows and have not yet tested with osgViewer. The OpenGL spec states clearly that, if an occlusion query result is not yet ready, an app can go ahead and attempt to retrieve it, and OpenGL will simply block until the result is ready. Indeed, this is how OcclusionQueryNode is written, and this has worked fine on several platforms and configurations until Todd's test program. By trial and error and dumb luck, we were able to workaround the crash by inserting a wait loop that forces the app to only retrieve the query after OpenGL says it is available. As this should not be required (OpenGL should do this implicitly, and more efficiently), the wait loop code is not compiled by default. Developers requiring this work around must explicitly add "-D FORCE_QUERY_RESULT_AVAILABLE_BEFORE_RETRIEVAL" to the compile options to include the wait loop."
This commit is contained in:
@@ -232,6 +232,19 @@ struct RetrieveQueriesCallback : public osg::Camera::DrawCallback
|
||||
osg::notify( osg::DEBUG_INFO ) <<
|
||||
"osgOQ: RQCB: Retrieving..." << std::endl;
|
||||
|
||||
#ifdef FORCE_QUERY_RESULT_AVAILABLE_BEFORE_RETRIEVAL
|
||||
|
||||
// Should not need to do this, but is required on some platforms to
|
||||
// work aroung issues in the device driver. For example, without this
|
||||
// code, we've seen crashes on 64-bit Mac/Linux NVIDIA systems doing
|
||||
// multithreaded, multipipe rendering (as in a CAVE).
|
||||
GLint ready( 0 );
|
||||
while( !ready )
|
||||
{
|
||||
ext->glGetQueryObjectiv( tr->_id, GL_QUERY_RESULT_AVAILABLE, &ready );
|
||||
};
|
||||
#endif
|
||||
|
||||
ext->glGetQueryObjectiv( tr->_id, GL_QUERY_RESULT, &(tr->_numPixels) );
|
||||
if (tr->_numPixels < 0)
|
||||
osg::notify( osg::WARN ) << "osgOQ: RQCB: " <<
|
||||
|
||||
Reference in New Issue
Block a user