From 2db100e803f0e7dd38626eb285f969ce1ff8748b Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 14:39:52 +0300 Subject: [PATCH 1/4] Only update PushBuffer if any uniform has actually changed Also mutualises `uniformFirewall` and `currentValue` and removes a bunch of unneeded code. --- libs/breakpad | 2 +- libs/crunch | 2 +- src/engine/renderer/gl_shader.cpp | 28 +- src/engine/renderer/gl_shader.h | 438 +++++++---------------------- src/engine/renderer/tr_backend.cpp | 7 +- src/engine/renderer/tr_bsp.cpp | 7 +- 6 files changed, 135 insertions(+), 349 deletions(-) diff --git a/libs/breakpad b/libs/breakpad index ad5451e89c..fd6cc4ce9f 160000 --- a/libs/breakpad +++ b/libs/breakpad @@ -1 +1 @@ -Subproject commit ad5451e89cf451a90f598ab911f59a1458f1ebda +Subproject commit fd6cc4ce9f41047b13ca1e041726ef7dedb594bd diff --git a/libs/crunch b/libs/crunch index e242bb2a7a..371d9f0cf7 160000 --- a/libs/crunch +++ b/libs/crunch @@ -1 +1 @@ -Subproject commit e242bb2a7ae7efc44d144fd5d621b35baddeab25 +Subproject commit 371d9f0cf74ce31c5d210897c2fb366b830558c0 diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 959cd17e88..fdac7a1d0d 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -218,6 +218,12 @@ GLShaderManager::~GLShaderManager() = default; void GLShaderManager::FreeAll() { + for ( const std::unique_ptr& shader : _shaders ) { + if ( shader.get()->uniformStorage ) { + Z_Free( shader.get()->uniformStorage ); + } + } + _shaders.clear(); deformShaderCount = 0; @@ -236,8 +242,8 @@ void GLShaderManager::FreeAll() { Z_Free( program.uniformBlockIndexes ); } - if ( program.uniformFirewall ) { - Z_Free( program.uniformFirewall ); + if ( program.uniformStorage ) { + Z_Free( program.uniformStorage ); } } @@ -266,7 +272,7 @@ void GLShaderManager::UpdateShaderProgramUniformLocations( GLShader* shader, Sha shaderProgram->uniformLocations = ( GLint* ) Z_Malloc( sizeof( GLint ) * numUniforms ); // create buffer for uniform firewall - shaderProgram->uniformFirewall = ( byte* ) Z_Malloc( uniformSize ); + shaderProgram->uniformStorage = ( uint32_t* ) Z_Malloc( uniformSize ); // update uniforms for (GLUniform *uniform : shader->_uniforms) @@ -1273,10 +1279,16 @@ void GLShaderManager::InitShader( GLShader* shader ) { for ( std::size_t i = 0; i < shader->_uniforms.size(); i++ ) { GLUniform* uniform = shader->_uniforms[i]; uniform->SetLocationIndex( i ); - uniform->SetFirewallIndex( shader->_uniformStorageSize ); - shader->_uniformStorageSize += uniform->GetSize(); + uniform->SetUniformStorageOffset( shader->_uniformStorageSize ); + + const uint32_t size = uniform->_components ? uniform->_std430Size * uniform->_components : uniform->_std430Size; + shader->_uniformStorageSize += size; } + shader->_uniformStorageSize *= sizeof( uint32_t ); + + shader->uniformStorage = ( uint32_t* ) Z_Malloc( shader->_uniformStorageSize ); + for ( std::size_t i = 0; i < shader->_uniformBlocks.size(); i++ ) { GLUniformBlock* uniformBlock = shader->_uniformBlocks[i]; uniformBlock->SetLocationIndex( i ); @@ -2136,10 +2148,6 @@ bool GLCompileMacro_USE_BSP_SURFACE::HasConflictingMacros(size_t permutation, co return false; } -uint32_t* GLUniform::WriteToBuffer( uint32_t * ) { - Sys::Error( "WriteToBuffer not implemented for GLUniform '%s'", _name ); -} - void GLShader::RegisterUniform( GLUniform* uniform ) { _uniforms.push_back( uniform ); } @@ -2425,6 +2433,8 @@ void GLShader::WriteUniformsToBuffer( uint32_t* buffer, const Mode mode, const i bufPtr = uniform->WriteToBuffer( bufPtr ); } } + + uniformsUpdated = false; } GLShader_generic::GLShader_generic() : diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 78e62ad221..6e4bf35354 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -28,8 +28,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "GLUtils.h" #include -#define USE_UNIFORM_FIREWALL 1 - // *INDENT-OFF* static const unsigned int MAX_SHADER_MACROS = 10; static const unsigned int GL_SHADER_VERSION = 6; @@ -128,7 +126,7 @@ struct ShaderProgramDescriptor { GLint* uniformLocations; GLuint* uniformBlockIndexes = nullptr; - byte* uniformFirewall; + uint32_t* uniformStorage; uint32_t checkSum; @@ -204,6 +202,7 @@ class GLShader { std::vector computeShaderDescriptors; size_t _uniformStorageSize; + std::vector _uniforms; std::vector _pushUniforms; std::vector _materialSystemUniforms; @@ -281,6 +280,9 @@ class GLShader { PUSH }; + uint32_t* uniformStorage = nullptr; + bool uniformsUpdated = true; + void MarkProgramForBuilding(); GLuint GetProgram( const bool buildOneShader ); void BindProgram(); @@ -345,6 +347,7 @@ class GLUniform { const GLuint _std430BaseSize; GLuint _std430Size; // includes padding that depends on the other uniforms in the struct const GLuint _std430Alignment; + GLuint _nextUniformOffset; const UpdateType _updateType; const int _components; @@ -352,8 +355,8 @@ class GLUniform { protected: GLShader* _shader; - size_t _firewallIndex; size_t _locationIndex; + size_t _uniformStorageOffset; GLUniform( GLShader* shader, const char* name, const char* type, const GLuint std430Size, const GLuint std430Alignment, const UpdateType updateType, const int components = 0, @@ -363,6 +366,7 @@ class GLUniform { _std430BaseSize( std430Size ), _std430Size( std430Size ), _std430Alignment( std430Alignment ), + _nextUniformOffset( components ? components * 4 : std430Size ), _updateType( updateType ), _components( components ), _isTexture( isTexture ), @@ -370,19 +374,61 @@ class GLUniform { _shader->RegisterUniform( this ); } - public: - virtual ~GLUniform() = default; + bool CacheValue( void* value ) { + uint32_t* currentValue; + + const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ); + + if ( bufferUniform ) { + currentValue = _shader->uniformStorage + _uniformStorageOffset; + } else { + ShaderProgramDescriptor* p = _shader->GetProgram(); + ASSERT_EQ( p, glState.currentProgram ); + + currentValue = p->uniformStorage + _uniformStorageOffset; + } + + const uint32_t size = _components ? _std430Size * _components : _std430Size; + const bool updated = memcmp( currentValue, value, size * sizeof( uint32_t ) ); + + if ( updated ) { + memcpy( currentValue, value, size * sizeof( uint32_t ) ); + _shader->uniformsUpdated = true; + } - void SetFirewallIndex( size_t offSetValue ) { - _firewallIndex = offSetValue; + return updated && !bufferUniform; } + public: + virtual ~GLUniform() = default; + void SetLocationIndex( size_t index ) { _locationIndex = index; } + void SetUniformStorageOffset( size_t index ) { + _uniformStorageOffset = index; + } + // This should return a pointer to the memory right after the one this uniform wrote to - virtual uint32_t* WriteToBuffer( uint32_t* buffer ); + uint32_t* WriteToBuffer( uint32_t* buffer ) { + uint32_t* currentValue; + + const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ); + + if ( bufferUniform ) { + currentValue = _shader->uniformStorage + _uniformStorageOffset; + } else { + return buffer; + } + + const uint32_t size = _components ? _std430Size * _components : _std430Size; + memcpy( buffer, currentValue, size * sizeof( uint32_t ) ); + + return buffer + _nextUniformOffset; + } void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, _name.c_str() ); @@ -545,38 +591,22 @@ class GLUniformSampler : protected GLUniform { } void SetValue( GLuint value ) { - currentValue = value; + if ( !CacheValue( &value ) ) { + return; + } } - void SetValueBindless( GLint64 value ) { - currentValueBindless = value; - - if ( glConfig.usingBindlessTextures ) { - if ( _shader->UseMaterialSystem() && _updateType == TEXDATA_OR_PUSH ) { - return; - } - - if ( glConfig.pushBufferAvailable && _updateType <= FRAME ) { - return; - } - - glUniformHandleui64ARB( GetLocation(), currentValueBindless ); + void SetValueBindless( GLuint64 value ) { + if ( !glConfig.usingBindlessTextures ) { + return; } - } - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - if ( glConfig.usingBindlessTextures ) { - memcpy( buffer, ¤tValueBindless, sizeof( GLuint64 ) ); - } else { - memcpy( buffer, ¤tValue, sizeof( GLint ) ); + if ( !CacheValue( &value ) ) { + return; } - return buffer + _std430Size; + glUniformHandleui64ARB( GetLocation(), value ); } - - private: - GLuint64 currentValueBindless = 0; - GLuint currentValue = 0; }; class GLUniformSampler2D : protected GLUniformSampler { @@ -611,32 +641,16 @@ class GLUniform1i : protected GLUniform { protected: GLUniform1i( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "int", 1, 1, updateType ) - { + GLUniform( shader, name, "int", 1, 1, updateType ) { } inline void SetValue( int value ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - currentValue = value; - return; - } - - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - int *firewall = ( int * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( *firewall == value ) - { + if ( !CacheValue( &value ) ) { return; } - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1i( p->uniformLocations[ _locationIndex ], value ); } public: @@ -644,14 +658,6 @@ class GLUniform1i : protected GLUniform { return sizeof( int ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( int ) ); - return buffer + _std430Size; - } - - private: - int currentValue = 0; }; class GLUniform1ui : protected GLUniform { @@ -661,39 +667,17 @@ class GLUniform1ui : protected GLUniform { } inline void SetValue( uint value ) { - ShaderProgramDescriptor* p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - currentValue = value; - return; - } - - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - uint* firewall = ( uint* ) &p->uniformFirewall[_firewallIndex]; - - if ( *firewall == value ) { + if ( !CacheValue( &value ) ) { return; } - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1ui( p->uniformLocations[_locationIndex], value ); } public: size_t GetSize() override { return sizeof( uint ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( uint ) ); - return buffer + _std430Size; - } - - private: - uint currentValue = 0; }; class GLUniform1Bool : protected GLUniform { @@ -704,25 +688,11 @@ class GLUniform1Bool : protected GLUniform { } inline void SetValue( int value ) { - ShaderProgramDescriptor* p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - currentValue = value; - return; - } - - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - int* firewall = ( int* ) &p->uniformFirewall[_firewallIndex]; - - if ( *firewall == value ) { + if ( !CacheValue( &value ) ) { return; } - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1i( p->uniformLocations[_locationIndex], value ); } @@ -730,46 +700,22 @@ class GLUniform1Bool : protected GLUniform { size_t GetSize() override { return sizeof( int ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( int ) ); - return buffer + _std430Size; - } - - private: - int currentValue = 0; }; class GLUniform1f : protected GLUniform { protected: GLUniform1f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "float", 1, 1, updateType ) - { + GLUniform( shader, name, "float", 1, 1, updateType ) { } inline void SetValue( float value ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - currentValue = value; + if ( !CacheValue( &value ) ) { return; } - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - float *firewall = ( float * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( *firewall == value ) - { - return; - } - - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1f( p->uniformLocations[ _locationIndex ], value ); } public: @@ -777,77 +723,40 @@ class GLUniform1f : protected GLUniform { return sizeof( float ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( float ) ); - return buffer + _std430Size; - } - - private: - float currentValue = 0; }; class GLUniform1fv : protected GLUniform { protected: GLUniform1fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : - GLUniform( shader, name, "float", 1, 1, updateType, size ) - { - currentValue.reserve( size ); + GLUniform( shader, name, "float", 1, 1, updateType, size ) { } inline void SetValue( int numFloats, float *f ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue.data(), f, numFloats * sizeof( float ) ); + if ( !CacheValue( f ) ) { return; } - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - - glUniform1fv( p->uniformLocations[ _locationIndex ], numFloats, f ); + ShaderProgramDescriptor* p = _shader->GetProgram(); + glUniform1fv( p->uniformLocations[_locationIndex], numFloats, f ); } - - private: - std::vector currentValue; }; class GLUniform2f : protected GLUniform { protected: GLUniform2f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "vec2", 2, 2, updateType ) - { - currentValue[0] = 0.0; - currentValue[1] = 0.0; + GLUniform( shader, name, "vec2", 2, 2, updateType ) { } inline void SetValue( const vec2_t v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - Vector2Copy( v, currentValue ); - return; - } - - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - vec2_t *firewall = ( vec2_t * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( ( *firewall )[ 0 ] == v[ 0 ] && ( *firewall )[ 1 ] == v[ 1 ] ) - { + if ( !CacheValue( ( void* ) v ) ) { return; } - ( *firewall )[ 0 ] = v[ 0 ]; - ( *firewall )[ 1 ] = v[ 1 ]; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform2f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ] ); } @@ -855,49 +764,22 @@ class GLUniform2f : protected GLUniform { return sizeof( vec2_t ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( vec2_t ) ); - return buffer + _std430Size; - } - - private: - vec2_t currentValue; }; class GLUniform3f : protected GLUniform { protected: GLUniform3f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "vec3", 3, 4, updateType ) - { - currentValue[0] = 0.0; - currentValue[1] = 0.0; - currentValue[2] = 0.0; + GLUniform( shader, name, "vec3", 3, 4, updateType ) { } inline void SetValue( const vec3_t v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - VectorCopy( v, currentValue ); - return; - } - - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - vec3_t *firewall = ( vec3_t * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( VectorCompare( *firewall, v ) ) - { + if ( !CacheValue( ( void* ) v ) ) { return; } - VectorCopy( v, *firewall ); -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform3f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ] ); } public: @@ -905,50 +787,22 @@ class GLUniform3f : protected GLUniform { return sizeof( vec3_t ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( vec3_t ) ); - return buffer + _std430Size; - } - - private: - vec3_t currentValue; }; class GLUniform4f : protected GLUniform { protected: GLUniform4f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "vec4", 4, 4, updateType ) - { - currentValue[0] = 0.0; - currentValue[1] = 0.0; - currentValue[2] = 0.0; - currentValue[3] = 0.0; + GLUniform( shader, name, "vec4", 4, 4, updateType ) { } inline void SetValue( const vec4_t v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - Vector4Copy( v, currentValue ); + if ( !CacheValue( ( void* ) v ) ) { return; } - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - vec4_t *firewall = ( vec4_t * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( !memcmp( *firewall, v, sizeof( *firewall ) ) ) - { - return; - } - - Vector4Copy( v, *firewall ); -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform4f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); } public: @@ -956,81 +810,40 @@ class GLUniform4f : protected GLUniform { return sizeof( vec4_t ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( vec4_t ) ); - return buffer + _std430Size; - } - - private: - vec4_t currentValue; }; class GLUniform4fv : protected GLUniform { protected: GLUniform4fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : - GLUniform( shader, name, "vec4", 4, 4, updateType, size ) - { - currentValue.reserve( size ); + GLUniform( shader, name, "vec4", 4, 4, updateType, size ) { } inline void SetValue( int numV, vec4_t *v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue.data(), v, numV * sizeof( vec4_t ) ); + if ( !CacheValue( v ) ) { return; } - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform4fv( p->uniformLocations[ _locationIndex ], numV, &v[ 0 ][ 0 ] ); } - - public: - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, currentValue.data(), currentValue.size() * sizeof( float ) ); - return buffer + _std430Size * _components; - } - - private: - std::vector currentValue; }; class GLUniformMatrix4f : protected GLUniform { protected: GLUniformMatrix4f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "mat4", 16, 4, updateType ) - { - MatrixIdentity( currentValue ); + GLUniform( shader, name, "mat4", 16, 4, updateType ) { } inline void SetValue( GLboolean transpose, const matrix_t m ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - MatrixCopy( m, currentValue ); + if ( !CacheValue( ( void* ) m ) ) { return; } - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - matrix_t *firewall = ( matrix_t * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( MatrixCompare( m, *firewall ) ) - { - return; - } - - MatrixCopy( m, *firewall ); -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix4fv( p->uniformLocations[ _locationIndex ], 1, transpose, m ); } public: @@ -1038,14 +851,6 @@ class GLUniformMatrix4f : protected GLUniform { return sizeof( matrix_t ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( matrix_t ) ); - return buffer + _std430Size; - } - - private: - matrix_t currentValue; }; class GLUniformMatrix32f : protected GLUniform { @@ -1055,59 +860,38 @@ class GLUniformMatrix32f : protected GLUniform { } inline void SetValue( GLboolean transpose, const vec_t* m ) { - ShaderProgramDescriptor* p = _shader->GetProgram(); + vec_t value[12] {}; + memcpy( value, m, 6 * sizeof( vec_t ) ); - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue, m, 6 * sizeof( float ) ); + if ( !CacheValue( value ) ) { return; } - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix3x2fv( p->uniformLocations[_locationIndex], 1, transpose, m ); } public: size_t GetSize() override { return 6 * sizeof( float ); } - - private: - vec_t currentValue[6] {}; }; class GLUniformMatrix4fv : protected GLUniform { protected: GLUniformMatrix4fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : - GLUniform( shader, name, "mat4", 16, 4, updateType, size ) - { - currentValue.reserve( size * 16 ); + GLUniform( shader, name, "mat4", 16, 4, updateType, size ) { } inline void SetValue( int numMatrices, GLboolean transpose, const matrix_t *m ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue.data(), m, numMatrices * sizeof( matrix_t ) ); + if ( !CacheValue( ( void* ) m ) ) { return; } - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix4fv( p->uniformLocations[ _locationIndex ], numMatrices, transpose, &m[ 0 ][ 0 ] ); } - - public: - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, currentValue.data(), currentValue.size() * sizeof( float ) ); - return buffer + _std430Size * _components; - } - - private: - std::vector currentValue; }; class GLUniformMatrix34fv : protected GLUniform @@ -1120,27 +904,13 @@ class GLUniformMatrix34fv : protected GLUniform inline void SetValue( int numMatrices, GLboolean transpose, const float *m ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue.data(), m, numMatrices * sizeof( matrix_t ) ); + if ( !CacheValue( ( void* ) m ) ) { return; } - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - - glUniformMatrix3x4fv( p->uniformLocations[ _locationIndex ], numMatrices, transpose, m ); - } - - public: - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, currentValue.data(), currentValue.size() * sizeof( float ) ); - return buffer + _std430Size * _components; + ShaderProgramDescriptor* p = _shader->GetProgram(); + glUniformMatrix3x4fv( p->uniformLocations[_locationIndex], numMatrices, transpose, m ); } - - private: - std::vector currentValue; }; class GLUniformBlock @@ -2606,7 +2376,7 @@ class u_Bones : { public: u_Bones( GLShader *shader ) : - GLUniform4fv( shader, "u_Bones", MAX_BONES, PUSH ) + GLUniform4fv( shader, "u_Bones", MAX_BONES * 2, PUSH ) { } diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index ee8427aa94..b7848e9d2c 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -2820,8 +2820,6 @@ static void SetFrameUniforms() { GLIMP_LOGCOMMENT( "--- SetFrameUniforms ---" ); - uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::FRAME ); - globalUBOProxy->SetUniform_blurVec( tr.refdef.blurVec ); globalUBOProxy->SetUniform_numLights( tr.refdef.numLights ); @@ -2842,6 +2840,11 @@ static void SetFrameUniforms() { materialSystem.SetFrameUniforms(); } + if ( !globalUBOProxy->uniformsUpdated ) { + return; + } + + uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::FRAME ); globalUBOProxy->WriteUniformsToBuffer( data, GLShader::PUSH, GLUniform::FRAME ); pushBuffer.PushGlobalUniforms(); diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index a91b5fbfcb..d03844d401 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -4644,8 +4644,6 @@ static void SetWorldLight() { static void SetConstUniforms() { GLIMP_LOGCOMMENT( "--- SetConstUniforms ---" ); - uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::CONST ); - globalUBOProxy->SetUniform_LightGridOrigin( tr.world->lightGridGLOrigin ); globalUBOProxy->SetUniform_LightGridScale( tr.world->lightGridGLScale ); @@ -4687,6 +4685,11 @@ static void SetConstUniforms() { materialSystem.SetConstUniforms(); } + if ( !globalUBOProxy->uniformsUpdated ) { + return; + } + + uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::CONST ); globalUBOProxy->WriteUniformsToBuffer( data, GLShader::PUSH, GLUniform::CONST ); pushBuffer.PushGlobalUniforms(); From 03ebb6be051ed5d41d1ef69fa44e0ef3a8f2be49 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 25 Jun 2025 08:55:28 +0300 Subject: [PATCH 2/4] NUKE unused GLUniform.GetSize() --- src/engine/renderer/gl_shader.h | 54 +-------------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 6e4bf35354..ed944a04ab 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -345,7 +345,6 @@ class GLUniform { // In multiples of 4 bytes // FIXME: the uniform structs are actually std140 so it would be more relevant to provide std140 info const GLuint _std430BaseSize; - GLuint _std430Size; // includes padding that depends on the other uniforms in the struct const GLuint _std430Alignment; GLuint _nextUniformOffset; @@ -374,7 +373,7 @@ class GLUniform { _shader->RegisterUniform( this ); } - bool CacheValue( void* value ) { + bool CacheValue( const void* value ) { uint32_t* currentValue; const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) @@ -433,10 +432,6 @@ class GLUniform { void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, _name.c_str() ); } - - virtual size_t GetSize() { - return 0; - } }; class GLShaderManager { @@ -586,10 +581,6 @@ class GLUniformSampler : protected GLUniform { } public: - size_t GetSize() override { - return sizeof( GLuint64 ); - } - void SetValue( GLuint value ) { if ( !CacheValue( &value ) ) { return; @@ -653,11 +644,6 @@ class GLUniform1i : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1i( p->uniformLocations[ _locationIndex ], value ); } -public: - size_t GetSize() override - { - return sizeof( int ); - } }; class GLUniform1ui : protected GLUniform { @@ -674,10 +660,6 @@ class GLUniform1ui : protected GLUniform { ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1ui( p->uniformLocations[_locationIndex], value ); } - public: - size_t GetSize() override { - return sizeof( uint ); - } }; class GLUniform1Bool : protected GLUniform { @@ -695,11 +677,6 @@ class GLUniform1Bool : protected GLUniform { ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1i( p->uniformLocations[_locationIndex], value ); } - - public: - size_t GetSize() override { - return sizeof( int ); - } }; class GLUniform1f : protected GLUniform @@ -718,11 +695,6 @@ class GLUniform1f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1f( p->uniformLocations[ _locationIndex ], value ); } -public: - size_t GetSize() override - { - return sizeof( float ); - } }; class GLUniform1fv : protected GLUniform @@ -759,11 +731,6 @@ class GLUniform2f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform2f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ] ); } - - size_t GetSize() override - { - return sizeof( vec2_t ); - } }; class GLUniform3f : protected GLUniform @@ -782,11 +749,6 @@ class GLUniform3f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform3f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ] ); } -public: - size_t GetSize() override - { - return sizeof( vec3_t ); - } }; class GLUniform4f : protected GLUniform @@ -805,11 +767,6 @@ class GLUniform4f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform4f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); } -public: - size_t GetSize() override - { - return sizeof( vec4_t ); - } }; class GLUniform4fv : protected GLUniform @@ -846,11 +803,6 @@ class GLUniformMatrix4f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix4fv( p->uniformLocations[ _locationIndex ], 1, transpose, m ); } -public: - size_t GetSize() override - { - return sizeof( matrix_t ); - } }; class GLUniformMatrix32f : protected GLUniform { @@ -870,10 +822,6 @@ class GLUniformMatrix32f : protected GLUniform { ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix3x2fv( p->uniformLocations[_locationIndex], 1, transpose, m ); } - public: - size_t GetSize() override { - return 6 * sizeof( float ); - } }; class GLUniformMatrix4fv : protected GLUniform From 857f94fd0b870b732989cef8e2fefc89eb58a0fa Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 25 Jun 2025 08:58:40 +0300 Subject: [PATCH 3/4] Add GLUniform.bufferSize as a shorthand for _std430Size * max( 1, _components ) --- src/engine/renderer/gl_shader.cpp | 3 +-- src/engine/renderer/gl_shader.h | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index fdac7a1d0d..0526d2c5aa 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1281,8 +1281,7 @@ void GLShaderManager::InitShader( GLShader* shader ) { uniform->SetLocationIndex( i ); uniform->SetUniformStorageOffset( shader->_uniformStorageSize ); - const uint32_t size = uniform->_components ? uniform->_std430Size * uniform->_components : uniform->_std430Size; - shader->_uniformStorageSize += size; + shader->_uniformStorageSize += uniform->_bufferSize; } shader->_uniformStorageSize *= sizeof( uint32_t ); diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index ed944a04ab..5fb67382be 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -346,6 +346,7 @@ class GLUniform { // FIXME: the uniform structs are actually std140 so it would be more relevant to provide std140 info const GLuint _std430BaseSize; const GLuint _std430Alignment; + const GLuint _bufferSize; GLuint _nextUniformOffset; const UpdateType _updateType; @@ -365,6 +366,7 @@ class GLUniform { _std430BaseSize( std430Size ), _std430Size( std430Size ), _std430Alignment( std430Alignment ), + _bufferSize( components ? components * 4 : std430Size ), _nextUniformOffset( components ? components * 4 : std430Size ), _updateType( updateType ), _components( components ), @@ -388,11 +390,10 @@ class GLUniform { currentValue = p->uniformStorage + _uniformStorageOffset; } - const uint32_t size = _components ? _std430Size * _components : _std430Size; - const bool updated = memcmp( currentValue, value, size * sizeof( uint32_t ) ); + const bool updated = memcmp( currentValue, value, _bufferSize * sizeof( uint32_t ) ); if ( updated ) { - memcpy( currentValue, value, size * sizeof( uint32_t ) ); + memcpy( currentValue, value, _bufferSize * sizeof( uint32_t ) ); _shader->uniformsUpdated = true; } @@ -423,8 +424,7 @@ class GLUniform { return buffer; } - const uint32_t size = _components ? _std430Size * _components : _std430Size; - memcpy( buffer, currentValue, size * sizeof( uint32_t ) ); + memcpy( buffer, currentValue, _bufferSize * sizeof( uint32_t ) ); return buffer + _nextUniformOffset; } From 553f6d95c1e6c4f756528a37240b3c2a9706c105 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 9 Jan 2026 04:29:56 +0300 Subject: [PATCH 4/4] GLUniform cache clean-up --- src/engine/renderer/gl_shader.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 5fb67382be..84b658bde1 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -345,6 +345,7 @@ class GLUniform { // In multiples of 4 bytes // FIXME: the uniform structs are actually std140 so it would be more relevant to provide std140 info const GLuint _std430BaseSize; + GLuint _std430Size; // includes padding that depends on the other uniforms in the struct const GLuint _std430Alignment; const GLuint _bufferSize; GLuint _nextUniformOffset; @@ -379,13 +380,13 @@ class GLUniform { uint32_t* currentValue; const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ); + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ); if ( bufferUniform ) { currentValue = _shader->uniformStorage + _uniformStorageOffset; } else { ShaderProgramDescriptor* p = _shader->GetProgram(); - ASSERT_EQ( p, glState.currentProgram ); + DAEMON_ASSERT_EQ( p, glState.currentProgram ); currentValue = p->uniformStorage + _uniformStorageOffset; } @@ -416,7 +417,7 @@ class GLUniform { uint32_t* currentValue; const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ); + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ); if ( bufferUniform ) { currentValue = _shader->uniformStorage + _uniformStorageOffset;