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..0526d2c5aa 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,15 @@ 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 ); + + shader->_uniformStorageSize += uniform->_bufferSize; } + 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 +2147,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 +2432,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..84b658bde1 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,8 @@ class GLUniform { const GLuint _std430BaseSize; GLuint _std430Size; // includes padding that depends on the other uniforms in the struct const GLuint _std430Alignment; + const GLuint _bufferSize; + GLuint _nextUniformOffset; const UpdateType _updateType; const int _components; @@ -352,8 +356,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 +367,8 @@ class GLUniform { _std430BaseSize( std430Size ), _std430Size( std430Size ), _std430Alignment( std430Alignment ), + _bufferSize( components ? components * 4 : std430Size ), + _nextUniformOffset( components ? components * 4 : std430Size ), _updateType( updateType ), _components( components ), _isTexture( isTexture ), @@ -370,26 +376,62 @@ class GLUniform { _shader->RegisterUniform( this ); } - public: - virtual ~GLUniform() = default; + bool CacheValue( const void* value ) { + uint32_t* currentValue; + + const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ); + + if ( bufferUniform ) { + currentValue = _shader->uniformStorage + _uniformStorageOffset; + } else { + ShaderProgramDescriptor* p = _shader->GetProgram(); + DAEMON_ASSERT_EQ( p, glState.currentProgram ); + + currentValue = p->uniformStorage + _uniformStorageOffset; + } + + const bool updated = memcmp( currentValue, value, _bufferSize * sizeof( uint32_t ) ); + + if ( updated ) { + memcpy( currentValue, value, _bufferSize * 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; - void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { - shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, _name.c_str() ); + const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ); + + if ( bufferUniform ) { + currentValue = _shader->uniformStorage + _uniformStorageOffset; + } else { + return buffer; + } + + memcpy( buffer, currentValue, _bufferSize * sizeof( uint32_t ) ); + + return buffer + _nextUniformOffset; } - virtual size_t GetSize() { - return 0; + void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { + shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, _name.c_str() ); } }; @@ -540,43 +582,23 @@ class GLUniformSampler : protected GLUniform { } public: - size_t GetSize() override { - return sizeof( GLuint64 ); - } - 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,47 +633,18 @@ 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; + if ( !CacheValue( &value ) ) { return; } - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - int *firewall = ( int * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( *firewall == value ) - { - return; - } - - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1i( p->uniformLocations[ _locationIndex ], value ); } -public: - 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 GLUniform1ui : protected GLUniform { @@ -661,39 +654,13 @@ 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,348 +671,139 @@ 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 ); } - - public: - 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: - size_t GetSize() override - { - 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 ] ); } - - size_t GetSize() override - { - 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: - size_t GetSize() override - { - 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: - size_t GetSize() override - { - 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: - size_t GetSize() override - { - 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 +813,34 @@ 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 +853,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 +2325,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();