From b8d158dc5ec21978d11793980dc7307e05856d64 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Thu, 19 Jun 2025 00:12:31 +0300 Subject: [PATCH 01/12] Defer shader building This will be required for PushBuffer. --- src/engine/renderer/gl_shader.cpp | 2 +- src/engine/renderer/gl_shader.h | 31 +++++++++++++++++++++++++------ src/engine/renderer/tr_shade.cpp | 10 +++++++--- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index b8d3efca39..7138ff4937 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -2992,7 +2992,7 @@ void GLShader_fxaa::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderPro GLShader_cull::GLShader_cull() : GLShader( "cull", - false, "cull" ), + false, "cull", true ), u_Frame( this ), u_ViewID( this ), u_SurfaceDescriptorsCount( this ), diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index e13df92ff8..beafc052f5 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -103,6 +103,8 @@ class GLShader { GLuint std430Size = 0; uint32_t padding = 0; + + const bool worldShader; protected: int _activeMacros = 0; ShaderProgramDescriptor* currentProgram; @@ -131,19 +133,21 @@ class GLShader { fragmentShaderName( newFragmentShaderName ), hasVertexShader( true ), hasFragmentShader( true ), - hasComputeShader( false ) { + hasComputeShader( false ), + worldShader( false ) { } GLShader( const std::string& name, const bool useMaterialSystem, - const std::string newComputeShaderName ) : + const std::string newComputeShaderName, const bool newWorldShader = false ) : _name( name ), _vertexAttribsRequired( 0 ), _useMaterialSystem( useMaterialSystem ), computeShaderName( newComputeShaderName ), hasVertexShader( false ), hasFragmentShader( false ), - hasComputeShader( true ) { + hasComputeShader( true ), + worldShader( newWorldShader ) { } public: @@ -387,19 +391,34 @@ class GLShaderManager { void GenerateWorldHeaders(); template - void LoadShader( T *& shader ) { - if( !deformShaderCount ) { + void LoadShader( T*& shader ) { + if ( !deformShaderCount ) { Q_UNUSED( GetDeformShaderIndex( nullptr, 0 ) ); initTime = 0; initCount = 0; } shader = new T(); - InitShader( shader ); _shaders.emplace_back( shader ); _shaderBuildQueue.push( shader ); } + void InitShaders() { + for ( const std::unique_ptr& shader : _shaders ) { + if ( !shader.get()->worldShader ) { + InitShader( shader.get() ); + } + } + } + + void InitWorldShaders() { + for ( const std::unique_ptr& shader : _shaders ) { + if ( shader.get()->worldShader ) { + InitShader( shader.get() ); + } + } + } + int GetDeformShaderIndex( deformStage_t *deforms, int numDeforms ); bool BuildPermutation( GLShader* shader, int macroIndex, int deformIndex, const bool buildOneShader ); diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index abb1a2a8d2..adc705763a 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -190,10 +190,10 @@ void GLSL_InitWorldShaders() { // Material system shaders that are always loaded if material system is available if ( glConfig2.usingMaterialSystem ) { - gl_shaderManager.LoadShader( gl_cullShader ); - gl_cullShader->MarkProgramForBuilding( 0 ); } + + gl_shaderManager.InitWorldShaders(); } static void GLSL_InitGPUShadersOrError() @@ -224,6 +224,9 @@ static void GLSL_InitGPUShadersOrError() gl_shaderManager.LoadShader( gl_lightMappingShaderMaterial ); gl_shaderManager.LoadShader( gl_clearSurfacesShader ); + /* Load gl_cullShader so we can post-process it correctly for push buffer, + it will only actually be built in GLSL_InitWorldShaders() */ + gl_shaderManager.LoadShader( gl_cullShader ); gl_shaderManager.LoadShader( gl_processSurfacesShader ); gl_shaderManager.LoadShader( gl_depthReductionShader ); @@ -320,7 +323,6 @@ static void GLSL_InitGPUShadersOrError() gl_contrastShader->MarkProgramForBuilding( 0 ); } - // portal process effect gl_shaderManager.LoadShader( gl_portalShader ); @@ -371,6 +373,8 @@ static void GLSL_InitGPUShadersOrError() gl_fxaaShader->MarkProgramForBuilding( 0 ); } + gl_shaderManager.InitShaders(); + if ( r_lazyShaders.Get() == 0 ) { gl_shaderManager.BuildAll( false ); From b7ad8ed10baf4362c775ccecc38dd56f93bdbcfa Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 20 Jun 2025 13:45:18 +0300 Subject: [PATCH 02/12] Bind lightgrid/deluxegrid to separate slots from lightmap/deluxemap --- src/engine/renderer/Material.cpp | 4 ++-- src/engine/renderer/gl_shader.cpp | 4 ++-- src/engine/renderer/tr_local.h | 2 ++ src/engine/renderer/tr_shade.cpp | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 89f3c7a210..c95626d426 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -828,12 +828,12 @@ void BindShaderLightMapping( Material* material ) { // bind u_LightGrid1 if ( material->enableGridLighting ) { - gl_lightMappingShaderMaterial->SetUniform_LightGrid1Bindless( GL_BindToTMU( BIND_LIGHTMAP, tr.lightGrid1Image ) ); + gl_lightMappingShaderMaterial->SetUniform_LightGrid1Bindless( GL_BindToTMU( BIND_LIGHTGRID1, tr.lightGrid1Image ) ); } // bind u_LightGrid2 if ( material->enableGridDeluxeMapping ) { - gl_lightMappingShaderMaterial->SetUniform_LightGrid2Bindless( GL_BindToTMU( BIND_DELUXEMAP, tr.lightGrid2Image ) ); + gl_lightMappingShaderMaterial->SetUniform_LightGrid2Bindless( GL_BindToTMU( BIND_LIGHTGRID2, tr.lightGrid2Image ) ); } if ( glConfig2.realtimeLighting ) { diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 7138ff4937..b99997da78 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -2455,9 +2455,9 @@ void GLShader_lightMapping::SetShaderProgramUniforms( ShaderProgramDescriptor *s glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), BIND_HEIGHTMAP ); glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), BIND_MATERIALMAP ); glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightMap" ), BIND_LIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid1" ), BIND_LIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid1" ), BIND_LIGHTGRID1 ); glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DeluxeMap" ), BIND_DELUXEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid2" ), BIND_DELUXEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid2" ), BIND_LIGHTGRID2 ); glUniform1i( glGetUniformLocation( shaderProgram->id, "u_GlowMap" ), BIND_GLOWMAP ); glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 4f47fa0e44..9a6b29c4c1 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -448,6 +448,8 @@ enum class ssaoMode { BIND_LIGHTMAP, BIND_DELUXEMAP, BIND_GLOWMAP, + BIND_LIGHTGRID1, + BIND_LIGHTGRID2, BIND_ENVIRONMENTMAP0, BIND_ENVIRONMENTMAP1, BIND_LIGHTTILES, diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index adc705763a..e44517a906 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -1188,7 +1188,7 @@ void Render_lightMapping( shaderStage_t *pStage ) GL_BindToTMU( BIND_LIGHTMAP, lightmap ) ); } else { - gl_lightMappingShader->SetUniform_LightGrid1Bindless( GL_BindToTMU( BIND_LIGHTMAP, lightmap ) ); + gl_lightMappingShader->SetUniform_LightGrid1Bindless( GL_BindToTMU( BIND_LIGHTGRID1, lightmap ) ); } // bind u_DeluxeMap @@ -1197,7 +1197,7 @@ void Render_lightMapping( shaderStage_t *pStage ) GL_BindToTMU( BIND_DELUXEMAP, deluxemap ) ); } else { - gl_lightMappingShader->SetUniform_LightGrid2Bindless( GL_BindToTMU( BIND_DELUXEMAP, deluxemap ) ); + gl_lightMappingShader->SetUniform_LightGrid2Bindless( GL_BindToTMU( BIND_LIGHTGRID2, deluxemap ) ); } // bind u_GlowMap From 8a798fad0f7cabe5b92e17b929ec2e758d7eda48 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:06:40 +0300 Subject: [PATCH 03/12] Use separate binds/uniforms for depthtile1/2 textures --- src/engine/renderer/gl_shader.cpp | 4 +-- src/engine/renderer/gl_shader.h | 28 +++++++++++++++++-- .../renderer/glsl_source/depthtile2_fp.glsl | 4 +-- .../renderer/glsl_source/lighttile_fp.glsl | 4 +-- src/engine/renderer/tr_backend.cpp | 4 +-- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index b99997da78..5c672656ca 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -2950,7 +2950,7 @@ void GLShader_depthtile1::SetShaderProgramUniforms( ShaderProgramDescriptor *sha GLShader_depthtile2::GLShader_depthtile2() : GLShader( "depthtile2", ATTR_POSITION, false, "screenSpace", "depthtile2" ), - u_DepthMap( this ) { + u_DepthTile1( this ) { } void GLShader_depthtile2::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) @@ -2961,7 +2961,7 @@ void GLShader_depthtile2::SetShaderProgramUniforms( ShaderProgramDescriptor *sha GLShader_lighttile::GLShader_lighttile() : GLShader( "lighttile", ATTR_POSITION | ATTR_TEXCOORD, false, "lighttile", "lighttile" ), - u_DepthMap( this ), + u_DepthTile2( this ), u_Lights( this ), u_numLights( this ), u_lightLayer( this ), diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index beafc052f5..1cc7e18ca6 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1840,6 +1840,30 @@ class u_FogMap : } }; +class u_DepthTile1 : + GLUniformSampler2D { + public: + u_DepthTile1( GLShader* shader ) : + GLUniformSampler2D( shader, "u_DepthTile1" ) { + } + + void SetUniform_DepthTile1Bindless( GLuint64 bindlessHandle ) { + this->SetValueBindless( bindlessHandle ); + } +}; + +class u_DepthTile2 : + GLUniformSampler2D { + public: + u_DepthTile2( GLShader* shader ) : + GLUniformSampler2D( shader, "u_DepthTile2" ) { + } + + void SetUniform_DepthTile2Bindless( GLuint64 bindlessHandle ) { + this->SetValueBindless( bindlessHandle ); + } +}; + class u_LightTiles : GLUniformSampler3D { public: @@ -3674,7 +3698,7 @@ class GLShader_depthtile1 : class GLShader_depthtile2 : public GLShader, - public u_DepthMap { + public u_DepthTile1 { public: GLShader_depthtile2(); void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; @@ -3682,7 +3706,7 @@ class GLShader_depthtile2 : class GLShader_lighttile : public GLShader, - public u_DepthMap, + public u_DepthTile2, public u_Lights, public u_numLights, public u_lightLayer, diff --git a/src/engine/renderer/glsl_source/depthtile2_fp.glsl b/src/engine/renderer/glsl_source/depthtile2_fp.glsl index 7ede250cc6..92ae506a50 100644 --- a/src/engine/renderer/glsl_source/depthtile2_fp.glsl +++ b/src/engine/renderer/glsl_source/depthtile2_fp.glsl @@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* depthtile2_fp.glsl */ -uniform sampler2D u_DepthMap; +uniform sampler2D u_DepthTile1; #if __VERSION__ > 120 out vec4 outputColor; @@ -51,7 +51,7 @@ void main() for( x = -0.375; x < 0.5; x += 0.25 ) { for( y = -0.375; y < 0.5; y += 0.25 ) { - vec4 data = texture2D( u_DepthMap, st + vec2(x, y) * r_tileStep ); + vec4 data = texture2D( u_DepthTile1, st + vec2(x, y) * r_tileStep ); if( data.y < 99999.0 ) { accum.x = max( accum.x, data.x ); accum.y = min( accum.y, data.y ); diff --git a/src/engine/renderer/glsl_source/lighttile_fp.glsl b/src/engine/renderer/glsl_source/lighttile_fp.glsl index 559199a298..6c135a687a 100644 --- a/src/engine/renderer/glsl_source/lighttile_fp.glsl +++ b/src/engine/renderer/glsl_source/lighttile_fp.glsl @@ -59,7 +59,7 @@ Light GetLight( in uint idx ) { uniform int u_numLights; uniform mat4 u_ModelMatrix; -uniform sampler2D u_DepthMap; +uniform sampler2D u_DepthTile2; uniform int u_lightLayer; uniform vec3 u_zFar; @@ -96,7 +96,7 @@ vec3 ProjToView( vec2 inp ) { } void main() { - vec2 minmax = texture2D( u_DepthMap, 0.5 * vPosition + 0.5 ).xy; + vec2 minmax = texture2D( u_DepthTile2, 0.5 * vPosition + 0.5 ).xy; float minx = vPosition.x - r_tileStep.x; float maxx = vPosition.x + r_tileStep.x; diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index b0dbce22c9..e836607616 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -1160,7 +1160,7 @@ void RB_RenderPostDepthLightTile() GL_Scissor( 0, 0, w, h ); gl_depthtile2Shader->BindProgram( 0 ); - gl_depthtile2Shader->SetUniform_DepthMapBindless( + gl_depthtile2Shader->SetUniform_DepthTile1Bindless( GL_BindToTMU( 0, tr.depthtile1RenderImage ) ); @@ -1180,7 +1180,7 @@ void RB_RenderPostDepthLightTile() gl_lighttileShader->SetUniformBlock_Lights( tr.dlightUBO ); - gl_lighttileShader->SetUniform_DepthMapBindless( + gl_lighttileShader->SetUniform_DepthTile2Bindless( GL_BindToTMU( 1, tr.depthtile2RenderImage ) ); From 1826e0b44f3b6a2135550672ee696e2af1374075 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:16:09 +0300 Subject: [PATCH 04/12] Generalise shader post-processing Will be required for PushBuffer. Also added back `_isTexture` to `GLUniform` because it will also be needed for PushBuffer. --- src/engine/renderer/gl_shader.cpp | 138 ++++++++++++++++-------------- src/engine/renderer/gl_shader.h | 14 ++- 2 files changed, 88 insertions(+), 64 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 5c672656ca..beeebd1ab8 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1514,22 +1514,75 @@ void GLShaderManager::SaveShaderBinary( ShaderProgramDescriptor* descriptor ) { cacheSaveCount++; } +std::string GLShaderManager::RemoveUniformsFromShaderText( const std::string& shaderText, const std::vector& uniforms ) { + std::istringstream shaderTextStream( shaderText ); + std::string shaderMain; + + std::string line; + /* Remove local uniform declarations, but avoid removing uniform / storage blocks; + * their values will be sourced from a buffer instead + * Global uniforms (like u_ViewOrigin) will still be set as regular uniforms */ + while ( std::getline( shaderTextStream, line, '\n' ) ) { + bool skip = false; + if ( line.find( "uniform" ) < line.find( "//" ) && line.find( ";" ) != std::string::npos ) { + for ( GLUniform* uniform : uniforms ) { + const size_t pos = line.find( uniform->_name ); + if ( pos != std::string::npos && !Str::cisalpha( line[pos + uniform->_name.size()] ) ) { + skip = true; + break; + } + } + } + + if ( skip ) { + continue; + } + + shaderMain += line + "\n"; + } + + return shaderMain; +} + +void GLShaderManager::GenerateUniformStructDefinesText( const std::vector& uniforms, const uint32_t padding, + const uint32_t paddingCount, const std::string& definesName, + std::string& uniformStruct, std::string& uniformDefines ) { + for ( GLUniform* uniform : uniforms ) { + uniformStruct += " " + ( uniform->_isTexture ? "uvec2" : uniform->_type ) + " " + uniform->_name; + + if ( uniform->_components ) { + uniformStruct += "[" + std::to_string( uniform->_components ) + "]"; + } + uniformStruct += ";\n"; + + uniformDefines += "#define "; + uniformDefines += uniform->_name; + + if ( uniform->_isTexture ) { + uniformDefines += "_initial"; + } + + uniformDefines += " " + definesName + "."; + uniformDefines += uniform->_name; + + uniformDefines += "\n"; + } + + // Array of structs is aligned to the largest member of the struct + for ( uint32_t i = 0; i < padding; i++ ) { + uniformStruct += " int uniform_padding" + std::to_string( i + paddingCount ); + uniformStruct += ";\n"; + } + + uniformDefines += "\n"; +} + // This will generate all the extra code for material system shaders std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::string& shaderText, const uint32_t offset ) { if ( !shader->std430Size ) { return shaderText; } - std::string newShaderText; - std::string materialStruct = "\nstruct Material {\n"; - // 6 kb for materials - const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430Size(); - std::string materialBlock = "layout(std140, binding = " - + std::to_string( BufferBind::MATERIALS ) - + ") uniform materialsUBO {\n" - " Material materials[" + std::to_string( count ) + "]; \n" - "};\n\n"; - std::string texBuf = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? "layout(std140, binding = " + std::to_string( BufferBind::TEX_DATA ) @@ -1569,7 +1622,6 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str "};\n\n" "#define u_LightMap_initial lightMapData[( baseInstance >> 24 ) & 0xFF].u_LightMap\n" "#define u_DeluxeMap_initial lightMapData[( baseInstance >> 24 ) & 0xFF].u_DeluxeMap\n\n"; - std::string materialDefines; /* Generate the struct and defines in the form of: * struct Material { @@ -1582,62 +1634,24 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str * #define uniformx materials[baseInstance].uniformx */ - for( GLUniform* uniform : shader->_materialSystemUniforms ) { - materialStruct += " " + uniform->_type + " " + uniform->_name; - - if ( uniform->_components ) { - materialStruct += "[" + std::to_string( uniform->_components ) + "]"; - } - materialStruct += ";\n"; - - materialDefines += "#define "; - materialDefines += uniform->_name; - - materialDefines += " materials[baseInstance & 0xFFF]."; - materialDefines += uniform->_name; - - materialDefines += "\n"; - } - - // Array of structs is aligned to the largest member of the struct - for ( uint i = 0; i < shader->padding; i++ ) { - materialStruct += " int material_padding" + std::to_string( i ); - materialStruct += ";\n"; - } + std::string materialStruct = "\nstruct Material {\n"; + std::string materialDefines; + GenerateUniformStructDefinesText( shader->_materialSystemUniforms, shader->padding, + 0, "materials[baseInstance & 0xFFF]", materialStruct, materialDefines ); materialStruct += "};\n\n"; - materialDefines += "\n"; - std::istringstream shaderTextStream( shaderText ); - std::string shaderMain; - - std::string line; - - /* Remove local uniform declarations, but avoid removing uniform / storage blocks; - * their values will be sourced from a buffer instead - * Global uniforms (like u_ViewOrigin) will still be set as regular uniforms */ - while( std::getline( shaderTextStream, line, '\n' ) ) { - bool skip = false; - if ( line.find( "uniform" ) < line.find( "//" ) && line.find( ";" ) != std::string::npos ) { - for ( GLUniform* uniform : shader->_materialSystemUniforms ) { - const size_t pos = line.find( uniform->_name ); - if ( pos != std::string::npos && !Str::cisalpha( line[pos + strlen( uniform->_name.c_str() )] ) ) { - skip = true; - break; - } - } - } - - if ( skip ) { - continue; - } - - shaderMain += line + "\n"; - } + // 6 kb for materials + const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430Size(); + std::string materialBlock = "layout(std140, binding = " + + std::to_string( BufferBind::MATERIALS ) + + ") uniform materialsUBO {\n" + " Material materials[" + std::to_string( count ) + "]; \n" + "};\n\n"; - materialDefines += "\n"; + std::string shaderMain = RemoveUniformsFromShaderText( shaderText, shader->_materialSystemUniforms ); - newShaderText = "#define USE_MATERIAL_SYSTEM\n" + materialStruct + materialBlock + texDataBlock + materialDefines; + std::string newShaderText = "#define USE_MATERIAL_SYSTEM\n" + materialStruct + materialBlock + texDataBlock + materialDefines; shaderMain.insert( offset, newShaderText ); return shaderMain; } diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 1cc7e18ca6..b1ce07b22a 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -322,6 +322,7 @@ class GLUniform { const bool _global; // This uniform won't go into the materials UBO if true const int _components; + const bool _isTexture; protected: GLShader* _shader; @@ -329,13 +330,15 @@ class GLUniform { size_t _locationIndex; GLUniform( GLShader* shader, const char* name, const char* type, const GLuint std430Size, const GLuint std430Alignment, - const bool global, const int components = 0 ) : + const bool global, const int components = 0, + const bool isTexture = false ) : _name( name ), _type( type ), _std430Size( std430Size ), _std430Alignment( std430Alignment ), _global( global ), _components( components ), + _isTexture( isTexture ), _shader( shader ) { _shader->RegisterUniform( this ); } @@ -458,14 +461,21 @@ class GLShaderManager { ShaderProgramDescriptor* out ); void SaveShaderBinary( ShaderProgramDescriptor* descriptor ); + void GenerateUniformStructDefinesText( const std::vector& uniforms, const uint32_t padding, + const uint32_t paddingCount, const std::string& definesName, + std::string& uniformStruct, std::string& uniformDefines ); + std::string RemoveUniformsFromShaderText( const std::string& shaderText, const std::vector& uniforms ); std::string ShaderPostProcess( GLShader *shader, const std::string& shaderText, const uint32_t offset ); std::string BuildDeformShaderText( const std::string& steps ); std::string ProcessInserts( const std::string& shaderText ) const; + void LinkProgram( GLuint program ) const; void BindAttribLocations( GLuint program ) const; void PrintShaderSource( Str::StringRef programName, GLuint object, std::vector& infoLogLines ) const; + std::vector ParseInfoLog( const std::string& infoLog ) const; std::string GetInfoLog( GLuint object ) const; + std::string BuildShaderText( const std::string& mainShaderText, const std::vector& headers, const std::string& macros ); ShaderDescriptor* FindShader( const std::string& name, const std::string& mainText, const GLenum type, const std::vector& headers, @@ -478,7 +488,7 @@ class GLUniformSampler : protected GLUniform { protected: GLUniformSampler( GLShader* shader, const char* name, const char* type ) : GLUniform( shader, name, type, glConfig2.bindlessTexturesAvailable ? 2 : 1, - glConfig2.bindlessTexturesAvailable ? 2 : 1, true ) { + glConfig2.bindlessTexturesAvailable ? 2 : 1, true, 0, true ) { } inline GLint GetLocation() { From 6f3b8ea153fc4cb398bff105db125e6f44724501 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:32:54 +0300 Subject: [PATCH 05/12] depthTextureInitial -> u_DepthMap Needed for `PushBuffer`. --- src/engine/renderer/gl_shader.cpp | 3 ++- src/engine/renderer/gl_shader.h | 1 + src/engine/renderer/glsl_source/depthReduction_cp.glsl | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index beeebd1ab8..bbc09fb189 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -3029,11 +3029,12 @@ GLShader_depthReduction::GLShader_depthReduction() : false, "depthReduction" ), u_ViewWidth( this ), u_ViewHeight( this ), + u_DepthMap( this ), u_InitialDepthLevel( this ) { } void GLShader_depthReduction::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "depthTextureInitial" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); } GLShader_clearSurfaces::GLShader_clearSurfaces() : diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index b1ce07b22a..f5fea59e54 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -3761,6 +3761,7 @@ class GLShader_depthReduction : public GLShader, public u_ViewWidth, public u_ViewHeight, + public u_DepthMap, public u_InitialDepthLevel { public: GLShader_depthReduction(); diff --git a/src/engine/renderer/glsl_source/depthReduction_cp.glsl b/src/engine/renderer/glsl_source/depthReduction_cp.glsl index 10349dd1be..47dc8606b3 100644 --- a/src/engine/renderer/glsl_source/depthReduction_cp.glsl +++ b/src/engine/renderer/glsl_source/depthReduction_cp.glsl @@ -39,7 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Keep this to 8x8 because we don't want extra shared mem etc. to be allocated, and to minimize wasted lanes layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -layout(binding = 0) uniform sampler2D depthTextureInitial; +layout(binding = 0) uniform sampler2D u_DepthMap; layout(r32f, binding = 1) uniform readonly image2D depthImageIn; layout(r32f, binding = 2) uniform writeonly image2D depthImageOut; @@ -57,7 +57,7 @@ void main() { // Depth buffer uses a packed D24S8 format, so we have to copy it over to an r32f image first if( u_InitialDepthLevel ) { - vec4 depthOut = texelFetch( depthTextureInitial, position, 0 ); + vec4 depthOut = texelFetch( u_DepthMap, position, 0 ); imageStore( depthImageOut, position, depthOut ); } else { float depth[4]; From 612d023aead49f5706a033f008a5eaba5e1e3778 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:29:17 +0300 Subject: [PATCH 06/12] NUKE useless buffer unmapping and R_SyncRenderThread() in material system Deleting the buffer automatically unmaps it. --- src/engine/renderer/Material.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index c95626d426..c0755de02a 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1729,17 +1729,7 @@ void MaterialSystem::Free() { texData.clear(); dynamicTexData.clear(); - R_SyncRenderThread(); - - surfaceCommandsSSBO.UnmapBuffer(); - culledCommandsBuffer.UnmapBuffer(); - atomicCommandCountersBuffer.UnmapBuffer(); - texDataBuffer.UnmapBuffer(); - lightMapDataUBO.UnmapBuffer(); - if ( totalPortals > 0 ) { - portalSurfacesSSBO.UnmapBuffer(); - for ( PortalView& portalView : portalStack ) { memset( portalView.views, 0, MAX_VIEWS * sizeof( uint32_t ) ); portalView.count = 0; From 05a4e587ce1143062624373251c71f3e0116ab31 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:30:47 +0300 Subject: [PATCH 07/12] Add PushBuffer Adds `PushBuffer` class, `pushBuffer` global, and the supporting code for `glconfig2`. --- src/engine/renderer/BufferBind.h | 5 +++-- src/engine/renderer/GLMemory.cpp | 32 ++++++++++++++++++++++++++++++++ src/engine/renderer/GLMemory.h | 25 ++++++++++++++++++++++++- src/engine/renderer/tr_public.h | 1 + src/engine/sys/sdl_glimp.cpp | 5 +++++ 5 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/engine/renderer/BufferBind.h b/src/engine/renderer/BufferBind.h index 3c4d537664..d6972709bf 100644 --- a/src/engine/renderer/BufferBind.h +++ b/src/engine/renderer/BufferBind.h @@ -42,9 +42,10 @@ namespace BufferBind { MATERIALS = 0, TEX_DATA = 1, LIGHTMAP_DATA = 2, - LIGHTS = 3, + GLOBAL_DATA = 3, + LIGHTS = 4, - SURFACE_BATCHES = 4, + SURFACE_BATCHES = 5, // SSBO SURFACE_DESCRIPTORS = 0, diff --git a/src/engine/renderer/GLMemory.cpp b/src/engine/renderer/GLMemory.cpp index aeb4343391..baea8e721f 100644 --- a/src/engine/renderer/GLMemory.cpp +++ b/src/engine/renderer/GLMemory.cpp @@ -37,10 +37,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "GLMemory.h" +#include "gl_shader.h" + // 128 MB, should be enough to fit anything in BAR without going overboard const GLsizeiptr GLStagingBuffer::SIZE = 128 * 1024 * 1024 / sizeof( uint32_t ); GLStagingBuffer stagingBuffer; +PushBuffer pushBuffer; void GLBufferCopy( GLBuffer* src, GLBuffer* dst, GLintptr srcOffset, GLintptr dstOffset, GLsizeiptr size ) { glCopyNamedBufferSubData( src->id, dst->id, @@ -130,3 +133,32 @@ void GLStagingBuffer::FreeGLBuffer() { current = 0; last = 0; } + +void PushBuffer::InitGLBuffers() { + globalUBO.GenBuffer(); +} + +void PushBuffer::FreeGLBuffers() { + globalUBO.DelBuffer(); +} + +uint32_t* PushBuffer::MapGlobalUniformData( const int updateType ) { + switch ( updateType ) { + case GLUniform::CONST: + globalUBOData = stagingBuffer.MapBuffer( constUniformsSize ); + stagingBuffer.QueueStagingCopy( &globalUBO, 0 ); + break; + case GLUniform::FRAME: + globalUBOData = stagingBuffer.MapBuffer( frameUniformsSize ); + stagingBuffer.QueueStagingCopy( &globalUBO, constUniformsSize ); + break; + default: + ASSERT_UNREACHABLE(); + } + + return globalUBOData; +} + +void PushBuffer::PushGlobalUniforms() { + stagingBuffer.FlushAll(); +} \ No newline at end of file diff --git a/src/engine/renderer/GLMemory.h b/src/engine/renderer/GLMemory.h index 69f56ac74d..f555025301 100644 --- a/src/engine/renderer/GLMemory.h +++ b/src/engine/renderer/GLMemory.h @@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "common/Common.h" #include "GL/glew.h" + #include "tr_local.h" #include "BufferBind.h" @@ -318,6 +319,28 @@ class GLStagingBuffer { GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT ); }; +struct PushBuffer { + uint32_t constUniformsSize; + uint32_t frameUniformsSize; + uint32_t globalUBOSize; + uint32_t* globalUBOData; + + uint32_t pushStart = UINT32_MAX; + uint32_t pushEnd = 0; + + uint32_t sector = 0; + const uint32_t MAX_SECTORS = 1024; + + GLUBO globalUBO = GLUBO( "globalUniforms", BufferBind::GLOBAL_DATA, 0, 0 ); + + void InitGLBuffers(); + void FreeGLBuffers(); + + uint32_t* MapGlobalUniformData( const int updateType ); + void PushGlobalUniforms(); +}; + extern GLStagingBuffer stagingBuffer; +extern PushBuffer pushBuffer; -#endif // GLMEMORY_H +#endif // GLMEMORY_H \ No newline at end of file diff --git a/src/engine/renderer/tr_public.h b/src/engine/renderer/tr_public.h index 5a0c4f1150..4622c40f86 100644 --- a/src/engine/renderer/tr_public.h +++ b/src/engine/renderer/tr_public.h @@ -120,6 +120,7 @@ struct glconfig2_t bool usingMaterialSystem; // are we using it right now bool geometryCacheAvailable; bool usingGeometryCache; + bool pushBufferAvailable; bool gpuShader4Available; bool gpuShader5Available; bool textureGatherAvailable; diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index 19d4087ac0..c289091de5 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -2591,6 +2591,11 @@ static void GLimp_InitExtensions() glConfig2.geometryCacheAvailable = glConfig2.vertexAttribBindingAvailable && glConfig2.directStateAccessAvailable; + glConfig2.pushBufferAvailable = + glConfig2.directStateAccessAvailable + && glConfig2.explicitUniformLocationAvailable + && glConfig2.uniformBufferObjectAvailable; + glConfig2.materialSystemAvailable = glConfig2.bindlessTexturesAvailable && glConfig2.computeShaderAvailable From 453fa33987f80b5e9ce5c0632208007fb4db8e19 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:41:54 +0300 Subject: [PATCH 08/12] Generalise uniform post-processing Also adds `GLShader.pushSkip` and `GLShader._pushUniforms`. Add `padding` back to the `GLShader` size calculations in material system. --- src/engine/renderer/Material.cpp | 2 +- src/engine/renderer/gl_shader.cpp | 96 ++++++++++++++++++++----------- src/engine/renderer/gl_shader.h | 19 ++++-- 3 files changed, 79 insertions(+), 38 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index c0755de02a..83da04e4ea 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1313,7 +1313,7 @@ void MaterialSystem::ProcessStage( MaterialSurface* surface, shaderStage_t* pSta material.bspSurface = surface->bspSurface; pStage->materialProcessor( &material, pStage, surface ); - pStage->paddedSize = material.shader->GetSTD430Size(); + pStage->paddedSize = material.shader->GetSTD430PaddedSize(); // HACK: Copy the shaderStage_t and MaterialSurface that we need into the material, so we can use it with glsl_restart material.refStage = pStage; diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index bbc09fb189..4d2984895a 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1642,7 +1642,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str materialStruct += "};\n\n"; // 6 kb for materials - const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430Size(); + const uint32_t count = ( 4096 + 2048 ) / shader->GetSTD430PaddedSize(); std::string materialBlock = "layout(std140, binding = " + std::to_string( BufferBind::MATERIALS ) + ") uniform materialsUBO {\n" @@ -2108,59 +2108,91 @@ static int FindUniformForAlignment( std::vector& uniforms, const GLu return -1; } -// Compute std430 size/alignment and sort uniforms from highest to lowest alignment -void GLShader::PostProcessUniforms() { - if ( !_useMaterialSystem ) { - return; - } - - for ( GLUniform* uniform : _uniforms ) { - if ( !uniform->_global ) { - _materialSystemUniforms.emplace_back( uniform ); - } - } - - std::sort( _materialSystemUniforms.begin(), _materialSystemUniforms.end(), +GLuint GLShaderManager::SortUniforms( std::vector& uniforms ) { + std::sort( uniforms.begin(), uniforms.end(), []( const GLUniform* lhs, const GLUniform* rhs ) { return lhs->_std430Size > rhs->_std430Size; } ); - // Sort uniforms from highest to lowest alignment so we don't need to pad uniforms (other than vec3s) - const uint numUniforms = _materialSystemUniforms.size(); + const uint numUniforms = uniforms.size(); std::vector tmp; + GLuint structSize = 0; while ( tmp.size() < numUniforms ) { // Higher-alignment uniforms first to avoid wasting memory - GLuint size = _materialSystemUniforms[0]->_std430Size; - GLuint components = _materialSystemUniforms[0]->_components; + GLuint size = uniforms[0]->_std430Size; + GLuint components = uniforms[0]->_components; size = components ? PAD( size, 4 ) * components : size; GLuint alignmentConsume = 4 - size % 4; + GLuint usedSpace = size; - GLUniform* tmpUniform = _materialSystemUniforms[0]; - tmp.emplace_back( _materialSystemUniforms[0] ); - _materialSystemUniforms.erase( _materialSystemUniforms.begin() ); + GLUniform* tmpUniform = uniforms[0]; + tmp.emplace_back( uniforms[0] ); + uniforms.erase( uniforms.begin() ); int uniform; - while ( ( alignmentConsume & 3 ) && _materialSystemUniforms.size() - && ( uniform = FindUniformForAlignment( _materialSystemUniforms, alignmentConsume ) ) != -1 ) { - alignmentConsume -= _materialSystemUniforms[uniform]->_std430Size; + while ( ( alignmentConsume & 3 ) && uniforms.size() + && ( uniform = FindUniformForAlignment( uniforms, alignmentConsume ) ) != -1 ) { + alignmentConsume -= uniforms[uniform]->_std430Size; + usedSpace += uniforms[uniform]->_std430Size; - tmpUniform = _materialSystemUniforms[uniform]; + tmpUniform = uniforms[uniform]; - tmp.emplace_back( _materialSystemUniforms[uniform] ); - _materialSystemUniforms.erase( _materialSystemUniforms.begin() + uniform ); + tmp.emplace_back( uniforms[uniform] ); + uniforms.erase( uniforms.begin() + uniform ); } - if ( alignmentConsume ) { + if ( alignmentConsume & 3 ) { tmpUniform->_std430Size += alignmentConsume; } - size = PAD( size, 4 ); - std430Size += size; - padding = alignmentConsume; + if ( uniforms.size() ) { + structSize += PAD( size, 4 ); + } else { + structSize += usedSpace; + } } - _materialSystemUniforms = tmp; + uniforms = tmp; + + return structSize; +} + +std::vector GLShaderManager::ProcessUniforms( const GLUniform::UpdateType minType, const GLUniform::UpdateType maxType, + const bool skipTextures, + std::vector& uniforms, GLuint& structSize, GLuint& padding ) { + std::vector tmp; + + tmp.reserve( uniforms.size() ); + for ( GLUniform* uniform : uniforms ) { + if ( uniform->_updateType >= minType && uniform->_updateType <= maxType + && ( !uniform->_isTexture || !skipTextures ) ) { + tmp.emplace_back( uniform ); + } + } + + structSize = SortUniforms( tmp ); + + const GLuint structAlignment = 4; // Material buffer is now a UBO, so it uses std140 layout, which is aligned to vec4 + if ( structSize > 0 ) { + padding = ( structAlignment - ( structSize % structAlignment ) ) % structAlignment; + } + + return tmp; +} + +// Compute std140 size/alignment and sort uniforms from highest to lowest alignment +void GLShader::PostProcessUniforms() { + if ( _useMaterialSystem ) { + _materialSystemUniforms = gl_shaderManager.ProcessUniforms( GLUniform::MATERIAL_OR_PUSH, GLUniform::MATERIAL_OR_PUSH, + true, _uniforms, std430Size, padding ); + } + + if ( glConfig2.pushBufferAvailable && !pushSkip ) { + GLuint unused; + _pushUniforms = gl_shaderManager.ProcessUniforms( GLUniform::CONST, GLUniform::FRAME, + false, _uniforms, unused, unused ); + } } uint32_t GLShader::GetUniqueCompileMacros( size_t permutation, const int type ) const { diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index f5fea59e54..fd00e7ff3e 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -105,6 +105,7 @@ class GLShader { uint32_t padding = 0; const bool worldShader; + const bool pushSkip; protected: int _activeMacros = 0; ShaderProgramDescriptor* currentProgram; @@ -119,13 +120,15 @@ class GLShader { size_t _uniformStorageSize; std::vector _uniforms; + std::vector _pushUniforms; std::vector _materialSystemUniforms; std::vector _uniformBlocks; std::vector _compileMacros; GLShader( const std::string& name, uint32_t vertexAttribsRequired, const bool useMaterialSystem, - const std::string newVertexShaderName, const std::string newFragmentShaderName ) : + const std::string newVertexShaderName, const std::string newFragmentShaderName, + const bool newPushSkip = false ) : _name( name ), _vertexAttribsRequired( vertexAttribsRequired ), _useMaterialSystem( useMaterialSystem ), @@ -134,7 +137,8 @@ class GLShader { hasVertexShader( true ), hasFragmentShader( true ), hasComputeShader( false ), - worldShader( false ) { + worldShader( false ), + pushSkip( newPushSkip ) { } GLShader( const std::string& name, @@ -147,7 +151,8 @@ class GLShader { hasVertexShader( false ), hasFragmentShader( false ), hasComputeShader( true ), - worldShader( newWorldShader ) { + worldShader( newWorldShader ), + pushSkip( false ) { } public: @@ -217,8 +222,8 @@ class GLShader { _vertexAttribs &= ~bit; } - GLuint GetSTD430Size() const { - return std430Size; + GLuint GetSTD430PaddedSize() const { + return std430Size + padding; } bool UseMaterialSystem() const { @@ -393,6 +398,10 @@ class GLShaderManager { void GenerateBuiltinHeaders(); void GenerateWorldHeaders(); + static GLuint SortUniforms( std::vector& uniforms ); + static std::vector ProcessUniforms( const GLUniform::UpdateType minType, const GLUniform::UpdateType maxType, + const bool skipTextures, std::vector& uniforms, GLuint& structSize, GLuint& padding ); + template void LoadShader( T*& shader ) { if ( !deformShaderCount ) { From 2df8798a294cdcab2b05e77222a96c38989855e3 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:43:24 +0300 Subject: [PATCH 09/12] Add GlobalUBOProxy Will be required for `PushBuffer` to set global uniform values outside of their shaders. --- src/engine/renderer/gl_shader.cpp | 36 +++++++++++++++++++++++++++++++ src/engine/renderer/gl_shader.h | 36 +++++++++++++++++++++++++++++++ src/engine/renderer/tr_shade.cpp | 3 +++ 3 files changed, 75 insertions(+) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 4d2984895a..1115e3bb2e 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -77,6 +77,7 @@ GLShader_screen *gl_screenShader = nullptr; GLShader_screenMaterial *gl_screenShaderMaterial = nullptr; GLShader_skybox *gl_skyboxShader = nullptr; GLShader_skyboxMaterial *gl_skyboxShaderMaterial = nullptr; +GlobalUBOProxy *globalUBOProxy = nullptr; GLShaderManager gl_shaderManager; namespace // Implementation details @@ -3082,3 +3083,38 @@ GLShader_processSurfaces::GLShader_processSurfaces() : u_ViewID( this ), u_SurfaceCommandsOffset( this ) { } + +GlobalUBOProxy::GlobalUBOProxy() : + /* HACK: A GLShader* is required to initialise uniforms, + but we don't need the GLSL shader itself, so we won't actually build it */ + GLShader( "proxy", 0, + false, "screenSpace", "generic", true ), + // CONST + u_ColorMap3D( this ), + u_DepthMap( this ), + u_PortalMap( this ), + u_FogMap( this ), + u_DepthTile1( this ), + u_DepthTile2( this ), + u_LightTiles( this ), + u_LightGrid1( this ), + u_LightGrid2( this ), + u_LightGridOrigin( this ), + u_LightGridScale( this ), + u_GlobalLightFactor( this ), + u_FirstPortalGroup( this ), + u_TotalPortals( this ), + u_SurfaceDescriptorsCount( this ), + u_ProfilerZero( this ), + // FRAME + u_Frame( this ), + u_UseFrustumCulling( this ), + u_UseOcclusionCulling( this ), + u_blurVec( this ), + u_numLights( this ), + u_ColorModulate( this ), + u_InverseGamma( this ), + u_Tonemap( this ), + u_TonemapParms( this ), + u_TonemapExposure( this ) { +} \ No newline at end of file diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index fd00e7ff3e..18018c3186 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -3793,6 +3793,41 @@ class GLShader_processSurfaces : GLShader_processSurfaces(); }; +class GlobalUBOProxy : + public GLShader, + // CONST + public u_ColorMap3D, + public u_DepthMap, + public u_PortalMap, + public u_FogMap, + public u_DepthTile1, + public u_DepthTile2, + public u_LightTiles, + public u_LightGrid1, + public u_LightGrid2, + public u_LightGridOrigin, + public u_LightGridScale, + public u_GlobalLightFactor, + public u_FirstPortalGroup, + public u_TotalPortals, + public u_SurfaceDescriptorsCount, + public u_ProfilerZero, + // FRAME + public u_Frame, + public u_UseFrustumCulling, + public u_UseOcclusionCulling, + public u_blurVec, + public u_numLights, + public u_ColorModulate, + public u_InverseGamma, + public u_Tonemap, + public u_TonemapParms, + public u_TonemapExposure { + + public: + GlobalUBOProxy(); +}; + std::string GetShaderPath(); @@ -3832,6 +3867,7 @@ extern GLShader_screen *gl_screenShader; extern GLShader_screenMaterial *gl_screenShaderMaterial; extern GLShader_skybox *gl_skyboxShader; extern GLShader_skyboxMaterial *gl_skyboxShaderMaterial; +extern GlobalUBOProxy *globalUBOProxy; extern GLShaderManager gl_shaderManager; #endif // GL_SHADER_H diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index e44517a906..0922809b0c 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -217,6 +217,8 @@ static void GLSL_InitGPUShadersOrError() // standard light mapping gl_shaderManager.LoadShader( gl_lightMappingShader ); + gl_shaderManager.LoadShader( globalUBOProxy ); + // Material system shaders that are always loaded if material system is available if ( glConfig2.usingMaterialSystem ) { @@ -458,6 +460,7 @@ void GLSL_ShutdownGPUShaders() gl_genericShader = nullptr; gl_genericShaderMaterial = nullptr; + globalUBOProxy = nullptr; gl_cullShader = nullptr; gl_depthReductionShader = nullptr; gl_clearSurfacesShader = nullptr; From e6519d56c3abb09a5aff1879474ba55739bc1ac9 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:53:06 +0300 Subject: [PATCH 10/12] Add `PostProcessGlobalUniforms()` This will set `GLShaderManager.globalUniformBlock` to the struct + defines text, which will be the same for all shaders. --- src/engine/renderer/GLMemory.cpp | 4 +++ src/engine/renderer/gl_shader.cpp | 57 +++++++++++++++++++++++++++++-- src/engine/renderer/gl_shader.h | 7 ++++ src/engine/renderer/tr_shade.cpp | 1 + src/engine/renderer/tr_vbo.cpp | 8 +++++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/engine/renderer/GLMemory.cpp b/src/engine/renderer/GLMemory.cpp index baea8e721f..fe8f4e10c7 100644 --- a/src/engine/renderer/GLMemory.cpp +++ b/src/engine/renderer/GLMemory.cpp @@ -136,6 +136,10 @@ void GLStagingBuffer::FreeGLBuffer() { void PushBuffer::InitGLBuffers() { globalUBO.GenBuffer(); + + globalUBO.BufferStorage( pushBuffer.constUniformsSize + pushBuffer.frameUniformsSize, 1, nullptr ); + + globalUBO.BindBufferBase(); } void PushBuffer::FreeGLBuffers() { diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 1115e3bb2e..5ed5c8ecb1 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1275,8 +1275,6 @@ std::string GLShaderManager::BuildShaderText( const std::string& mainShaderText, void GLShaderManager::InitShader( GLShader* shader ) { const int start = Sys::Milliseconds(); - shader->PostProcessUniforms(); - shader->_uniformStorageSize = 0; for ( std::size_t i = 0; i < shader->_uniforms.size(); i++ ) { GLUniform* uniform = shader->_uniforms[i]; @@ -1578,6 +1576,61 @@ void GLShaderManager::GenerateUniformStructDefinesText( const std::vector* uniforms = &( ( GLShader* ) globalUBOProxy )->_uniforms; + std::vector constUniforms = + ProcessUniforms( GLUniform::CONST, GLUniform::CONST, false, *uniforms, size, padding ); + + GenerateUniformStructDefinesText( constUniforms, padding, 0, "globalUniforms", uniformStruct, uniformDefines ); + + uint32_t paddingCount = padding; + + pushBuffer.constUniformsSize = size + padding; + + std::vector frameUniforms = + ProcessUniforms( GLUniform::FRAME, GLUniform::FRAME, false, *uniforms, size, padding ); + + GenerateUniformStructDefinesText( frameUniforms, padding, paddingCount, "globalUniforms", uniformStruct, uniformDefines ); + + pushBuffer.frameUniformsSize = size + padding; + + uniformStruct += "};\n\n"; + + globalUniformBlock = uniformStruct + uniformBlock + uniformDefines; + + uniforms = &( ( GLShader* ) globalUBOProxy )->_pushUniforms; + uniforms->clear(); + + for ( GLUniform* uniform : constUniforms ) { + uniforms->push_back( uniform ); + } + + for ( GLUniform* uniform : frameUniforms ) { + uniforms->push_back( uniform ); + } +} + // This will generate all the extra code for material system shaders std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::string& shaderText, const uint32_t offset ) { if ( !shader->std430Size ) { diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 18018c3186..0e5b0c9927 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -390,6 +390,8 @@ class GLShaderManager { GLHeader GLWorldHeader; GLHeader GLEngineConstants; + std::string globalUniformBlock; + GLShaderManager() {} ~GLShaderManager(); @@ -411,6 +413,9 @@ class GLShaderManager { } shader = new T(); + + shader->PostProcessUniforms(); + _shaders.emplace_back( shader ); _shaderBuildQueue.push( shader ); } @@ -437,6 +442,8 @@ class GLShaderManager { void BuildAll( const bool buildOnlyMarked ); void FreeAll(); + void PostProcessGlobalUniforms(); + void BindBuffers(); private: struct InfoLogEntry { diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 0922809b0c..d1c0f3b766 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -375,6 +375,7 @@ static void GLSL_InitGPUShadersOrError() gl_fxaaShader->MarkProgramForBuilding( 0 ); } + gl_shaderManager.PostProcessGlobalUniforms(); gl_shaderManager.InitShaders(); if ( r_lazyShaders.Get() == 0 ) diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index a452b1a788..d21ae23e19 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -766,6 +766,10 @@ void R_InitVBOs() stagingBuffer.InitGLBuffer(); } + if ( glConfig2.pushBufferAvailable ) { + pushBuffer.InitGLBuffers(); + } + GL_CheckErrors(); } @@ -842,6 +846,10 @@ void R_ShutdownVBOs() stagingBuffer.FreeGLBuffer(); } + if ( glConfig2.pushBufferAvailable ) { + pushBuffer.FreeGLBuffers(); + } + tess.verts = tess.vertsBuffer = nullptr; tess.indexes = tess.indexesBuffer = nullptr; } From c34c037944b5804a4a812d76001c84457fa9356e Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 13:01:37 +0300 Subject: [PATCH 11/12] GLUniform._global -> _updateType This will be required for `PushBuffer` to correctly sort uniforms. Also updates `GLShader.WriteUniformsToBuffer()` to use `mode` and `filter` arguments to select the correct uniforms. --- src/engine/renderer/Material.cpp | 16 +- src/engine/renderer/gl_shader.cpp | 20 +- src/engine/renderer/gl_shader.h | 420 +++++++++++++++--------------- 3 files changed, 241 insertions(+), 215 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 83da04e4ea..e16ee7f1b3 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -160,7 +160,7 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage, boo gl_genericShaderMaterial->SetUniform_DepthScale( pStage->depthFadeValue ); } - gl_genericShaderMaterial->WriteUniformsToBuffer( materials ); + gl_genericShaderMaterial->WriteUniformsToBuffer( materials, GLShader::MATERIAL ); } void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage, bool, bool vertexLit, bool fullbright ) { @@ -212,7 +212,7 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage, gl_lightMappingShaderMaterial->SetUniform_SpecularExponent( specExpMin, specExpMax ); } - gl_lightMappingShaderMaterial->WriteUniformsToBuffer( materials ); + gl_lightMappingShaderMaterial->WriteUniformsToBuffer( materials, GLShader::MATERIAL ); } void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { @@ -253,7 +253,7 @@ void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage, bo gl_reflectionShaderMaterial->SetUniform_ReliefOffsetBias( shader->reliefOffsetBias ); } - gl_reflectionShaderMaterial->WriteUniformsToBuffer( materials ); + gl_reflectionShaderMaterial->WriteUniformsToBuffer( materials, GLShader::MATERIAL ); } void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { @@ -264,7 +264,7 @@ void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage, bool, // u_AlphaThreshold gl_skyboxShaderMaterial->SetUniform_AlphaTest( GLS_ATEST_NONE ); - gl_skyboxShaderMaterial->WriteUniformsToBuffer( materials ); + gl_skyboxShaderMaterial->WriteUniformsToBuffer( materials, GLShader::MATERIAL ); } void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { @@ -277,7 +277,7 @@ void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage, bool, this seems to be the only material system shader that might need it to not be global */ gl_screenShaderMaterial->SetUniform_CurrentMapBindless( BindAnimatedImage( 0, &pStage->bundle[TB_COLORMAP] ) ); - gl_screenShaderMaterial->WriteUniformsToBuffer( materials ); + gl_screenShaderMaterial->WriteUniformsToBuffer( materials, GLShader::MATERIAL ); } void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { @@ -296,7 +296,7 @@ void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage, bool gl_heatHazeShaderMaterial->SetUniform_NormalScale( normalScale ); } - gl_heatHazeShaderMaterial->WriteUniformsToBuffer( materials ); + gl_heatHazeShaderMaterial->WriteUniformsToBuffer( materials, GLShader::MATERIAL ); } void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { @@ -348,7 +348,7 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage, bool, gl_liquidShaderMaterial->SetUniform_NormalScale( normalScale ); } - gl_liquidShaderMaterial->WriteUniformsToBuffer( materials ); + gl_liquidShaderMaterial->WriteUniformsToBuffer( materials, GLShader::MATERIAL ); } void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { @@ -356,7 +356,7 @@ void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage, bool, boo materials += pStage->bufferOffset; - gl_fogQuake3ShaderMaterial->WriteUniformsToBuffer( materials ); + gl_fogQuake3ShaderMaterial->WriteUniformsToBuffer( materials, GLShader::MATERIAL ); } /* diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 5ed5c8ecb1..38b12c2bc5 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -2428,10 +2428,24 @@ void GLShader::SetRequiredVertexPointers() GL_VertexAttribsState( attribs ); } -void GLShader::WriteUniformsToBuffer( uint32_t* buffer ) { +void GLShader::WriteUniformsToBuffer( uint32_t* buffer, const Mode mode, const int filter ) { uint32_t* bufPtr = buffer; - for ( GLUniform* uniform : _materialSystemUniforms ) { - bufPtr = uniform->WriteToBuffer( bufPtr ); + std::vector* uniforms; + switch ( mode ) { + case MATERIAL: + uniforms = &_materialSystemUniforms; + break; + case PUSH: + uniforms = &_pushUniforms; + break; + default: + ASSERT_UNREACHABLE(); + } + + for ( GLUniform* uniform : *uniforms ) { + if ( filter == -1 || uniform->_updateType == filter ) { + bufPtr = uniform->WriteToBuffer( bufPtr ); + } } } diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 0e5b0c9927..61bd75b621 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -191,6 +191,11 @@ class GLShader { virtual void SetShaderProgramUniforms( ShaderProgramDescriptor* /*shaderProgram*/ ) { }; int SelectProgram(); public: + enum Mode { + MATERIAL, + PUSH + }; + void MarkProgramForBuilding( int deformIndex ); GLuint GetProgram( int deformIndex, const bool buildOneShader ); void BindProgram( int deformIndex ); @@ -230,7 +235,7 @@ class GLShader { return _useMaterialSystem; } - void WriteUniformsToBuffer( uint32_t* buffer ); + void WriteUniformsToBuffer( uint32_t* buffer, const Mode mode, const int filter = -1 ); }; struct ShaderEntry { @@ -318,6 +323,18 @@ struct ShaderProgramDescriptor { class GLUniform { public: + enum UpdateType { + CONST, // Set once at map load + FRAME, // Set at the start of a frame + PUSH, // Set based on the surface/shader/etc. + // Set based on the surface/shader/etc. If the material system is enabled, will go into the materials UBO instead + MATERIAL_OR_PUSH, + // Set based on the surface/shader/etc. If the material system is enabled, will go into the texbundles buffer instead + TEXDATA_OR_PUSH, + LEGACY, // These won't actually go into the buffer, it's only to skip uniforms used as fallbacks for older devices + SKIP + }; + const std::string _name; const std::string _type; @@ -325,7 +342,7 @@ class GLUniform { GLuint _std430Size; const GLuint _std430Alignment; - const bool _global; // This uniform won't go into the materials UBO if true + const UpdateType _updateType; const int _components; const bool _isTexture; @@ -335,13 +352,13 @@ class GLUniform { size_t _locationIndex; GLUniform( GLShader* shader, const char* name, const char* type, const GLuint std430Size, const GLuint std430Alignment, - const bool global, const int components = 0, + const UpdateType updateType, const int components = 0, const bool isTexture = false ) : _name( name ), _type( type ), _std430Size( std430Size ), _std430Alignment( std430Alignment ), - _global( global ), + _updateType( updateType ), _components( components ), _isTexture( isTexture ), _shader( shader ) { @@ -502,15 +519,15 @@ class GLShaderManager { class GLUniformSampler : protected GLUniform { protected: - GLUniformSampler( GLShader* shader, const char* name, const char* type ) : + GLUniformSampler( GLShader* shader, const char* name, const char* type, const UpdateType updateType ) : GLUniform( shader, name, type, glConfig2.bindlessTexturesAvailable ? 2 : 1, - glConfig2.bindlessTexturesAvailable ? 2 : 1, true, 0, true ) { + glConfig2.bindlessTexturesAvailable ? 2 : 1, updateType, 0, true ) { } inline GLint GetLocation() { ShaderProgramDescriptor* p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { + if ( !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); } @@ -529,9 +546,17 @@ class GLUniformSampler : protected GLUniform { void SetValueBindless( GLint64 value ) { currentValueBindless = value; - if ( glConfig2.usingBindlessTextures && ( !_shader->UseMaterialSystem() || _global ) ) { - glUniformHandleui64ARB( GetLocation(), currentValueBindless ); + if ( glConfig2.usingBindlessTextures ) { + if ( _shader->UseMaterialSystem() && _updateType == TEXDATA_OR_PUSH ) { + return; + } + + if ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) { + return; + } } + + glUniformHandleui64ARB( GetLocation(), currentValueBindless ); } uint32_t* WriteToBuffer( uint32_t* buffer ) override { @@ -551,37 +576,37 @@ class GLUniformSampler : protected GLUniform { class GLUniformSampler2D : protected GLUniformSampler { protected: - GLUniformSampler2D( GLShader* shader, const char* name ) : - GLUniformSampler( shader, name, "sampler2D" ) { + GLUniformSampler2D( GLShader* shader, const char* name, const UpdateType updateType ) : + GLUniformSampler( shader, name, "sampler2D", updateType ) { } }; class GLUniformSampler3D : protected GLUniformSampler { protected: - GLUniformSampler3D( GLShader* shader, const char* name ) : - GLUniformSampler( shader, name, "sampler3D" ) { + GLUniformSampler3D( GLShader* shader, const char* name, const UpdateType updateType ) : + GLUniformSampler( shader, name, "sampler3D", updateType ) { } }; class GLUniformUSampler3D : protected GLUniformSampler { protected: - GLUniformUSampler3D( GLShader* shader, const char* name ) : - GLUniformSampler( shader, name, "usampler3D" ) { + GLUniformUSampler3D( GLShader* shader, const char* name, const UpdateType updateType ) : + GLUniformSampler( shader, name, "usampler3D", updateType ) { } }; class GLUniformSamplerCube : protected GLUniformSampler { protected: - GLUniformSamplerCube( GLShader* shader, const char* name ) : - GLUniformSampler( shader, name, "samplerCube" ) { + GLUniformSamplerCube( GLShader* shader, const char* name, const UpdateType updateType ) : + GLUniformSampler( shader, name, "samplerCube", updateType ) { } }; class GLUniform1i : protected GLUniform { protected: - GLUniform1i( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "int", 1, 1, global ) + GLUniform1i( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "int", 1, 1, updateType ) { } @@ -589,15 +614,14 @@ class GLUniform1i : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { currentValue = value; return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) int *firewall = ( int * ) &p->uniformFirewall[ _firewallIndex ]; @@ -627,22 +651,21 @@ class GLUniform1i : protected GLUniform class GLUniform1ui : protected GLUniform { protected: - GLUniform1ui( GLShader* shader, const char* name, const bool global = false ) : - GLUniform( shader, name, "uint", 1, 1, global ) { + GLUniform1ui( GLShader* shader, const char* name, const UpdateType updateType ) : + GLUniform( shader, name, "uint", 1, 1, updateType ) { } inline void SetValue( uint value ) { ShaderProgramDescriptor* p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { currentValue = value; return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) uint* firewall = ( uint* ) &p->uniformFirewall[_firewallIndex]; @@ -671,22 +694,21 @@ class GLUniform1ui : protected GLUniform { class GLUniform1Bool : protected GLUniform { protected: // GLSL std430 bool is always 4 bytes, which might not correspond to C++ bool - GLUniform1Bool( GLShader* shader, const char* name, const bool global ) : - GLUniform( shader, name, "bool", 1, 1, global ) { + GLUniform1Bool( GLShader* shader, const char* name, const UpdateType updateType ) : + GLUniform( shader, name, "bool", 1, 1, updateType ) { } inline void SetValue( int value ) { ShaderProgramDescriptor* p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { currentValue = value; return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) int* firewall = ( int* ) &p->uniformFirewall[_firewallIndex]; @@ -705,7 +727,7 @@ class GLUniform1Bool : protected GLUniform { } uint32_t* WriteToBuffer( uint32_t *buffer ) override { - memcpy( buffer, ¤tValue, sizeof( bool ) ); + memcpy( buffer, ¤tValue, sizeof( int ) ); return buffer + _std430Size; } @@ -716,8 +738,8 @@ class GLUniform1Bool : protected GLUniform { class GLUniform1f : protected GLUniform { protected: - GLUniform1f( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "float", 1, 1, global ) + GLUniform1f( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "float", 1, 1, updateType ) { } @@ -725,15 +747,14 @@ class GLUniform1f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { currentValue = value; return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) float *firewall = ( float * ) &p->uniformFirewall[ _firewallIndex ]; @@ -764,8 +785,8 @@ class GLUniform1f : protected GLUniform class GLUniform1fv : protected GLUniform { protected: - GLUniform1fv( GLShader *shader, const char *name, const int size ) : - GLUniform( shader, name, "float", 1, 1, false, size ) + GLUniform1fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : + GLUniform( shader, name, "float", 1, 1, updateType, size ) { currentValue.reserve( size ); } @@ -774,15 +795,14 @@ class GLUniform1fv : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { memcpy( currentValue.data(), f, numFloats * sizeof( float ) ); return; } + ASSERT_EQ( p, glState.currentProgram ); + glUniform1fv( p->uniformLocations[ _locationIndex ], numFloats, f ); } @@ -798,8 +818,8 @@ class GLUniform1fv : protected GLUniform class GLUniform2f : protected GLUniform { protected: - GLUniform2f( GLShader *shader, const char *name ) : - GLUniform( shader, name, "vec2", 2, 2, false ) + GLUniform2f( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "vec2", 2, 2, updateType ) { currentValue[0] = 0.0; currentValue[1] = 0.0; @@ -809,15 +829,14 @@ class GLUniform2f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { Vector2Copy( v, currentValue ); return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) vec2_t *firewall = ( vec2_t * ) &p->uniformFirewall[ _firewallIndex ]; @@ -849,8 +868,8 @@ class GLUniform2f : protected GLUniform class GLUniform3f : protected GLUniform { protected: - GLUniform3f( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "vec3", 3, 4, global ) + GLUniform3f( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "vec3", 3, 4, updateType ) { currentValue[0] = 0.0; currentValue[1] = 0.0; @@ -861,15 +880,14 @@ class GLUniform3f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { VectorCopy( v, currentValue ); return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) vec3_t *firewall = ( vec3_t * ) &p->uniformFirewall[ _firewallIndex ]; @@ -900,8 +918,8 @@ class GLUniform3f : protected GLUniform class GLUniform4f : protected GLUniform { protected: - GLUniform4f( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "vec4", 4, 4, global ) + GLUniform4f( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "vec4", 4, 4, updateType ) { currentValue[0] = 0.0; currentValue[1] = 0.0; @@ -913,15 +931,14 @@ class GLUniform4f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { Vector4Copy( v, currentValue ); return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) vec4_t *firewall = ( vec4_t * ) &p->uniformFirewall[ _firewallIndex ]; @@ -952,8 +969,8 @@ class GLUniform4f : protected GLUniform class GLUniform4fv : protected GLUniform { protected: - GLUniform4fv( GLShader *shader, const char *name, const int size ) : - GLUniform( shader, name, "vec4", 4, 4, false, size ) + GLUniform4fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : + GLUniform( shader, name, "vec4", 4, 4, updateType, size ) { currentValue.reserve( size ); } @@ -962,15 +979,14 @@ class GLUniform4fv : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { memcpy( currentValue.data(), v, numV * sizeof( vec4_t ) ); return; } + ASSERT_EQ( p, glState.currentProgram ); + glUniform4fv( p->uniformLocations[ _locationIndex ], numV, &v[ 0 ][ 0 ] ); } @@ -987,8 +1003,8 @@ class GLUniform4fv : protected GLUniform class GLUniformMatrix4f : protected GLUniform { protected: - GLUniformMatrix4f( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "mat4", 16, 4, global ) + GLUniformMatrix4f( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "mat4", 16, 4, updateType ) { MatrixIdentity( currentValue ); } @@ -997,15 +1013,14 @@ class GLUniformMatrix4f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { MatrixCopy( m, currentValue ); return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) matrix_t *firewall = ( matrix_t * ) &p->uniformFirewall[ _firewallIndex ]; @@ -1035,22 +1050,21 @@ class GLUniformMatrix4f : protected GLUniform class GLUniformMatrix32f : protected GLUniform { protected: - GLUniformMatrix32f( GLShader* shader, const char* name, const bool global = false ) : - GLUniform( shader, name, "mat3x2", 6, 2, global ) { + GLUniformMatrix32f( GLShader* shader, const char* name, const UpdateType updateType ) : + GLUniform( shader, name, "mat3x2", 12, 4, updateType ) { } inline void SetValue( GLboolean transpose, const vec_t* m ) { ShaderProgramDescriptor* p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { memcpy( currentValue, m, 6 * sizeof( float ) ); return; } + ASSERT_EQ( p, glState.currentProgram ); + glUniformMatrix3x2fv( p->uniformLocations[_locationIndex], 1, transpose, m ); } public: @@ -1070,8 +1084,8 @@ class GLUniformMatrix32f : protected GLUniform { class GLUniformMatrix4fv : protected GLUniform { protected: - GLUniformMatrix4fv( GLShader *shader, const char *name, const int size ) : - GLUniform( shader, name, "mat4", 16, 4, false, size ) + GLUniformMatrix4fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : + GLUniform( shader, name, "mat4", 16, 4, updateType, size ) { currentValue.reserve( size * 16 ); } @@ -1080,15 +1094,14 @@ class GLUniformMatrix4fv : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { memcpy( currentValue.data(), m, numMatrices * sizeof( matrix_t ) ); return; } + ASSERT_EQ( p, glState.currentProgram ); + glUniformMatrix4fv( p->uniformLocations[ _locationIndex ], numMatrices, transpose, &m[ 0 ][ 0 ] ); } @@ -1105,8 +1118,8 @@ class GLUniformMatrix4fv : protected GLUniform class GLUniformMatrix34fv : protected GLUniform { protected: - GLUniformMatrix34fv( GLShader *shader, const char *name, const int size ) : - GLUniform( shader, name, "mat3x4", 12, 4, false, size ) + GLUniformMatrix34fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : + GLUniform( shader, name, "mat3x4", 12, 4, updateType, size ) { } @@ -1114,15 +1127,14 @@ class GLUniformMatrix34fv : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) ) { memcpy( currentValue.data(), m, numMatrices * sizeof( matrix_t ) ); return; } + ASSERT_EQ( p, glState.currentProgram ); + glUniformMatrix3x4fv( p->uniformLocations[ _locationIndex ], numMatrices, transpose, m ); } @@ -1702,7 +1714,7 @@ class u_ColorMap : GLUniformSampler2D { public: u_ColorMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_ColorMap" ) { + GLUniformSampler2D( shader, "u_ColorMap", PUSH ) { } void SetUniform_ColorMapBindless( GLuint64 bindlessHandle ) { @@ -1714,7 +1726,7 @@ class u_ColorMap3D : GLUniformSampler3D { public: u_ColorMap3D( GLShader* shader ) : - GLUniformSampler3D( shader, "u_ColorMap3D" ) { + GLUniformSampler3D( shader, "u_ColorMap3D", CONST ) { } void SetUniform_ColorMap3DBindless( GLuint64 bindlessHandle ) { @@ -1726,7 +1738,7 @@ class u_ColorMapCube : GLUniformSamplerCube { public: u_ColorMapCube( GLShader* shader ) : - GLUniformSamplerCube( shader, "u_ColorMapCube" ) { + GLUniformSamplerCube( shader, "u_ColorMapCube", TEXDATA_OR_PUSH ) { } void SetUniform_ColorMapCubeBindless( GLuint64 bindlessHandle ) { @@ -1738,7 +1750,7 @@ class u_DepthMap : GLUniformSampler2D { public: u_DepthMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthMap" ) { + GLUniformSampler2D( shader, "u_DepthMap", CONST ) { } void SetUniform_DepthMapBindless( GLuint64 bindlessHandle ) { @@ -1750,7 +1762,7 @@ class u_DiffuseMap : GLUniformSampler2D { public: u_DiffuseMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DiffuseMap" ) { + GLUniformSampler2D( shader, "u_DiffuseMap", TEXDATA_OR_PUSH ) { } void SetUniform_DiffuseMapBindless( GLuint64 bindlessHandle ) { @@ -1762,7 +1774,7 @@ class u_HeightMap : GLUniformSampler2D { public: u_HeightMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_HeightMap" ) { + GLUniformSampler2D( shader, "u_HeightMap", TEXDATA_OR_PUSH ) { } void SetUniform_HeightMapBindless( GLuint64 bindlessHandle ) { @@ -1774,7 +1786,7 @@ class u_NormalMap : GLUniformSampler2D { public: u_NormalMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_NormalMap" ) { + GLUniformSampler2D( shader, "u_NormalMap", TEXDATA_OR_PUSH ) { } void SetUniform_NormalMapBindless( GLuint64 bindlessHandle ) { @@ -1786,7 +1798,7 @@ class u_MaterialMap : GLUniformSampler2D { public: u_MaterialMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_MaterialMap" ) { + GLUniformSampler2D( shader, "u_MaterialMap", TEXDATA_OR_PUSH ) { } void SetUniform_MaterialMapBindless( GLuint64 bindlessHandle ) { @@ -1798,7 +1810,7 @@ class u_LightMap : GLUniformSampler { public: u_LightMap( GLShader* shader ) : - GLUniformSampler( shader, "u_LightMap", "sampler2D" ) { + GLUniformSampler( shader, "u_LightMap", "sampler2D", TEXDATA_OR_PUSH ) { } void SetUniform_LightMapBindless( GLuint64 bindlessHandle ) { @@ -1810,7 +1822,7 @@ class u_DeluxeMap : GLUniformSampler { public: u_DeluxeMap( GLShader* shader ) : - GLUniformSampler( shader, "u_DeluxeMap", "sampler2D" ) { + GLUniformSampler( shader, "u_DeluxeMap", "sampler2D", TEXDATA_OR_PUSH ) { } void SetUniform_DeluxeMapBindless( GLuint64 bindlessHandle ) { @@ -1822,7 +1834,7 @@ class u_GlowMap : GLUniformSampler2D { public: u_GlowMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_GlowMap" ) { + GLUniformSampler2D( shader, "u_GlowMap", TEXDATA_OR_PUSH ) { } void SetUniform_GlowMapBindless( GLuint64 bindlessHandle ) { @@ -1834,7 +1846,7 @@ class u_PortalMap : GLUniformSampler2D { public: u_PortalMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_PortalMap" ) { + GLUniformSampler2D( shader, "u_PortalMap", CONST ) { } void SetUniform_PortalMapBindless( GLuint64 bindlessHandle ) { @@ -1846,7 +1858,7 @@ class u_CloudMap : GLUniformSampler2D { public: u_CloudMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_CloudMap" ) { + GLUniformSampler2D( shader, "u_CloudMap", PUSH ) { } void SetUniform_CloudMapBindless( GLuint64 bindlessHandle ) { @@ -1858,7 +1870,7 @@ class u_FogMap : GLUniformSampler2D { public: u_FogMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_FogMap" ) { + GLUniformSampler2D( shader, "u_FogMap", CONST ) { } void SetUniform_FogMapBindless( GLuint64 bindlessHandle ) { @@ -1870,7 +1882,7 @@ class u_DepthTile1 : GLUniformSampler2D { public: u_DepthTile1( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthTile1" ) { + GLUniformSampler2D( shader, "u_DepthTile1", CONST ) { } void SetUniform_DepthTile1Bindless( GLuint64 bindlessHandle ) { @@ -1882,7 +1894,7 @@ class u_DepthTile2 : GLUniformSampler2D { public: u_DepthTile2( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthTile2" ) { + GLUniformSampler2D( shader, "u_DepthTile2", CONST ) { } void SetUniform_DepthTile2Bindless( GLuint64 bindlessHandle ) { @@ -1894,7 +1906,7 @@ class u_LightTiles : GLUniformSampler3D { public: u_LightTiles( GLShader* shader ) : - GLUniformSampler3D( shader, "u_LightTiles" ) { + GLUniformSampler3D( shader, "u_LightTiles", CONST ) { } void SetUniform_LightTilesBindless( GLuint64 bindlessHandle ) { @@ -1906,7 +1918,7 @@ class u_LightGrid1 : GLUniformSampler3D { public: u_LightGrid1( GLShader* shader ) : - GLUniformSampler3D( shader, "u_LightGrid1" ) { + GLUniformSampler3D( shader, "u_LightGrid1", CONST ) { } void SetUniform_LightGrid1Bindless( GLuint64 bindlessHandle ) { @@ -1918,7 +1930,7 @@ class u_LightGrid2 : GLUniformSampler3D { public: u_LightGrid2( GLShader* shader ) : - GLUniformSampler3D( shader, "u_LightGrid2" ) { + GLUniformSampler3D( shader, "u_LightGrid2", CONST ) { } void SetUniform_LightGrid2Bindless( GLuint64 bindlessHandle ) { @@ -1930,7 +1942,7 @@ class u_EnvironmentMap0 : GLUniformSamplerCube { public: u_EnvironmentMap0( GLShader* shader ) : - GLUniformSamplerCube( shader, "u_EnvironmentMap0" ) { + GLUniformSamplerCube( shader, "u_EnvironmentMap0", PUSH ) { } void SetUniform_EnvironmentMap0Bindless( GLuint64 bindlessHandle ) { @@ -1942,7 +1954,7 @@ class u_EnvironmentMap1 : GLUniformSamplerCube { public: u_EnvironmentMap1( GLShader* shader ) : - GLUniformSamplerCube( shader, "u_EnvironmentMap1" ) { + GLUniformSamplerCube( shader, "u_EnvironmentMap1", PUSH ) { } void SetUniform_EnvironmentMap1Bindless( GLuint64 bindlessHandle ) { @@ -1954,7 +1966,7 @@ class u_CurrentMap : GLUniformSampler2D { public: u_CurrentMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_CurrentMap" ) { + GLUniformSampler2D( shader, "u_CurrentMap", PUSH ) { } void SetUniform_CurrentMapBindless( GLuint64 bindlessHandle ) { @@ -1967,7 +1979,7 @@ class u_TextureMatrix : { public: u_TextureMatrix( GLShader *shader ) : - GLUniformMatrix32f( shader, "u_TextureMatrix", true ) + GLUniformMatrix32f( shader, "u_TextureMatrix", TEXDATA_OR_PUSH ) { } @@ -1991,7 +2003,7 @@ class u_AlphaThreshold : { public: u_AlphaThreshold( GLShader *shader ) : - GLUniform1f( shader, "u_AlphaThreshold" ) + GLUniform1f( shader, "u_AlphaThreshold", MATERIAL_OR_PUSH ) { } @@ -2049,7 +2061,7 @@ class u_ViewOrigin : { public: u_ViewOrigin( GLShader *shader ) : - GLUniform3f( shader, "u_ViewOrigin", true ) + GLUniform3f( shader, "u_ViewOrigin", PUSH ) { } @@ -2064,7 +2076,7 @@ class u_RefractionIndex : { public: u_RefractionIndex( GLShader *shader ) : - GLUniform1f( shader, "u_RefractionIndex" ) + GLUniform1f( shader, "u_RefractionIndex", MATERIAL_OR_PUSH ) { } @@ -2079,7 +2091,7 @@ class u_FresnelPower : { public: u_FresnelPower( GLShader *shader ) : - GLUniform1f( shader, "u_FresnelPower" ) + GLUniform1f( shader, "u_FresnelPower", MATERIAL_OR_PUSH ) { } @@ -2094,7 +2106,7 @@ class u_FresnelScale : { public: u_FresnelScale( GLShader *shader ) : - GLUniform1f( shader, "u_FresnelScale" ) + GLUniform1f( shader, "u_FresnelScale", MATERIAL_OR_PUSH ) { } @@ -2109,7 +2121,7 @@ class u_FresnelBias : { public: u_FresnelBias( GLShader *shader ) : - GLUniform1f( shader, "u_FresnelBias" ) + GLUniform1f( shader, "u_FresnelBias", MATERIAL_OR_PUSH ) { } @@ -2124,7 +2136,7 @@ class u_NormalScale : { public: u_NormalScale( GLShader *shader ) : - GLUniform3f( shader, "u_NormalScale" ) + GLUniform3f( shader, "u_NormalScale", MATERIAL_OR_PUSH ) { } @@ -2140,7 +2152,7 @@ class u_FogDensity : { public: u_FogDensity( GLShader *shader ) : - GLUniform1f( shader, "u_FogDensity" ) + GLUniform1f( shader, "u_FogDensity", MATERIAL_OR_PUSH ) { } @@ -2155,7 +2167,7 @@ class u_FogColor : { public: u_FogColor( GLShader *shader ) : - GLUniform3f( shader, "u_FogColor" ) + GLUniform3f( shader, "u_FogColor", MATERIAL_OR_PUSH ) { } @@ -2170,7 +2182,7 @@ class u_CloudHeight : GLUniform1f { public: u_CloudHeight( GLShader* shader ) : - GLUniform1f( shader, "u_CloudHeight" ) { + GLUniform1f( shader, "u_CloudHeight", PUSH ) { } void SetUniform_CloudHeight( const float cloudHeight ) { @@ -2183,7 +2195,7 @@ class u_Color_Float : { public: u_Color_Float( GLShader *shader ) : - GLUniform4f( shader, "u_Color" ) + GLUniform4f( shader, "u_Color", LEGACY ) { } @@ -2198,7 +2210,7 @@ class u_Color_Uint : { public: u_Color_Uint( GLShader *shader ) : - GLUniform1ui( shader, "u_Color" ) + GLUniform1ui( shader, "u_Color", MATERIAL_OR_PUSH ) { } @@ -2225,7 +2237,7 @@ class u_ColorGlobal_Float : { public: u_ColorGlobal_Float( GLShader *shader ) : - GLUniform4f( shader, "u_ColorGlobal", true ) + GLUniform4f( shader, "u_ColorGlobal", LEGACY ) { } @@ -2239,7 +2251,7 @@ class u_ColorGlobal_Uint : GLUniform1ui { public: u_ColorGlobal_Uint( GLShader* shader ) : - GLUniform1ui( shader, "u_ColorGlobal", true ) { + GLUniform1ui( shader, "u_ColorGlobal", MATERIAL_OR_PUSH ) { } void SetUniform_ColorGlobal_Uint( const Color::Color& color ) { @@ -2263,7 +2275,7 @@ class u_Frame : GLUniform1ui { public: u_Frame( GLShader* shader ) : - GLUniform1ui( shader, "u_Frame" ) { + GLUniform1ui( shader, "u_Frame", FRAME ) { } void SetUniform_Frame( const uint frame ) { @@ -2275,7 +2287,7 @@ class u_ViewID : GLUniform1ui { public: u_ViewID( GLShader* shader ) : - GLUniform1ui( shader, "u_ViewID" ) { + GLUniform1ui( shader, "u_ViewID", PUSH ) { } void SetUniform_ViewID( const uint viewID ) { @@ -2287,7 +2299,7 @@ class u_FirstPortalGroup : GLUniform1ui { public: u_FirstPortalGroup( GLShader* shader ) : - GLUniform1ui( shader, "u_FirstPortalGroup" ) { + GLUniform1ui( shader, "u_FirstPortalGroup", CONST ) { } void SetUniform_FirstPortalGroup( const uint firstPortalGroup ) { @@ -2299,7 +2311,7 @@ class u_TotalPortals : GLUniform1ui { public: u_TotalPortals( GLShader* shader ) : - GLUniform1ui( shader, "u_TotalPortals" ) { + GLUniform1ui( shader, "u_TotalPortals", CONST ) { } void SetUniform_TotalPortals( const uint totalPortals ) { @@ -2311,7 +2323,7 @@ class u_ViewWidth : GLUniform1ui { public: u_ViewWidth( GLShader* shader ) : - GLUniform1ui( shader, "u_ViewWidth" ) { + GLUniform1ui( shader, "u_ViewWidth", PUSH ) { } void SetUniform_ViewWidth( const uint viewWidth ) { @@ -2323,7 +2335,7 @@ class u_ViewHeight : GLUniform1ui { public: u_ViewHeight( GLShader* shader ) : - GLUniform1ui( shader, "u_ViewHeight" ) { + GLUniform1ui( shader, "u_ViewHeight", PUSH ) { } void SetUniform_ViewHeight( const uint viewHeight ) { @@ -2335,7 +2347,7 @@ class u_InitialDepthLevel : GLUniform1Bool { public: u_InitialDepthLevel( GLShader* shader ) : - GLUniform1Bool( shader, "u_InitialDepthLevel", true ) { + GLUniform1Bool( shader, "u_InitialDepthLevel", PUSH ) { } void SetUniform_InitialDepthLevel( const int initialDepthLevel ) { @@ -2347,7 +2359,7 @@ class u_P00 : GLUniform1f { public: u_P00( GLShader* shader ) : - GLUniform1f( shader, "u_P00" ) { + GLUniform1f( shader, "u_P00", PUSH ) { } void SetUniform_P00( const float P00 ) { @@ -2359,7 +2371,7 @@ class u_P11 : GLUniform1f { public: u_P11( GLShader* shader ) : - GLUniform1f( shader, "u_P11" ) { + GLUniform1f( shader, "u_P11", PUSH ) { } void SetUniform_P11( const float P11 ) { @@ -2371,7 +2383,7 @@ class u_SurfaceDescriptorsCount : GLUniform1ui { public: u_SurfaceDescriptorsCount( GLShader* shader ) : - GLUniform1ui( shader, "u_SurfaceDescriptorsCount", true ) { + GLUniform1ui( shader, "u_SurfaceDescriptorsCount", CONST ) { } void SetUniform_SurfaceDescriptorsCount( const uint SurfaceDescriptorsCount ) { @@ -2383,7 +2395,7 @@ class u_UseFrustumCulling : GLUniform1Bool { public: u_UseFrustumCulling( GLShader* shader ) : - GLUniform1Bool( shader, "u_UseFrustumCulling", true ) { + GLUniform1Bool( shader, "u_UseFrustumCulling", FRAME ) { } void SetUniform_UseFrustumCulling( const int useFrustumCulling ) { @@ -2395,7 +2407,7 @@ class u_UseOcclusionCulling : GLUniform1Bool { public: u_UseOcclusionCulling( GLShader* shader ) : - GLUniform1Bool( shader, "u_UseOcclusionCulling", true ) { + GLUniform1Bool( shader, "u_UseOcclusionCulling", FRAME ) { } void SetUniform_UseOcclusionCulling( const int useOcclusionCulling ) { @@ -2407,7 +2419,7 @@ class u_ShowTris : GLUniform1Bool { public: u_ShowTris( GLShader* shader ) : - GLUniform1Bool( shader, "u_ShowTris", true ) { + GLUniform1Bool( shader, "u_ShowTris", PUSH ) { } void SetUniform_ShowTris( const int showTris ) { @@ -2419,7 +2431,7 @@ class u_CameraPosition : GLUniform3f { public: u_CameraPosition( GLShader* shader ) : - GLUniform3f( shader, "u_CameraPosition" ) { + GLUniform3f( shader, "u_CameraPosition", PUSH ) { } void SetUniform_CameraPosition( const vec3_t cameraPosition ) { @@ -2431,7 +2443,7 @@ class u_Frustum : GLUniform4fv { public: u_Frustum( GLShader* shader ) : - GLUniform4fv( shader, "u_Frustum", 6 ) { + GLUniform4fv( shader, "u_Frustum", 6, PUSH ) { } void SetUniform_Frustum( vec4_t frustum[6] ) { @@ -2443,7 +2455,7 @@ class u_SurfaceCommandsOffset : GLUniform1ui { public: u_SurfaceCommandsOffset( GLShader* shader ) : - GLUniform1ui( shader, "u_SurfaceCommandsOffset" ) { + GLUniform1ui( shader, "u_SurfaceCommandsOffset", PUSH ) { } void SetUniform_SurfaceCommandsOffset( const uint surfaceCommandsOffset ) { @@ -2455,7 +2467,7 @@ class u_MaterialColour : GLUniform3f { public: u_MaterialColour( GLShader* shader ) : - GLUniform3f( shader, "u_MaterialColour", true ) { + GLUniform3f( shader, "u_MaterialColour", PUSH ) { } void SetUniform_MaterialColour( const vec3_t materialColour ) { @@ -2469,7 +2481,7 @@ class u_ProfilerZero : GLUniform1f { public: u_ProfilerZero( GLShader* shader ) : - GLUniform1f( shader, "u_ProfilerZero", true ) { + GLUniform1f( shader, "u_ProfilerZero", CONST ) { } void SetUniform_ProfilerZero() { @@ -2481,7 +2493,7 @@ class u_ProfilerRenderSubGroups : GLUniform1ui { public: u_ProfilerRenderSubGroups( GLShader* shader ) : - GLUniform1ui( shader, "u_ProfilerRenderSubGroups", true ) { + GLUniform1ui( shader, "u_ProfilerRenderSubGroups", PUSH ) { } void SetUniform_ProfilerRenderSubGroups( const uint renderSubGroups ) { @@ -2494,7 +2506,7 @@ class u_ModelMatrix : { public: u_ModelMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelMatrix", true ) + GLUniformMatrix4f( shader, "u_ModelMatrix", PUSH ) { } @@ -2509,7 +2521,7 @@ class u_ViewMatrix : { public: u_ViewMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ViewMatrix" ) + GLUniformMatrix4f( shader, "u_ViewMatrix", PUSH ) { } @@ -2524,7 +2536,7 @@ class u_ModelViewMatrix : { public: u_ModelViewMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelViewMatrix" ) + GLUniformMatrix4f( shader, "u_ModelViewMatrix", PUSH ) { } @@ -2539,7 +2551,7 @@ class u_ModelViewMatrixTranspose : { public: u_ModelViewMatrixTranspose( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelViewMatrixTranspose", true ) + GLUniformMatrix4f( shader, "u_ModelViewMatrixTranspose", PUSH ) { } @@ -2554,7 +2566,7 @@ class u_ProjectionMatrixTranspose : { public: u_ProjectionMatrixTranspose( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ProjectionMatrixTranspose", true ) + GLUniformMatrix4f( shader, "u_ProjectionMatrixTranspose", PUSH ) { } @@ -2569,7 +2581,7 @@ class u_ModelViewProjectionMatrix : { public: u_ModelViewProjectionMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelViewProjectionMatrix", true ) + GLUniformMatrix4f( shader, "u_ModelViewProjectionMatrix", PUSH ) { } @@ -2584,7 +2596,7 @@ class u_UnprojectMatrix : { public: u_UnprojectMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_UnprojectMatrix", true ) + GLUniformMatrix4f( shader, "u_UnprojectMatrix", PUSH ) { } @@ -2598,7 +2610,7 @@ class u_UseCloudMap : GLUniform1Bool { public: u_UseCloudMap( GLShader* shader ) : - GLUniform1Bool( shader, "u_UseCloudMap", true ) { + GLUniform1Bool( shader, "u_UseCloudMap", PUSH ) { } void SetUniform_UseCloudMap( const bool useCloudMap ) { @@ -2611,7 +2623,7 @@ class u_Bones : { public: u_Bones( GLShader *shader ) : - GLUniform4fv( shader, "u_Bones", MAX_BONES ) + GLUniform4fv( shader, "u_Bones", MAX_BONES, PUSH ) { } @@ -2626,7 +2638,7 @@ class u_VertexInterpolation : { public: u_VertexInterpolation( GLShader *shader ) : - GLUniform1f( shader, "u_VertexInterpolation" ) + GLUniform1f( shader, "u_VertexInterpolation", PUSH ) { } @@ -2641,7 +2653,7 @@ class u_InversePortalRange : { public: u_InversePortalRange( GLShader *shader ) : - GLUniform1f( shader, "u_InversePortalRange" ) + GLUniform1f( shader, "u_InversePortalRange", PUSH ) { } @@ -2656,7 +2668,7 @@ class u_DepthScale : { public: u_DepthScale( GLShader *shader ) : - GLUniform1f( shader, "u_DepthScale" ) + GLUniform1f( shader, "u_DepthScale", MATERIAL_OR_PUSH ) { } @@ -2671,7 +2683,7 @@ class u_ReliefDepthScale : { public: u_ReliefDepthScale( GLShader *shader ) : - GLUniform1f( shader, "u_ReliefDepthScale" ) + GLUniform1f( shader, "u_ReliefDepthScale", MATERIAL_OR_PUSH ) { } @@ -2686,7 +2698,7 @@ class u_ReliefOffsetBias : { public: u_ReliefOffsetBias( GLShader *shader ) : - GLUniform1f( shader, "u_ReliefOffsetBias" ) + GLUniform1f( shader, "u_ReliefOffsetBias", MATERIAL_OR_PUSH ) { } @@ -2701,7 +2713,7 @@ class u_EnvironmentInterpolation : { public: u_EnvironmentInterpolation( GLShader *shader ) : - GLUniform1f( shader, "u_EnvironmentInterpolation", true ) + GLUniform1f( shader, "u_EnvironmentInterpolation", PUSH ) { } @@ -2716,7 +2728,7 @@ class u_Time : { public: u_Time( GLShader *shader ) : - GLUniform1f( shader, "u_Time", true ) // Source this from a buffer when entity support is added to the material system + GLUniform1f( shader, "u_Time", PUSH ) { } @@ -2731,7 +2743,7 @@ class u_GlobalLightFactor : { public: u_GlobalLightFactor( GLShader *shader ) : - GLUniform1f( shader, "u_GlobalLightFactor" ) + GLUniform1f( shader, "u_GlobalLightFactor", CONST ) { } @@ -2756,7 +2768,7 @@ class u_ColorModulate : { public: u_ColorModulate( GLShader *shader ) : - GLUniform4f( shader, "u_ColorModulate" ) + GLUniform4f( shader, "u_ColorModulate", FRAME ) { } @@ -2839,7 +2851,7 @@ class u_ColorModulateColorGen_Float : { public: u_ColorModulateColorGen_Float( GLShader* shader ) : - GLUniform4f( shader, "u_ColorModulateColorGen" ) + GLUniform4f( shader, "u_ColorModulateColorGen", LEGACY ) { } @@ -2871,7 +2883,7 @@ class u_ColorModulateColorGen_Uint : GLUniform1ui { public: u_ColorModulateColorGen_Uint( GLShader* shader ) : - GLUniform1ui( shader, "u_ColorModulateColorGen" ) { + GLUniform1ui( shader, "u_ColorModulateColorGen", MATERIAL_OR_PUSH ) { } void SetUniform_ColorModulateColorGen_Uint( @@ -2945,7 +2957,7 @@ class u_FogDistanceVector : { public: u_FogDistanceVector( GLShader *shader ) : - GLUniform4f( shader, "u_FogDistanceVector", true ) + GLUniform4f( shader, "u_FogDistanceVector", PUSH ) { } @@ -2960,7 +2972,7 @@ class u_FogDepthVector : { public: u_FogDepthVector( GLShader *shader ) : - GLUniform4f( shader, "u_FogDepthVector", true ) + GLUniform4f( shader, "u_FogDepthVector", PUSH ) { } @@ -2975,7 +2987,7 @@ class u_FogEyeT : { public: u_FogEyeT( GLShader *shader ) : - GLUniform1f( shader, "u_FogEyeT", true ) + GLUniform1f( shader, "u_FogEyeT", PUSH ) { } @@ -2989,7 +3001,7 @@ class u_DeformEnable : GLUniform1f { public: u_DeformEnable( GLShader* shader ) : - GLUniform1f( shader, "u_DeformEnable", true ) { + GLUniform1f( shader, "u_DeformEnable", PUSH ) { } void SetUniform_DeformEnable( const bool value ) { @@ -3002,7 +3014,7 @@ class u_DeformMagnitude : { public: u_DeformMagnitude( GLShader *shader ) : - GLUniform1f( shader, "u_DeformMagnitude" ) + GLUniform1f( shader, "u_DeformMagnitude", MATERIAL_OR_PUSH ) { } @@ -3017,7 +3029,7 @@ class u_blurVec : { public: u_blurVec( GLShader *shader ) : - GLUniform3f( shader, "u_blurVec" ) + GLUniform3f( shader, "u_blurVec", FRAME ) { } @@ -3031,7 +3043,7 @@ class u_Horizontal : GLUniform1Bool { public: u_Horizontal( GLShader* shader ) : - GLUniform1Bool( shader, "u_Horizontal", true ) { + GLUniform1Bool( shader, "u_Horizontal", PUSH ) { } void SetUniform_Horizontal( bool horizontal ) { @@ -3044,7 +3056,7 @@ class u_TexScale : { public: u_TexScale( GLShader *shader ) : - GLUniform2f( shader, "u_TexScale" ) + GLUniform2f( shader, "u_TexScale", PUSH ) { } @@ -3059,7 +3071,7 @@ class u_SpecularExponent : { public: u_SpecularExponent( GLShader *shader ) : - GLUniform2f( shader, "u_SpecularExponent" ) + GLUniform2f( shader, "u_SpecularExponent", MATERIAL_OR_PUSH ) { } @@ -3079,7 +3091,7 @@ class u_InverseGamma : { public: u_InverseGamma( GLShader *shader ) : - GLUniform1f( shader, "u_InverseGamma" ) + GLUniform1f( shader, "u_InverseGamma", FRAME ) { } @@ -3093,7 +3105,7 @@ class u_Tonemap : GLUniform1Bool { public: u_Tonemap( GLShader* shader ) : - GLUniform1Bool( shader, "u_Tonemap", true ) { + GLUniform1Bool( shader, "u_Tonemap", FRAME ) { } void SetUniform_Tonemap( bool tonemap ) { @@ -3105,7 +3117,7 @@ class u_TonemapParms : GLUniform4f { public: u_TonemapParms( GLShader* shader ) : - GLUniform4f( shader, "u_TonemapParms", true ) { + GLUniform4f( shader, "u_TonemapParms", FRAME ) { } void SetUniform_TonemapParms( vec4_t tonemapParms ) { @@ -3117,7 +3129,7 @@ class u_TonemapExposure : GLUniform1f { public: u_TonemapExposure( GLShader* shader ) : - GLUniform1f( shader, "u_TonemapExposure", true ) { + GLUniform1f( shader, "u_TonemapExposure", FRAME ) { } void SetUniform_TonemapExposure( float tonemapExposure ) { @@ -3130,7 +3142,7 @@ class u_LightGridOrigin : { public: u_LightGridOrigin( GLShader *shader ) : - GLUniform3f( shader, "u_LightGridOrigin", true ) + GLUniform3f( shader, "u_LightGridOrigin", CONST ) { } @@ -3145,7 +3157,7 @@ class u_LightGridScale : { public: u_LightGridScale( GLShader *shader ) : - GLUniform3f( shader, "u_LightGridScale", true ) + GLUniform3f( shader, "u_LightGridScale", CONST ) { } @@ -3160,7 +3172,7 @@ class u_zFar : { public: u_zFar( GLShader *shader ) : - GLUniform3f( shader, "u_zFar" ) + GLUniform3f( shader, "u_zFar", PUSH ) { } @@ -3174,7 +3186,7 @@ class u_UnprojectionParams : GLUniform3f { public: u_UnprojectionParams( GLShader* shader ) : - GLUniform3f( shader, "u_UnprojectionParams" ) { + GLUniform3f( shader, "u_UnprojectionParams", PUSH ) { } void SetUniform_UnprojectionParams( const vec3_t value ) { @@ -3187,7 +3199,7 @@ class u_numLights : { public: u_numLights( GLShader *shader ) : - GLUniform1i( shader, "u_numLights", true ) + GLUniform1i( shader, "u_numLights", FRAME ) { } @@ -3202,7 +3214,7 @@ class u_lightLayer : { public: u_lightLayer( GLShader *shader ) : - GLUniform1i( shader, "u_lightLayer" ) + GLUniform1i( shader, "u_lightLayer", PUSH ) { } From 1bd0d74b51b41415a2d1416a78a648c1e57a808d Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 13:10:25 +0300 Subject: [PATCH 12/12] Add the remaining code for the global UBO in PushBuffer Post-process shaders to actually add the `globalUniformBlock`, add `SetConstUniforms()` and `SetFrameUniforms()` functions to the core and material system renderers, and add the supporting glsl code. --- src/engine/renderer/GLMemory.cpp | 4 ++ src/engine/renderer/GLMemory.h | 3 + src/engine/renderer/Material.cpp | 16 ++++++ src/engine/renderer/Material.h | 2 + src/engine/renderer/gl_shader.cpp | 12 +++- src/engine/renderer/gl_shader.h | 2 +- .../glsl_source/cameraEffects_fp.glsl | 4 ++ .../glsl_source/depthReduction_cp.glsl | 4 ++ .../renderer/glsl_source/depthtile1_fp.glsl | 4 ++ .../renderer/glsl_source/depthtile2_fp.glsl | 4 ++ .../renderer/glsl_source/fogGlobal_fp.glsl | 4 ++ .../renderer/glsl_source/generic_fp.glsl | 2 + .../renderer/glsl_source/lightMapping_fp.glsl | 1 + .../renderer/glsl_source/lighttile_fp.glsl | 4 ++ .../renderer/glsl_source/liquid_fp.glsl | 2 + .../renderer/glsl_source/material_fp.glsl | 41 ++++++++++++++ .../renderer/glsl_source/motionblur_fp.glsl | 4 ++ src/engine/renderer/glsl_source/ssao_fp.glsl | 4 ++ src/engine/renderer/tr_backend.cpp | 40 +++++++++++++ src/engine/renderer/tr_bsp.cpp | 56 +++++++++++++++++++ src/engine/renderer/tr_shade.cpp | 2 +- 21 files changed, 210 insertions(+), 5 deletions(-) diff --git a/src/engine/renderer/GLMemory.cpp b/src/engine/renderer/GLMemory.cpp index fe8f4e10c7..54a38ba26f 100644 --- a/src/engine/renderer/GLMemory.cpp +++ b/src/engine/renderer/GLMemory.cpp @@ -117,6 +117,10 @@ void GLStagingBuffer::FlushAll() { FlushStagingCopyQueue(); } +bool GLStagingBuffer::Active() const { + return buffer.id; +} + void GLStagingBuffer::InitGLBuffer() { buffer.GenBuffer(); diff --git a/src/engine/renderer/GLMemory.h b/src/engine/renderer/GLMemory.h index f555025301..8efe6921b6 100644 --- a/src/engine/renderer/GLMemory.h +++ b/src/engine/renderer/GLMemory.h @@ -173,6 +173,7 @@ class GLBuffer { void DelBuffer() { glDeleteBuffers( 1, &id ); + id = 0; mapped = false; } @@ -301,6 +302,8 @@ class GLStagingBuffer { void FlushStagingCopyQueue(); void FlushAll(); + bool Active() const; + void InitGLBuffer(); void FreeGLBuffer(); diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index e16ee7f1b3..44a2fb9959 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1495,6 +1495,22 @@ void MaterialSystem::UpdateDynamicSurfaces() { GL_CheckErrors(); } +void MaterialSystem::SetConstUniforms() { + globalUBOProxy->SetUniform_SurfaceDescriptorsCount( surfaceDescriptorsCount ); + uint32_t globalWorkGroupX = surfaceDescriptorsCount % MAX_COMMAND_COUNTERS == 0 ? + surfaceDescriptorsCount / MAX_COMMAND_COUNTERS : surfaceDescriptorsCount / MAX_COMMAND_COUNTERS + 1; + + globalUBOProxy->SetUniform_FirstPortalGroup( globalWorkGroupX ); + globalUBOProxy->SetUniform_TotalPortals( totalPortals ); +} + +void MaterialSystem::SetFrameUniforms() { + globalUBOProxy->SetUniform_Frame( nextFrame ); + + globalUBOProxy->SetUniform_UseFrustumCulling( r_gpuFrustumCulling.Get() ); + globalUBOProxy->SetUniform_UseOcclusionCulling( r_gpuOcclusionCulling.Get() ); +} + void MaterialSystem::UpdateFrameData() { gl_clearSurfacesShader->BindProgram( 0 ); gl_clearSurfacesShader->SetUniform_Frame( nextFrame ); diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 54d1309667..0ee36221ff 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -359,6 +359,8 @@ class MaterialSystem { void StartFrame(); void EndFrame(); + void SetConstUniforms(); + void SetFrameUniforms(); void GenerateDepthImages( const int width, const int height, imageParams_t imageParms ); diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 38b12c2bc5..3a8432b5b9 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1345,6 +1345,12 @@ void GLShaderManager::InitShader( GLShader* shader ) { ShaderDescriptor* desc = FindShader( shader->_name, shaderType.mainText, shaderType.GLType, shaderType.headers, uniqueMacros, compileMacros, true ); + if ( desc && glConfig2.pushBufferAvailable ) { + desc->shaderSource = RemoveUniformsFromShaderText( desc->shaderSource, shader->_pushUniforms ); + + desc->shaderSource.insert( shaderType.offset, globalUniformBlock ); + } + if ( desc && glConfig2.usingMaterialSystem && shader->_useMaterialSystem ) { desc->shaderSource = ShaderPostProcess( shader, desc->shaderSource, shaderType.offset ); } @@ -1600,7 +1606,7 @@ void GLShaderManager::PostProcessGlobalUniforms() { GLuint padding; std::vector* uniforms = &( ( GLShader* ) globalUBOProxy )->_uniforms; std::vector constUniforms = - ProcessUniforms( GLUniform::CONST, GLUniform::CONST, false, *uniforms, size, padding ); + ProcessUniforms( GLUniform::CONST, GLUniform::CONST, !glConfig2.usingBindlessTextures, *uniforms, size, padding ); GenerateUniformStructDefinesText( constUniforms, padding, 0, "globalUniforms", uniformStruct, uniformDefines ); @@ -1609,7 +1615,7 @@ void GLShaderManager::PostProcessGlobalUniforms() { pushBuffer.constUniformsSize = size + padding; std::vector frameUniforms = - ProcessUniforms( GLUniform::FRAME, GLUniform::FRAME, false, *uniforms, size, padding ); + ProcessUniforms( GLUniform::FRAME, GLUniform::FRAME, !glConfig2.usingBindlessTextures, *uniforms, size, padding ); GenerateUniformStructDefinesText( frameUniforms, padding, paddingCount, "globalUniforms", uniformStruct, uniformDefines ); @@ -2245,7 +2251,7 @@ void GLShader::PostProcessUniforms() { if ( glConfig2.pushBufferAvailable && !pushSkip ) { GLuint unused; _pushUniforms = gl_shaderManager.ProcessUniforms( GLUniform::CONST, GLUniform::FRAME, - false, _uniforms, unused, unused ); + !glConfig2.usingBindlessTextures, _uniforms, unused, unused ); } } diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 61bd75b621..20031f8a48 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -554,9 +554,9 @@ class GLUniformSampler : protected GLUniform { if ( glConfig2.pushBufferAvailable && _updateType <= FRAME ) { return; } - } glUniformHandleui64ARB( GetLocation(), currentValueBindless ); + } } uint32_t* WriteToBuffer( uint32_t* buffer ) override { diff --git a/src/engine/renderer/glsl_source/cameraEffects_fp.glsl b/src/engine/renderer/glsl_source/cameraEffects_fp.glsl index bae518595b..092cf3d9f2 100644 --- a/src/engine/renderer/glsl_source/cameraEffects_fp.glsl +++ b/src/engine/renderer/glsl_source/cameraEffects_fp.glsl @@ -22,6 +22,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* cameraEffects_fp.glsl */ +#define CAMERAEFFECTS_GLSL + uniform sampler2D u_CurrentMap; #if defined(r_colorGrading) @@ -53,6 +55,8 @@ DECLARE_OUTPUT(vec4) void main() { + #insert material_fp + // calculate the screen texcoord in the 0.0 to 1.0 range vec2 st = gl_FragCoord.st / r_FBufSize; diff --git a/src/engine/renderer/glsl_source/depthReduction_cp.glsl b/src/engine/renderer/glsl_source/depthReduction_cp.glsl index 47dc8606b3..d6501ca4b5 100644 --- a/src/engine/renderer/glsl_source/depthReduction_cp.glsl +++ b/src/engine/renderer/glsl_source/depthReduction_cp.glsl @@ -34,6 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* depthReduction_cp.glsl */ +#define DEPTHMAP_GLSL + #insert common_cp // Keep this to 8x8 because we don't want extra shared mem etc. to be allocated, and to minimize wasted lanes @@ -48,6 +50,8 @@ uniform uint u_ViewHeight; uniform bool u_InitialDepthLevel; void main() { + #insert material_fp + const uint globalInvocationID = GLOBAL_INVOCATION_ID; const ivec2 position = ivec2( gl_GlobalInvocationID.xy ); diff --git a/src/engine/renderer/glsl_source/depthtile1_fp.glsl b/src/engine/renderer/glsl_source/depthtile1_fp.glsl index 31798e0582..3cae1ca7cc 100644 --- a/src/engine/renderer/glsl_source/depthtile1_fp.glsl +++ b/src/engine/renderer/glsl_source/depthtile1_fp.glsl @@ -34,6 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* depthtile1_fp.glsl */ +#define DEPTHMAP_GLSL + uniform sampler2D u_DepthMap; IN(flat) vec3 unprojectionParams; @@ -63,6 +65,8 @@ float min16(in vec4 data0, in vec4 data1, in vec4 data2, in vec4 data3) } void main() { + #insert material_fp + vec2 st = gl_FragCoord.st * 4.0 * pixelScale; vec4 depth[4], mask[4]; diff --git a/src/engine/renderer/glsl_source/depthtile2_fp.glsl b/src/engine/renderer/glsl_source/depthtile2_fp.glsl index 92ae506a50..c5f19976b3 100644 --- a/src/engine/renderer/glsl_source/depthtile2_fp.glsl +++ b/src/engine/renderer/glsl_source/depthtile2_fp.glsl @@ -34,6 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* depthtile2_fp.glsl */ +#define DEPTHTILE1_GLSL + uniform sampler2D u_DepthTile1; #if __VERSION__ > 120 @@ -44,6 +46,8 @@ out vec4 outputColor; void main() { + #insert material_fp + vec2 st = gl_FragCoord.st * r_tileStep; float x, y; vec4 accum = vec4( 0.0, 99999.0, 0.0, 0.0 ); diff --git a/src/engine/renderer/glsl_source/fogGlobal_fp.glsl b/src/engine/renderer/glsl_source/fogGlobal_fp.glsl index 126fc12bcc..2962ac2376 100644 --- a/src/engine/renderer/glsl_source/fogGlobal_fp.glsl +++ b/src/engine/renderer/glsl_source/fogGlobal_fp.glsl @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert common +#define DEPTHMAP_GLSL + uniform sampler2D u_ColorMap; // fog texture uniform sampler2D u_DepthMap; @@ -40,6 +42,8 @@ out vec4 outputColor; void main() { + #insert material_fp + // calculate the screen texcoord in the 0.0 to 1.0 range vec2 st = gl_FragCoord.st / r_FBufSize; diff --git a/src/engine/renderer/glsl_source/generic_fp.glsl b/src/engine/renderer/glsl_source/generic_fp.glsl index b7d203a2b3..d7f5a7dd5d 100644 --- a/src/engine/renderer/glsl_source/generic_fp.glsl +++ b/src/engine/renderer/glsl_source/generic_fp.glsl @@ -36,6 +36,8 @@ IN(smooth) vec2 var_TexCoords; IN(smooth) vec4 var_Color; #if defined(USE_DEPTH_FADE) + #define DEPTHMAP_GLSL + IN(smooth) float var_FadeDepth; uniform sampler2D u_DepthMap; #endif diff --git a/src/engine/renderer/glsl_source/lightMapping_fp.glsl b/src/engine/renderer/glsl_source/lightMapping_fp.glsl index fee293836d..da72f901e2 100644 --- a/src/engine/renderer/glsl_source/lightMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_fp.glsl @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert reliefMapping_fp #define LIGHTMAPPING_GLSL +#define LIGHTGRID_GLSL uniform sampler2D u_DiffuseMap; uniform sampler2D u_MaterialMap; diff --git a/src/engine/renderer/glsl_source/lighttile_fp.glsl b/src/engine/renderer/glsl_source/lighttile_fp.glsl index 6c135a687a..4548c07b9d 100644 --- a/src/engine/renderer/glsl_source/lighttile_fp.glsl +++ b/src/engine/renderer/glsl_source/lighttile_fp.glsl @@ -34,6 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* lighttile_fp.glsl */ +#define DEPTHTILE2_GLSL + IN(smooth) vec2 vPosition; struct Light { @@ -96,6 +98,8 @@ vec3 ProjToView( vec2 inp ) { } void main() { + #insert material_fp + vec2 minmax = texture2D( u_DepthTile2, 0.5 * vPosition + 0.5 ).xy; float minx = vPosition.x - r_tileStep.x; diff --git a/src/engine/renderer/glsl_source/liquid_fp.glsl b/src/engine/renderer/glsl_source/liquid_fp.glsl index 5ff79607ec..5e918c3b41 100644 --- a/src/engine/renderer/glsl_source/liquid_fp.glsl +++ b/src/engine/renderer/glsl_source/liquid_fp.glsl @@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert reliefMapping_fp #define LIQUID_GLSL +#define DEPTHMAP_GLSL +#define LIGHTGRID_GLSL uniform sampler2D u_CurrentMap; uniform sampler2D u_PortalMap; diff --git a/src/engine/renderer/glsl_source/material_fp.glsl b/src/engine/renderer/glsl_source/material_fp.glsl index 9bf8caf54e..ac6d8c83e9 100644 --- a/src/engine/renderer/glsl_source/material_fp.glsl +++ b/src/engine/renderer/glsl_source/material_fp.glsl @@ -46,6 +46,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. in the beginning of main() once Any texture samplers should be passed to functions from main() or other functions */ +#ifdef HAVE_ARB_bindless_texture + + #if defined(CAMERAEFFECTS_GLSL) + sampler3D u_ColorMap3D = sampler3D( u_ColorMap3D_initial ); + #endif // !CAMERAEFFECTS_GLSL + + #if defined(FOGQUAKE3_GLSL) + sampler2D u_FogMap = sampler2D( u_FogMap_initial ); + #endif // !FOGQUAKE3_GLSL + + #if defined(LIQUID_GLSL) + sampler2D u_PortalMap = sampler2D( u_PortalMap_initial ); + #endif // !LIQUID_GLSL + + #if defined(DEPTHMAP_GLSL) + sampler2D u_DepthMap = sampler2D( u_DepthMap_initial ); + #endif // !DEPTHMAP_GLSL + + #if defined(DEPTHTILE1_GLSL) + sampler2D u_DepthTile1 = sampler2D( u_DepthTile1_initial ); + #endif // !DEPTHTILE1_GLSL + + #if defined(DEPTHTILE2_GLSL) + sampler2D u_DepthTile2 = sampler2D( u_DepthTile2_initial ); + #endif // !DEPTHTILE2_GLSL + + #if defined(DEPTHREDUCTION_GLSL) + sampler2D depthTextureInitial = sampler2D( depthTextureInitial_initial ); + #endif // !DEPTHREDUCTION_GLSL + + #if defined(COMPUTELIGHT_GLSL) + usampler3D u_LightTiles = usampler3D( u_LightTiles_initial ); + #endif // !COMPUTELIGHT_GLSL + + #if defined(LIGHTGRID_GLSL) + sampler3D u_LightGrid1 = sampler3D( u_LightGrid1_initial ); + sampler3D u_LightGrid2 = sampler3D( u_LightGrid2_initial ); + #endif // !LIGHTGRID_GLSL + +#endif // !HAVE_ARB_bindless_texture + #if defined(USE_MATERIAL_SYSTEM) #ifdef HAVE_ARB_bindless_texture diff --git a/src/engine/renderer/glsl_source/motionblur_fp.glsl b/src/engine/renderer/glsl_source/motionblur_fp.glsl index 2f2fd83937..9270a7b8f4 100644 --- a/src/engine/renderer/glsl_source/motionblur_fp.glsl +++ b/src/engine/renderer/glsl_source/motionblur_fp.glsl @@ -22,6 +22,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* motionblur_fp.glsl */ +#define DEPTHMAP_GLSL + uniform sampler2D u_ColorMap; uniform sampler2D u_DepthMap; @@ -35,6 +37,8 @@ out vec4 outputColor; void main() { + #insert material_fp + vec4 color = vec4( 0.0 ); // calculate the screen texcoord in the 0.0 to 1.0 range diff --git a/src/engine/renderer/glsl_source/ssao_fp.glsl b/src/engine/renderer/glsl_source/ssao_fp.glsl index 9aa19b81c5..af25b9742c 100644 --- a/src/engine/renderer/glsl_source/ssao_fp.glsl +++ b/src/engine/renderer/glsl_source/ssao_fp.glsl @@ -22,6 +22,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* ssao_fp.glsl */ +#define DEPTHMAP_GLSL + uniform sampler2D u_DepthMap; uniform vec3 u_UnprojectionParams; @@ -85,6 +87,8 @@ vec4 offsets[] = vec4[6]( void main() { + #insert material_fp + vec2 st = gl_FragCoord.st * pixelScale; vec4 occlusion = vec4( 0.0 ); vec4 total = vec4( 0.0 ); diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index e836607616..436a504c6c 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -2652,6 +2652,41 @@ static void RB_RenderPostProcess() GL_CheckErrors(); } +static void SetFrameUniforms() { + // This can happen with glsl_restart/vid_restart in R_SyncRenderThread() + if ( !stagingBuffer.Active() ) { + return; + } + + GLIMP_LOGCOMMENT( "--- SetFrameUniforms ---" ); + + uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::FRAME ); + + globalUBOProxy->SetUniform_blurVec( backEnd.refdef.blurVec ); + globalUBOProxy->SetUniform_numLights( backEnd.refdef.numLights ); + + globalUBOProxy->SetUniform_ColorModulate( backEnd.viewParms.gradingWeights ); + globalUBOProxy->SetUniform_InverseGamma( 1.0f / r_gamma->value ); + + const bool tonemap = r_toneMapping.Get() && r_highPrecisionRendering.Get() && glConfig2.textureFloatAvailable; + if ( tonemap ) { + vec4_t tonemapParms{ r_toneMappingContrast.Get(), r_toneMappingHighlightsCompressionSpeed.Get() }; + ComputeTonemapParams( tonemapParms[0], tonemapParms[1], r_toneMappingHDRMax.Get(), + r_toneMappingDarkAreaPointHDR.Get(), r_toneMappingDarkAreaPointLDR.Get(), tonemapParms[2], tonemapParms[3] ); + globalUBOProxy->SetUniform_TonemapParms( tonemapParms ); + globalUBOProxy->SetUniform_TonemapExposure( r_toneMappingExposure.Get() ); + } + globalUBOProxy->SetUniform_Tonemap( tonemap ); + + if ( glConfig2.usingMaterialSystem ) { + materialSystem.SetFrameUniforms(); + } + + globalUBOProxy->WriteUniformsToBuffer( data, GLShader::PUSH, GLUniform::FRAME ); + + pushBuffer.PushGlobalUniforms(); +} + /* ============================================================================ @@ -3630,6 +3665,11 @@ void RB_ExecuteRenderCommands( const void *data ) materialSystem.frameStart = true; + + if ( glConfig2.pushBufferAvailable ) { + SetFrameUniforms(); + } + while ( cmd != nullptr ) { cmd = cmd->ExecuteSelf(); diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index 3cd0c9b9be..f66cdd56de 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -4465,6 +4465,58 @@ static void SetWorldLight() { } } +static void SetConstUniforms() { + GLIMP_LOGCOMMENT( "--- SetConstUniforms ---" ); + + uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::CONST ); + + globalUBOProxy->SetUniform_LightGridOrigin( tr.world->lightGridGLOrigin ); + globalUBOProxy->SetUniform_LightGridScale( tr.world->lightGridGLScale ); + + globalUBOProxy->SetUniform_GlobalLightFactor( 1.0f / tr.identityLight ); + + globalUBOProxy->SetUniform_ProfilerZero(); + + if ( glConfig2.usingBindlessTextures ) { + if ( glConfig2.colorGrading ) { + globalUBOProxy->SetUniform_ColorMap3DBindless( GL_BindToTMU( 3, tr.colorGradeImage ) ); + } + + globalUBOProxy->SetUniform_DepthMapBindless( GL_BindToTMU( 1, tr.currentDepthImage ) ); + + globalUBOProxy->SetUniform_PortalMapBindless( GL_BindToTMU( 1, tr.portalRenderImage ) ); + + globalUBOProxy->SetUniform_FogMapBindless( + GL_BindToTMU( 0, tr.fogImage ) + ); + + if ( glConfig2.realtimeLighting ) { + globalUBOProxy->SetUniform_DepthTile1Bindless( + GL_BindToTMU( 0, tr.depthtile1RenderImage ) + ); + + globalUBOProxy->SetUniform_DepthTile2Bindless( + GL_BindToTMU( 1, tr.depthtile2RenderImage ) + ); + + globalUBOProxy->SetUniform_LightTilesBindless( + GL_BindToTMU( BIND_LIGHTTILES, tr.lighttileRenderImage ) + ); + } + + globalUBOProxy->SetUniform_LightGrid1Bindless( GL_BindToTMU( BIND_LIGHTGRID1, tr.lightGrid1Image ) ); + globalUBOProxy->SetUniform_LightGrid2Bindless( GL_BindToTMU( BIND_LIGHTGRID2, tr.lightGrid2Image ) ); + } + + if ( glConfig2.usingMaterialSystem ) { + materialSystem.SetConstUniforms(); + } + + globalUBOProxy->WriteUniformsToBuffer( data, GLShader::PUSH, GLUniform::CONST ); + + pushBuffer.PushGlobalUniforms(); +} + /* ================= RE_LoadWorldMap @@ -4608,6 +4660,10 @@ void RE_LoadWorldMap( const char *name ) tr.loadingMap = ""; GLSL_InitWorldShaders(); + if ( glConfig2.pushBufferAvailable ) { + SetConstUniforms(); + } + if ( glConfig2.reflectionMappingAvailable ) { tr.cubeProbeSpacing = r_cubeProbeSpacing.Get(); diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index d1c0f3b766..b4d0519891 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -1653,7 +1653,7 @@ void Render_fog( shaderStage_t* pStage ) // bind u_ColorMap gl_fogQuake3Shader->SetUniform_FogMapBindless( - GL_BindToTMU( 0, tr.fogImage ) + GL_BindToTMU( 0, tr.fogImage ) ); gl_fogQuake3Shader->SetRequiredVertexPointers();