@@ -2092,14 +2092,14 @@ GLint GLShader::GetUniformLocation( const GLchar *uniformName ) const {
20922092 return glGetUniformLocation ( p->id , uniformName );
20932093}
20942094
2095- static int FindUniformForAlignment ( std::vector<GLUniform*>& uniforms, const GLuint alignment ) {
2096- for ( uint32_t i = 0 ; i < uniforms.size (); i++ ) {
2097- if ( uniforms[i]-> _std430Size <= alignment ) {
2098- return i ;
2095+ static auto FindUniformForOffset ( std::vector<GLUniform*>& uniforms, const GLuint baseOffset ) {
2096+ for ( auto it = uniforms. begin (); it != uniforms.end (); ++it ) {
2097+ if ( 0 == ( ( (*it)-> _std430Alignment - 1 ) & baseOffset ) ) {
2098+ return it ;
20992099 }
21002100 }
21012101
2102- return - 1 ;
2102+ return uniforms. end () ;
21032103}
21042104
21052105// Compute std430 size/alignment and sort uniforms from highest to lowest alignment
@@ -2108,52 +2108,36 @@ void GLShader::PostProcessUniforms() {
21082108 return ;
21092109 }
21102110
2111+ std::vector<GLUniform*> uniformQueue;
21112112 for ( GLUniform* uniform : _uniforms ) {
21122113 if ( !uniform->_global ) {
2113- _materialSystemUniforms .emplace_back ( uniform );
2114+ uniformQueue .emplace_back ( uniform );
21142115 }
21152116 }
21162117
2117- std::sort ( _materialSystemUniforms .begin (), _materialSystemUniforms .end (),
2118+ std::stable_sort ( uniformQueue .begin (), uniformQueue .end (),
21182119 []( const GLUniform* lhs, const GLUniform* rhs ) {
2119- return lhs->_std430Size > rhs->_std430Size ;
2120+ return lhs->_std430Alignment > rhs->_std430Alignment ;
21202121 }
21212122 );
21222123
21232124 // Sort uniforms from highest to lowest alignment so we don't need to pad uniforms (other than vec3s)
2124- const uint numUniforms = _materialSystemUniforms.size ();
2125- std::vector<GLUniform*> tmp;
2126- while ( tmp.size () < numUniforms ) {
2127- // Higher-alignment uniforms first to avoid wasting memory
2128- GLuint size = _materialSystemUniforms[0 ]->_std430Size ;
2129- GLuint components = _materialSystemUniforms[0 ]->_components ;
2130- size = components ? PAD ( size, 4 ) * components : size;
2131- GLuint alignmentConsume = PAD ( size, 4 ) - size;
2132-
2133- GLUniform* tmpUniform = _materialSystemUniforms[0 ];
2134- tmp.emplace_back ( _materialSystemUniforms[0 ] );
2135- _materialSystemUniforms.erase ( _materialSystemUniforms.begin () );
2136-
2137- int uniform;
2138- while ( alignmentConsume && _materialSystemUniforms.size ()
2139- && ( uniform = FindUniformForAlignment ( _materialSystemUniforms, alignmentConsume ) ) != -1 ) {
2140- alignmentConsume -= _materialSystemUniforms[uniform]->_std430Size ;
2141-
2142- tmpUniform = _materialSystemUniforms[uniform];
2143-
2144- tmp.emplace_back ( _materialSystemUniforms[uniform] );
2145- _materialSystemUniforms.erase ( _materialSystemUniforms.begin () + uniform );
2146- }
2147-
2148- if ( alignmentConsume ) {
2149- tmpUniform->_std430Size += alignmentConsume;
2125+ GLuint align = 1 ;
2126+ std430Size = 0 ;
2127+ _materialSystemUniforms.clear ();
2128+ while ( !uniformQueue.empty () || std430Size & ( align - 1 ) ) {
2129+ auto iterNext = FindUniformForOffset ( uniformQueue, std430Size );
2130+ if ( iterNext == uniformQueue.end () ) {
2131+ // add 1 unit of padding
2132+ ++std430Size;
2133+ ++_materialSystemUniforms.back ()->_std430Size ;
2134+ } else {
2135+ std430Size += ( *iterNext )->_std430Size ;
2136+ align = std::max ( align, ( *iterNext )->_std430Alignment );
2137+ _materialSystemUniforms.push_back ( *iterNext );
2138+ uniformQueue.erase ( iterNext );
21502139 }
2151-
2152- size = PAD ( size, 4 );
2153- std430Size += size;
21542140 }
2155-
2156- _materialSystemUniforms = tmp;
21572141}
21582142
21592143uint32_t GLShader::GetUniqueCompileMacros ( size_t permutation, const int type ) const {
0 commit comments