diff --git a/src.cmake b/src.cmake index 4d3d2b5f7b..025649e22f 100644 --- a/src.cmake +++ b/src.cmake @@ -93,6 +93,8 @@ set(RENDERERLIST ${ENGINE_DIR}/renderer/tr_fbo.cpp ${ENGINE_DIR}/renderer/tr_flares.cpp ${ENGINE_DIR}/renderer/tr_font.cpp + ${ENGINE_DIR}/renderer/GeometryCache.cpp + ${ENGINE_DIR}/renderer/GeometryCache.h ${ENGINE_DIR}/renderer/InternalImage.cpp ${ENGINE_DIR}/renderer/InternalImage.h ${ENGINE_DIR}/renderer/Material.cpp diff --git a/src/engine/renderer/GeometryCache.cpp b/src/engine/renderer/GeometryCache.cpp new file mode 100644 index 0000000000..8845df99fc --- /dev/null +++ b/src/engine/renderer/GeometryCache.cpp @@ -0,0 +1,102 @@ +/* +=========================================================================== + +Daemon BSD Source Code +Copyright (c) 2025 Daemon Developers +All rights reserved. + +This file is part of the Daemon BSD Source Code (Daemon Source Code). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================== +*/ +// GeometryCache.cpp + +#include "common/Common.h" + +#include "GeometryCache.h" + +#include "tr_local.h" + +GeometryCache geometryCache; + +void GeometryCache::Bind() { + VAO.Bind(); +} + +void GeometryCache::InitGLBuffers() { + inputVBO.GenBuffer(); + VBO.GenBuffer(); + IBO.GenBuffer(); + + VAO.GenVAO(); +} + +void GeometryCache::FreeGLBuffers() { + inputVBO.DelBuffer(); + VBO.DelBuffer(); + IBO.DelBuffer(); + + VAO.DelVAO(); +} + +void GeometryCache::AllocBuffers() { + VBO.BufferData( mapVerticesNumber * 8, nullptr, GL_STATIC_DRAW ); + + IBO.BufferData( mapIndicesNumber, nullptr, GL_STATIC_DRAW ); +} + +void GeometryCache::AddMapGeometry( const uint32_t verticesNumber, const uint32_t indicesNumber, + const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd, + const glIndex_t* indices ) { + mapVerticesNumber = verticesNumber; + mapIndicesNumber = indicesNumber; + + VAO.Bind(); + + AllocBuffers(); + + VAO.SetAttrs( attrBegin, attrEnd ); + + VAO.SetVertexBuffer( VBO, 0 ); + VAO.SetIndexBuffer( IBO ); + + VBO.BufferStorage( mapVerticesNumber * 8, 1, nullptr ); + VBO.MapAll(); + uint32_t* VBOVerts = VBO.GetData(); + for ( const vertexAttributeSpec_t* spec = attrBegin; spec < attrEnd; spec++ ) { + vboAttributeLayout_t& attr = VAO.attrs[spec->attrIndex]; + + R_CopyVertexAttribute( attr, *spec, mapVerticesNumber, ( byte* ) VBOVerts ); + } + VBO.UnmapBuffer(); + + IBO.BufferStorage( mapIndicesNumber, 1, nullptr ); + IBO.MapAll(); + uint32_t* IBOIndices = IBO.GetData(); + memcpy( IBOIndices, indices, mapIndicesNumber * sizeof( uint32_t ) ); + IBO.UnmapBuffer(); + + glBindVertexArray( backEnd.currentVAO ); +} diff --git a/src/engine/renderer/GeometryCache.h b/src/engine/renderer/GeometryCache.h new file mode 100644 index 0000000000..42f6d5c724 --- /dev/null +++ b/src/engine/renderer/GeometryCache.h @@ -0,0 +1,68 @@ +/* +=========================================================================== + +Daemon BSD Source Code +Copyright (c) 2025 Daemon Developers +All rights reserved. + +This file is part of the Daemon BSD Source Code (Daemon Source Code). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================== +*/ +// GeometryCache.h + +#ifndef GEOMETRY_CACHE_H +#define GEOMETRY_CACHE_H + +#include "gl_shader.h" +#include "Material.h" + +class GeometryCache { + public: + void Bind(); + + void InitGLBuffers(); + void FreeGLBuffers(); + + void AllocBuffers(); + void AddMapGeometry( const uint32_t verticesNumber, const uint32_t indicesNumber, + const vertexAttributeSpec_t* attrBegin, + const vertexAttributeSpec_t* attrEnd, + const glIndex_t* indices ); + + private: + uint32_t mapVerticesNumber; + uint32_t mapIndicesNumber; + + GLVAO VAO = GLVAO( 0 ); + + GLBuffer inputVBO = GLBuffer( "geometryCacheInputVBO", Util::ordinal( BufferBind::GEOMETRY_CACHE_INPUT_VBO ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); + GLBuffer VBO = GLBuffer( "geometryCacheVBO", Util::ordinal( BufferBind::GEOMETRY_CACHE_VBO ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); + GLBuffer IBO = GLBuffer( "geometryCacheIBO", Util::ordinal( BufferBind::UNUSED ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +}; + +extern GeometryCache geometryCache; + +#endif // GEOMETRY_CACHE_H diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 07fcaa61d2..8d60435dec 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -36,6 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "tr_local.h" #include "Material.h" #include "ShadeCommon.h" +#include "GeometryCache.h" GLUBO materialsUBO( "materials", Util::ordinal( BufferBind::MATERIALS ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); GLBuffer texDataBuffer( "texData", Util::ordinal( BufferBind::TEX_DATA ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); @@ -1353,9 +1354,6 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, material.cullType = shader->cullType; material.usePolygonOffset = shader->polygonOffset; - material.vbo = glState.currentVBO; - material.ibo = glState.currentIBO; - material.bspSurface = drawSurf->bspSurface; pStage->materialProcessor( &material, pStage, drawSurf ); pStage->paddedSize = material.shader->GetPaddedSize(); @@ -1454,11 +1452,6 @@ void MaterialSystem::GenerateWorldMaterials() { continue; } - // The verts aren't used; it's only to get the VBO/IBO. - Tess_Begin( Tess_StageIteratorDummy, shader, nullptr, true, -1, 0 ); - rb_surfaceTable[Util::ordinal( *( drawSurf->surface ) )]( drawSurf->surface ); - Tess_Clear(); - // Only add the main surface for surfaces with depth pre-pass or fog to the total count if ( !drawSurf->materialSystemSkip ) { totalDrawSurfs++; @@ -2058,6 +2051,8 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS materialsUBO.BindBufferBase(); + geometryCache.Bind(); + for ( MaterialPack& materialPack : materialPacks ) { if ( materialPack.fromSort >= fromSort && materialPack.toSort <= toSort ) { for ( Material& material : materialPack.materials ) { @@ -2067,6 +2062,8 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS } } + glBindVertexArray( backEnd.currentVAO ); + // Draw the skybox here because we skipped R_AddWorldSurfaces() const bool environmentFogDraw = ( fromSort <= shaderSort_t::SS_ENVIRONMENT_FOG ) && ( toSort >= shaderSort_t::SS_ENVIRONMENT_FOG ); const bool environmentNoFogDraw = ( fromSort <= shaderSort_t::SS_ENVIRONMENT_NOFOG ) && toSort >= ( shaderSort_t::SS_ENVIRONMENT_NOFOG ); @@ -2150,10 +2147,6 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) material.shaderBinder( &material ); - R_BindVBO( material.vbo ); - R_BindIBO( material.ibo ); - material.shader->SetRequiredVertexPointers(); - if ( !material.texturesResident ) { for ( Texture* texture : material.textures ) { if ( !texture->IsResident() ) { diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index ea49e676b1..aac4e40391 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -114,9 +114,6 @@ struct Material { bool usePolygonOffset = false; - VBO_t* vbo; - IBO_t* ibo; - fog_t* fog = nullptr; std::vector drawSurfs; @@ -125,7 +122,7 @@ struct Material { std::vector textures; bool operator==( const Material& other ) { - return program == other.program && stateBits == other.stateBits && vbo == other.vbo && ibo == other.ibo + return program == other.program && stateBits == other.stateBits && fog == other.fog && cullType == other.cullType && usePolygonOffset == other.usePolygonOffset; } @@ -288,7 +285,10 @@ enum class BufferBind { COMMAND_COUNTERS_ATOMIC = 0, COMMAND_COUNTERS_STORAGE = 4, // Avoid needlessly rebinding buffers PORTAL_SURFACES = 5, - DEBUG = 10 + GEOMETRY_CACHE_INPUT_VBO = 6, + GEOMETRY_CACHE_VBO = 7, + DEBUG = 10, + UNUSED = INT32_MAX }; class MaterialSystem { diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index e75a0c6d59..2e357c651f 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1370,6 +1370,8 @@ class GLUniformBlock class GLBuffer { public: + friend class GLVAO; + std::string name; const GLuint64 SYNC_TIMEOUT = 10000000000; // 10 seconds @@ -1530,6 +1532,77 @@ class GLAtomicCounterBuffer : public GLBuffer { } }; +class GLVAO { + public: + vboAttributeLayout_t attrs[ATTR_INDEX_MAX]; + uint32_t enabledAttrs; + + GLVAO( const GLuint newVBOBindingPoint ) : + VBOBindingPoint( newVBOBindingPoint ) { + } + + ~GLVAO() = default; + + void Bind() { + glBindVertexArray( id ); + } + + void SetAttrs( const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd ) { + uint32_t ofs = 0; + for ( const vertexAttributeSpec_t* spec = attrBegin; spec < attrEnd; spec++ ) { + vboAttributeLayout_t& attr = attrs[spec->attrIndex]; + ASSERT_NQ( spec->numComponents, 0U ); + attr.componentType = spec->componentStorageType; + if ( attr.componentType == GL_HALF_FLOAT && !glConfig2.halfFloatVertexAvailable ) { + attr.componentType = GL_FLOAT; + } + attr.numComponents = spec->numComponents; + attr.normalize = spec->attrOptions & ATTR_OPTION_NORMALIZE ? GL_TRUE : GL_FALSE; + + attr.ofs = ofs; + ofs += attr.numComponents * R_ComponentSize( attr.componentType ); + ofs = ( ofs + 3 ) & ~3; // 4 is minimum alignment for any vertex attribute + + enabledAttrs |= 1 << spec->attrIndex; + } + + stride = ofs; + + for ( const vertexAttributeSpec_t* spec = attrBegin; spec < attrEnd; spec++ ) { + const int index = spec->attrIndex; + vboAttributeLayout_t& attr = attrs[index]; + + attr.stride = stride; + + glEnableVertexArrayAttrib( id, index ); + glVertexArrayAttribFormat( id, index, attr.numComponents, attr.componentType, + attr.normalize, attr.ofs ); + glVertexArrayAttribBinding( id, index, VBOBindingPoint ); + } + } + + void SetVertexBuffer( const GLBuffer buffer, const GLuint offset ) { + glVertexArrayVertexBuffer( id, VBOBindingPoint, buffer.id, offset, stride ); + } + + void SetIndexBuffer( const GLBuffer buffer ) { + glVertexArrayElementBuffer( id, buffer.id ); + } + + void GenVAO() { + glGenVertexArrays( 1, &id ); + } + + void DelVAO() { + glDeleteVertexArrays( 1, &id ); + } + + private: + GLuint id; + const GLuint VBOBindingPoint; + GLuint stride; +}; + class GLCompileMacro { private: diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index be7529506f..c040d89579 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_bsp.c #include "tr_local.h" #include "framework/CommandSystem.h" +#include "GeometryCache.h" /* ======================================================== @@ -3208,6 +3209,10 @@ static void R_CreateWorldVBO() { ATTR_INDEX_TEXCOORD, GL_FLOAT, GL_HALF_FLOAT, &vboVerts[ 0 ].st, 4, sizeof( *vboVerts ), 0 }, }; + if ( glConfig2.usingGeometryCache ) { + geometryCache.AddMapGeometry( vboNumVerts, vboNumIndexes, std::begin( attrs ), std::end( attrs ), vboIdxs ); + } + s_worldData.vbo = R_CreateStaticVBO( "staticWorld_VBO", std::begin( attrs ), std::end( attrs ), vboNumVerts ); s_worldData.ibo = R_CreateStaticIBO2( "staticWorld_IBO", numTriangles, vboIdxs ); diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index c69eaad77b..2108f5106e 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "framework/CvarSystem.h" #include "DetectGLVendors.h" #include "Material.h" +#include "GeometryCache.h" #ifdef _WIN32 extern "C" { @@ -1563,7 +1564,9 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p R_DoneFreeType(); - materialSystem.Free(); + if ( glConfig2.usingMaterialSystem ) { + materialSystem.Free(); + } // shut down platform specific OpenGL stuff if ( destroyWindow ) diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 201f142a0a..9e91673491 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -3715,6 +3715,10 @@ inline bool checkGLErrors() ============================================================ */ + uint32_t R_ComponentSize( GLenum type ); + void R_CopyVertexAttribute( const vboAttributeLayout_t& attrib, const vertexAttributeSpec_t& spec, + uint32_t count, byte* interleavedData ); + VBO_t *R_CreateStaticVBO( Str::StringRef name, const vertexAttributeSpec_t *attrBegin, const vertexAttributeSpec_t *attrEnd, uint32_t numVerts, uint32_t numFrames = 0 ); diff --git a/src/engine/renderer/tr_public.h b/src/engine/renderer/tr_public.h index 5f4a253aaf..5cf5a414a3 100644 --- a/src/engine/renderer/tr_public.h +++ b/src/engine/renderer/tr_public.h @@ -103,6 +103,7 @@ struct glconfig2_t bool shadingLanguage420PackAvailable; bool explicitUniformLocationAvailable; bool directStateAccessAvailable; + bool vertexAttribBindingAvailable; bool shaderImageLoadStoreAvailable; bool shaderAtomicCountersAvailable; bool shaderAtomicCounterOpsAvailable; @@ -117,6 +118,8 @@ struct glconfig2_t bool shaderSubgroupQuadAvailable; bool materialSystemAvailable; // do the driver/hardware support it bool usingMaterialSystem; // are we using it right now + bool geometryCacheAvailable; + bool usingGeometryCache; bool gpuShader4Available; bool gpuShader5Available; bool textureGatherAvailable; diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 88891a0757..4f1ee75a40 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -177,6 +177,7 @@ static void EnableAvailableFeatures() glConfig2.usingMaterialSystem = r_materialSystem.Get() && glConfig2.materialSystemAvailable; glConfig2.usingBindlessTextures = glConfig2.usingMaterialSystem || ( r_preferBindlessTextures.Get() && glConfig2.bindlessTexturesAvailable ); + glConfig2.usingGeometryCache = glConfig2.usingMaterialSystem && glConfig2.geometryCacheAvailable; } // For shaders that require map data for compile-time values diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index 85bc83e700..b73751fa64 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_vbo.c #include "tr_local.h" #include "Material.h" +#include "GeometryCache.h" // interleaved data: position, colour, qtangent, texcoord // -> struct shaderVertex_t in tr_local.h @@ -74,7 +75,7 @@ static void R_SetVBOAttributeLayouts( VBO_t *vbo ) } } -static uint32_t ComponentSize( GLenum type ) +uint32_t R_ComponentSize( GLenum type ) { switch ( type ) { @@ -90,7 +91,7 @@ static uint32_t ComponentSize( GLenum type ) return 4; } - Sys::Error( "VBO ComponentSize: unknown type %d", type ); + Sys::Error( "VBO R_ComponentSize: unknown type %d", type ); } #if defined( GL_ARB_buffer_storage ) && defined( GL_ARB_sync ) @@ -208,7 +209,7 @@ VBO_t *R_CreateDynamicVBO( const char *name, int numVertexes, uint32_t stateBits return vbo; } -static void CopyVertexAttribute( +void R_CopyVertexAttribute( const vboAttributeLayout_t &attrib, const vertexAttributeSpec_t &spec, uint32_t count, byte *interleavedData ) { @@ -225,7 +226,7 @@ static void CopyVertexAttribute( if ( attrib.componentType == spec.componentInputType ) { - uint32_t size = attrib.numComponents * ComponentSize( attrib.componentType ); + uint32_t size = attrib.numComponents * R_ComponentSize( attrib.componentType ); for ( uint32_t v = count; ; ) { @@ -332,7 +333,7 @@ VBO_t *R_CreateStaticVBO( uint32_t &ofs = spec->attrOptions & ATTR_OPTION_HAS_FRAMES ? ofsFrameful : ofsFrameless; attrib.ofs = ofs; - ofs += attrib.numComponents * ComponentSize( attrib.componentType ); + ofs += attrib.numComponents * R_ComponentSize( attrib.componentType ); ofs = ( ofs + 3 ) & ~3; // 4 is minimum alignment for any vertex attribute } @@ -352,12 +353,12 @@ VBO_t *R_CreateStaticVBO( attrib.stride = ofsFrameful; attrib.frameOffset = numVerts * ofsFrameful; attrib.ofs += framelessSize; - CopyVertexAttribute( attrib, *spec, numVerts * numFrames, interleavedData ); + R_CopyVertexAttribute( attrib, *spec, numVerts * numFrames, interleavedData ); } else { attrib.stride = ofsFrameless; - CopyVertexAttribute( attrib, *spec, numVerts, interleavedData ); + R_CopyVertexAttribute( attrib, *spec, numVerts, interleavedData ); } } @@ -773,6 +774,10 @@ void R_InitVBOs() materialSystem.InitGLBuffers(); } + if ( glConfig2.usingGeometryCache ) { + geometryCache.InitGLBuffers(); + } + GL_CheckErrors(); } @@ -845,6 +850,10 @@ void R_ShutdownVBOs() materialSystem.FreeGLBuffers(); } + if ( glConfig2.usingGeometryCache ) { + geometryCache.FreeGLBuffers(); + } + tess.verts = tess.vertsBuffer = nullptr; tess.indexes = tess.indexesBuffer = nullptr; } diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index 9b9d5296a1..d09480322f 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -108,6 +108,8 @@ static Cvar::Cvar r_arb_texture_gather( "r_arb_texture_gather", "Use GL_ARB_texture_gather if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_uniform_buffer_object( "r_arb_uniform_buffer_object", "Use GL_ARB_uniform_buffer_object if available", Cvar::NONE, true ); +static Cvar::Cvar r_arb_vertex_attrib_binding( "r_arb_vertex_attrib_binding", + "Use GL_ARB_vertex_attrib_binding if available", Cvar::NONE, true ); static Cvar::Cvar r_ext_draw_buffers( "r_ext_draw_buffers", "Use GL_EXT_draw_buffers if available", Cvar::NONE, true ); static Cvar::Cvar r_ext_gpu_shader4( "r_ext_gpu_shader4", @@ -1996,6 +1998,7 @@ static void GLimp_InitExtensions() Cvar::Latch( r_arb_sync ); Cvar::Latch( r_arb_texture_gather ); Cvar::Latch( r_arb_uniform_buffer_object ); + Cvar::Latch( r_arb_vertex_attrib_binding ); Cvar::Latch( r_ext_draw_buffers ); Cvar::Latch( r_ext_gpu_shader4 ); Cvar::Latch( r_ext_texture_filter_anisotropic ); @@ -2550,12 +2553,18 @@ static void GLimp_InitExtensions() // made required in OpenGL 4.5 glConfig2.directStateAccessAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_NONE, ARB_direct_state_access, r_arb_direct_state_access.Get() ); + // made required in OpenGL 4.3 + glConfig2.vertexAttribBindingAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_NONE, ARB_vertex_attrib_binding, r_arb_vertex_attrib_binding.Get() ); + + glConfig2.geometryCacheAvailable = glConfig2.vertexAttribBindingAvailable && glConfig2.directStateAccessAvailable; + glConfig2.materialSystemAvailable = glConfig2.shaderDrawParametersAvailable && glConfig2.SSBOAvailable && glConfig2.multiDrawIndirectAvailable && glConfig2.bindlessTexturesAvailable && glConfig2.computeShaderAvailable && glConfig2.shadingLanguage420PackAvailable && glConfig2.explicitUniformLocationAvailable && glConfig2.shaderImageLoadStoreAvailable && glConfig2.shaderAtomicCountersAvailable && glConfig2.indirectParametersAvailable - && glConfig2.directStateAccessAvailable; + && glConfig2.directStateAccessAvailable + && glConfig2.geometryCacheAvailable; // This requires GLEW 2.2+, so skip if it's a lower version #ifdef GL_KHR_shader_subgroup