Skip to content

Commit b54267e

Browse files
committed
Generalise uniform post-processing
Also adds `GLShader.pushSkip` and `GLShader._pushUniforms`. Add `padding` back to the `GLShader` size calculations in material system.
1 parent 096daaa commit b54267e

File tree

3 files changed

+79
-38
lines changed

3 files changed

+79
-38
lines changed

src/engine/renderer/Material.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1313,7 +1313,7 @@ void MaterialSystem::ProcessStage( MaterialSurface* surface, shaderStage_t* pSta
13131313

13141314
material.bspSurface = surface->bspSurface;
13151315
pStage->materialProcessor( &material, pStage, surface );
1316-
pStage->paddedSize = material.shader->GetSTD430Size();
1316+
pStage->paddedSize = material.shader->GetSTD430PaddedSize();
13171317

13181318
// HACK: Copy the shaderStage_t and MaterialSurface that we need into the material, so we can use it with glsl_restart
13191319
material.refStage = pStage;

src/engine/renderer/gl_shader.cpp

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,7 +1643,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str
16431643
materialStruct += "};\n\n";
16441644

16451645
// 6 kb for materials
1646-
const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430Size();
1646+
const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430PaddedSize();
16471647
std::string materialBlock = "layout(std140, binding = "
16481648
+ std::to_string( BufferBind::MATERIALS )
16491649
+ ") uniform materialsUBO {\n"
@@ -2109,59 +2109,91 @@ static int FindUniformForAlignment( std::vector<GLUniform*>& uniforms, const GLu
21092109
return -1;
21102110
}
21112111

2112-
// Compute std430 size/alignment and sort uniforms from highest to lowest alignment
2113-
void GLShader::PostProcessUniforms() {
2114-
if ( !_useMaterialSystem ) {
2115-
return;
2116-
}
2117-
2118-
for ( GLUniform* uniform : _uniforms ) {
2119-
if ( !uniform->_global ) {
2120-
_materialSystemUniforms.emplace_back( uniform );
2121-
}
2122-
}
2123-
2124-
std::sort( _materialSystemUniforms.begin(), _materialSystemUniforms.end(),
2112+
GLuint GLShaderManager::SortUniforms( std::vector<GLUniform*>& uniforms ) {
2113+
std::sort( uniforms.begin(), uniforms.end(),
21252114
[]( const GLUniform* lhs, const GLUniform* rhs ) {
21262115
return lhs->_std430Size > rhs->_std430Size;
21272116
}
21282117
);
21292118

2130-
// Sort uniforms from highest to lowest alignment so we don't need to pad uniforms (other than vec3s)
2131-
const uint numUniforms = _materialSystemUniforms.size();
2119+
const uint numUniforms = uniforms.size();
21322120
std::vector<GLUniform*> tmp;
2121+
GLuint structSize = 0;
21332122
while ( tmp.size() < numUniforms ) {
21342123
// Higher-alignment uniforms first to avoid wasting memory
2135-
GLuint size = _materialSystemUniforms[0]->_std430Size;
2136-
GLuint components = _materialSystemUniforms[0]->_components;
2124+
GLuint size = uniforms[0]->_std430Size;
2125+
GLuint components = uniforms[0]->_components;
21372126
size = components ? PAD( size, 4 ) * components : size;
21382127
GLuint alignmentConsume = 4 - size % 4;
2128+
GLuint usedSpace = size;
21392129

2140-
GLUniform* tmpUniform = _materialSystemUniforms[0];
2141-
tmp.emplace_back( _materialSystemUniforms[0] );
2142-
_materialSystemUniforms.erase( _materialSystemUniforms.begin() );
2130+
GLUniform* tmpUniform = uniforms[0];
2131+
tmp.emplace_back( uniforms[0] );
2132+
uniforms.erase( uniforms.begin() );
21432133

21442134
int uniform;
2145-
while ( ( alignmentConsume & 3 ) && _materialSystemUniforms.size()
2146-
&& ( uniform = FindUniformForAlignment( _materialSystemUniforms, alignmentConsume ) ) != -1 ) {
2147-
alignmentConsume -= _materialSystemUniforms[uniform]->_std430Size;
2135+
while ( ( alignmentConsume & 3 ) && uniforms.size()
2136+
&& ( uniform = FindUniformForAlignment( uniforms, alignmentConsume ) ) != -1 ) {
2137+
alignmentConsume -= uniforms[uniform]->_std430Size;
2138+
usedSpace += uniforms[uniform]->_std430Size;
21482139

2149-
tmpUniform = _materialSystemUniforms[uniform];
2140+
tmpUniform = uniforms[uniform];
21502141

2151-
tmp.emplace_back( _materialSystemUniforms[uniform] );
2152-
_materialSystemUniforms.erase( _materialSystemUniforms.begin() + uniform );
2142+
tmp.emplace_back( uniforms[uniform] );
2143+
uniforms.erase( uniforms.begin() + uniform );
21532144
}
21542145

2155-
if ( alignmentConsume ) {
2146+
if ( alignmentConsume & 3 ) {
21562147
tmpUniform->_std430Size += alignmentConsume;
21572148
}
21582149

2159-
size = PAD( size, 4 );
2160-
std430Size += size;
2161-
padding = alignmentConsume;
2150+
if ( uniforms.size() ) {
2151+
structSize += PAD( size, 4 );
2152+
} else {
2153+
structSize += usedSpace;
2154+
}
21622155
}
21632156

2164-
_materialSystemUniforms = tmp;
2157+
uniforms = tmp;
2158+
2159+
return structSize;
2160+
}
2161+
2162+
std::vector<GLUniform*> GLShaderManager::ProcessUniforms( const GLUniform::UpdateType minType, const GLUniform::UpdateType maxType,
2163+
const bool skipTextures,
2164+
std::vector<GLUniform*>& uniforms, GLuint& structSize, GLuint& padding ) {
2165+
std::vector<GLUniform*> tmp;
2166+
2167+
tmp.reserve( uniforms.size() );
2168+
for ( GLUniform* uniform : uniforms ) {
2169+
if ( uniform->_updateType >= minType && uniform->_updateType <= maxType
2170+
&& ( !uniform->_isTexture || !skipTextures ) ) {
2171+
tmp.emplace_back( uniform );
2172+
}
2173+
}
2174+
2175+
structSize = SortUniforms( tmp );
2176+
2177+
const GLuint structAlignment = 4; // Material buffer is now a UBO, so it uses std140 layout, which is aligned to vec4
2178+
if ( structSize > 0 ) {
2179+
padding = ( structAlignment - ( structSize % structAlignment ) ) % structAlignment;
2180+
}
2181+
2182+
return tmp;
2183+
}
2184+
2185+
// Compute std140 size/alignment and sort uniforms from highest to lowest alignment
2186+
void GLShader::PostProcessUniforms() {
2187+
if ( _useMaterialSystem ) {
2188+
_materialSystemUniforms = gl_shaderManager.ProcessUniforms( GLUniform::MATERIAL_OR_PUSH, GLUniform::MATERIAL_OR_PUSH,
2189+
true, _uniforms, std430Size, padding );
2190+
}
2191+
2192+
if ( glConfig2.pushBufferAvailable && !pushSkip ) {
2193+
GLuint unused;
2194+
_pushUniforms = gl_shaderManager.ProcessUniforms( GLUniform::CONST, GLUniform::FRAME,
2195+
false, _uniforms, unused, unused );
2196+
}
21652197
}
21662198

21672199
uint32_t GLShader::GetUniqueCompileMacros( size_t permutation, const int type ) const {

src/engine/renderer/gl_shader.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ class GLShader {
189189
uint32_t padding = 0;
190190

191191
const bool worldShader;
192+
const bool pushSkip;
192193
protected:
193194
int _activeMacros = 0;
194195
ShaderProgramDescriptor* currentProgram;
@@ -203,13 +204,15 @@ class GLShader {
203204

204205
size_t _uniformStorageSize;
205206
std::vector<GLUniform*> _uniforms;
207+
std::vector<GLUniform*> _pushUniforms;
206208
std::vector<GLUniform*> _materialSystemUniforms;
207209
std::vector<GLUniformBlock*> _uniformBlocks;
208210
std::vector<GLCompileMacro*> _compileMacros;
209211

210212
GLShader( const std::string& name, uint32_t vertexAttribsRequired,
211213
const bool useMaterialSystem,
212-
const std::string newVertexShaderName, const std::string newFragmentShaderName ) :
214+
const std::string newVertexShaderName, const std::string newFragmentShaderName,
215+
const bool newPushSkip = false ) :
213216
_name( name ),
214217
_vertexAttribsRequired( vertexAttribsRequired ),
215218
_useMaterialSystem( useMaterialSystem ),
@@ -218,7 +221,8 @@ class GLShader {
218221
hasVertexShader( true ),
219222
hasFragmentShader( true ),
220223
hasComputeShader( false ),
221-
worldShader( false ) {
224+
worldShader( false ),
225+
pushSkip( newPushSkip ) {
222226
}
223227

224228
GLShader( const std::string& name,
@@ -231,7 +235,8 @@ class GLShader {
231235
hasVertexShader( false ),
232236
hasFragmentShader( false ),
233237
hasComputeShader( true ),
234-
worldShader( newWorldShader ) {
238+
worldShader( newWorldShader ),
239+
pushSkip( false ) {
235240
}
236241

237242
public:
@@ -301,8 +306,8 @@ class GLShader {
301306
_vertexAttribs &= ~bit;
302307
}
303308

304-
GLuint GetSTD430Size() const {
305-
return std430Size;
309+
GLuint GetSTD430PaddedSize() const {
310+
return std430Size + padding;
306311
}
307312

308313
bool UseMaterialSystem() const {
@@ -394,6 +399,10 @@ class GLShaderManager {
394399
void GenerateBuiltinHeaders();
395400
void GenerateWorldHeaders();
396401

402+
static GLuint SortUniforms( std::vector<GLUniform*>& uniforms );
403+
static std::vector<GLUniform*> ProcessUniforms( const GLUniform::UpdateType minType, const GLUniform::UpdateType maxType,
404+
const bool skipTextures, std::vector<GLUniform*>& uniforms, GLuint& structSize, GLuint& padding );
405+
397406
template<class T>
398407
void LoadShader( T*& shader ) {
399408
if ( !deformShaderCount ) {

0 commit comments

Comments
 (0)