@@ -1642,7 +1642,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str
1642
1642
materialStruct += " };\n\n " ;
1643
1643
1644
1644
// 6 kb for materials
1645
- const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430Size ();
1645
+ const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430PaddedSize ();
1646
1646
std::string materialBlock = " layout(std140, binding = "
1647
1647
+ std::to_string ( BufferBind::MATERIALS )
1648
1648
+ " ) uniform materialsUBO {\n "
@@ -2108,59 +2108,91 @@ static int FindUniformForAlignment( std::vector<GLUniform*>& uniforms, const GLu
2108
2108
return -1 ;
2109
2109
}
2110
2110
2111
- // Compute std430 size/alignment and sort uniforms from highest to lowest alignment
2112
- void GLShader::PostProcessUniforms () {
2113
- if ( !_useMaterialSystem ) {
2114
- return ;
2115
- }
2116
-
2117
- for ( GLUniform* uniform : _uniforms ) {
2118
- if ( !uniform->_global ) {
2119
- _materialSystemUniforms.emplace_back ( uniform );
2120
- }
2121
- }
2122
-
2123
- std::sort ( _materialSystemUniforms.begin (), _materialSystemUniforms.end (),
2111
+ GLuint GLShaderManager::SortUniforms ( std::vector<GLUniform*>& uniforms ) {
2112
+ std::sort ( uniforms.begin (), uniforms.end (),
2124
2113
[]( const GLUniform* lhs, const GLUniform* rhs ) {
2125
2114
return lhs->_std430Size > rhs->_std430Size ;
2126
2115
}
2127
2116
);
2128
2117
2129
- // Sort uniforms from highest to lowest alignment so we don't need to pad uniforms (other than vec3s)
2130
- const uint numUniforms = _materialSystemUniforms.size ();
2118
+ const uint numUniforms = uniforms.size ();
2131
2119
std::vector<GLUniform*> tmp;
2120
+ GLuint structSize = 0 ;
2132
2121
while ( tmp.size () < numUniforms ) {
2133
2122
// Higher-alignment uniforms first to avoid wasting memory
2134
- GLuint size = _materialSystemUniforms [0 ]->_std430Size ;
2135
- GLuint components = _materialSystemUniforms [0 ]->_components ;
2123
+ GLuint size = uniforms [0 ]->_std430Size ;
2124
+ GLuint components = uniforms [0 ]->_components ;
2136
2125
size = components ? PAD ( size, 4 ) * components : size;
2137
2126
GLuint alignmentConsume = 4 - size % 4 ;
2127
+ GLuint usedSpace = size;
2138
2128
2139
- GLUniform* tmpUniform = _materialSystemUniforms [0 ];
2140
- tmp.emplace_back ( _materialSystemUniforms [0 ] );
2141
- _materialSystemUniforms .erase ( _materialSystemUniforms .begin () );
2129
+ GLUniform* tmpUniform = uniforms [0 ];
2130
+ tmp.emplace_back ( uniforms [0 ] );
2131
+ uniforms .erase ( uniforms .begin () );
2142
2132
2143
2133
int uniform;
2144
- while ( ( alignmentConsume & 3 ) && _materialSystemUniforms.size ()
2145
- && ( uniform = FindUniformForAlignment ( _materialSystemUniforms, alignmentConsume ) ) != -1 ) {
2146
- alignmentConsume -= _materialSystemUniforms[uniform]->_std430Size ;
2134
+ while ( ( alignmentConsume & 3 ) && uniforms.size ()
2135
+ && ( uniform = FindUniformForAlignment ( uniforms, alignmentConsume ) ) != -1 ) {
2136
+ alignmentConsume -= uniforms[uniform]->_std430Size ;
2137
+ usedSpace += uniforms[uniform]->_std430Size ;
2147
2138
2148
- tmpUniform = _materialSystemUniforms [uniform];
2139
+ tmpUniform = uniforms [uniform];
2149
2140
2150
- tmp.emplace_back ( _materialSystemUniforms [uniform] );
2151
- _materialSystemUniforms .erase ( _materialSystemUniforms .begin () + uniform );
2141
+ tmp.emplace_back ( uniforms [uniform] );
2142
+ uniforms .erase ( uniforms .begin () + uniform );
2152
2143
}
2153
2144
2154
- if ( alignmentConsume ) {
2145
+ if ( alignmentConsume & 3 ) {
2155
2146
tmpUniform->_std430Size += alignmentConsume;
2156
2147
}
2157
2148
2158
- size = PAD ( size, 4 );
2159
- std430Size += size;
2160
- padding = alignmentConsume;
2149
+ if ( uniforms.size () ) {
2150
+ structSize += PAD ( size, 4 );
2151
+ } else {
2152
+ structSize += usedSpace;
2153
+ }
2161
2154
}
2162
2155
2163
- _materialSystemUniforms = tmp;
2156
+ uniforms = tmp;
2157
+
2158
+ return structSize;
2159
+ }
2160
+
2161
+ std::vector<GLUniform*> GLShaderManager::ProcessUniforms ( const GLUniform::UpdateType minType, const GLUniform::UpdateType maxType,
2162
+ const bool skipTextures,
2163
+ std::vector<GLUniform*>& uniforms, GLuint& structSize, GLuint& padding ) {
2164
+ std::vector<GLUniform*> tmp;
2165
+
2166
+ tmp.reserve ( uniforms.size () );
2167
+ for ( GLUniform* uniform : uniforms ) {
2168
+ if ( uniform->_updateType >= minType && uniform->_updateType <= maxType
2169
+ && ( !uniform->_isTexture || !skipTextures ) ) {
2170
+ tmp.emplace_back ( uniform );
2171
+ }
2172
+ }
2173
+
2174
+ structSize = SortUniforms ( tmp );
2175
+
2176
+ const GLuint structAlignment = 4 ; // Material buffer is now a UBO, so it uses std140 layout, which is aligned to vec4
2177
+ if ( structSize > 0 ) {
2178
+ padding = ( structAlignment - ( structSize % structAlignment ) ) % structAlignment;
2179
+ }
2180
+
2181
+ return tmp;
2182
+ }
2183
+
2184
+ // Compute std140 size/alignment and sort uniforms from highest to lowest alignment
2185
+ void GLShader::PostProcessUniforms () {
2186
+ if ( _useMaterialSystem ) {
2187
+ _materialSystemUniforms = gl_shaderManager.ProcessUniforms ( GLUniform::MATERIAL_OR_PUSH, GLUniform::MATERIAL_OR_PUSH,
2188
+ true , _uniforms, std430Size, padding );
2189
+ }
2190
+
2191
+ if ( glConfig2.pushBufferAvailable && !pushSkip ) {
2192
+ GLuint unused;
2193
+ _pushUniforms = gl_shaderManager.ProcessUniforms ( GLUniform::CONST, GLUniform::FRAME,
2194
+ false , _uniforms, unused, unused );
2195
+ }
2164
2196
}
2165
2197
2166
2198
uint32_t GLShader::GetUniqueCompileMacros ( size_t permutation, const int type ) const {
0 commit comments