diff --git a/Engine/source/gfx/gl/gfxGLCardProfiler.cpp b/Engine/source/gfx/gl/gfxGLCardProfiler.cpp index 46119253b..760a0d5ed 100644 --- a/Engine/source/gfx/gl/gfxGLCardProfiler.cpp +++ b/Engine/source/gfx/gl/gfxGLCardProfiler.cpp @@ -56,54 +56,32 @@ void GFXGLCardProfiler::setupCardCapabilities() { GLint maxTexSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); - - const char* versionString = reinterpret_cast(glGetString(GL_VERSION)); - F32 glVersion = dAtof(versionString); // OpenGL doesn't have separate maximum width/height. setCapability("maxTextureWidth", maxTexSize); setCapability("maxTextureHeight", 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. - bool suppAnisotropic = gglHasExtension( EXT_texture_filter_anisotropic ); - setCapability( "GL::suppAnisotropic", suppAnisotropic ); + setCapability("GL_EXT_texture_filter_anisotropic", gglHasExtension(EXT_texture_filter_anisotropic)); - // check to see if we have the fragment shader extension or the gl version is high enough for glsl to be core - // also check to see if the language version is high enough - F32 glslVersion = dAtof(reinterpret_cast(glGetString( GL_SHADING_LANGUAGE_VERSION))); - bool suppSPU = (gglHasExtension(ARB_fragment_shader) || glVersion >= 1.999f) && glslVersion >= 1.0999; - setCapability("GL::suppFragmentShader", suppSPU); - - bool suppAppleFence = gglHasExtension(APPLE_fence); - setCapability("GL::APPLE::suppFence", suppAppleFence); - - // When enabled, call glGenerateMipmapEXT() to generate mipmaps instead of relying on GL_GENERATE_MIPMAP - setCapability("GL::Workaround::needsExplicitGenerateMipmap", false); - // 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 - setCapability("GL::Workaround::X1600DepthBufferCopy", false); - // 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) - setCapability("GL::Workaround::HD2600DepthBufferCopy", false); - - // Certain Intel drivers have a divide by 0 crash if mipmaps are specified with - // glTexSubImage2D. - setCapability("GL::Workaround::noManualMips", false); + // Check for buffer storage + setCapability("GL_ARB_buffer_storage", gglHasExtension(ARB_buffer_storage)); + + // Check for shader model 5.0 + setCapability("GL_ARB_gpu_shader5", gglHasExtension(ARB_gpu_shader5)); + + // Check for texture storage + setCapability("GL_ARB_texture_storage", gglHasExtension(ARB_texture_storage)); + + // Check for sampler objects + setCapability("GL_ARB_sampler_objects", gglHasExtension(ARB_sampler_objects)); + + // Check for copy image support + setCapability("GL_ARB_copy_image", gglHasExtension(ARB_copy_image)); + + // Check for vertex attrib binding + setCapability("GL_ARB_vertex_attrib_binding", gglHasExtension(ARB_vertex_attrib_binding)); } bool GFXGLCardProfiler::_queryCardCap(const String& query, U32& foundResult) diff --git a/Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h b/Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h index 6d7d0e4b1..6047255eb 100644 --- a/Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h +++ b/Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h @@ -158,7 +158,7 @@ public: const U32 cSizeInMB = 10; 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; glBufferStorage(mBinding, mBufferSize, NULL, flags); @@ -198,7 +198,7 @@ public: outOffset = mBufferFreePos; - if( gglHasExtension(ARB_buffer_storage) ) + if( GFXGL->mCapabilities.bufferStorage ) { outPtr = (U8*)(mBufferPtr) + mBufferFreePos; } @@ -227,7 +227,7 @@ public: void unlock() { - if( gglHasExtension(ARB_buffer_storage) ) + if( GFXGL->mCapabilities.bufferStorage ) { return; } diff --git a/Engine/source/gfx/gl/gfxGLDevice.cpp b/Engine/source/gfx/gl/gfxGLDevice.cpp index f59e8ac92..b5881dd2a 100644 --- a/Engine/source/gfx/gl/gfxGLDevice.cpp +++ b/Engine/source/gfx/gl/gfxGLDevice.cpp @@ -140,10 +140,18 @@ void GFXGLDevice::initGLState() 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. 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 ); if( vendorStr.find("NVIDIA", 0, String::NoCase | String::Left) != String::NPos) @@ -216,6 +224,9 @@ GFXGLDevice::GFXGLDevice(U32 adapterIndex) : mCurrentVB_Divisor[i] = 0; } + // Initiailize capabilities to false. + memset(&mCapabilities, 0, sizeof(GLCapabilities)); + loadGLCore(); GFXGLEnumTranslate::init(); diff --git a/Engine/source/gfx/gl/gfxGLDevice.h b/Engine/source/gfx/gl/gfxGLDevice.h index 902bfb3f6..fc37d3220 100644 --- a/Engine/source/gfx/gl/gfxGLDevice.h +++ b/Engine/source/gfx/gl/gfxGLDevice.h @@ -45,6 +45,18 @@ class GFXGLVertexDecl; class GFXGLDevice : public GFXDevice { public: + struct GLCapabilities + { + bool anisotropicFiltering; + bool bufferStorage; + bool shaderModel5; + bool textureStorage; + bool samplerObjects; + bool copyImage; + bool vertexAttributeBinding; + }; + GLCapabilities mCapabilities; + void zombify(); void resurrect(); GFXGLDevice(U32 adapterIndex); diff --git a/Engine/source/gfx/gl/gfxGLShader.cpp b/Engine/source/gfx/gl/gfxGLShader.cpp index 2e63c61fe..50578cb5b 100644 --- a/Engine/source/gfx/gl/gfxGLShader.cpp +++ b/Engine/source/gfx/gl/gfxGLShader.cpp @@ -23,6 +23,7 @@ #include "platform/platform.h" #include "gfx/gl/gfxGLShader.h" #include "gfx/gl/gfxGLVertexAttribLocation.h" +#include "gfx/gl/gfxGLDevice.h" #include "core/frameAllocator.h" #include "core/stream/fileStream.h" @@ -956,7 +957,7 @@ bool GFXGLShader::_loadShaderFromStream( GLuint shader, buffers.push_back( dStrdup( 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"; buffers.push_back( dStrdup( extension ) ); diff --git a/Engine/source/gfx/gl/gfxGLStateBlock.cpp b/Engine/source/gfx/gl/gfxGLStateBlock.cpp index 34f816dc9..1d23e4b2c 100644 --- a/Engine/source/gfx/gl/gfxGLStateBlock.cpp +++ b/Engine/source/gfx/gl/gfxGLStateBlock.cpp @@ -39,7 +39,7 @@ GFXGLStateBlock::GFXGLStateBlock(const GFXStateBlockDesc& desc) : mDesc(desc), mCachedHashValue(desc.getHashValue()) { - if( !gglHasExtension(ARB_sampler_objects) ) + if( !GFXGL->mCapabilities.samplerObjects ) return; static Map mSamplersMap; @@ -165,7 +165,7 @@ void GFXGLStateBlock::activate(const GFXGLStateBlock* oldState) #undef CHECK_TOGGLE_STATE //sampler objects - if( gglHasExtension(ARB_sampler_objects) ) + if( GFXGL->mCapabilities.samplerObjects ) { for (U32 i = 0; i < getMin(getOwningDevice()->getNumSamplers(), (U32) TEXTURE_STAGE_COUNT); i++) { diff --git a/Engine/source/gfx/gl/gfxGLTextureManager.cpp b/Engine/source/gfx/gl/gfxGLTextureManager.cpp index 70a5e4303..c0d43087a 100644 --- a/Engine/source/gfx/gl/gfxGLTextureManager.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureManager.cpp @@ -146,7 +146,7 @@ void GFXGLTextureManager::innerCreateTexture( GFXGLTextureObject *retTex, glTexParameteri(binding, GL_TEXTURE_MAX_LEVEL, retTex->mMipLevels-1 ); - if( gglHasExtension(ARB_texture_storage) ) + if( GFXGL->mCapabilities.textureStorage ) { if(binding == GL_TEXTURE_2D) 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()); texture->mFormat = dds->mFormat; U32 numMips = dds->mSurfaces[0]->mMips.size(); - if(GFX->getCardProfiler()->queryProfile("GL::Workaround::noManualMips")) - numMips = 1; + for(U32 i = 0; i < numMips; i++) { if(isCompressedFormat(dds->mFormat)) diff --git a/Engine/source/gfx/gl/gfxGLTextureObject.cpp b/Engine/source/gfx/gl/gfxGLTextureObject.cpp index ed229e5d9..219343b5f 100644 --- a/Engine/source/gfx/gl/gfxGLTextureObject.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureObject.cpp @@ -211,7 +211,7 @@ void GFXGLTextureObject::bind(U32 textureUnit) glBindTexture(mBinding, mHandle); GFXGL->getOpenglCache()->setCacheBindedTex(textureUnit, mBinding, mHandle); - if( gglHasExtension(ARB_sampler_objects) ) + if(GFXGL->mCapabilities.samplerObjects) return; GFXGLStateBlockRef sb = mGLDevice->getCurrentStateBlock(); @@ -298,8 +298,8 @@ void GFXGLTextureObject::reloadFromCache() else if(mBinding == GL_TEXTURE_1D) 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) - glGenerateMipmapEXT(mBinding); + if(mMipLevels != 1) + glGenerateMipmap(mBinding); delete[] mZombieCache; mZombieCache = NULL; diff --git a/Engine/source/gfx/gl/gfxGLTextureTarget.cpp b/Engine/source/gfx/gl/gfxGLTextureTarget.cpp index 202265107..384871dd9 100644 --- a/Engine/source/gfx/gl/gfxGLTextureTarget.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureTarget.cpp @@ -410,7 +410,7 @@ void GFXGLTextureTarget::resolveTo(GFXTextureObject* obj) AssertFatal(dynamic_cast(obj), "GFXGLTextureTarget::resolveTo - Incorrect type of texture, expected a GFXGLTextureObject"); GFXGLTextureObject* glTexture = static_cast(obj); - if( gglHasExtension(ARB_copy_image) && mTargets[Color0]->isCompatible(glTexture) ) + if( GFXGL->mCapabilities.copyImage && mTargets[Color0]->isCompatible(glTexture) ) { 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; diff --git a/Engine/source/gfx/gl/gfxGLVertexBuffer.cpp b/Engine/source/gfx/gl/gfxGLVertexBuffer.cpp index 132172c1a..2cf4cb625 100644 --- a/Engine/source/gfx/gl/gfxGLVertexBuffer.cpp +++ b/Engine/source/gfx/gl/gfxGLVertexBuffer.cpp @@ -78,7 +78,7 @@ void GFXGLVertexBuffer::lock( U32 vertexStart, U32 vertexEnd, void **vertexPtr ) if( mBufferType == GFXBufferTypeVolatile ) { AssertFatal(vertexStart == 0, ""); - if( gglHasExtension(ARB_vertex_attrib_binding) ) + if( GFXGL->mCapabilities.vertexAttributeBinding ) { getCircularVolatileVertexBuffer()->lock( mNumVerts * mVertexSize, 0, mBufferOffset, *vertexPtr ); } @@ -136,7 +136,7 @@ void GFXGLVertexBuffer::prepare() void GFXGLVertexBuffer::prepare(U32 stream, U32 divisor) { - if( gglHasExtension(ARB_vertex_attrib_binding) ) + if( GFXGL->mCapabilities.vertexAttributeBinding ) { glBindVertexBuffer( stream, mBuffer, mBufferOffset, mVertexSize ); glVertexBindingDivisor( stream, divisor ); diff --git a/Engine/source/gfx/gl/gfxGLVertexDecl.cpp b/Engine/source/gfx/gl/gfxGLVertexDecl.cpp index 10eda4401..948a2b2de 100644 --- a/Engine/source/gfx/gl/gfxGLVertexDecl.cpp +++ b/Engine/source/gfx/gl/gfxGLVertexDecl.cpp @@ -15,7 +15,7 @@ void GFXGLVertexDecl::init(const GFXVertexFormat *format) void GFXGLVertexDecl::prepareVertexFormat() const { AssertFatal(mFormat, "GFXGLVertexDecl - Not inited"); - if( gglHasExtension(ARB_vertex_attrib_binding) ) + if( GFXGL->mCapabilities.vertexAttributeBinding ) { 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); AssertFatal(mFormat, "GFXGLVertexDecl - Not inited"); - if( gglHasExtension(ARB_vertex_attrib_binding) ) + if( GFXGL->mCapabilities.vertexAttributeBinding ) return; // Bind the buffer... diff --git a/Engine/source/gfx/gl/gfxGLWindowTarget.cpp b/Engine/source/gfx/gl/gfxGLWindowTarget.cpp index 5f8808cae..116ad75e3 100644 --- a/Engine/source/gfx/gl/gfxGLWindowTarget.cpp +++ b/Engine/source/gfx/gl/gfxGLWindowTarget.cpp @@ -78,7 +78,7 @@ void GFXGLWindowTarget::resolveTo(GFXTextureObject* obj) AssertFatal(dynamic_cast(obj), "GFXGLTextureTarget::resolveTo - Incorrect type of texture, expected a GFXGLTextureObject"); GFXGLTextureObject* glTexture = static_cast(obj); - if( gglHasExtension(ARB_copy_image) ) + if( GFXGL->mCapabilities.copyImage ) { if(mBackBufferColorTex.getWidth() == glTexture->getWidth() && mBackBufferColorTex.getHeight() == glTexture->getHeight()