Merge pull request #1597 from JeffProgrammer/glextlookup

OpenGL Extension Caching
This commit is contained in:
Areloch 2016-05-24 01:03:01 -05:00
commit 5ee1fb3917
12 changed files with 60 additions and 59 deletions

View file

@ -56,54 +56,32 @@ void GFXGLCardProfiler::setupCardCapabilities()
{ {
GLint maxTexSize; GLint maxTexSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
const char* versionString = reinterpret_cast<const char*>(glGetString(GL_VERSION));
F32 glVersion = dAtof(versionString);
// OpenGL doesn't have separate maximum width/height. // OpenGL doesn't have separate maximum width/height.
setCapability("maxTextureWidth", maxTexSize); setCapability("maxTextureWidth", maxTexSize);
setCapability("maxTextureHeight", maxTexSize); setCapability("maxTextureHeight", maxTexSize);
setCapability("maxTextureSize", maxTexSize); setCapability("maxTextureSize", maxTexSize);
// If extensions haven't been inited, we're in trouble here.
bool suppVBO = (gglHasExtension(ARB_vertex_buffer_object) || glVersion >= 1.499f);
setCapability("GL::suppVertexBufferObject", suppVBO);
// check if render to texture supported is available
bool suppRTT = gglHasExtension(EXT_framebuffer_object);
setCapability("GL::suppRenderTexture", suppRTT);
bool suppBlit = gglHasExtension(EXT_framebuffer_blit);
setCapability("GL::suppRTBlit", suppBlit);
bool suppFloatTex = gglHasExtension(ARB_texture_float);
setCapability("GL::suppFloatTexture", suppFloatTex);
// Check for anisotropic filtering support. // Check for anisotropic filtering support.
bool suppAnisotropic = gglHasExtension( EXT_texture_filter_anisotropic ); setCapability("GL_EXT_texture_filter_anisotropic", gglHasExtension(EXT_texture_filter_anisotropic));
setCapability( "GL::suppAnisotropic", suppAnisotropic );
// check to see if we have the fragment shader extension or the gl version is high enough for glsl to be core // Check for buffer storage
// also check to see if the language version is high enough setCapability("GL_ARB_buffer_storage", gglHasExtension(ARB_buffer_storage));
F32 glslVersion = dAtof(reinterpret_cast<const char*>(glGetString( GL_SHADING_LANGUAGE_VERSION)));
bool suppSPU = (gglHasExtension(ARB_fragment_shader) || glVersion >= 1.999f) && glslVersion >= 1.0999; // Check for shader model 5.0
setCapability("GL::suppFragmentShader", suppSPU); setCapability("GL_ARB_gpu_shader5", gglHasExtension(ARB_gpu_shader5));
bool suppAppleFence = gglHasExtension(APPLE_fence); // Check for texture storage
setCapability("GL::APPLE::suppFence", suppAppleFence); setCapability("GL_ARB_texture_storage", gglHasExtension(ARB_texture_storage));
// When enabled, call glGenerateMipmapEXT() to generate mipmaps instead of relying on GL_GENERATE_MIPMAP // Check for sampler objects
setCapability("GL::Workaround::needsExplicitGenerateMipmap", false); setCapability("GL_ARB_sampler_objects", gglHasExtension(ARB_sampler_objects));
// When enabled, binds and unbinds a texture target before doing the depth buffer copy. Failure to do
// so will cause a hard freeze on Mac OS 10.4 with a Radeon X1600 // Check for copy image support
setCapability("GL::Workaround::X1600DepthBufferCopy", false); setCapability("GL_ARB_copy_image", gglHasExtension(ARB_copy_image));
// When enabled, does not copy the last column and row of the depth buffer in a depth buffer copy. Failure
// to do so will cause a kernel panic on Mac OS 10.5(.1) with a Radeon HD 2600 (fixed in 10.5.2) // Check for vertex attrib binding
setCapability("GL::Workaround::HD2600DepthBufferCopy", false); setCapability("GL_ARB_vertex_attrib_binding", gglHasExtension(ARB_vertex_attrib_binding));
// Certain Intel drivers have a divide by 0 crash if mipmaps are specified with
// glTexSubImage2D.
setCapability("GL::Workaround::noManualMips", false);
} }
bool GFXGLCardProfiler::_queryCardCap(const String& query, U32& foundResult) bool GFXGLCardProfiler::_queryCardCap(const String& query, U32& foundResult)

View file

@ -158,7 +158,7 @@ public:
const U32 cSizeInMB = 10; const U32 cSizeInMB = 10;
mBufferSize = (cSizeInMB << 20); mBufferSize = (cSizeInMB << 20);
if( gglHasExtension(ARB_buffer_storage) ) if( GFXGL->mCapabilities.bufferStorage )
{ {
const GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; const GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
glBufferStorage(mBinding, mBufferSize, NULL, flags); glBufferStorage(mBinding, mBufferSize, NULL, flags);
@ -198,7 +198,7 @@ public:
outOffset = mBufferFreePos; outOffset = mBufferFreePos;
if( gglHasExtension(ARB_buffer_storage) ) if( GFXGL->mCapabilities.bufferStorage )
{ {
outPtr = (U8*)(mBufferPtr) + mBufferFreePos; outPtr = (U8*)(mBufferPtr) + mBufferFreePos;
} }
@ -227,7 +227,7 @@ public:
void unlock() void unlock()
{ {
if( gglHasExtension(ARB_buffer_storage) ) if( GFXGL->mCapabilities.bufferStorage )
{ {
return; return;
} }

View file

@ -140,10 +140,18 @@ void GFXGLDevice::initGLState()
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// [JTH 5/6/2016] GLSL 1.50 is really SM 4.0
// Setting mPixelShaderVersion to 3.0 will allow Advanced Lighting to run. // Setting mPixelShaderVersion to 3.0 will allow Advanced Lighting to run.
mPixelShaderVersion = 3.0; mPixelShaderVersion = 3.0;
mSupportsAnisotropic = mCardProfiler->queryProfile( "GL::suppAnisotropic" ); // Set capability extensions.
mCapabilities.anisotropicFiltering = mCardProfiler->queryProfile("GL_EXT_texture_filter_anisotropic");
mCapabilities.bufferStorage = mCardProfiler->queryProfile("GL_ARB_buffer_storage");
mCapabilities.shaderModel5 = mCardProfiler->queryProfile("GL_ARB_gpu_shader5");
mCapabilities.textureStorage = mCardProfiler->queryProfile("GL_ARB_texture_storage");
mCapabilities.samplerObjects = mCardProfiler->queryProfile("GL_ARB_sampler_objects");
mCapabilities.copyImage = mCardProfiler->queryProfile("GL_ARB_copy_image");
mCapabilities.vertexAttributeBinding = mCardProfiler->queryProfile("GL_ARB_vertex_attrib_binding");
String vendorStr = (const char*)glGetString( GL_VENDOR ); String vendorStr = (const char*)glGetString( GL_VENDOR );
if( vendorStr.find("NVIDIA", 0, String::NoCase | String::Left) != String::NPos) if( vendorStr.find("NVIDIA", 0, String::NoCase | String::Left) != String::NPos)
@ -216,6 +224,9 @@ GFXGLDevice::GFXGLDevice(U32 adapterIndex) :
mCurrentVB_Divisor[i] = 0; mCurrentVB_Divisor[i] = 0;
} }
// Initiailize capabilities to false.
memset(&mCapabilities, 0, sizeof(GLCapabilities));
loadGLCore(); loadGLCore();
GFXGLEnumTranslate::init(); GFXGLEnumTranslate::init();

View file

@ -45,6 +45,18 @@ class GFXGLVertexDecl;
class GFXGLDevice : public GFXDevice class GFXGLDevice : public GFXDevice
{ {
public: public:
struct GLCapabilities
{
bool anisotropicFiltering;
bool bufferStorage;
bool shaderModel5;
bool textureStorage;
bool samplerObjects;
bool copyImage;
bool vertexAttributeBinding;
};
GLCapabilities mCapabilities;
void zombify(); void zombify();
void resurrect(); void resurrect();
GFXGLDevice(U32 adapterIndex); GFXGLDevice(U32 adapterIndex);

View file

@ -23,6 +23,7 @@
#include "platform/platform.h" #include "platform/platform.h"
#include "gfx/gl/gfxGLShader.h" #include "gfx/gl/gfxGLShader.h"
#include "gfx/gl/gfxGLVertexAttribLocation.h" #include "gfx/gl/gfxGLVertexAttribLocation.h"
#include "gfx/gl/gfxGLDevice.h"
#include "core/frameAllocator.h" #include "core/frameAllocator.h"
#include "core/stream/fileStream.h" #include "core/stream/fileStream.h"
@ -956,7 +957,7 @@ bool GFXGLShader::_loadShaderFromStream( GLuint shader,
buffers.push_back( dStrdup( versionDecl ) ); buffers.push_back( dStrdup( versionDecl ) );
lengths.push_back( dStrlen( versionDecl ) ); lengths.push_back( dStrlen( versionDecl ) );
if(gglHasExtension(ARB_gpu_shader5)) if(GFXGL->mCapabilities.shaderModel5)
{ {
const char *extension = "#extension GL_ARB_gpu_shader5 : enable\r\n"; const char *extension = "#extension GL_ARB_gpu_shader5 : enable\r\n";
buffers.push_back( dStrdup( extension ) ); buffers.push_back( dStrdup( extension ) );

View file

@ -39,7 +39,7 @@ GFXGLStateBlock::GFXGLStateBlock(const GFXStateBlockDesc& desc) :
mDesc(desc), mDesc(desc),
mCachedHashValue(desc.getHashValue()) mCachedHashValue(desc.getHashValue())
{ {
if( !gglHasExtension(ARB_sampler_objects) ) if( !GFXGL->mCapabilities.samplerObjects )
return; return;
static Map<GFXSamplerStateDesc, U32> mSamplersMap; static Map<GFXSamplerStateDesc, U32> mSamplersMap;
@ -165,7 +165,7 @@ void GFXGLStateBlock::activate(const GFXGLStateBlock* oldState)
#undef CHECK_TOGGLE_STATE #undef CHECK_TOGGLE_STATE
//sampler objects //sampler objects
if( gglHasExtension(ARB_sampler_objects) ) if( GFXGL->mCapabilities.samplerObjects )
{ {
for (U32 i = 0; i < getMin(getOwningDevice()->getNumSamplers(), (U32) TEXTURE_STAGE_COUNT); i++) for (U32 i = 0; i < getMin(getOwningDevice()->getNumSamplers(), (U32) TEXTURE_STAGE_COUNT); i++)
{ {

View file

@ -146,7 +146,7 @@ void GFXGLTextureManager::innerCreateTexture( GFXGLTextureObject *retTex,
glTexParameteri(binding, GL_TEXTURE_MAX_LEVEL, retTex->mMipLevels-1 ); glTexParameteri(binding, GL_TEXTURE_MAX_LEVEL, retTex->mMipLevels-1 );
if( gglHasExtension(ARB_texture_storage) ) if( GFXGL->mCapabilities.textureStorage )
{ {
if(binding == GL_TEXTURE_2D) if(binding == GL_TEXTURE_2D)
glTexStorage2D( retTex->getBinding(), retTex->mMipLevels, GFXGLTextureInternalFormat[format], width, height ); glTexStorage2D( retTex->getBinding(), retTex->mMipLevels, GFXGLTextureInternalFormat[format], width, height );
@ -304,8 +304,7 @@ bool GFXGLTextureManager::_loadTexture(GFXTextureObject *aTexture, DDSFile *dds)
glBindTexture(texture->getBinding(), texture->getHandle()); glBindTexture(texture->getBinding(), texture->getHandle());
texture->mFormat = dds->mFormat; texture->mFormat = dds->mFormat;
U32 numMips = dds->mSurfaces[0]->mMips.size(); U32 numMips = dds->mSurfaces[0]->mMips.size();
if(GFX->getCardProfiler()->queryProfile("GL::Workaround::noManualMips"))
numMips = 1;
for(U32 i = 0; i < numMips; i++) for(U32 i = 0; i < numMips; i++)
{ {
if(isCompressedFormat(dds->mFormat)) if(isCompressedFormat(dds->mFormat))

View file

@ -211,7 +211,7 @@ void GFXGLTextureObject::bind(U32 textureUnit)
glBindTexture(mBinding, mHandle); glBindTexture(mBinding, mHandle);
GFXGL->getOpenglCache()->setCacheBindedTex(textureUnit, mBinding, mHandle); GFXGL->getOpenglCache()->setCacheBindedTex(textureUnit, mBinding, mHandle);
if( gglHasExtension(ARB_sampler_objects) ) if(GFXGL->mCapabilities.samplerObjects)
return; return;
GFXGLStateBlockRef sb = mGLDevice->getCurrentStateBlock(); GFXGLStateBlockRef sb = mGLDevice->getCurrentStateBlock();
@ -298,8 +298,8 @@ void GFXGLTextureObject::reloadFromCache()
else if(mBinding == GL_TEXTURE_1D) else if(mBinding == GL_TEXTURE_1D)
glTexSubImage1D(mBinding, 0, 0, (mTextureSize.x > 1 ? mTextureSize.x : mTextureSize.y), GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], mZombieCache); glTexSubImage1D(mBinding, 0, 0, (mTextureSize.x > 1 ? mTextureSize.x : mTextureSize.y), GFXGLTextureFormat[mFormat], GFXGLTextureType[mFormat], mZombieCache);
if(GFX->getCardProfiler()->queryProfile("GL::Workaround::needsExplicitGenerateMipmap") && mMipLevels != 1) if(mMipLevels != 1)
glGenerateMipmapEXT(mBinding); glGenerateMipmap(mBinding);
delete[] mZombieCache; delete[] mZombieCache;
mZombieCache = NULL; mZombieCache = NULL;

View file

@ -410,7 +410,7 @@ void GFXGLTextureTarget::resolveTo(GFXTextureObject* obj)
AssertFatal(dynamic_cast<GFXGLTextureObject*>(obj), "GFXGLTextureTarget::resolveTo - Incorrect type of texture, expected a GFXGLTextureObject"); AssertFatal(dynamic_cast<GFXGLTextureObject*>(obj), "GFXGLTextureTarget::resolveTo - Incorrect type of texture, expected a GFXGLTextureObject");
GFXGLTextureObject* glTexture = static_cast<GFXGLTextureObject*>(obj); GFXGLTextureObject* glTexture = static_cast<GFXGLTextureObject*>(obj);
if( gglHasExtension(ARB_copy_image) && mTargets[Color0]->isCompatible(glTexture) ) if( GFXGL->mCapabilities.copyImage && mTargets[Color0]->isCompatible(glTexture) )
{ {
GLenum binding = mTargets[Color0]->getBinding(); GLenum binding = mTargets[Color0]->getBinding();
binding = (binding >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && binding <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) ? GL_TEXTURE_CUBE_MAP : binding; binding = (binding >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && binding <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) ? GL_TEXTURE_CUBE_MAP : binding;

View file

@ -78,7 +78,7 @@ void GFXGLVertexBuffer::lock( U32 vertexStart, U32 vertexEnd, void **vertexPtr )
if( mBufferType == GFXBufferTypeVolatile ) if( mBufferType == GFXBufferTypeVolatile )
{ {
AssertFatal(vertexStart == 0, ""); AssertFatal(vertexStart == 0, "");
if( gglHasExtension(ARB_vertex_attrib_binding) ) if( GFXGL->mCapabilities.vertexAttributeBinding )
{ {
getCircularVolatileVertexBuffer()->lock( mNumVerts * mVertexSize, 0, mBufferOffset, *vertexPtr ); getCircularVolatileVertexBuffer()->lock( mNumVerts * mVertexSize, 0, mBufferOffset, *vertexPtr );
} }
@ -136,7 +136,7 @@ void GFXGLVertexBuffer::prepare()
void GFXGLVertexBuffer::prepare(U32 stream, U32 divisor) void GFXGLVertexBuffer::prepare(U32 stream, U32 divisor)
{ {
if( gglHasExtension(ARB_vertex_attrib_binding) ) if( GFXGL->mCapabilities.vertexAttributeBinding )
{ {
glBindVertexBuffer( stream, mBuffer, mBufferOffset, mVertexSize ); glBindVertexBuffer( stream, mBuffer, mBufferOffset, mVertexSize );
glVertexBindingDivisor( stream, divisor ); glVertexBindingDivisor( stream, divisor );

View file

@ -15,7 +15,7 @@ void GFXGLVertexDecl::init(const GFXVertexFormat *format)
void GFXGLVertexDecl::prepareVertexFormat() const void GFXGLVertexDecl::prepareVertexFormat() const
{ {
AssertFatal(mFormat, "GFXGLVertexDecl - Not inited"); AssertFatal(mFormat, "GFXGLVertexDecl - Not inited");
if( gglHasExtension(ARB_vertex_attrib_binding) ) if( GFXGL->mCapabilities.vertexAttributeBinding )
{ {
for ( U32 i=0; i < glVerticesFormat.size(); i++ ) for ( U32 i=0; i < glVerticesFormat.size(); i++ )
{ {
@ -36,7 +36,7 @@ void GFXGLVertexDecl::prepareBuffer_old(U32 stream, GLint mBuffer, GLint mDiviso
PROFILE_SCOPE(GFXGLVertexDecl_prepare); PROFILE_SCOPE(GFXGLVertexDecl_prepare);
AssertFatal(mFormat, "GFXGLVertexDecl - Not inited"); AssertFatal(mFormat, "GFXGLVertexDecl - Not inited");
if( gglHasExtension(ARB_vertex_attrib_binding) ) if( GFXGL->mCapabilities.vertexAttributeBinding )
return; return;
// Bind the buffer... // Bind the buffer...

View file

@ -78,7 +78,7 @@ void GFXGLWindowTarget::resolveTo(GFXTextureObject* obj)
AssertFatal(dynamic_cast<GFXGLTextureObject*>(obj), "GFXGLTextureTarget::resolveTo - Incorrect type of texture, expected a GFXGLTextureObject"); AssertFatal(dynamic_cast<GFXGLTextureObject*>(obj), "GFXGLTextureTarget::resolveTo - Incorrect type of texture, expected a GFXGLTextureObject");
GFXGLTextureObject* glTexture = static_cast<GFXGLTextureObject*>(obj); GFXGLTextureObject* glTexture = static_cast<GFXGLTextureObject*>(obj);
if( gglHasExtension(ARB_copy_image) ) if( GFXGL->mCapabilities.copyImage )
{ {
if(mBackBufferColorTex.getWidth() == glTexture->getWidth() if(mBackBufferColorTex.getWidth() == glTexture->getWidth()
&& mBackBufferColorTex.getHeight() == glTexture->getHeight() && mBackBufferColorTex.getHeight() == glTexture->getHeight()