Skip to content

Commit 5ae10a8

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 8a5ed34 commit 5ae10a8

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
@@ -1642,7 +1642,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str
16421642
materialStruct += "};\n\n";
16431643

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

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(),
21242113
[]( const GLUniform* lhs, const GLUniform* rhs ) {
21252114
return lhs->_std430Size > rhs->_std430Size;
21262115
}
21272116
);
21282117

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();
21312119
std::vector<GLUniform*> tmp;
2120+
GLuint structSize = 0;
21322121
while ( tmp.size() < numUniforms ) {
21332122
// 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;
21362125
size = components ? PAD( size, 4 ) * components : size;
21372126
GLuint alignmentConsume = 4 - size % 4;
2127+
GLuint usedSpace = size;
21382128

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() );
21422132

21432133
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;
21472138

2148-
tmpUniform = _materialSystemUniforms[uniform];
2139+
tmpUniform = uniforms[uniform];
21492140

2150-
tmp.emplace_back( _materialSystemUniforms[uniform] );
2151-
_materialSystemUniforms.erase( _materialSystemUniforms.begin() + uniform );
2141+
tmp.emplace_back( uniforms[uniform] );
2142+
uniforms.erase( uniforms.begin() + uniform );
21522143
}
21532144

2154-
if ( alignmentConsume ) {
2145+
if ( alignmentConsume & 3 ) {
21552146
tmpUniform->_std430Size += alignmentConsume;
21562147
}
21572148

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+
}
21612154
}
21622155

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+
}
21642196
}
21652197

21662198
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
@@ -105,6 +105,7 @@ class GLShader {
105105
uint32_t padding = 0;
106106

107107
const bool worldShader;
108+
const bool pushSkip;
108109
protected:
109110
int _activeMacros = 0;
110111
ShaderProgramDescriptor* currentProgram;
@@ -119,13 +120,15 @@ class GLShader {
119120

120121
size_t _uniformStorageSize;
121122
std::vector<GLUniform*> _uniforms;
123+
std::vector<GLUniform*> _pushUniforms;
122124
std::vector<GLUniform*> _materialSystemUniforms;
123125
std::vector<GLUniformBlock*> _uniformBlocks;
124126
std::vector<GLCompileMacro*> _compileMacros;
125127

126128
GLShader( const std::string& name, uint32_t vertexAttribsRequired,
127129
const bool useMaterialSystem,
128-
const std::string newVertexShaderName, const std::string newFragmentShaderName ) :
130+
const std::string newVertexShaderName, const std::string newFragmentShaderName,
131+
const bool newPushSkip = false ) :
129132
_name( name ),
130133
_vertexAttribsRequired( vertexAttribsRequired ),
131134
_useMaterialSystem( useMaterialSystem ),
@@ -134,7 +137,8 @@ class GLShader {
134137
hasVertexShader( true ),
135138
hasFragmentShader( true ),
136139
hasComputeShader( false ),
137-
worldShader( false ) {
140+
worldShader( false ),
141+
pushSkip( newPushSkip ) {
138142
}
139143

140144
GLShader( const std::string& name,
@@ -147,7 +151,8 @@ class GLShader {
147151
hasVertexShader( false ),
148152
hasFragmentShader( false ),
149153
hasComputeShader( true ),
150-
worldShader( newWorldShader ) {
154+
worldShader( newWorldShader ),
155+
pushSkip( false ) {
151156
}
152157

153158
public:
@@ -217,8 +222,8 @@ class GLShader {
217222
_vertexAttribs &= ~bit;
218223
}
219224

220-
GLuint GetSTD430Size() const {
221-
return std430Size;
225+
GLuint GetSTD430PaddedSize() const {
226+
return std430Size + padding;
222227
}
223228

224229
bool UseMaterialSystem() const {
@@ -393,6 +398,10 @@ class GLShaderManager {
393398
void GenerateBuiltinHeaders();
394399
void GenerateWorldHeaders();
395400

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

0 commit comments

Comments
 (0)