From 93e97c56cd1b15d1c2845ee65b4754fc30208c4b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Thu, 19 Jun 2014 21:49:33 +0200 Subject: [PATCH] Implement occlusion queries for AMD/ATI in the OpenGL driver --- .../src/3d/driver/opengl/driver_opengl.cpp | 46 ++++++++++++++----- code/nel/src/3d/driver/opengl/driver_opengl.h | 1 + .../driver/opengl/driver_opengl_extension.cpp | 33 +++++++++++++ .../driver/opengl/driver_opengl_extension.h | 14 +++++- 4 files changed, 81 insertions(+), 13 deletions(-) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 9ec29f0ba..3d6031caf 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -2657,7 +2657,7 @@ void CDriverGL::checkTextureOn() const bool CDriverGL::supportOcclusionQuery() const { H_AUTO_OGL(CDriverGL_supportOcclusionQuery) - return _Extensions.NVOcclusionQuery; + return _Extensions.NVOcclusionQuery || _Extensions.ARBOcclusionQuery; } // *************************************************************************** @@ -2688,11 +2688,14 @@ bool CDriverGL::supportFrameBufferObject() const IOcclusionQuery *CDriverGL::createOcclusionQuery() { H_AUTO_OGL(CDriverGL_createOcclusionQuery) - nlassert(_Extensions.NVOcclusionQuery); + nlassert(_Extensions.NVOcclusionQuery || _Extensions.ARBOcclusionQuery); #ifndef USE_OPENGLES GLuint id; - nglGenOcclusionQueriesNV(1, &id); + if (_Extensions.NVOcclusionQuery) + nglGenOcclusionQueriesNV(1, &id); + else + nglGenQueriesARB(1, &id); if (id == 0) return NULL; COcclusionQueryGL *oqgl = new COcclusionQueryGL; oqgl->Driver = this; @@ -2719,7 +2722,10 @@ void CDriverGL::deleteOcclusionQuery(IOcclusionQuery *oq) oqgl->Driver = NULL; nlassert(oqgl->ID != 0); GLuint id = oqgl->ID; - nglDeleteOcclusionQueriesNV(1, &id); + if (_Extensions.NVOcclusionQuery) + nglDeleteOcclusionQueriesNV(1, &id); + else + nglDeleteQueriesARB(1, &id); _OcclusionQueryList.erase(oqgl->Iterator); if (oqgl == _CurrentOcclusionQuery) { @@ -2738,7 +2744,10 @@ void COcclusionQueryGL::begin() nlassert(Driver); nlassert(Driver->_CurrentOcclusionQuery == NULL); // only one query at a time nlassert(ID); - nglBeginOcclusionQueryNV(ID); + if (Driver->_Extensions.NVOcclusionQuery) + nglBeginOcclusionQueryNV(ID); + else + nglBeginQueryARB(GL_SAMPLES_PASSED, ID); Driver->_CurrentOcclusionQuery = this; OcclusionType = NotAvailable; VisibleCount = 0; @@ -2754,7 +2763,10 @@ void COcclusionQueryGL::end() nlassert(Driver); nlassert(Driver->_CurrentOcclusionQuery == this); // only one query at a time nlassert(ID); - nglEndOcclusionQueryNV(); + if (Driver->_Extensions.NVOcclusionQuery) + nglEndOcclusionQueryNV(); + else + nglEndQueryARB(GL_SAMPLES_PASSED); Driver->_CurrentOcclusionQuery = NULL; #endif } @@ -2770,15 +2782,25 @@ IOcclusionQuery::TOcclusionType COcclusionQueryGL::getOcclusionType() nlassert(Driver->_CurrentOcclusionQuery != this); // can't query result between a begin/end pair! if (OcclusionType == NotAvailable) { - GLuint result; - // retrieve result - nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_AVAILABLE_NV, &result); - if (result != GL_FALSE) + if (Driver->_Extensions.NVOcclusionQuery) { - nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_NV, &result); + GLuint result; + // retrieve result + nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_AVAILABLE_NV, &result); + if (result != GL_FALSE) + { + nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_NV, &result); + OcclusionType = result != 0 ? NotOccluded : Occluded; + VisibleCount = (uint) result; + // Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation (Direct3D ...) + } + } + else + { + GLuint result; + nglGetQueryObjectuivARB(ID, GL_QUERY_RESULT, &result); OcclusionType = result != 0 ? NotOccluded : Occluded; VisibleCount = (uint) result; - // Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation (Direct3D ...) } } #endif diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 6217ea850..241b3bb95 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1591,6 +1591,7 @@ private: // @} // misc public: + friend class COcclusionQueryGL; static GLenum NLCubeFaceToGLCubeFace[6]; static CMaterial::CTexEnv _TexEnvReplace; // occlusion query diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp index f24855ea8..515d553aa 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.cpp @@ -449,6 +449,16 @@ PFNGLENDOCCLUSIONQUERYNVPROC nglEndOcclusionQueryNV; PFNGLGETOCCLUSIONQUERYIVNVPROC nglGetOcclusionQueryivNV; PFNGLGETOCCLUSIONQUERYUIVNVPROC nglGetOcclusionQueryuivNV; +// ARB_occlusion_query +PFNGLGENQUERIESPROC nglGenQueriesARB; +PFNGLDELETEQUERIESPROC nglDeleteQueriesARB; +PFNGLISQUERYPROC nglIsQueryARB; +PFNGLBEGINQUERYPROC nglBeginQueryARB; +PFNGLENDQUERYPROC nglEndQueryARB; +PFNGLGETQUERYIVPROC nglGetQueryivARB; +PFNGLGETQUERYOBJECTIVPROC nglGetQueryObjectivARB; +PFNGLGETQUERYOBJECTUIVPROC nglGetQueryObjectuivARB; + // GL_EXT_framebuffer_object PFNGLISRENDERBUFFEREXTPROC nglIsRenderbufferEXT; PFNGLISFRAMEBUFFEREXTPROC nglIsFramebufferEXT; @@ -1371,6 +1381,26 @@ static bool setupNVOcclusionQuery(const char *glext) return true; } +// *************************************************************************** +static bool setupARBOcclusionQuery(const char *glext) +{ + H_AUTO_OGL(setupARBOcclusionQuery); + CHECK_EXT("ARB_occlusion_query"); + +#ifndef USE_OPENGLES + CHECK_ADDRESS(PFNGLGENQUERIESPROC, glGenQueriesARB); + CHECK_ADDRESS(PFNGLDELETEQUERIESPROC, glDeleteQueriesARB); + CHECK_ADDRESS(PFNGLISQUERYPROC, glIsQueryARB); + CHECK_ADDRESS(PFNGLBEGINQUERYPROC, glBeginQueryARB); + CHECK_ADDRESS(PFNGLENDQUERYPROC, glEndQueryARB); + CHECK_ADDRESS(PFNGLGETQUERYIVPROC, glGetQueryivARB); + CHECK_ADDRESS(PFNGLGETQUERYOBJECTIVPROC, glGetQueryObjectivARB); + CHECK_ADDRESS(PFNGLGETQUERYOBJECTUIVPROC, glGetQueryObjectuivARB); +#endif + + return true; +} + // *************************************************************************** static bool setupNVTextureRectangle(const char *glext) @@ -1663,6 +1693,9 @@ void registerGlExtensions(CGlExtensions &ext) // Check NV_occlusion_query ext.NVOcclusionQuery = setupNVOcclusionQuery(glext); + // Check ARB_occlusion_query + ext.ARBOcclusionQuery = setupARBOcclusionQuery(glext); + // Check GL_NV_texture_rectangle ext.NVTextureRectangle = setupNVTextureRectangle(glext); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h index 83d2d529f..07599366c 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_extension.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl_extension.h @@ -58,6 +58,7 @@ struct CGlExtensions bool EXTVertexShader; bool NVTextureShader; bool NVOcclusionQuery; + bool ARBOcclusionQuery; bool NVTextureRectangle; bool EXTTextureRectangle; bool ARBTextureRectangle; @@ -178,6 +179,7 @@ public: ARBTextureNonPowerOfTwo = false; ARBMultisample = false; NVOcclusionQuery = false; + ARBOcclusionQuery = false; FrameBufferObject = false; FrameBufferBlit = false; FrameBufferMultisample = false; @@ -239,6 +241,7 @@ public: result += EXTSecondaryColor ? "EXTSecondaryColor " : ""; result += EXTBlendColor ? "EXTBlendColor " : ""; result += NVOcclusionQuery ? "NVOcclusionQuery " : ""; + result += ARBOcclusionQuery ? "ARBOcclusionQuery " : ""; result += NVStateVARWithoutFlush ? "NVStateVARWithoutFlush " : ""; result += ARBMultisample ? "ARBMultisample " : ""; result += NVXGPUMemoryInfo ? "NVXGPUMemoryInfo " : ""; @@ -737,7 +740,16 @@ extern PFNGLENDOCCLUSIONQUERYNVPROC nglEndOcclusionQueryNV; extern PFNGLGETOCCLUSIONQUERYIVNVPROC nglGetOcclusionQueryivNV; extern PFNGLGETOCCLUSIONQUERYUIVNVPROC nglGetOcclusionQueryuivNV; - +// ARB_occlusion_query +//================================== +extern PFNGLGENQUERIESPROC nglGenQueriesARB; +extern PFNGLDELETEQUERIESPROC nglDeleteQueriesARB; +extern PFNGLISQUERYPROC nglIsQueryARB; +extern PFNGLBEGINQUERYPROC nglBeginQueryARB; +extern PFNGLENDQUERYPROC nglEndQueryARB; +extern PFNGLGETQUERYIVPROC nglGetQueryivARB; +extern PFNGLGETQUERYOBJECTIVPROC nglGetQueryObjectivARB; +extern PFNGLGETQUERYOBJECTUIVPROC nglGetQueryObjectuivARB; #ifdef NL_OS_WINDOWS