Skip to content

Commit 5b7d732

Browse files
committed
Clarify function of material uniform struct packing
It's actually std140 not std430, so fix comment and GLShader member names to reflect that. (GLUniform still has the old _std430XXX names though.) Since it cannot handle arrays, add an assert that the uniforms are not arrays. Also delete WriteToBuffer implementations that assume std430 layout for arrays.
1 parent 4a85964 commit 5b7d732

File tree

4 files changed

+21
-32
lines changed

4 files changed

+21
-32
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->GetSTD140Size();
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: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,7 +1578,7 @@ void GLShaderManager::GenerateUniformStructDefinesText( const std::vector<GLUnif
15781578

15791579
// This will generate all the extra code for material system shaders
15801580
std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::string& shaderText, const uint32_t offset ) {
1581-
if ( !shader->std430Size ) {
1581+
if ( !shader->std140Size ) {
15821582
return shaderText;
15831583
}
15841584

@@ -1641,7 +1641,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str
16411641
materialStruct += "};\n\n";
16421642

16431643
// 6 kb for materials
1644-
const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430Size();
1644+
const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD140Size();
16451645
std::string materialBlock = "layout(std140, binding = "
16461646
+ std::to_string( BufferBind::MATERIALS )
16471647
+ ") uniform materialsUBO {\n"
@@ -2084,8 +2084,8 @@ bool GLCompileMacro_USE_BSP_SURFACE::HasConflictingMacros(size_t permutation, co
20842084
return false;
20852085
}
20862086

2087-
uint32_t* GLUniform::WriteToBuffer( uint32_t* buffer ) {
2088-
return buffer;
2087+
uint32_t* GLUniform::WriteToBuffer( uint32_t * ) {
2088+
Sys::Error( "WriteToBuffer not implemented for GLUniform '%s'", _name );
20892089
}
20902090

20912091
void GLShader::RegisterUniform( GLUniform* uniform ) {
@@ -2107,7 +2107,9 @@ static auto FindUniformForOffset( std::vector<GLUniform*>& uniforms, const GLuin
21072107
return uniforms.end();
21082108
}
21092109

2110-
// Compute std430 size/alignment and sort uniforms from highest to lowest alignment
2110+
// Compute std140 size/alignment and sort uniforms from highest to lowest alignment
2111+
// Note: using the std430 uniform size will give the wrong result for matrix types where
2112+
// the number of rows is not 4
21112113
void GLShader::PostProcessUniforms() {
21122114
if ( !_useMaterialSystem ) {
21132115
return;
@@ -2128,17 +2130,18 @@ void GLShader::PostProcessUniforms() {
21282130

21292131
// Sort uniforms from highest to lowest alignment so we don't need to pad uniforms (other than vec3s)
21302132
GLuint align = 4; // mininum alignment since this will be used as an std140 array element
2131-
std430Size = 0;
2133+
std140Size = 0;
21322134
_materialSystemUniforms.clear();
2133-
while ( !uniformQueue.empty() || std430Size & ( align - 1 ) ) {
2134-
auto iterNext = FindUniformForOffset( uniformQueue, std430Size );
2135+
while ( !uniformQueue.empty() || std140Size & ( align - 1 ) ) {
2136+
auto iterNext = FindUniformForOffset( uniformQueue, std140Size );
21352137
if ( iterNext == uniformQueue.end() ) {
21362138
// add 1 unit of padding
2137-
++std430Size;
2139+
++std140Size;
21382140
++_materialSystemUniforms.back()->_std430Size;
21392141
} else {
2142+
ASSERT_EQ( 0, ( *iterNext )->_components ); // array handling not implemented
21402143
( *iterNext )->_std430Size = ( *iterNext )->_std430BaseSize;
2141-
std430Size += ( *iterNext )->_std430Size;
2144+
std140Size += ( *iterNext )->_std430Size;
21422145
align = std::max( align, ( *iterNext )->_std430Alignment );
21432146
_materialSystemUniforms.push_back( *iterNext );
21442147
uniformQueue.erase( iterNext );

src/engine/renderer/gl_shader.h

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ class GLShader {
185185
const bool hasFragmentShader;
186186
const bool hasComputeShader;
187187

188-
GLuint std430Size = 0;
188+
GLuint std140Size = 0;
189189

190190
const bool worldShader;
191191
protected:
@@ -300,8 +300,8 @@ class GLShader {
300300
_vertexAttribs &= ~bit;
301301
}
302302

303-
GLuint GetSTD430Size() const {
304-
return std430Size;
303+
GLuint GetSTD140Size() const {
304+
return std140Size;
305305
}
306306

307307
bool UseMaterialSystem() const {
@@ -317,6 +317,7 @@ class GLUniform {
317317
const std::string _type;
318318

319319
// In multiples of 4 bytes
320+
// FIXME: the uniform structs are actually std140 so it would be more relevant to provide std140 info
320321
const GLuint _std430BaseSize;
321322
GLuint _std430Size; // includes padding that depends on the other uniforms in the struct
322323
const GLuint _std430Alignment;
@@ -690,11 +691,6 @@ class GLUniform1Bool : protected GLUniform {
690691
return sizeof( int );
691692
}
692693

693-
uint32_t* WriteToBuffer( uint32_t *buffer ) override {
694-
memcpy( buffer, &currentValue, sizeof( bool ) );
695-
return buffer + _std430Size;
696-
}
697-
698694
private:
699695
int currentValue = 0;
700696
};
@@ -772,11 +768,6 @@ class GLUniform1fv : protected GLUniform
772768
glUniform1fv( p->uniformLocations[ _locationIndex ], numFloats, f );
773769
}
774770

775-
uint32_t* WriteToBuffer( uint32_t* buffer ) override {
776-
memcpy( buffer, currentValue.data(), currentValue.size() * sizeof( float ) );
777-
return buffer + _components * _std430Size;
778-
}
779-
780771
private:
781772
std::vector<float> currentValue;
782773
};
@@ -1044,11 +1035,6 @@ class GLUniformMatrix32f : protected GLUniform {
10441035
return 6 * sizeof( float );
10451036
}
10461037

1047-
uint32_t* WriteToBuffer( uint32_t* buffer ) override {
1048-
memcpy( buffer, currentValue, 6 * sizeof( float ) );
1049-
return buffer + _std430Size * _components;
1050-
}
1051-
10521038
private:
10531039
vec_t currentValue[6] {};
10541040
};

src/engine/renderer/gl_shader_test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ TEST(MaterialUniformPackingTest, OneMatrix)
6767

6868
Shader1 shader1;
6969
std::vector<GLUniform*> uniforms = shader1.GetUniforms();
70-
EXPECT_EQ(shader1.GetSTD430Size(), 16u);
70+
EXPECT_EQ(shader1.GetSTD140Size(), 16u);
7171
ASSERT_EQ(uniforms.size(), 1);
7272
EXPECT_EQ(uniforms[0], Get<u_ModelViewMatrix>(shader1));
7373
EXPECT_EQ(uniforms[0]->_std430Size, 16u);
@@ -85,7 +85,7 @@ TEST(MaterialUniformPackingTest, TwoFloats)
8585

8686
Shader1 shader1;
8787
std::vector<GLUniform*> uniforms = shader1.GetUniforms();
88-
EXPECT_EQ(shader1.GetSTD430Size(), 4u);
88+
EXPECT_EQ(shader1.GetSTD140Size(), 4u);
8989
ASSERT_EQ(uniforms.size(), 2);
9090
EXPECT_EQ(uniforms[0], Get<u_DeformMagnitude>(shader1));
9191
EXPECT_EQ(uniforms[0]->_std430Size, 1u);
@@ -110,7 +110,7 @@ TEST(MaterialUniformPackingTest, Vec3Handling)
110110

111111
Shader1 shader1;
112112
std::vector<GLUniform*> uniforms = shader1.GetUniforms();
113-
EXPECT_EQ(shader1.GetSTD430Size(), 12u);
113+
EXPECT_EQ(shader1.GetSTD140Size(), 12u);
114114
ASSERT_EQ(uniforms.size(), 4);
115115
EXPECT_EQ(uniforms[0], Get<u_FogColor>(shader1));
116116
EXPECT_EQ(uniforms[0]->_std430Size, 3u);

0 commit comments

Comments
 (0)