Implement occlusion queries for AMD/ATI in the OpenGL driver

This commit is contained in:
kaetemi 2014-06-19 21:49:33 +02:00
parent a07d54e819
commit 0c3baeb4de
4 changed files with 81 additions and 13 deletions

View file

@ -2657,7 +2657,7 @@ void CDriverGL::checkTextureOn() const
bool CDriverGL::supportOcclusionQuery() const bool CDriverGL::supportOcclusionQuery() const
{ {
H_AUTO_OGL(CDriverGL_supportOcclusionQuery) H_AUTO_OGL(CDriverGL_supportOcclusionQuery)
return _Extensions.NVOcclusionQuery; return _Extensions.NVOcclusionQuery || _Extensions.ARBOcclusionQuery;
} }
// *************************************************************************** // ***************************************************************************
@ -2688,11 +2688,14 @@ bool CDriverGL::supportFrameBufferObject() const
IOcclusionQuery *CDriverGL::createOcclusionQuery() IOcclusionQuery *CDriverGL::createOcclusionQuery()
{ {
H_AUTO_OGL(CDriverGL_createOcclusionQuery) H_AUTO_OGL(CDriverGL_createOcclusionQuery)
nlassert(_Extensions.NVOcclusionQuery); nlassert(_Extensions.NVOcclusionQuery || _Extensions.ARBOcclusionQuery);
#ifndef USE_OPENGLES #ifndef USE_OPENGLES
GLuint id; GLuint id;
if (_Extensions.NVOcclusionQuery)
nglGenOcclusionQueriesNV(1, &id); nglGenOcclusionQueriesNV(1, &id);
else
nglGenQueriesARB(1, &id);
if (id == 0) return NULL; if (id == 0) return NULL;
COcclusionQueryGL *oqgl = new COcclusionQueryGL; COcclusionQueryGL *oqgl = new COcclusionQueryGL;
oqgl->Driver = this; oqgl->Driver = this;
@ -2719,7 +2722,10 @@ void CDriverGL::deleteOcclusionQuery(IOcclusionQuery *oq)
oqgl->Driver = NULL; oqgl->Driver = NULL;
nlassert(oqgl->ID != 0); nlassert(oqgl->ID != 0);
GLuint id = oqgl->ID; GLuint id = oqgl->ID;
if (_Extensions.NVOcclusionQuery)
nglDeleteOcclusionQueriesNV(1, &id); nglDeleteOcclusionQueriesNV(1, &id);
else
nglDeleteQueriesARB(1, &id);
_OcclusionQueryList.erase(oqgl->Iterator); _OcclusionQueryList.erase(oqgl->Iterator);
if (oqgl == _CurrentOcclusionQuery) if (oqgl == _CurrentOcclusionQuery)
{ {
@ -2738,7 +2744,10 @@ void COcclusionQueryGL::begin()
nlassert(Driver); nlassert(Driver);
nlassert(Driver->_CurrentOcclusionQuery == NULL); // only one query at a time nlassert(Driver->_CurrentOcclusionQuery == NULL); // only one query at a time
nlassert(ID); nlassert(ID);
if (Driver->_Extensions.NVOcclusionQuery)
nglBeginOcclusionQueryNV(ID); nglBeginOcclusionQueryNV(ID);
else
nglBeginQueryARB(GL_SAMPLES_PASSED, ID);
Driver->_CurrentOcclusionQuery = this; Driver->_CurrentOcclusionQuery = this;
OcclusionType = NotAvailable; OcclusionType = NotAvailable;
VisibleCount = 0; VisibleCount = 0;
@ -2754,7 +2763,10 @@ void COcclusionQueryGL::end()
nlassert(Driver); nlassert(Driver);
nlassert(Driver->_CurrentOcclusionQuery == this); // only one query at a time nlassert(Driver->_CurrentOcclusionQuery == this); // only one query at a time
nlassert(ID); nlassert(ID);
if (Driver->_Extensions.NVOcclusionQuery)
nglEndOcclusionQueryNV(); nglEndOcclusionQueryNV();
else
nglEndQueryARB(GL_SAMPLES_PASSED);
Driver->_CurrentOcclusionQuery = NULL; Driver->_CurrentOcclusionQuery = NULL;
#endif #endif
} }
@ -2769,6 +2781,8 @@ IOcclusionQuery::TOcclusionType COcclusionQueryGL::getOcclusionType()
nlassert(ID); nlassert(ID);
nlassert(Driver->_CurrentOcclusionQuery != this); // can't query result between a begin/end pair! nlassert(Driver->_CurrentOcclusionQuery != this); // can't query result between a begin/end pair!
if (OcclusionType == NotAvailable) if (OcclusionType == NotAvailable)
{
if (Driver->_Extensions.NVOcclusionQuery)
{ {
GLuint result; GLuint result;
// retrieve result // retrieve result
@ -2781,6 +2795,14 @@ IOcclusionQuery::TOcclusionType COcclusionQueryGL::getOcclusionType()
// Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation (Direct3D ...) // 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;
}
}
#endif #endif
return OcclusionType; return OcclusionType;
} }

View file

@ -1591,6 +1591,7 @@ private:
// @} // @}
// misc // misc
public: public:
friend class COcclusionQueryGL;
static GLenum NLCubeFaceToGLCubeFace[6]; static GLenum NLCubeFaceToGLCubeFace[6];
static CMaterial::CTexEnv _TexEnvReplace; static CMaterial::CTexEnv _TexEnvReplace;
// occlusion query // occlusion query

View file

@ -449,6 +449,16 @@ PFNGLENDOCCLUSIONQUERYNVPROC nglEndOcclusionQueryNV;
PFNGLGETOCCLUSIONQUERYIVNVPROC nglGetOcclusionQueryivNV; PFNGLGETOCCLUSIONQUERYIVNVPROC nglGetOcclusionQueryivNV;
PFNGLGETOCCLUSIONQUERYUIVNVPROC nglGetOcclusionQueryuivNV; 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 // GL_EXT_framebuffer_object
PFNGLISRENDERBUFFEREXTPROC nglIsRenderbufferEXT; PFNGLISRENDERBUFFEREXTPROC nglIsRenderbufferEXT;
PFNGLISFRAMEBUFFEREXTPROC nglIsFramebufferEXT; PFNGLISFRAMEBUFFEREXTPROC nglIsFramebufferEXT;
@ -1371,6 +1381,26 @@ static bool setupNVOcclusionQuery(const char *glext)
return true; 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) static bool setupNVTextureRectangle(const char *glext)
@ -1663,6 +1693,9 @@ void registerGlExtensions(CGlExtensions &ext)
// Check NV_occlusion_query // Check NV_occlusion_query
ext.NVOcclusionQuery = setupNVOcclusionQuery(glext); ext.NVOcclusionQuery = setupNVOcclusionQuery(glext);
// Check ARB_occlusion_query
ext.ARBOcclusionQuery = setupARBOcclusionQuery(glext);
// Check GL_NV_texture_rectangle // Check GL_NV_texture_rectangle
ext.NVTextureRectangle = setupNVTextureRectangle(glext); ext.NVTextureRectangle = setupNVTextureRectangle(glext);

View file

@ -58,6 +58,7 @@ struct CGlExtensions
bool EXTVertexShader; bool EXTVertexShader;
bool NVTextureShader; bool NVTextureShader;
bool NVOcclusionQuery; bool NVOcclusionQuery;
bool ARBOcclusionQuery;
bool NVTextureRectangle; bool NVTextureRectangle;
bool EXTTextureRectangle; bool EXTTextureRectangle;
bool ARBTextureRectangle; bool ARBTextureRectangle;
@ -178,6 +179,7 @@ public:
ARBTextureNonPowerOfTwo = false; ARBTextureNonPowerOfTwo = false;
ARBMultisample = false; ARBMultisample = false;
NVOcclusionQuery = false; NVOcclusionQuery = false;
ARBOcclusionQuery = false;
FrameBufferObject = false; FrameBufferObject = false;
FrameBufferBlit = false; FrameBufferBlit = false;
FrameBufferMultisample = false; FrameBufferMultisample = false;
@ -239,6 +241,7 @@ public:
result += EXTSecondaryColor ? "EXTSecondaryColor " : ""; result += EXTSecondaryColor ? "EXTSecondaryColor " : "";
result += EXTBlendColor ? "EXTBlendColor " : ""; result += EXTBlendColor ? "EXTBlendColor " : "";
result += NVOcclusionQuery ? "NVOcclusionQuery " : ""; result += NVOcclusionQuery ? "NVOcclusionQuery " : "";
result += ARBOcclusionQuery ? "ARBOcclusionQuery " : "";
result += NVStateVARWithoutFlush ? "NVStateVARWithoutFlush " : ""; result += NVStateVARWithoutFlush ? "NVStateVARWithoutFlush " : "";
result += ARBMultisample ? "ARBMultisample " : ""; result += ARBMultisample ? "ARBMultisample " : "";
result += NVXGPUMemoryInfo ? "NVXGPUMemoryInfo " : ""; result += NVXGPUMemoryInfo ? "NVXGPUMemoryInfo " : "";
@ -737,7 +740,16 @@ extern PFNGLENDOCCLUSIONQUERYNVPROC nglEndOcclusionQueryNV;
extern PFNGLGETOCCLUSIONQUERYIVNVPROC nglGetOcclusionQueryivNV; extern PFNGLGETOCCLUSIONQUERYIVNVPROC nglGetOcclusionQueryivNV;
extern PFNGLGETOCCLUSIONQUERYUIVNVPROC nglGetOcclusionQueryuivNV; 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 #ifdef NL_OS_WINDOWS