From f79ca114c265c4178c7d1c57e5c71b8f6528b0bb Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 30 May 2025 00:06:59 +0300 Subject: [PATCH 1/4] Implement staging buffer and use it for material system Adds `GLStagingBuffer` and `GLBufferCopy()`. `GLStagingBuffer` allows setting buffer storage and map flags to 0 on the destination buffers, which pretty much guarantees that they will go into VRAM. The data is uploaded through mapping `stagingBuffer` and doing a copy of the data on the GPU. --- src.cmake | 2 + src/engine/renderer/BufferBind.h | 1 + src/engine/renderer/GLMemory.cpp | 128 +++++++++++++++++++++++++++++++ src/engine/renderer/GLMemory.h | 78 +++++++++++++++++++ src/engine/renderer/Material.cpp | 117 +++++++++++++++------------- src/engine/renderer/gl_shader.h | 11 ++- src/engine/renderer/shaders.cpp | 2 +- src/engine/renderer/tr_vbo.cpp | 9 +++ 8 files changed, 290 insertions(+), 58 deletions(-) create mode 100644 src/engine/renderer/GLMemory.cpp create mode 100644 src/engine/renderer/GLMemory.h diff --git a/src.cmake b/src.cmake index 8f5f4773dd..e5e4f4974b 100644 --- a/src.cmake +++ b/src.cmake @@ -97,6 +97,8 @@ set(RENDERERLIST ${ENGINE_DIR}/renderer/GeometryCache.h ${ENGINE_DIR}/renderer/GeometryOptimiser.cpp ${ENGINE_DIR}/renderer/GeometryOptimiser.h + ${ENGINE_DIR}/renderer/GLMemory.cpp + ${ENGINE_DIR}/renderer/GLMemory.h ${ENGINE_DIR}/renderer/InternalImage.cpp ${ENGINE_DIR}/renderer/InternalImage.h ${ENGINE_DIR}/renderer/Material.cpp diff --git a/src/engine/renderer/BufferBind.h b/src/engine/renderer/BufferBind.h index 7f4b2c7c8f..3c4d537664 100644 --- a/src/engine/renderer/BufferBind.h +++ b/src/engine/renderer/BufferBind.h @@ -58,6 +58,7 @@ namespace BufferBind { COMMAND_COUNTERS_STORAGE = 9, TEX_DATA_STORAGE = 11, + STAGING = 12, DEBUG = 10, diff --git a/src/engine/renderer/GLMemory.cpp b/src/engine/renderer/GLMemory.cpp new file mode 100644 index 0000000000..e1efaa5544 --- /dev/null +++ b/src/engine/renderer/GLMemory.cpp @@ -0,0 +1,128 @@ +/* +=========================================================================== + +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. + +=========================================================================== +*/ +// GLMemory.cpp + +#include "common/Common.h" + +#include "GLMemory.h" + +// 128 MB, should be enough to fit anything in BAR without going overboard +const GLsizeiptr GLStagingBuffer::SIZE = 128 * 1024 * 1024 / sizeof( uint32_t ); + +GLStagingBuffer stagingBuffer; + +void GLBufferCopy( GLBuffer* src, GLBuffer* dst, GLintptr srcOffset, GLintptr dstOffset, GLsizeiptr size ) { + glCopyNamedBufferSubData( src->id, dst->id, + srcOffset * sizeof( uint32_t ), dstOffset * sizeof( uint32_t ), size * sizeof( uint32_t ) ); +} + +uint32_t* GLStagingBuffer::MapBuffer( const GLsizeiptr size ) { + if ( size > SIZE ) { + Sys::Drop( "Couldn't map GL staging buffer: size too large (%u/%u)", size, SIZE ); + } + + if ( pointer + size > SIZE ) { + FlushAll(); + + GLsync sync = glFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); + + constexpr GLuint64 SYNC_TIMEOUT = 10000000000; // 10 seconds + if ( glClientWaitSync( sync, GL_SYNC_FLUSH_COMMANDS_BIT, SYNC_TIMEOUT ) == GL_TIMEOUT_EXPIRED ) { + Sys::Drop( "Failed GL staging buffer copy sync" ); + } + glDeleteSync( sync ); + + pointer = 0; + current = 0; + last = 0; + } + + uint32_t* ret = buffer.GetData() + pointer; + last = pointer; + pointer += size; + + return ret; +} + +void GLStagingBuffer::FlushBuffer() { + buffer.FlushRange( current, pointer - current ); + + GL_CheckErrors(); + + current = pointer; +} + +void GLStagingBuffer::QueueStagingCopy( GLBuffer* dst, const GLsizeiptr dstOffset ) { + copyQueue[currentCopy].dst = dst; + copyQueue[currentCopy].dstOffset = dstOffset; + copyQueue[currentCopy].stagingOffset = last; + copyQueue[currentCopy].size = pointer - last; + + currentCopy++; + + if ( currentCopy == MAX_COPIES ) { + FlushStagingCopyQueue(); + } +} + +void GLStagingBuffer::FlushStagingCopyQueue() { + for ( GLStagingCopy& copy : copyQueue ) { + if ( copy.dst ) { + GLBufferCopy( &buffer, copy.dst, copy.stagingOffset, copy.dstOffset, copy.size ); + copy.dst = nullptr; + } + } + + currentCopy = 0; + + GL_CheckErrors(); +} + +void GLStagingBuffer::FlushAll() { + FlushBuffer(); + FlushStagingCopyQueue(); +} + +void GLStagingBuffer::InitGLBuffer() { + buffer.GenBuffer(); + + buffer.BufferStorage( SIZE, 1, nullptr ); + buffer.MapAll(); + + GL_CheckErrors(); +} + +void GLStagingBuffer::FreeGLBuffer() { + buffer.DelBuffer(); +} diff --git a/src/engine/renderer/GLMemory.h b/src/engine/renderer/GLMemory.h new file mode 100644 index 0000000000..faba711ec7 --- /dev/null +++ b/src/engine/renderer/GLMemory.h @@ -0,0 +1,78 @@ +/* +=========================================================================== + +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. + +=========================================================================== +*/ +// GLMemory.h + +#ifndef GLMEMORY_H +#define GLMEMORY_H + +#include "gl_shader.h" + +void GLBufferCopy( GLBuffer* src, GLBuffer* dst, GLintptr srcOffset, GLintptr dstOffset, GLsizeiptr size ); + +struct GLStagingCopy { + GLBuffer* dst; + GLsizeiptr stagingOffset; + GLsizeiptr dstOffset; + GLsizeiptr size; +}; + +class GLStagingBuffer { + public: + uint32_t* MapBuffer( const GLsizeiptr size ); + void FlushBuffer(); + void QueueStagingCopy( GLBuffer* dst, const GLsizeiptr dstOffset ); + void FlushStagingCopyQueue(); + void FlushAll(); + + void InitGLBuffer(); + void FreeGLBuffer(); + + private: + static const GLsizeiptr SIZE; + + GLsizeiptr pointer = 0; + GLsizeiptr current = 0; + GLsizeiptr last = 0; + + static const uint32_t MAX_COPIES = 16; + GLStagingCopy copyQueue[MAX_COPIES]; + uint32_t currentCopy = 0; + + GLBuffer buffer = GLBuffer( "staging", BufferBind::STAGING, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT, + GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT ); +}; + +extern GLStagingBuffer stagingBuffer; + +#endif // GLMEMORY_H diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index c27ac58f06..c88d94f89c 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -38,16 +38,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "BufferBind.h" #include "ShadeCommon.h" #include "GeometryCache.h" +#include "GLMemory.h" -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 ); +GLUBO materialsUBO( "materials", BufferBind::MATERIALS, 0, 0 ); +GLBuffer texDataBuffer( "texData", BufferBind::TEX_DATA, 0, 0 ); +GLUBO lightMapDataUBO( "lightMapData", BufferBind::LIGHTMAP_DATA, 0, 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 surfaceDescriptorsSSBO( "surfaceDescriptors", BufferBind::SURFACE_DESCRIPTORS, 0, 0 ); +GLSSBO surfaceCommandsSSBO( "surfaceCommands", BufferBind::SURFACE_COMMANDS, 0, 0 ); +GLBuffer culledCommandsBuffer( "culledCommands", BufferBind::CULLED_COMMANDS, 0, 0 ); +GLUBO surfaceBatchesUBO( "surfaceBatches", BufferBind::SURFACE_BATCHES, 0, 0 ); +GLBuffer atomicCommandCountersBuffer( "atomicCommandCounters", BufferBind::COMMAND_COUNTERS_ATOMIC, 0, 0 ); GLSSBO portalSurfacesSSBO( "portalSurfaces", BufferBind::PORTAL_SURFACES, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT, 0 ); GLSSBO debugSSBO( "debug", BufferBind::DEBUG, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); @@ -426,10 +427,13 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { totalStageSize = offset; // 4 bytes per component - materialsUBO.BufferData( offset, nullptr, GL_DYNAMIC_DRAW ); - uint32_t* materialsData = materialsUBO.MapBufferRange( offset ); + materialsUBO.BufferStorage( totalStageSize, 1, nullptr ); - GenerateMaterialsBuffer( materialStages, offset, materialsData ); + uint32_t* materialsData = stagingBuffer.MapBuffer( totalStageSize ); + + GenerateMaterialsBuffer( materialStages, totalStageSize, materialsData ); + + stagingBuffer.QueueStagingCopy( &materialsUBO, 0 ); for ( shaderStage_t* pStage : materialStages ) { if ( pStage->dynamic ) { @@ -437,7 +441,7 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { } } - materialsUBO.UnmapBuffer(); + GL_CheckErrors(); } void MaterialSystem::GenerateMaterialsBuffer( std::vector& stages, const uint32_t size, uint32_t* materialsData ) { @@ -537,11 +541,6 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s totalDrawSurfs = surfaces.size(); - surfaceDescriptorsCount = totalDrawSurfs; - descriptorSize = BOUNDING_SPHERE_SIZE + maxStages; - surfaceDescriptorsSSBO.BufferData( surfaceDescriptorsCount * descriptorSize, nullptr, GL_STATIC_DRAW ); - uint32_t* surfaceDescriptors = surfaceDescriptorsSSBO.MapBufferRange( surfaceDescriptorsCount * descriptorSize ); - if ( glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ) { texDataBufferType = GL_UNIFORM_BUFFER; texDataBindingPoint = BufferBind::TEX_DATA; @@ -550,10 +549,11 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s texDataBindingPoint = BufferBind::TEX_DATA_STORAGE; } - texDataBuffer.BufferStorage( ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE, 1, nullptr ); - texDataBuffer.MapAll(); - TexBundle* textureBundles = ( TexBundle* ) texDataBuffer.GetData(); - memset( textureBundles, 0, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE * sizeof( uint32_t ) ); + const uint32_t texDataSize = ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE; + texDataBuffer.BufferStorage( texDataSize, 1, nullptr ); + + TexBundle* textureBundles = ( TexBundle* ) stagingBuffer.MapBuffer( texDataSize ); + memset( textureBundles, 0, texDataSize * sizeof( uint32_t ) ); GenerateTexturesBuffer( texData, textureBundles ); @@ -561,15 +561,14 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s GenerateTexturesBuffer( dynamicTexData, textureBundles ); + stagingBuffer.QueueStagingCopy( &texDataBuffer, 0 ); + dynamicTexDataOffset = texData.size() * TEX_BUNDLE_SIZE; dynamicTexDataSize = dynamicTexData.size() * TEX_BUNDLE_SIZE; - texDataBuffer.FlushAll(); - texDataBuffer.UnmapBuffer(); - lightMapDataUBO.BufferStorage( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1, nullptr ); - lightMapDataUBO.MapAll(); - uint64_t* lightMapData = ( uint64_t* ) lightMapDataUBO.GetData(); + + uint64_t* lightMapData = ( uint64_t* ) stagingBuffer.MapBuffer( MAX_LIGHTMAPS * LIGHTMAP_SIZE ); memset( lightMapData, 0, MAX_LIGHTMAPS * LIGHTMAP_SIZE * sizeof( uint32_t ) ); for ( uint32_t i = 0; i < tr.lightmaps.size(); i++ ) { @@ -604,25 +603,20 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s lightMapData[255 * 2 + 1] = tr.blackImage->texture->bindlessTextureHandle; } - lightMapDataUBO.FlushAll(); - lightMapDataUBO.UnmapBuffer(); + stagingBuffer.QueueStagingCopy( &lightMapDataUBO, 0 ); surfaceCommandsCount = totalBatchCount * SURFACE_COMMANDS_PER_BATCH; - surfaceCommandsSSBO.BufferStorage( surfaceCommandsCount * SURFACE_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); - surfaceCommandsSSBO.MapAll(); - SurfaceCommand* surfaceCommands = ( SurfaceCommand* ) surfaceCommandsSSBO.GetData(); - memset( surfaceCommands, 0, surfaceCommandsCount * sizeof( SurfaceCommand ) * MAX_VIEWFRAMES ); - culledCommandsBuffer.BufferStorage( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); - culledCommandsBuffer.MapAll(); - GLIndirectCommand* culledCommands = ( GLIndirectCommand* ) culledCommandsBuffer.GetData(); + GLIndirectCommand* culledCommands = + ( GLIndirectCommand* ) stagingBuffer.MapBuffer( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES ); memset( culledCommands, 0, surfaceCommandsCount * sizeof( GLIndirectCommand ) * MAX_VIEWFRAMES ); - culledCommandsBuffer.FlushAll(); - surfaceBatchesUBO.BufferData( MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE, nullptr, GL_STATIC_DRAW ); + stagingBuffer.QueueStagingCopy( &culledCommandsBuffer, 0 ); + + surfaceBatchesUBO.BufferStorage( MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE, 1, nullptr ); SurfaceCommandBatch* surfaceCommandBatches = - ( SurfaceCommandBatch* ) surfaceBatchesUBO.MapBufferRange( MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE ); + ( SurfaceCommandBatch* ) stagingBuffer.MapBuffer( MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE ); // memset( (void*) surfaceCommandBatches, 0, MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE ); // Fuck off gcc @@ -643,11 +637,14 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s } } + stagingBuffer.QueueStagingCopy( &surfaceBatchesUBO, 0 ); + atomicCommandCountersBuffer.BufferStorage( MAX_COMMAND_COUNTERS * MAX_VIEWS, MAX_FRAMES, nullptr ); - atomicCommandCountersBuffer.MapAll(); - uint32_t* atomicCommandCounters = ( uint32_t* ) atomicCommandCountersBuffer.GetData(); + uint32_t* atomicCommandCounters = stagingBuffer.MapBuffer( MAX_COMMAND_COUNTERS * MAX_VIEWS ); memset( atomicCommandCounters, 0, MAX_COMMAND_COUNTERS * MAX_VIEWFRAMES * sizeof( uint32_t ) ); + stagingBuffer.QueueStagingCopy( &atomicCommandCountersBuffer, 0 ); + /* For use in debugging compute shaders Intended for use with Nsight Graphics to format the output */ if ( r_materialDebug.Get() ) { @@ -659,6 +656,22 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s debugSSBO.UnmapBuffer(); } + stagingBuffer.FlushAll(); + + surfaceDescriptorsCount = totalDrawSurfs; + descriptorSize = BOUNDING_SPHERE_SIZE + maxStages; + surfaceDescriptorsSSBO.BufferStorage( surfaceDescriptorsCount* descriptorSize, 1, nullptr ); + uint32_t* surfaceDescriptors = stagingBuffer.MapBuffer( surfaceDescriptorsCount * descriptorSize ); + + stagingBuffer.QueueStagingCopy( &surfaceDescriptorsSSBO, 0 ); + + surfaceCommandsSSBO.BufferStorage( surfaceCommandsCount * SURFACE_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); + SurfaceCommand* surfaceCommands = + ( SurfaceCommand* ) stagingBuffer.MapBuffer( surfaceCommandsCount * SURFACE_COMMAND_SIZE * MAX_VIEWFRAMES ); + memset( surfaceCommands, 0, surfaceCommandsCount * sizeof( SurfaceCommand ) * MAX_VIEWFRAMES ); + + stagingBuffer.QueueStagingCopy( &surfaceCommandsSSBO, 0 ); + for ( MaterialSurface& surface : surfaces ) { if ( surface.skyBrush ) { continue; @@ -702,6 +715,8 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s for ( int i = 0; i < MAX_VIEWFRAMES; i++ ) { memcpy( surfaceCommands + surfaceCommandsCount * i, surfaceCommands, surfaceCommandsCount * sizeof( SurfaceCommand ) ); } + + stagingBuffer.FlushAll(); uint32_t totalCount = 0; for ( MaterialPack& pack : materialPacks ) { @@ -712,16 +727,6 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s totalStageSize * 4 / 1024.0f, dynamicStagesSize * 4 / 1024.0f, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE * 4 / 1024.0f ); - surfaceDescriptorsSSBO.UnmapBuffer(); - - surfaceCommandsSSBO.UnmapBuffer(); - - culledCommandsBuffer.UnmapBuffer(); - - atomicCommandCountersBuffer.UnmapBuffer(); - - surfaceBatchesUBO.UnmapBuffer(); - GL_CheckErrors(); } @@ -1471,25 +1476,27 @@ void MaterialSystem::AddStageTextures( MaterialSurface* surface, shader_t* shade } } -// Dynamic surfaces are those whose values in the SSBO can be updated +// Dynamic surfaces are those whose values in the UBOs/SSBO might require updating void MaterialSystem::UpdateDynamicSurfaces() { if ( dynamicStagesSize > 0 ) { - uint32_t* materialsData = materialsUBO.MapBufferRange( dynamicStagesOffset, dynamicStagesSize ); + uint32_t* materialsData = stagingBuffer.MapBuffer( dynamicStagesSize ); GenerateMaterialsBuffer( dynamicStages, dynamicStagesSize, materialsData ); - materialsUBO.UnmapBuffer(); + stagingBuffer.QueueStagingCopy( &materialsUBO, dynamicStagesOffset ); } if ( dynamicTexDataSize > 0 ) { TexBundle* textureBundles = - ( TexBundle* ) texDataBuffer.MapBufferRange( dynamicTexDataOffset, dynamicTexDataSize ); + ( TexBundle* ) stagingBuffer.MapBuffer( dynamicTexDataSize ); GenerateTexturesBuffer( dynamicTexData, textureBundles ); - texDataBuffer.UnmapBuffer(); + stagingBuffer.QueueStagingCopy( &texDataBuffer, dynamicTexDataOffset ); } + stagingBuffer.FlushAll(); + GL_CheckErrors(); } diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 0499697c71..93369af69d 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1284,6 +1284,8 @@ class GLBuffer { std::string name; const GLuint64 SYNC_TIMEOUT = 10000000000; // 10 seconds + GLuint id; + GLBuffer( const char* newName, const GLuint newBindingPoint, const GLbitfield newFlags, const GLbitfield newMapFlags ) : name( newName ), internalTarget( 0 ), @@ -1332,6 +1334,8 @@ class GLBuffer { maxAreas = areaCount; glNamedBufferStorage( id, areaSize * areaCount * sizeof( uint32_t ), data, flags ); syncs.resize( areaCount ); + + GL_CheckErrors(); } void AreaIncr() { @@ -1372,6 +1376,10 @@ class GLBuffer { glFlushMappedNamedBufferRange( id, 0, maxAreas * areaSize * sizeof( uint32_t ) ); } + void FlushRange( const GLsizeiptr offset, const GLsizeiptr size ) { + glFlushMappedNamedBufferRange( id, offset * sizeof( uint32_t ), size * sizeof( uint32_t ) ); + } + uint32_t* MapBufferRange( const GLuint count ) { return MapBufferRange( 0, count ); } @@ -1400,14 +1408,13 @@ class GLBuffer { void DelBuffer() { glDeleteBuffers( 1, &id ); + mapped = false; } private: const GLenum internalTarget; const GLuint internalBindingPoint; - GLuint id; - bool mapped = false; const GLbitfield flags; const GLbitfield mapFlags; diff --git a/src/engine/renderer/shaders.cpp b/src/engine/renderer/shaders.cpp index d3cb0e6225..a2252be139 100644 --- a/src/engine/renderer/shaders.cpp +++ b/src/engine/renderer/shaders.cpp @@ -72,7 +72,7 @@ std::unordered_map shadermap({ { "depthReduction_cp.glsl", std::string( reinterpret_cast< const char* >( depthReduction_cp_glsl ), sizeof( depthReduction_cp_glsl ) ) }, { "processSurfaces_cp.glsl", std::string( reinterpret_cast< const char* >( processSurfaces_cp_glsl ), sizeof( processSurfaces_cp_glsl ) ) }, - // Screen-space shaders + // Screen-space shaders { "screenSpace_vp.glsl", std::string( reinterpret_cast< const char* >( screenSpace_vp_glsl ), sizeof( screenSpace_vp_glsl ) ) }, { "blur_fp.glsl", std::string( reinterpret_cast< const char* >( blur_fp_glsl ), sizeof( blur_fp_glsl ) ) }, { "cameraEffects_fp.glsl", std::string( reinterpret_cast< const char* >( cameraEffects_fp_glsl ), sizeof( cameraEffects_fp_glsl ) ) }, diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index 5868845d2f..a452b1a788 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" #include "Material.h" #include "GeometryCache.h" +#include "GLMemory.h" // interleaved data: position, colour, qtangent, texcoord // -> struct shaderVertex_t in tr_local.h @@ -761,6 +762,10 @@ void R_InitVBOs() geometryCache.InitGLBuffers(); } + if ( glConfig2.directStateAccessAvailable && glConfig2.uniformBufferObjectAvailable ) { + stagingBuffer.InitGLBuffer(); + } + GL_CheckErrors(); } @@ -833,6 +838,10 @@ void R_ShutdownVBOs() geometryCache.FreeGLBuffers(); } + if ( glConfig2.directStateAccessAvailable && glConfig2.uniformBufferObjectAvailable ) { + stagingBuffer.FreeGLBuffer(); + } + tess.verts = tess.vertsBuffer = nullptr; tess.indexes = tess.indexesBuffer = nullptr; } From cfc723a952ca0ec2ba433fefb3989745ca178832 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sun, 8 Jun 2025 12:03:23 +0300 Subject: [PATCH 2/4] Use staging buffer for the geometry cache --- src/engine/renderer/GeometryCache.cpp | 24 +++++++++--------------- src/engine/renderer/GeometryCache.h | 5 ++--- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/engine/renderer/GeometryCache.cpp b/src/engine/renderer/GeometryCache.cpp index 8845df99fc..085011a33a 100644 --- a/src/engine/renderer/GeometryCache.cpp +++ b/src/engine/renderer/GeometryCache.cpp @@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "common/Common.h" #include "GeometryCache.h" - +#include "GLMemory.h" #include "tr_local.h" GeometryCache geometryCache; @@ -61,12 +61,6 @@ void GeometryCache::FreeGLBuffers() { 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 ) { @@ -75,28 +69,28 @@ void GeometryCache::AddMapGeometry( const uint32_t verticesNumber, const uint32_ 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(); + uint32_t* VBOVerts = stagingBuffer.MapBuffer( mapVerticesNumber * 8 ); 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(); + + stagingBuffer.QueueStagingCopy( &VBO, 0 ); IBO.BufferStorage( mapIndicesNumber, 1, nullptr ); - IBO.MapAll(); - uint32_t* IBOIndices = IBO.GetData(); + uint32_t* IBOIndices = stagingBuffer.MapBuffer( mapIndicesNumber ); memcpy( IBOIndices, indices, mapIndicesNumber * sizeof( uint32_t ) ); - IBO.UnmapBuffer(); + + stagingBuffer.QueueStagingCopy( &IBO, 0 ); + + stagingBuffer.FlushAll(); glBindVertexArray( backEnd.currentVAO ); } diff --git a/src/engine/renderer/GeometryCache.h b/src/engine/renderer/GeometryCache.h index 7709540e20..ad01502ff2 100644 --- a/src/engine/renderer/GeometryCache.h +++ b/src/engine/renderer/GeometryCache.h @@ -46,7 +46,6 @@ class GeometryCache { void InitGLBuffers(); void FreeGLBuffers(); - void AllocBuffers(); void AddMapGeometry( const uint32_t verticesNumber, const uint32_t indicesNumber, const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd, @@ -59,8 +58,8 @@ class GeometryCache { GLVAO VAO = GLVAO( 0 ); 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 ); + GLBuffer VBO = GLBuffer( "geometryCacheVBO", BufferBind::GEOMETRY_CACHE_VBO, 0, 0 ); + GLBuffer IBO = GLBuffer( "geometryCacheIBO", BufferBind::GEOMETRY_CACHE_IBO, 0, 0 ); }; extern GeometryCache geometryCache; From 0f9e3dcb78f32581f8e57de403d5e106ffdfebd7 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sun, 8 Jun 2025 11:41:52 +0300 Subject: [PATCH 3/4] Fix missing static --- src/engine/renderer/tr_bsp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index 23b85e2cde..3cd0c9b9be 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -919,7 +919,7 @@ static void ParseTriangleSurface( dsurface_t* ds, drawVert_t* verts, bspSurface_ // We may have a nodraw surface, because they might still need to be around for movement clipping if ( s_worldData.shaders[LittleLong( ds->shaderNum )].surfaceFlags & SURF_NODRAW ) { - surfaceType_t skipData = surfaceType_t::SF_SKIP; + static surfaceType_t skipData = surfaceType_t::SF_SKIP; surf->data = &skipData; return; } From e14f912a6995e360c3b4c28def3b29adb8e03877 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Tue, 10 Jun 2025 21:16:55 +0300 Subject: [PATCH 4/4] Material system clean-up --- src/engine/renderer/Material.cpp | 123 +++++++++---------- src/engine/renderer/Material.h | 4 +- src/engine/renderer/gl_shader.cpp | 2 +- src/engine/renderer/gl_shader.h | 12 +- src/engine/renderer/glsl_source/cull_cp.glsl | 4 +- 5 files changed, 69 insertions(+), 76 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index c88d94f89c..e665bff887 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -501,46 +501,7 @@ void MaterialSystem::GenerateTexturesBuffer( std::vector& textures, void MaterialSystem::GenerateWorldCommandBuffer( std::vector& surfaces ) { Log::Debug( "Generating world command buffer" ); - totalBatchCount = 0; - - for ( MaterialSurface& surface : surfaces ) { - if ( surface.skyBrush ) { - continue; - } - - for ( uint8_t stage = 0; stage < surface.stages; stage++ ) { - Material* material = &materialPacks[surface.materialPackIDs[stage]].materials[surface.materialIDs[stage]]; - material->drawCommandCount++; - } - } - - uint32_t batchOffset = 0; - uint32_t globalID = 0; - for ( MaterialPack& pack : materialPacks ) { - for ( Material& material : pack.materials ) { - material.surfaceCommandBatchOffset = batchOffset; - - const uint32_t cmdCount = material.drawCommandCount; - const uint32_t batchCount = cmdCount % SURFACE_COMMANDS_PER_BATCH == 0 ? cmdCount / SURFACE_COMMANDS_PER_BATCH - : cmdCount / SURFACE_COMMANDS_PER_BATCH + 1; - - material.surfaceCommandBatchOffset = batchOffset; - material.surfaceCommandBatchCount = batchCount; - - batchOffset += batchCount; - material.globalID = globalID; - - material.drawCommandCount = 0; - - totalBatchCount += batchCount; - globalID++; - } - } - - Log::Debug( "Total batch count: %u", totalBatchCount ); - - totalDrawSurfs = surfaces.size(); - + // TexBundles if ( glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ) { texDataBufferType = GL_UNIFORM_BUFFER; texDataBindingPoint = BufferBind::TEX_DATA; @@ -566,6 +527,7 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s dynamicTexDataOffset = texData.size() * TEX_BUNDLE_SIZE; dynamicTexDataSize = dynamicTexData.size() * TEX_BUNDLE_SIZE; + // Lightmaps/Deluxemaps lightMapDataUBO.BufferStorage( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1, nullptr ); uint64_t* lightMapData = ( uint64_t* ) stagingBuffer.MapBuffer( MAX_LIGHTMAPS * LIGHTMAP_SIZE ); @@ -605,14 +567,43 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s stagingBuffer.QueueStagingCopy( &lightMapDataUBO, 0 ); - surfaceCommandsCount = totalBatchCount * SURFACE_COMMANDS_PER_BATCH; + // Surface batches + for ( MaterialSurface& surface : surfaces ) { + if ( surface.skyBrush ) { + continue; + } - culledCommandsBuffer.BufferStorage( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); - GLIndirectCommand* culledCommands = - ( GLIndirectCommand* ) stagingBuffer.MapBuffer( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES ); - memset( culledCommands, 0, surfaceCommandsCount * sizeof( GLIndirectCommand ) * MAX_VIEWFRAMES ); + for ( uint8_t stage = 0; stage < surface.stages; stage++ ) { + Material* material = &materialPacks[surface.materialPackIDs[stage]].materials[surface.materialIDs[stage]]; + material->drawCommandCount++; + } + } + + totalBatchCount = 0; + uint32_t batchOffset = 0; + uint32_t globalID = 0; + for ( MaterialPack& pack : materialPacks ) { + for ( Material& material : pack.materials ) { + material.surfaceCommandBatchOffset = batchOffset; + + const uint32_t cmdCount = material.drawCommandCount; + const uint32_t batchCount = cmdCount % SURFACE_COMMANDS_PER_BATCH == 0 ? cmdCount / SURFACE_COMMANDS_PER_BATCH + : cmdCount / SURFACE_COMMANDS_PER_BATCH + 1; + + material.surfaceCommandBatchOffset = batchOffset; + material.surfaceCommandBatchCount = batchCount; + + batchOffset += batchCount; + material.globalID = globalID; + + material.drawCommandCount = 0; + + totalBatchCount += batchCount; + globalID++; + } + } - stagingBuffer.QueueStagingCopy( &culledCommandsBuffer, 0 ); + Log::Debug( "Total batch count: %u", totalBatchCount ); surfaceBatchesUBO.BufferStorage( MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE, 1, nullptr ); SurfaceCommandBatch* surfaceCommandBatches = @@ -639,12 +630,6 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s stagingBuffer.QueueStagingCopy( &surfaceBatchesUBO, 0 ); - atomicCommandCountersBuffer.BufferStorage( MAX_COMMAND_COUNTERS * MAX_VIEWS, MAX_FRAMES, nullptr ); - uint32_t* atomicCommandCounters = stagingBuffer.MapBuffer( MAX_COMMAND_COUNTERS * MAX_VIEWS ); - memset( atomicCommandCounters, 0, MAX_COMMAND_COUNTERS * MAX_VIEWFRAMES * sizeof( uint32_t ) ); - - stagingBuffer.QueueStagingCopy( &atomicCommandCountersBuffer, 0 ); - /* For use in debugging compute shaders Intended for use with Nsight Graphics to format the output */ if ( r_materialDebug.Get() ) { @@ -656,21 +641,31 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s debugSSBO.UnmapBuffer(); } + // Surfaces + surfaceCommandsCount = totalBatchCount * SURFACE_COMMANDS_PER_BATCH; + + culledCommandsBuffer.BufferStorage( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); + + atomicCommandCountersBuffer.BufferStorage( MAX_COMMAND_COUNTERS * MAX_VIEWS, MAX_FRAMES, nullptr ); + uint32_t* atomicCommandCounters = stagingBuffer.MapBuffer( MAX_COMMAND_COUNTERS * MAX_VIEWS ); + memset( atomicCommandCounters, 0, MAX_COMMAND_COUNTERS * MAX_VIEWFRAMES * sizeof( uint32_t ) ); + + stagingBuffer.QueueStagingCopy( &atomicCommandCountersBuffer, 0 ); + stagingBuffer.FlushAll(); - surfaceDescriptorsCount = totalDrawSurfs; + surfaceDescriptorsCount = surfaces.size(); + descriptorSize = BOUNDING_SPHERE_SIZE + maxStages; - surfaceDescriptorsSSBO.BufferStorage( surfaceDescriptorsCount* descriptorSize, 1, nullptr ); + surfaceDescriptorsSSBO.BufferStorage( surfaceDescriptorsCount * descriptorSize, 1, nullptr ); uint32_t* surfaceDescriptors = stagingBuffer.MapBuffer( surfaceDescriptorsCount * descriptorSize ); stagingBuffer.QueueStagingCopy( &surfaceDescriptorsSSBO, 0 ); surfaceCommandsSSBO.BufferStorage( surfaceCommandsCount * SURFACE_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); SurfaceCommand* surfaceCommands = - ( SurfaceCommand* ) stagingBuffer.MapBuffer( surfaceCommandsCount * SURFACE_COMMAND_SIZE * MAX_VIEWFRAMES ); - memset( surfaceCommands, 0, surfaceCommandsCount * sizeof( SurfaceCommand ) * MAX_VIEWFRAMES ); - - stagingBuffer.QueueStagingCopy( &surfaceCommandsSSBO, 0 ); + ( SurfaceCommand* ) stagingBuffer.MapBuffer( surfaceCommandsCount * SURFACE_COMMAND_SIZE ); + memset( surfaceCommands, 0, surfaceCommandsCount * sizeof( SurfaceCommand ) ); for ( MaterialSurface& surface : surfaces ) { if ( surface.skyBrush ) { @@ -713,7 +708,7 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s } for ( int i = 0; i < MAX_VIEWFRAMES; i++ ) { - memcpy( surfaceCommands + surfaceCommandsCount * i, surfaceCommands, surfaceCommandsCount * sizeof( SurfaceCommand ) ); + stagingBuffer.QueueStagingCopy( &surfaceCommandsSSBO, i * surfaceCommandsCount * SURFACE_COMMAND_SIZE ); } stagingBuffer.FlushAll(); @@ -722,7 +717,7 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector& s for ( MaterialPack& pack : materialPacks ) { totalCount += pack.materials.size(); } - Log::Notice( "Generated %u BSP materials from %u BSP surfaces", totalCount, totalDrawSurfs ); + Log::Notice( "Generated %u BSP materials from %u BSP surfaces", totalCount, surfaceDescriptorsCount ); Log::Notice( "Materials UBO: total: %.2f kb, dynamic: %.2f kb, texData: %.2f kb", totalStageSize * 4 / 1024.0f, dynamicStagesSize * 4 / 1024.0f, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE * 4 / 1024.0f ); @@ -1584,12 +1579,12 @@ void MaterialSystem::CullSurfaces() { } gl_cullShader->BindProgram( 0 ); - uint32_t globalWorkGroupX = totalDrawSurfs % MAX_COMMAND_COUNTERS == 0 ? - totalDrawSurfs / MAX_COMMAND_COUNTERS : totalDrawSurfs / MAX_COMMAND_COUNTERS + 1; + uint32_t globalWorkGroupX = surfaceDescriptorsCount % MAX_COMMAND_COUNTERS == 0 ? + surfaceDescriptorsCount / MAX_COMMAND_COUNTERS : surfaceDescriptorsCount / MAX_COMMAND_COUNTERS + 1; GL_Bind( depthImage ); gl_cullShader->SetUniform_Frame( nextFrame ); gl_cullShader->SetUniform_ViewID( view ); - gl_cullShader->SetUniform_TotalDrawSurfs( totalDrawSurfs ); + gl_cullShader->SetUniform_SurfaceDescriptorsCount( surfaceDescriptorsCount ); gl_cullShader->SetUniform_UseFrustumCulling( r_gpuFrustumCulling.Get() ); gl_cullShader->SetUniform_UseOcclusionCulling( r_gpuOcclusionCulling.Get() ); gl_cullShader->SetUniform_CameraPosition( origin ); @@ -1753,7 +1748,7 @@ void MaterialSystem::Free() { buildOneShader = true; - totalDrawSurfs = 0; + surfaceDescriptorsCount = 0; currentFrame = 0; nextFrame = 1; diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 2ab9d2fadd..8ce90cbb19 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -401,11 +401,9 @@ class MaterialSystem { image_t* depthImage; int depthImageLevels; - uint32_t totalDrawSurfs; - uint32_t totalBatchCount = 0; - uint32_t surfaceCommandsCount = 0; uint32_t surfaceDescriptorsCount = 0; + uint32_t totalBatchCount = 0; uint32_t packIDs[3] = { 0, 0, 0 }; diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 498aaff20d..3c9dd7b681 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -3028,7 +3028,7 @@ GLShader_cull::GLShader_cull() : false, "cull" ), u_Frame( this ), u_ViewID( this ), - u_TotalDrawSurfs( this ), + u_SurfaceDescriptorsCount( this ), u_SurfaceCommandsOffset( this ), u_Frustum( this ), u_UseFrustumCulling( this ), diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 93369af69d..60c44bf2e8 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -2764,15 +2764,15 @@ class u_P11 : } }; -class u_TotalDrawSurfs : +class u_SurfaceDescriptorsCount : GLUniform1ui { public: - u_TotalDrawSurfs( GLShader* shader ) : - GLUniform1ui( shader, "u_TotalDrawSurfs", true ) { + u_SurfaceDescriptorsCount( GLShader* shader ) : + GLUniform1ui( shader, "u_SurfaceDescriptorsCount", true ) { } - void SetUniform_TotalDrawSurfs( const uint totalDrawSurfs ) { - this->SetValue( totalDrawSurfs ); + void SetUniform_SurfaceDescriptorsCount( const uint SurfaceDescriptorsCount ) { + this->SetValue( SurfaceDescriptorsCount ); } }; @@ -4153,7 +4153,7 @@ class GLShader_cull : public GLShader, public u_Frame, public u_ViewID, - public u_TotalDrawSurfs, + public u_SurfaceDescriptorsCount, public u_SurfaceCommandsOffset, public u_Frustum, public u_UseFrustumCulling, diff --git a/src/engine/renderer/glsl_source/cull_cp.glsl b/src/engine/renderer/glsl_source/cull_cp.glsl index 201cdc2844..7333e3ffd2 100644 --- a/src/engine/renderer/glsl_source/cull_cp.glsl +++ b/src/engine/renderer/glsl_source/cull_cp.glsl @@ -70,7 +70,7 @@ layout(std430, binding = BIND_PORTAL_SURFACES) restrict buffer portalSurfacesSSB uniform uint u_Frame; uniform uint u_ViewID; -uniform uint u_TotalDrawSurfs; +uniform uint u_SurfaceDescriptorsCount; uniform uint u_SurfaceCommandsOffset; uniform vec4 u_Frustum[6]; // xyz - normal, w - distance uniform bool u_UseFrustumCulling; @@ -198,7 +198,7 @@ void main() { } // Regular surfaces - if( globalInvocationID >= u_TotalDrawSurfs ) { + if( globalInvocationID >= u_SurfaceDescriptorsCount ) { return; } SurfaceDescriptor surface = surfaces[globalInvocationID];