diff --git a/src.cmake b/src.cmake index 24d7d227a1..8f5f4773dd 100644 --- a/src.cmake +++ b/src.cmake @@ -78,6 +78,7 @@ set(COMMONTESTLIST ) set(RENDERERLIST + ${ENGINE_DIR}/renderer/BufferBind.h ${ENGINE_DIR}/renderer/DetectGLVendors.cpp ${ENGINE_DIR}/renderer/DetectGLVendors.h ${ENGINE_DIR}/renderer/gl_shader.cpp diff --git a/src/engine/renderer/BufferBind.h b/src/engine/renderer/BufferBind.h new file mode 100644 index 0000000000..7f4b2c7c8f --- /dev/null +++ b/src/engine/renderer/BufferBind.h @@ -0,0 +1,69 @@ +/* +=========================================================================== + +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. + +=========================================================================== +*/ +// BufferBind.h + +#ifndef BUFFERBIND_H +#define BUFFERBIND_H + +namespace BufferBind { + enum : uint32_t { + // UBO + MATERIALS = 0, + TEX_DATA = 1, + LIGHTMAP_DATA = 2, + LIGHTS = 3, + + SURFACE_BATCHES = 4, + + // SSBO + SURFACE_DESCRIPTORS = 0, + SURFACE_COMMANDS = 1, + CULLED_COMMANDS = 2, + PORTAL_SURFACES = 4, + + GEOMETRY_CACHE_INPUT_VBO = 5, + GEOMETRY_CACHE_VBO = 6, + GEOMETRY_CACHE_IBO = 7, + + COMMAND_COUNTERS_STORAGE = 9, + TEX_DATA_STORAGE = 11, + + DEBUG = 10, + + // Atomic + COMMAND_COUNTERS_ATOMIC = 0 + }; +}; + +#endif // BUFFERBIND_H diff --git a/src/engine/renderer/GeometryCache.h b/src/engine/renderer/GeometryCache.h index 42f6d5c724..7709540e20 100644 --- a/src/engine/renderer/GeometryCache.h +++ b/src/engine/renderer/GeometryCache.h @@ -58,9 +58,9 @@ class GeometryCache { 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 ); + GLBuffer inputVBO = GLBuffer( "geometryCacheInputVBO", BufferBind::GEOMETRY_CACHE_INPUT_VBO, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); + GLBuffer VBO = GLBuffer( "geometryCacheVBO", BufferBind::GEOMETRY_CACHE_VBO, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); + GLBuffer IBO = GLBuffer( "geometryCacheIBO", BufferBind::GEOMETRY_CACHE_IBO, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); }; extern GeometryCache geometryCache; diff --git a/src/engine/renderer/GeometryOptimiser.cpp b/src/engine/renderer/GeometryOptimiser.cpp index 4de4c4e058..7b8793803c 100644 --- a/src/engine/renderer/GeometryOptimiser.cpp +++ b/src/engine/renderer/GeometryOptimiser.cpp @@ -716,6 +716,8 @@ std::vector OptimiseMapGeometryMaterial( world_t* world, bspSur materialSystem.GeneratePortalBoundingSpheres(); materialSystem.GenerateWorldCommandBuffer( processedMaterialSurfaces ); + materialSystem.BindBuffers(); + vertexAttributeSpec_t attrs[] { { ATTR_INDEX_POSITION, GL_FLOAT, GL_FLOAT, &vertices[0].xyz, 3, sizeof( *vertices ), 0 }, { ATTR_INDEX_COLOR, GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE, &vertices[0].lightColor, 4, sizeof( *vertices ), ATTR_OPTION_NORMALIZE }, diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index b90e4fc1a4..c27ac58f06 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -35,21 +35,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "tr_local.h" #include "Material.h" +#include "BufferBind.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 ); -GLUBO lightMapDataUBO( "lightMapData", Util::ordinal( BufferBind::LIGHTMAP_DATA ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO materialsUBO( "materials", BufferBind::MATERIALS, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLBuffer texDataBuffer( "texData", BufferBind::TEX_DATA, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO lightMapDataUBO( "lightMapData", BufferBind::LIGHTMAP_DATA, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLSSBO surfaceDescriptorsSSBO( "surfaceDescriptors", Util::ordinal( BufferBind::SURFACE_DESCRIPTORS ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); -GLSSBO surfaceCommandsSSBO( "surfaceCommands", Util::ordinal( BufferBind::SURFACE_COMMANDS ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLBuffer culledCommandsBuffer( "culledCommands", Util::ordinal( BufferBind::CULLED_COMMANDS ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLUBO surfaceBatchesUBO( "surfaceBatches", Util::ordinal( BufferBind::SURFACE_BATCHES ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); -GLBuffer atomicCommandCountersBuffer( "atomicCommandCounters", Util::ordinal( BufferBind::COMMAND_COUNTERS_ATOMIC ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLSSBO portalSurfacesSSBO( "portalSurfaces", Util::ordinal( BufferBind::PORTAL_SURFACES ), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT, 0 ); +GLSSBO surfaceDescriptorsSSBO( "surfaceDescriptors", BufferBind::SURFACE_DESCRIPTORS, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLSSBO surfaceCommandsSSBO( "surfaceCommands", BufferBind::SURFACE_COMMANDS, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLBuffer culledCommandsBuffer( "culledCommands", BufferBind::CULLED_COMMANDS, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO surfaceBatchesUBO( "surfaceBatches", BufferBind::SURFACE_BATCHES, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLBuffer atomicCommandCountersBuffer( "atomicCommandCounters", BufferBind::COMMAND_COUNTERS_ATOMIC, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLSSBO portalSurfacesSSBO( "portalSurfaces", BufferBind::PORTAL_SURFACES, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT, 0 ); -GLSSBO debugSSBO( "debug", Util::ordinal( BufferBind::DEBUG ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLSSBO debugSSBO( "debug", BufferBind::DEBUG, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); PortalView portalStack[MAX_VIEWS]; @@ -541,7 +542,13 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s surfaceDescriptorsSSBO.BufferData( surfaceDescriptorsCount * descriptorSize, nullptr, GL_STATIC_DRAW ); uint32_t* surfaceDescriptors = surfaceDescriptorsSSBO.MapBufferRange( surfaceDescriptorsCount * descriptorSize ); - texDataBufferType = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER; + if ( glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ) { + texDataBufferType = GL_UNIFORM_BUFFER; + texDataBindingPoint = BufferBind::TEX_DATA; + } else { + texDataBufferType = GL_SHADER_STORAGE_BUFFER; + texDataBindingPoint = BufferBind::TEX_DATA_STORAGE; + } texDataBuffer.BufferStorage( ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE, 1, nullptr ); texDataBuffer.MapAll(); @@ -718,6 +725,31 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s GL_CheckErrors(); } +void MaterialSystem::BindBuffers() { + materialsUBO.BindBufferBase(); + texDataBuffer.BindBufferBase( texDataBufferType, texDataBindingPoint ); + lightMapDataUBO.BindBufferBase(); + + culledCommandsBuffer.BindBuffer( GL_DRAW_INDIRECT_BUFFER ); + atomicCommandCountersBuffer.BindBuffer( GL_PARAMETER_BUFFER_ARB ); + + atomicCommandCountersBuffer.BindBufferBase( GL_SHADER_STORAGE_BUFFER, BufferBind::COMMAND_COUNTERS_STORAGE ); + + surfaceDescriptorsSSBO.BindBufferBase(); + surfaceCommandsSSBO.BindBufferBase(); + culledCommandsBuffer.BindBufferBase( GL_SHADER_STORAGE_BUFFER ); + surfaceBatchesUBO.BindBufferBase(); + atomicCommandCountersBuffer.BindBufferBase( GL_ATOMIC_COUNTER_BUFFER ); + + if ( totalPortals > 0 ) { + portalSurfacesSSBO.BindBufferBase(); + } + + if ( r_materialDebug.Get() ) { + debugSSBO.BindBufferBase(); + } +} + void MaterialSystem::GenerateDepthImages( const int width, const int height, imageParams_t imageParms ) { imageParms.bits ^= ( IF_NOPICMIP | IF_PACKED_DEPTH24_STENCIL8 ); imageParms.bits |= IF_ONECOMP32F; @@ -805,8 +837,6 @@ void BindShaderLightMapping( Material* material ) { } if ( glConfig2.realtimeLighting ) { - gl_lightMappingShaderMaterial->SetUniformBlock_Lights( tr.dlightUBO ); - // bind u_LightTiles gl_lightMappingShaderMaterial->SetUniform_LightTilesBindless( GL_BindToTMU( BIND_LIGHTTILES, tr.lighttileRenderImage ) @@ -1464,14 +1494,10 @@ void MaterialSystem::UpdateDynamicSurfaces() { } void MaterialSystem::UpdateFrameData() { - atomicCommandCountersBuffer.BindBufferBase( GL_SHADER_STORAGE_BUFFER, Util::ordinal( BufferBind::COMMAND_COUNTERS_STORAGE ) ); - gl_clearSurfacesShader->BindProgram( 0 ); gl_clearSurfacesShader->SetUniform_Frame( nextFrame ); gl_clearSurfacesShader->DispatchCompute( MAX_VIEWS, 1, 1 ); - atomicCommandCountersBuffer.UnBindBufferBase( GL_SHADER_STORAGE_BUFFER, Util::ordinal( BufferBind::COMMAND_COUNTERS_STORAGE ) ); - GL_CheckErrors(); } @@ -1523,6 +1549,8 @@ void MaterialSystem::DepthReduction() { glMemoryBarrier( GL_SHADER_IMAGE_ACCESS_BARRIER_BIT ); } + + GL_CheckErrors(); } void MaterialSystem::CullSurfaces() { @@ -1530,22 +1558,6 @@ void MaterialSystem::CullSurfaces() { DepthReduction(); } - surfaceDescriptorsSSBO.BindBufferBase(); - surfaceCommandsSSBO.BindBufferBase(); - culledCommandsBuffer.BindBufferBase( GL_SHADER_STORAGE_BUFFER ); - surfaceBatchesUBO.BindBufferBase(); - atomicCommandCountersBuffer.BindBufferBase( GL_ATOMIC_COUNTER_BUFFER ); - - if ( totalPortals > 0 ) { - portalSurfacesSSBO.BindBufferBase(); - } - - if ( r_materialDebug.Get() ) { - debugSSBO.BindBufferBase(); - } - - GL_CheckErrors(); - for ( uint32_t view = 0; view < frames[nextFrame].viewCount; view++ ) { vec3_t origin; frustum_t* frustum = &frames[nextFrame].viewFrames[view].frustum; @@ -1616,20 +1628,6 @@ void MaterialSystem::CullSurfaces() { gl_processSurfacesShader->DispatchCompute( totalBatchCount, 1, 1 ); } - surfaceDescriptorsSSBO.UnBindBufferBase(); - surfaceCommandsSSBO.UnBindBufferBase(); - culledCommandsBuffer.UnBindBufferBase( GL_SHADER_STORAGE_BUFFER ); - surfaceBatchesUBO.UnBindBufferBase(); - atomicCommandCountersBuffer.UnBindBufferBase( GL_ATOMIC_COUNTER_BUFFER ); - - if ( totalPortals > 0 ) { - portalSurfacesSSBO.UnBindBufferBase(); - } - - if ( r_materialDebug.Get() ) { - debugSSBO.UnBindBufferBase(); - } - GL_CheckErrors(); } @@ -1848,7 +1846,6 @@ void MaterialSystem::AddPortalSurfaces() { return; } - portalSurfacesSSBO.BindBufferBase(); PortalSurface* portalSurfs = ( PortalSurface* ) portalSurfacesSSBO.GetCurrentAreaData(); viewCount = 0; // This will recursively find potentially visible portals in each view based on the data read back from the GPU @@ -1887,8 +1884,6 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS frameStart = false; } - materialsUBO.BindBufferBase(); - geometryCache.Bind(); for ( MaterialPack& materialPack : materialPacks ) { @@ -2019,13 +2014,6 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) } material.texturesResident = true; - culledCommandsBuffer.BindBuffer( GL_DRAW_INDIRECT_BUFFER ); - - atomicCommandCountersBuffer.BindBuffer( GL_PARAMETER_BUFFER_ARB ); - - texDataBuffer.BindBufferBase( texDataBufferType ); - lightMapDataUBO.BindBufferBase(); - if ( r_showGlobalMaterials.Get() && material.sort != 0 && ( material.shaderBinder == BindShaderLightMapping || material.shaderBinder == BindShaderGeneric3D ) ) { vec3_t color; @@ -2136,13 +2124,6 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) } } - culledCommandsBuffer.UnBindBuffer( GL_DRAW_INDIRECT_BUFFER ); - - atomicCommandCountersBuffer.UnBindBuffer( GL_PARAMETER_BUFFER_ARB ); - - texDataBuffer.UnBindBufferBase( texDataBufferType ); - lightMapDataUBO.UnBindBufferBase(); - if ( material.usePolygonOffset ) { glDisable( GL_POLYGON_OFFSET_FILL ); } diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index d11b3abb5b..2ab9d2fadd 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -306,23 +306,6 @@ struct SurfaceCommandBatch { uint32_t materialIDs[2] { 0, 0 }; }; -enum class BufferBind { - MATERIALS = 1, // LightTile UBO uses binding point 0, so avoid it here - TEX_DATA = 6, - LIGHTMAP_DATA = 2, - SURFACE_DESCRIPTORS = 0, - SURFACE_COMMANDS = 1, - CULLED_COMMANDS = 2, - SURFACE_BATCHES = 3, - COMMAND_COUNTERS_ATOMIC = 0, - COMMAND_COUNTERS_STORAGE = 4, // Avoid needlessly rebinding buffers - PORTAL_SURFACES = 5, - GEOMETRY_CACHE_INPUT_VBO = 6, - GEOMETRY_CACHE_VBO = 7, - DEBUG = 10, - UNUSED = INT32_MAX -}; - class MaterialSystem { public: vec3_t worldViewBounds[2]; @@ -381,6 +364,8 @@ class MaterialSystem { void InitGLBuffers(); void FreeGLBuffers(); + void BindBuffers(); + uint32_t GetTexDataSize() const { return texData.size(); } @@ -428,6 +413,7 @@ class MaterialSystem { std::vector dynamicStages; GLenum texDataBufferType; + GLuint texDataBindingPoint; std::vector texData; std::vector dynamicTexData; diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index b6635e88c0..498aaff20d 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -286,7 +286,7 @@ void GLShaderManager::UpdateShaderProgramUniformLocations( GLShader* shader, Sha uniform->UpdateShaderProgramUniformLocation( shaderProgram ); } - if( glConfig2.uniformBufferObjectAvailable ) { + if( glConfig2.uniformBufferObjectAvailable && !glConfig2.shadingLanguage420PackAvailable ) { // create buffer for storing uniform block indexes shaderProgram->uniformBlockIndexes = ( GLuint* ) Z_Malloc( sizeof( GLuint ) * numUniformBlocks ); @@ -303,6 +303,10 @@ static inline void AddDefine( std::string& defines, const std::string& define, i defines += Str::Format("#ifndef %s\n#define %s %d\n#endif\n", define, define, value); } +static inline void AddDefine( std::string& defines, const std::string& define, uint32_t value ) { + defines += Str::Format( "#ifndef %s\n#define %s %d\n#endif\n", define, define, value ); +} + // Epsilon for float is 5.96e-08, so exponential notation with 8 decimal places should give exact values. static inline void AddDefine( std::string& defines, const std::string& define, float value ) @@ -412,6 +416,7 @@ struct addedExtension_t { static const std::vector fragmentVertexAddedExtensions = { { glConfig2.gpuShader4Available, 130, "EXT_gpu_shader4" }, { glConfig2.gpuShader5Available, 400, "ARB_gpu_shader5" }, + { glConfig2.shadingLanguage420PackAvailable, 420, "ARB_shading_language_420pack" }, { glConfig2.textureFloatAvailable, 130, "ARB_texture_float" }, { glConfig2.textureGatherAvailable, 400, "ARB_texture_gather" }, { glConfig2.textureIntegerAvailable, 0, "EXT_texture_integer" }, @@ -577,9 +582,10 @@ static std::string GenVertexHeader() { } if ( glConfig2.usingMaterialSystem ) { - AddDefine( str, "BIND_MATERIALS", Util::ordinal( BufferBind::MATERIALS ) ); - AddDefine( str, "BIND_TEX_DATA", Util::ordinal( BufferBind::TEX_DATA ) ); - AddDefine( str, "BIND_LIGHTMAP_DATA", Util::ordinal( BufferBind::LIGHTMAP_DATA ) ); + AddDefine( str, "BIND_MATERIALS", BufferBind::MATERIALS ); + AddDefine( str, "BIND_TEX_DATA", BufferBind::TEX_DATA ); + AddDefine( str, "BIND_TEX_DATA_STORAGE", BufferBind::TEX_DATA_STORAGE ); + AddDefine( str, "BIND_LIGHTMAP_DATA", BufferBind::LIGHTMAP_DATA ); } return str; @@ -616,10 +622,15 @@ static std::string GenFragmentHeader() { str += "#define baseInstance in_baseInstance\n\n"; } + if ( glConfig2.shadingLanguage420PackAvailable ) { + AddDefine( str, "BIND_LIGHTS", BufferBind::LIGHTS ); + } + if ( glConfig2.usingMaterialSystem ) { - AddDefine( str, "BIND_MATERIALS", Util::ordinal( BufferBind::MATERIALS ) ); - AddDefine( str, "BIND_TEX_DATA", Util::ordinal( BufferBind::TEX_DATA ) ); - AddDefine( str, "BIND_LIGHTMAP_DATA", Util::ordinal( BufferBind::LIGHTMAP_DATA ) ); + AddDefine( str, "BIND_MATERIALS", BufferBind::MATERIALS ); + AddDefine( str, "BIND_TEX_DATA", BufferBind::TEX_DATA ); + AddDefine( str, "BIND_TEX_DATA_STORAGE", BufferBind::TEX_DATA_STORAGE ); + AddDefine( str, "BIND_LIGHTMAP_DATA", BufferBind::LIGHTMAP_DATA ); } return str; @@ -636,15 +647,15 @@ static std::string GenComputeHeader() { AddDefine( str, "MAX_SURFACE_COMMAND_BATCHES", MAX_SURFACE_COMMAND_BATCHES ); AddDefine( str, "MAX_COMMAND_COUNTERS", MAX_COMMAND_COUNTERS ); - AddDefine( str, "BIND_SURFACE_DESCRIPTORS", Util::ordinal( BufferBind::SURFACE_DESCRIPTORS ) ); - AddDefine( str, "BIND_SURFACE_COMMANDS", Util::ordinal( BufferBind::SURFACE_COMMANDS ) ); - AddDefine( str, "BIND_CULLED_COMMANDS", Util::ordinal( BufferBind::CULLED_COMMANDS ) ); - AddDefine( str, "BIND_SURFACE_BATCHES", Util::ordinal( BufferBind::SURFACE_BATCHES ) ); - AddDefine( str, "BIND_COMMAND_COUNTERS_ATOMIC", Util::ordinal( BufferBind::COMMAND_COUNTERS_ATOMIC ) ); - AddDefine( str, "BIND_COMMAND_COUNTERS_STORAGE", Util::ordinal( BufferBind::COMMAND_COUNTERS_STORAGE ) ); - AddDefine( str, "BIND_PORTAL_SURFACES", Util::ordinal( BufferBind::PORTAL_SURFACES ) ); + AddDefine( str, "BIND_SURFACE_DESCRIPTORS", BufferBind::SURFACE_DESCRIPTORS ); + AddDefine( str, "BIND_SURFACE_COMMANDS", BufferBind::SURFACE_COMMANDS ); + AddDefine( str, "BIND_CULLED_COMMANDS", BufferBind::CULLED_COMMANDS ); + AddDefine( str, "BIND_SURFACE_BATCHES", BufferBind::SURFACE_BATCHES ); + AddDefine( str, "BIND_COMMAND_COUNTERS_ATOMIC", BufferBind::COMMAND_COUNTERS_ATOMIC ); + AddDefine( str, "BIND_COMMAND_COUNTERS_STORAGE", BufferBind::COMMAND_COUNTERS_STORAGE ); + AddDefine( str, "BIND_PORTAL_SURFACES", BufferBind::PORTAL_SURFACES ); - AddDefine( str, "BIND_DEBUG", Util::ordinal( BufferBind::DEBUG ) ); + AddDefine( str, "BIND_DEBUG", BufferBind::DEBUG ); } if ( glConfig2.usingBindlessTextures ) { @@ -1170,6 +1181,10 @@ void GLShaderManager::BuildAll( const bool buildOnlyMarked ) { cacheLoadCount, cacheLoadTime, cacheSaveCount, cacheSaveTime ); } +void GLShaderManager::BindBuffers() { + glBindBufferBase( GL_UNIFORM_BUFFER, BufferBind::LIGHTS, tr.dlightUBO ); +} + std::string GLShaderManager::ProcessInserts( const std::string& shaderText ) const { std::string out; std::istringstream shaderTextStream( shaderText ); @@ -1510,19 +1525,19 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str // 6 kb for materials const uint32_t count = ( 4096 + 2048 ) / shader->GetPaddedSize(); std::string materialBlock = "layout(std140, binding = " - + std::to_string( Util::ordinal( BufferBind::MATERIALS ) ) + + std::to_string( BufferBind::MATERIALS ) + ") uniform materialsUBO {\n" " Material materials[" + std::to_string( count ) + "]; \n" "};\n\n"; std::string texBuf = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? "layout(std140, binding = " - + std::to_string( Util::ordinal( BufferBind::TEX_DATA ) ) + + std::to_string( BufferBind::TEX_DATA ) + ") uniform texDataUBO {\n" " TexData texData[" + std::to_string( MAX_TEX_BUNDLES ) + "]; \n" "};\n\n" : "layout(std430, binding = " - + std::to_string( Util::ordinal( BufferBind::TEX_DATA ) ) + + std::to_string( BufferBind::TEX_DATA ) + ") restrict readonly buffer texDataSSBO {\n" " TexData texData[];\n" "};\n\n"; @@ -1548,7 +1563,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str " uvec2 u_DeluxeMap;\n" "};\n\n" "layout(std140, binding = " - + std::to_string( Util::ordinal( BufferBind::LIGHTMAP_DATA ) ) + + std::to_string( BufferBind::LIGHTMAP_DATA ) + ") uniform lightMapDataUBO {\n" " LightMapData lightMapData[256];\n" "};\n\n" diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index bcf4980db4..0499697c71 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define GL_SHADER_H #include "tr_local.h" +#include "BufferBind.h" #include #define USE_UNIFORM_FIREWALL 1 @@ -367,6 +368,8 @@ class GLShaderManager { bool BuildPermutation( GLShader* shader, int macroIndex, int deformIndex, const bool buildOneShader ); void BuildAll( const bool buildOnlyMarked ); void FreeAll(); + + void BindBuffers(); private: struct InfoLogEntry { int line; @@ -1231,12 +1234,13 @@ class GLUniformBlock protected: GLShader *_shader; std::string _name; - size_t _locationIndex; + size_t _locationIndex; // Only valid if GL_ARB_shading_language_420pack is not available + const GLuint _bindingPoint; // Only valid if GL_ARB_shading_language_420pack is available - GLUniformBlock( GLShader *shader, const char *name ) : + GLUniformBlock( GLShader *shader, const char *name, const GLuint bindingPoint ) : _shader( shader ), _name( name ), - _locationIndex( 0 ) + _bindingPoint( bindingPoint ) { _shader->RegisterUniformBlock( this ); } @@ -1258,10 +1262,14 @@ class GLUniformBlock } void SetBuffer( GLuint buffer ) { + if ( glConfig2.shadingLanguage420PackAvailable ) { + return; + } + ShaderProgramDescriptor *p = _shader->GetProgram(); - GLuint blockIndex = p->uniformBlockIndexes[ _locationIndex ]; + GLuint blockIndex = p->uniformBlockIndexes[_locationIndex]; - ASSERT_EQ(p, glState.currentProgram); + ASSERT_EQ( p, glState.currentProgram ); if( blockIndex != GL_INVALID_INDEX ) { glBindBufferBase( GL_UNIFORM_BUFFER, blockIndex, buffer ); @@ -3599,7 +3607,7 @@ class u_Lights : { public: u_Lights( GLShader *shader ) : - GLUniformBlock( shader, "u_Lights" ) + GLUniformBlock( shader, "u_Lights", BufferBind::LIGHTS ) { } diff --git a/src/engine/renderer/glsl_source/computeLight_fp.glsl b/src/engine/renderer/glsl_source/computeLight_fp.glsl index a84acbd8fd..633fb6ff81 100644 --- a/src/engine/renderer/glsl_source/computeLight_fp.glsl +++ b/src/engine/renderer/glsl_source/computeLight_fp.glsl @@ -153,7 +153,11 @@ struct Light { float angle; }; +#if defined( HAVE_ARB_shading_language_420pack ) +layout(std140, binding = BIND_LIGHTS) uniform u_Lights { +#else layout(std140) uniform u_Lights { +#endif Light lights[MAX_REF_LIGHTS]; }; diff --git a/src/engine/renderer/glsl_source/lighttile_fp.glsl b/src/engine/renderer/glsl_source/lighttile_fp.glsl index 331d46ca4a..559199a298 100644 --- a/src/engine/renderer/glsl_source/lighttile_fp.glsl +++ b/src/engine/renderer/glsl_source/lighttile_fp.glsl @@ -45,7 +45,11 @@ struct Light { float angle; }; +#if defined( HAVE_ARB_shading_language_420pack ) +layout(std140, binding = BIND_LIGHTS) uniform u_Lights { +#else layout(std140) uniform u_Lights { +#endif Light lights[MAX_REF_LIGHTS]; }; diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index b1d22dc6e9..65c645624b 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -1540,6 +1540,10 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p GLSL_FinishGPUShaders(); } + if ( glConfig2.shadingLanguage420PackAvailable ) { + gl_shaderManager.BindBuffers(); + } + /* TODO: Move this into a loading step and don't render it to the screen For now though do it here to avoid the ugly square rendering appearing on top of the loading screen */ if ( glConfig2.reflectionMappingAvailable ) {