From 3010f75135ea62cf1a9c20e11941dfc9fa765bfa Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:30:47 +0300 Subject: [PATCH 01/16] 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 | 24 +++++++++++++++++++++++- src/engine/renderer/tr_public.h | 1 + src/engine/sys/sdl_glimp.cpp | 6 ++++++ 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 4dbc12f2db..5948dd6fe5 100644 --- a/src/engine/renderer/GLMemory.h +++ b/src/engine/renderer/GLMemory.h @@ -321,6 +321,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 92a144e1d4..cb45db23ca 100644 --- a/src/engine/renderer/tr_public.h +++ b/src/engine/renderer/tr_public.h @@ -135,6 +135,7 @@ struct GLConfig 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 e4fc7dc59b..16fa8f6243 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -2548,6 +2548,11 @@ static void GLimp_InitExtensions() glConfig.geometryCacheAvailable = glConfig.vertexAttribBindingAvailable && glConfig.directStateAccessAvailable; + glConfig.pushBufferAvailable = + glConfig.directStateAccessAvailable + && glConfig.explicitUniformLocationAvailable + && glConfig.uniformBufferObjectAvailable; + glConfig.materialSystemAvailable = glConfig.bindlessTexturesAvailable && glConfig.computeShaderAvailable @@ -2557,6 +2562,7 @@ static void GLimp_InitExtensions() && glConfig.gpuShader4Available && glConfig.indirectParametersAvailable && glConfig.multiDrawIndirectAvailable + && glConfig.pushBufferAvailable && glConfig.shaderAtomicCountersAvailable && glConfig.shaderDrawParametersAvailable && glConfig.shaderImageLoadStoreAvailable From 3f527609752a5f93e57e143503c08e0f5e921d52 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:41:54 +0300 Subject: [PATCH 02/16] 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/gl_shader.cpp | 28 +++++++++++++++++++--------- src/engine/renderer/gl_shader.h | 15 ++++++++++++--- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index d6ec602b7f..fd838688d4 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -2096,11 +2096,7 @@ static auto FindUniformForOffset( std::vector& uniforms, const GLuin // Compute std140 size/alignment and sort uniforms from highest to lowest alignment // Note: using the std430 uniform size will give the wrong result for matrix types where // the number of rows is not 4 -void GLShader::PostProcessUniforms() { - if ( !_useMaterialSystem ) { - return; - } - +GLuint GLShaderManager::SortUniforms( std::vector& uniforms ) { std::vector uniformQueue; for ( GLUniform* uniform : _uniforms ) { if ( !uniform->_global ) { @@ -2116,15 +2112,15 @@ void GLShader::PostProcessUniforms() { // Sort uniforms from highest to lowest alignment so we don't need to pad uniforms (other than vec3s) GLuint align = 4; // mininum alignment since this will be used as an std140 array element - std140Size = 0; - _materialSystemUniforms.clear(); + GLuint structSize = 0; + uniforms.clear(); while ( !uniformQueue.empty() || std140Size & ( align - 1 ) ) { auto iterNext = FindUniformForOffset( uniformQueue, std140Size ); if ( iterNext == uniformQueue.end() ) { // add 1 unit of padding ASSERT( !_materialSystemUniforms.back()->_components); // array WriteToBuffer impls don't handle padding correctly ++std140Size; - ++_materialSystemUniforms.back()->_std430Size; + ++uniforms.back()->_std430Size; } else { ( *iterNext )->_std430Size = ( *iterNext )->_std430BaseSize; if ( ( *iterNext )->_components ) { @@ -2134,10 +2130,24 @@ void GLShader::PostProcessUniforms() { std140Size += ( *iterNext )->_std430Size; } align = std::max( align, ( *iterNext )->_std430Alignment ); - _materialSystemUniforms.push_back( *iterNext ); + uniforms.push_back( *iterNext ); uniformQueue.erase( iterNext ); } } + return structSize; +} + +void GLShader::PostProcessUniforms() { + if ( _useMaterialSystem ) { + _materialSystemUniforms = gl_shaderManager.ProcessUniforms( GLUniform::MATERIAL_OR_PUSH, GLUniform::MATERIAL_OR_PUSH, + true, _uniforms, std430Size, padding ); + } + + if ( glConfig.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 1ad4f90935..32275be8fa 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -188,6 +188,7 @@ class GLShader { GLuint std140Size = 0; const bool worldShader; + const bool pushSkip; protected: int _activeMacros = 0; ShaderProgramDescriptor* currentProgram; @@ -202,13 +203,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 ), @@ -217,7 +220,8 @@ class GLShader { hasVertexShader( true ), hasFragmentShader( true ), hasComputeShader( false ), - worldShader( false ) { + worldShader( false ), + pushSkip( newPushSkip ) { } GLShader( const std::string& name, @@ -230,7 +234,8 @@ class GLShader { hasVertexShader( false ), hasFragmentShader( false ), hasComputeShader( true ), - worldShader( newWorldShader ) { + worldShader( newWorldShader ), + pushSkip( false ) { } public: @@ -396,6 +401,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 75f77a25dd8a68f0c9c235a1d17cab98a583bd87 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:43:24 +0300 Subject: [PATCH 03/16] Add GlobalUBOProxy Will be required for `PushBuffer` to set global uniform values outside of their shaders. --- src/engine/renderer/gl_shader.cpp | 37 +++++++++++++++++++++++++++++++ src/engine/renderer/gl_shader.h | 37 +++++++++++++++++++++++++++++++ src/engine/renderer/tr_shade.cpp | 3 +++ 3 files changed, 77 insertions(+) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index fd838688d4..9f237d995d 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -81,6 +81,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 @@ -2962,3 +2963,39 @@ 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_SRGB( 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 32275be8fa..9cff5566cc 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -3755,6 +3755,42 @@ 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_SRGB, + 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(); @@ -3794,6 +3830,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 2431c68d7e..a9b20cec18 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -224,6 +224,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 ( glConfig.usingMaterialSystem ) { @@ -465,6 +467,7 @@ void GLSL_ShutdownGPUShaders() gl_genericShader = nullptr; gl_genericShaderMaterial = nullptr; + globalUBOProxy = nullptr; gl_cullShader = nullptr; gl_depthReductionShader = nullptr; gl_clearSurfacesShader = nullptr; From d948218348f5f707b4985a2375ae118aa04c6210 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 12:53:06 +0300 Subject: [PATCH 04/16] 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 9f237d995d..eea3ae0572 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1262,8 +1262,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]; @@ -1563,6 +1561,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->std140Size ) { diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 9cff5566cc..efaa949f3a 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -393,6 +393,8 @@ class GLShaderManager { GLHeader GLWorldHeader; GLHeader GLEngineConstants; + std::string globalUniformBlock; + GLShaderManager() {} ~GLShaderManager(); @@ -414,6 +416,9 @@ class GLShaderManager { } shader = new T(); + + shader->PostProcessUniforms(); + _shaders.emplace_back( shader ); _shaderBuildQueue.push( shader ); } @@ -440,6 +445,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 a9b20cec18..d783650409 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -382,6 +382,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 e68a0109c6..035ca58aed 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -760,6 +760,10 @@ void R_InitVBOs() stagingBuffer.InitGLBuffer(); } + if ( glConfig2.pushBufferAvailable ) { + pushBuffer.InitGLBuffers(); + } + GL_CheckErrors(); } @@ -837,6 +841,10 @@ void R_ShutdownVBOs() stagingBuffer.FreeGLBuffer(); } + if ( glConfig2.pushBufferAvailable ) { + pushBuffer.FreeGLBuffers(); + } + tess.verts = tess.vertsBuffer = nullptr; tess.indexes = tess.indexesBuffer = nullptr; } From d353d60505f3252da3bf5fea7ac844384f1f71e7 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 13:01:37 +0300 Subject: [PATCH 05/16] 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 | 416 +++++++++++++++--------------- 3 files changed, 239 insertions(+), 213 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index d5e3505268..9ff3b4a5ec 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -161,7 +161,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 ) { @@ -207,7 +207,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 ) { @@ -244,7 +244,7 @@ void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage, bo gl_reflectionShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); 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 ) { @@ -255,7 +255,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 ) { @@ -268,7 +268,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 ) { @@ -285,7 +285,7 @@ void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage, bool // bind u_NormalScale 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 ) { @@ -331,7 +331,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 ) { @@ -339,7 +339,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 eea3ae0572..1f151deb4d 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -2383,10 +2383,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 efaa949f3a..7a5925f3aa 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -274,6 +274,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 ); @@ -313,11 +318,23 @@ class GLShader { return _useMaterialSystem; } - void WriteUniformsToBuffer( uint32_t* buffer ); + void WriteUniformsToBuffer( uint32_t* buffer, const Mode mode, const int filter = -1 ); }; 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; @@ -327,7 +344,7 @@ class GLUniform { GLuint _std430Size; // includes padding that depends on the other uniforms in the struct 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; @@ -337,14 +354,14 @@ 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 ), _std430BaseSize( std430Size ), _std430Size( std430Size ), _std430Alignment( std430Alignment ), - _global( global ), + _updateType( updateType ), _components( components ), _isTexture( isTexture ), _shader( shader ) { @@ -505,16 +522,16 @@ 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, glConfig.bindlessTexturesAvailable ? 2 : 1, - glConfig.bindlessTexturesAvailable ? 2 : 1, true, 0, true ) { + glConfig.bindlessTexturesAvailable ? 2 : 1, updateType, 0, true ) { } inline GLint GetLocation() { ShaderProgramDescriptor* p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); + if ( !_shader->UseMaterialSystem() ) { + ASSERT_EQ( p, glState.currentProgram ); } return p->uniformLocations[_locationIndex]; @@ -532,7 +549,15 @@ class GLUniformSampler : protected GLUniform { void SetValueBindless( GLint64 value ) { currentValueBindless = value; - if ( glConfig.usingBindlessTextures && ( !_shader->UseMaterialSystem() || _global ) ) { + if ( glConfig.usingBindlessTextures ) { + if ( _shader->UseMaterialSystem() && _updateType == TEXDATA_OR_PUSH ) { + return; + } + + if ( glConfig.pushBufferAvailable && _updateType <= FRAME ) { + return; + } + glUniformHandleui64ARB( GetLocation(), currentValueBindless ); } } @@ -554,37 +579,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 ) { } @@ -592,15 +617,14 @@ class GLUniform1i : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { currentValue = value; return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) int *firewall = ( int * ) &p->uniformFirewall[ _firewallIndex ]; @@ -630,22 +654,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() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { currentValue = value; return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) uint* firewall = ( uint* ) &p->uniformFirewall[_firewallIndex]; @@ -674,22 +697,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() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { currentValue = value; return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) int* firewall = ( int* ) &p->uniformFirewall[_firewallIndex]; @@ -714,8 +736,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 ) { } @@ -723,15 +745,14 @@ class GLUniform1f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { currentValue = value; return; } + ASSERT_EQ( p, glState.currentProgram ); + #if defined( USE_UNIFORM_FIREWALL ) float *firewall = ( float * ) &p->uniformFirewall[ _firewallIndex ]; @@ -762,8 +783,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 ); } @@ -772,15 +793,14 @@ class GLUniform1fv : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { memcpy( currentValue.data(), f, numFloats * sizeof( float ) ); return; } + ASSERT_EQ( p, glState.currentProgram ); + glUniform1fv( p->uniformLocations[ _locationIndex ], numFloats, f ); } @@ -791,8 +811,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; @@ -802,15 +822,14 @@ class GLUniform2f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.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 ]; @@ -842,8 +861,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; @@ -854,15 +873,14 @@ class GLUniform3f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.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 ]; @@ -893,8 +911,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; @@ -906,15 +924,14 @@ class GLUniform4f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.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 ]; @@ -945,8 +962,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 ); } @@ -955,15 +972,14 @@ class GLUniform4fv : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.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 ] ); } @@ -980,8 +996,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 ); } @@ -990,15 +1006,14 @@ class GLUniformMatrix4f : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.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 ]; @@ -1028,22 +1043,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() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { memcpy( currentValue, m, 6 * sizeof( float ) ); return; } + ASSERT_EQ( p, glState.currentProgram ); + glUniformMatrix3x2fv( p->uniformLocations[_locationIndex], 1, transpose, m ); } public: @@ -1058,8 +1072,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 ); } @@ -1068,15 +1082,14 @@ class GLUniformMatrix4fv : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.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 ] ); } @@ -1093,8 +1106,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 ) { } @@ -1102,15 +1115,14 @@ class GLUniformMatrix34fv : protected GLUniform { ShaderProgramDescriptor *p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { + if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { memcpy( currentValue.data(), m, numMatrices * sizeof( matrix_t ) ); return; } + ASSERT_EQ( p, glState.currentProgram ); + glUniformMatrix3x4fv( p->uniformLocations[ _locationIndex ], numMatrices, transpose, m ); } @@ -1690,7 +1702,7 @@ class u_ColorMap : GLUniformSampler2D { public: u_ColorMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_ColorMap" ) { + GLUniformSampler2D( shader, "u_ColorMap", PUSH ) { } void SetUniform_ColorMapBindless( GLuint64 bindlessHandle ) { @@ -1702,7 +1714,7 @@ class u_ColorMap3D : GLUniformSampler3D { public: u_ColorMap3D( GLShader* shader ) : - GLUniformSampler3D( shader, "u_ColorMap3D" ) { + GLUniformSampler3D( shader, "u_ColorMap3D", CONST ) { } void SetUniform_ColorMap3DBindless( GLuint64 bindlessHandle ) { @@ -1714,7 +1726,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 ) { @@ -1726,7 +1738,7 @@ class u_DepthMap : GLUniformSampler2D { public: u_DepthMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthMap" ) { + GLUniformSampler2D( shader, "u_DepthMap", CONST ) { } void SetUniform_DepthMapBindless( GLuint64 bindlessHandle ) { @@ -1738,7 +1750,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 ) { @@ -1750,7 +1762,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 ) { @@ -1762,7 +1774,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 ) { @@ -1774,7 +1786,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 ) { @@ -1786,7 +1798,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 ) { @@ -1798,7 +1810,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 ) { @@ -1810,7 +1822,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 ) { @@ -1822,7 +1834,7 @@ class u_PortalMap : GLUniformSampler2D { public: u_PortalMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_PortalMap" ) { + GLUniformSampler2D( shader, "u_PortalMap", CONST ) { } void SetUniform_PortalMapBindless( GLuint64 bindlessHandle ) { @@ -1834,7 +1846,7 @@ class u_CloudMap : GLUniformSampler2D { public: u_CloudMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_CloudMap" ) { + GLUniformSampler2D( shader, "u_CloudMap", PUSH ) { } void SetUniform_CloudMapBindless( GLuint64 bindlessHandle ) { @@ -1846,7 +1858,7 @@ class u_DepthTile1 : GLUniformSampler2D { public: u_DepthTile1( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthTile1" ) { + GLUniformSampler2D( shader, "u_DepthTile1", CONST ) { } void SetUniform_DepthTile1Bindless( GLuint64 bindlessHandle ) { @@ -1858,7 +1870,7 @@ class u_DepthTile2 : GLUniformSampler2D { public: u_DepthTile2( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthTile2" ) { + GLUniformSampler2D( shader, "u_DepthTile2", CONST ) { } void SetUniform_DepthTile2Bindless( GLuint64 bindlessHandle ) { @@ -1870,7 +1882,7 @@ class u_LightTiles : GLUniformSampler3D { public: u_LightTiles( GLShader* shader ) : - GLUniformSampler3D( shader, "u_LightTiles" ) { + GLUniformSampler3D( shader, "u_LightTiles", CONST ) { } void SetUniform_LightTilesBindless( GLuint64 bindlessHandle ) { @@ -1882,7 +1894,7 @@ class u_LightGrid1 : GLUniformSampler3D { public: u_LightGrid1( GLShader* shader ) : - GLUniformSampler3D( shader, "u_LightGrid1" ) { + GLUniformSampler3D( shader, "u_LightGrid1", CONST ) { } void SetUniform_LightGrid1Bindless( GLuint64 bindlessHandle ) { @@ -1894,7 +1906,7 @@ class u_LightGrid2 : GLUniformSampler3D { public: u_LightGrid2( GLShader* shader ) : - GLUniformSampler3D( shader, "u_LightGrid2" ) { + GLUniformSampler3D( shader, "u_LightGrid2", CONST ) { } void SetUniform_LightGrid2Bindless( GLuint64 bindlessHandle ) { @@ -1906,7 +1918,7 @@ class u_EnvironmentMap0 : GLUniformSamplerCube { public: u_EnvironmentMap0( GLShader* shader ) : - GLUniformSamplerCube( shader, "u_EnvironmentMap0" ) { + GLUniformSamplerCube( shader, "u_EnvironmentMap0", PUSH ) { } void SetUniform_EnvironmentMap0Bindless( GLuint64 bindlessHandle ) { @@ -1918,7 +1930,7 @@ class u_EnvironmentMap1 : GLUniformSamplerCube { public: u_EnvironmentMap1( GLShader* shader ) : - GLUniformSamplerCube( shader, "u_EnvironmentMap1" ) { + GLUniformSamplerCube( shader, "u_EnvironmentMap1", PUSH ) { } void SetUniform_EnvironmentMap1Bindless( GLuint64 bindlessHandle ) { @@ -1930,7 +1942,7 @@ class u_CurrentMap : GLUniformSampler2D { public: u_CurrentMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_CurrentMap" ) { + GLUniformSampler2D( shader, "u_CurrentMap", PUSH ) { } void SetUniform_CurrentMapBindless( GLuint64 bindlessHandle ) { @@ -1943,7 +1955,7 @@ class u_TextureMatrix : { public: u_TextureMatrix( GLShader *shader ) : - GLUniformMatrix32f( shader, "u_TextureMatrix", true ) + GLUniformMatrix32f( shader, "u_TextureMatrix", TEXDATA_OR_PUSH ) { } @@ -1967,7 +1979,7 @@ class u_AlphaThreshold : { public: u_AlphaThreshold( GLShader *shader ) : - GLUniform1f( shader, "u_AlphaThreshold" ) + GLUniform1f( shader, "u_AlphaThreshold", MATERIAL_OR_PUSH ) { } @@ -2025,7 +2037,7 @@ class u_ViewOrigin : { public: u_ViewOrigin( GLShader *shader ) : - GLUniform3f( shader, "u_ViewOrigin", true ) + GLUniform3f( shader, "u_ViewOrigin", PUSH ) { } @@ -2040,7 +2052,7 @@ class u_RefractionIndex : { public: u_RefractionIndex( GLShader *shader ) : - GLUniform1f( shader, "u_RefractionIndex" ) + GLUniform1f( shader, "u_RefractionIndex", MATERIAL_OR_PUSH ) { } @@ -2055,7 +2067,7 @@ class u_FresnelPower : { public: u_FresnelPower( GLShader *shader ) : - GLUniform1f( shader, "u_FresnelPower" ) + GLUniform1f( shader, "u_FresnelPower", MATERIAL_OR_PUSH ) { } @@ -2070,7 +2082,7 @@ class u_FresnelScale : { public: u_FresnelScale( GLShader *shader ) : - GLUniform1f( shader, "u_FresnelScale" ) + GLUniform1f( shader, "u_FresnelScale", MATERIAL_OR_PUSH ) { } @@ -2085,7 +2097,7 @@ class u_FresnelBias : { public: u_FresnelBias( GLShader *shader ) : - GLUniform1f( shader, "u_FresnelBias" ) + GLUniform1f( shader, "u_FresnelBias", MATERIAL_OR_PUSH ) { } @@ -2100,7 +2112,7 @@ class u_NormalScale : { public: u_NormalScale( GLShader *shader ) : - GLUniform3f( shader, "u_NormalScale" ) + GLUniform3f( shader, "u_NormalScale", MATERIAL_OR_PUSH ) { } @@ -2116,7 +2128,7 @@ class u_FogDensity : { public: u_FogDensity( GLShader *shader ) : - GLUniform1f( shader, "u_FogDensity", true ) + GLUniform1f( shader, "u_FogDensity", PUSH ) { } @@ -2131,7 +2143,7 @@ class u_FogColor : { public: u_FogColor( GLShader *shader ) : - GLUniform3f( shader, "u_FogColor" ) + GLUniform3f( shader, "u_FogColor", MATERIAL_OR_PUSH ) { } @@ -2146,7 +2158,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 ) { @@ -2159,7 +2171,7 @@ class u_Color_Float : { public: u_Color_Float( GLShader *shader ) : - GLUniform4f( shader, "u_Color" ) + GLUniform4f( shader, "u_Color", LEGACY ) { } @@ -2174,7 +2186,7 @@ class u_Color_Uint : { public: u_Color_Uint( GLShader *shader ) : - GLUniform1ui( shader, "u_Color" ) + GLUniform1ui( shader, "u_Color", MATERIAL_OR_PUSH ) { } @@ -2201,7 +2213,7 @@ class u_ColorGlobal_Float : { public: u_ColorGlobal_Float( GLShader *shader ) : - GLUniform4f( shader, "u_ColorGlobal", true ) + GLUniform4f( shader, "u_ColorGlobal", LEGACY ) { } @@ -2215,7 +2227,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 ) { @@ -2239,7 +2251,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 ) { @@ -2251,7 +2263,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 ) { @@ -2263,7 +2275,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 ) { @@ -2275,7 +2287,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 ) { @@ -2287,7 +2299,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 ) { @@ -2299,7 +2311,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 ) { @@ -2311,7 +2323,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 ) { @@ -2323,7 +2335,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 ) { @@ -2335,7 +2347,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 ) { @@ -2347,7 +2359,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 ) { @@ -2359,7 +2371,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 ) { @@ -2371,7 +2383,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 ) { @@ -2383,7 +2395,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 ) { @@ -2395,7 +2407,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 ) { @@ -2407,7 +2419,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] ) { @@ -2419,7 +2431,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 ) { @@ -2431,7 +2443,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 ) { @@ -2445,7 +2457,7 @@ class u_ProfilerZero : GLUniform1f { public: u_ProfilerZero( GLShader* shader ) : - GLUniform1f( shader, "u_ProfilerZero", true ) { + GLUniform1f( shader, "u_ProfilerZero", CONST ) { } void SetUniform_ProfilerZero() { @@ -2457,7 +2469,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 ) { @@ -2470,7 +2482,7 @@ class u_ModelMatrix : { public: u_ModelMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelMatrix", true ) + GLUniformMatrix4f( shader, "u_ModelMatrix", PUSH ) { } @@ -2485,7 +2497,7 @@ class u_ViewMatrix : { public: u_ViewMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ViewMatrix" ) + GLUniformMatrix4f( shader, "u_ViewMatrix", PUSH ) { } @@ -2500,7 +2512,7 @@ class u_ModelViewMatrix : { public: u_ModelViewMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelViewMatrix" ) + GLUniformMatrix4f( shader, "u_ModelViewMatrix", PUSH ) { } @@ -2515,7 +2527,7 @@ class u_ModelViewMatrixTranspose : { public: u_ModelViewMatrixTranspose( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelViewMatrixTranspose", true ) + GLUniformMatrix4f( shader, "u_ModelViewMatrixTranspose", PUSH ) { } @@ -2530,7 +2542,7 @@ class u_ProjectionMatrixTranspose : { public: u_ProjectionMatrixTranspose( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ProjectionMatrixTranspose", true ) + GLUniformMatrix4f( shader, "u_ProjectionMatrixTranspose", PUSH ) { } @@ -2545,7 +2557,7 @@ class u_ModelViewProjectionMatrix : { public: u_ModelViewProjectionMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelViewProjectionMatrix", true ) + GLUniformMatrix4f( shader, "u_ModelViewProjectionMatrix", PUSH ) { } @@ -2560,7 +2572,7 @@ class u_UnprojectMatrix : { public: u_UnprojectMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_UnprojectMatrix", true ) + GLUniformMatrix4f( shader, "u_UnprojectMatrix", PUSH ) { } @@ -2574,7 +2586,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 ) { @@ -2587,7 +2599,7 @@ class u_Bones : { public: u_Bones( GLShader *shader ) : - GLUniform4fv( shader, "u_Bones", MAX_BONES ) + GLUniform4fv( shader, "u_Bones", MAX_BONES, PUSH ) { } @@ -2602,7 +2614,7 @@ class u_VertexInterpolation : { public: u_VertexInterpolation( GLShader *shader ) : - GLUniform1f( shader, "u_VertexInterpolation" ) + GLUniform1f( shader, "u_VertexInterpolation", PUSH ) { } @@ -2617,7 +2629,7 @@ class u_InversePortalRange : { public: u_InversePortalRange( GLShader *shader ) : - GLUniform1f( shader, "u_InversePortalRange" ) + GLUniform1f( shader, "u_InversePortalRange", PUSH ) { } @@ -2632,7 +2644,7 @@ class u_DepthScale : { public: u_DepthScale( GLShader *shader ) : - GLUniform1f( shader, "u_DepthScale" ) + GLUniform1f( shader, "u_DepthScale", MATERIAL_OR_PUSH ) { } @@ -2647,7 +2659,7 @@ class u_ReliefDepthScale : { public: u_ReliefDepthScale( GLShader *shader ) : - GLUniform1f( shader, "u_ReliefDepthScale" ) + GLUniform1f( shader, "u_ReliefDepthScale", MATERIAL_OR_PUSH ) { } @@ -2662,7 +2674,7 @@ class u_ReliefOffsetBias : { public: u_ReliefOffsetBias( GLShader *shader ) : - GLUniform1f( shader, "u_ReliefOffsetBias" ) + GLUniform1f( shader, "u_ReliefOffsetBias", MATERIAL_OR_PUSH ) { } @@ -2677,7 +2689,7 @@ class u_EnvironmentInterpolation : { public: u_EnvironmentInterpolation( GLShader *shader ) : - GLUniform1f( shader, "u_EnvironmentInterpolation", true ) + GLUniform1f( shader, "u_EnvironmentInterpolation", PUSH ) { } @@ -2692,7 +2704,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 ) { } @@ -2707,7 +2719,7 @@ class u_GlobalLightFactor : { public: u_GlobalLightFactor( GLShader *shader ) : - GLUniform1f( shader, "u_GlobalLightFactor" ) + GLUniform1f( shader, "u_GlobalLightFactor", CONST ) { } @@ -2732,7 +2744,7 @@ class u_ColorModulate : { public: u_ColorModulate( GLShader *shader ) : - GLUniform4f( shader, "u_ColorModulate" ) + GLUniform4f( shader, "u_ColorModulate", FRAME ) { } @@ -2815,7 +2827,7 @@ class u_ColorModulateColorGen_Float : { public: u_ColorModulateColorGen_Float( GLShader* shader ) : - GLUniform4f( shader, "u_ColorModulateColorGen" ) + GLUniform4f( shader, "u_ColorModulateColorGen", LEGACY ) { } @@ -2847,7 +2859,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( @@ -2921,7 +2933,7 @@ class u_FogDepthVector : { public: u_FogDepthVector( GLShader *shader ) : - GLUniform4f( shader, "u_FogDepthVector", true ) + GLUniform4f( shader, "u_FogDepthVector", PUSH ) { } @@ -2936,7 +2948,7 @@ class u_FogEyeT : { public: u_FogEyeT( GLShader *shader ) : - GLUniform1f( shader, "u_FogEyeT", true ) + GLUniform1f( shader, "u_FogEyeT", PUSH ) { } @@ -2950,7 +2962,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 ) { @@ -2963,7 +2975,7 @@ class u_DeformMagnitude : { public: u_DeformMagnitude( GLShader *shader ) : - GLUniform1f( shader, "u_DeformMagnitude" ) + GLUniform1f( shader, "u_DeformMagnitude", MATERIAL_OR_PUSH ) { } @@ -2978,7 +2990,7 @@ class u_blurVec : { public: u_blurVec( GLShader *shader ) : - GLUniform3f( shader, "u_blurVec" ) + GLUniform3f( shader, "u_blurVec", FRAME ) { } @@ -2992,7 +3004,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 ) { @@ -3005,7 +3017,7 @@ class u_TexScale : { public: u_TexScale( GLShader *shader ) : - GLUniform2f( shader, "u_TexScale" ) + GLUniform2f( shader, "u_TexScale", PUSH ) { } @@ -3020,7 +3032,7 @@ class u_SpecularExponent : { public: u_SpecularExponent( GLShader *shader ) : - GLUniform2f( shader, "u_SpecularExponent" ) + GLUniform2f( shader, "u_SpecularExponent", MATERIAL_OR_PUSH ) { } @@ -3040,7 +3052,7 @@ class u_InverseGamma : { public: u_InverseGamma( GLShader *shader ) : - GLUniform1f( shader, "u_InverseGamma" ) + GLUniform1f( shader, "u_InverseGamma", FRAME ) { } @@ -3054,7 +3066,7 @@ class u_SRGB : GLUniform1Bool { public: u_SRGB( GLShader* shader ) : - GLUniform1Bool( shader, "u_SRGB", true ) { + GLUniform1Bool( shader, "u_SRGB", CONST ) { } void SetUniform_SRGB( bool tonemap ) { @@ -3066,7 +3078,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 ) { @@ -3078,7 +3090,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 ) { @@ -3090,7 +3102,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 ) { @@ -3103,7 +3115,7 @@ class u_LightGridOrigin : { public: u_LightGridOrigin( GLShader *shader ) : - GLUniform3f( shader, "u_LightGridOrigin", true ) + GLUniform3f( shader, "u_LightGridOrigin", CONST ) { } @@ -3118,7 +3130,7 @@ class u_LightGridScale : { public: u_LightGridScale( GLShader *shader ) : - GLUniform3f( shader, "u_LightGridScale", true ) + GLUniform3f( shader, "u_LightGridScale", CONST ) { } @@ -3133,7 +3145,7 @@ class u_zFar : { public: u_zFar( GLShader *shader ) : - GLUniform3f( shader, "u_zFar" ) + GLUniform3f( shader, "u_zFar", PUSH ) { } @@ -3147,7 +3159,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 ) { @@ -3160,7 +3172,7 @@ class u_numLights : { public: u_numLights( GLShader *shader ) : - GLUniform1i( shader, "u_numLights", true ) + GLUniform1i( shader, "u_numLights", FRAME ) { } @@ -3175,7 +3187,7 @@ class u_lightLayer : { public: u_lightLayer( GLShader *shader ) : - GLUniform1i( shader, "u_lightLayer" ) + GLUniform1i( shader, "u_lightLayer", PUSH ) { } From c6a469ad51f2cae60eab03d9d880bbbbaf331ef6 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 1 Aug 2025 18:43:25 +0300 Subject: [PATCH 06/16] 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 | 24 +++++--- src/engine/renderer/Material.h | 2 + src/engine/renderer/gl_shader.cpp | 35 +++++++++++- .../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 | 2 + .../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 | 8 ++- src/engine/renderer/tr_backend.cpp | 40 +++++++++++++ src/engine/renderer/tr_bsp.cpp | 57 +++++++++++++++++++ 19 files changed, 232 insertions(+), 13 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 5948dd6fe5..f9552528bf 100644 --- a/src/engine/renderer/GLMemory.h +++ b/src/engine/renderer/GLMemory.h @@ -175,6 +175,7 @@ class GLBuffer { void DelBuffer() { glDeleteBuffers( 1, &id ); + id = 0; mapped = false; } @@ -303,6 +304,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 9ff3b4a5ec..ca9f4a16ef 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1593,9 +1593,24 @@ 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 ); gl_clearSurfacesShader->DispatchCompute( MAX_VIEWS, 1, 1 ); GL_CheckErrors(); @@ -1681,15 +1696,9 @@ void MaterialSystem::CullSurfaces() { uint32_t globalWorkGroupX = surfaceDescriptorsCount % MAX_COMMAND_COUNTERS == 0 ? surfaceDescriptorsCount / MAX_COMMAND_COUNTERS : surfaceDescriptorsCount / MAX_COMMAND_COUNTERS + 1; GL_Bind( depthImage ); - gl_cullShader->SetUniform_Frame( nextFrame ); gl_cullShader->SetUniform_ViewID( view ); - gl_cullShader->SetUniform_SurfaceDescriptorsCount( surfaceDescriptorsCount ); - gl_cullShader->SetUniform_UseFrustumCulling( r_gpuFrustumCulling.Get() ); - gl_cullShader->SetUniform_UseOcclusionCulling( r_gpuOcclusionCulling.Get() ); gl_cullShader->SetUniform_CameraPosition( origin ); gl_cullShader->SetUniform_ModelViewMatrix( viewMatrix ); - gl_cullShader->SetUniform_FirstPortalGroup( globalWorkGroupX ); - gl_cullShader->SetUniform_TotalPortals( totalPortals ); gl_cullShader->SetUniform_ViewWidth( depthImage->width ); gl_cullShader->SetUniform_ViewHeight( depthImage->height ); gl_cullShader->SetUniform_SurfaceCommandsOffset( surfaceCommandsCount * ( MAX_VIEWS * nextFrame + view ) ); @@ -1721,7 +1730,6 @@ void MaterialSystem::CullSurfaces() { gl_cullShader->DispatchCompute( globalWorkGroupX, 1, 1 ); gl_processSurfacesShader->BindProgram( 0 ); - gl_processSurfacesShader->SetUniform_Frame( nextFrame ); gl_processSurfacesShader->SetUniform_ViewID( view ); gl_processSurfacesShader->SetUniform_SurfaceCommandsOffset( surfaceCommandsCount * ( MAX_VIEWS * nextFrame + view ) ); diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index e9eb42eb1a..46ec632eb8 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -362,6 +362,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 1f151deb4d..368dfaf000 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1332,6 +1332,12 @@ void GLShaderManager::InitShader( GLShader* shader ) { ShaderDescriptor* desc = FindShader( shader->_name, shaderType.mainText, shaderType.GLType, shaderType.headers, uniqueMacros, compileMacros, true ); + if ( desc && glConfig.pushBufferAvailable ) { + desc->shaderSource = RemoveUniformsFromShaderText( desc->shaderSource, shader->_pushUniforms ); + + desc->shaderSource.insert( shaderType.offset, globalUniformBlock ); + } + if ( desc && glConfig.usingMaterialSystem && shader->_useMaterialSystem ) { desc->shaderSource = ShaderPostProcess( shader, desc->shaderSource, shaderType.offset ); } @@ -1585,7 +1591,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, !glConfig.usingBindlessTextures, *uniforms, size, padding ); GenerateUniformStructDefinesText( constUniforms, padding, 0, "globalUniforms", uniformStruct, uniformDefines ); @@ -1594,7 +1600,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, !glConfig.usingBindlessTextures, *uniforms, size, padding ); GenerateUniformStructDefinesText( frameUniforms, padding, paddingCount, "globalUniforms", uniformStruct, uniformDefines ); @@ -2191,6 +2197,29 @@ GLuint GLShaderManager::SortUniforms( std::vector& uniforms ) { 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; +} + void GLShader::PostProcessUniforms() { if ( _useMaterialSystem ) { _materialSystemUniforms = gl_shaderManager.ProcessUniforms( GLUniform::MATERIAL_OR_PUSH, GLUniform::MATERIAL_OR_PUSH, @@ -2200,7 +2229,7 @@ void GLShader::PostProcessUniforms() { if ( glConfig.pushBufferAvailable && !pushSkip ) { GLuint unused; _pushUniforms = gl_shaderManager.ProcessUniforms( GLUniform::CONST, GLUniform::FRAME, - false, _uniforms, unused, unused ); + !glConfig.usingBindlessTextures, _uniforms, unused, unused ); } } diff --git a/src/engine/renderer/glsl_source/cameraEffects_fp.glsl b/src/engine/renderer/glsl_source/cameraEffects_fp.glsl index 34eed66438..d5ed53ecb2 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) @@ -73,6 +75,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 7c57372238..00e8eca149 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 fff06f5b79..4506262ff1 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 869ba25edc..c7669638b4 100644 --- a/src/engine/renderer/glsl_source/fogGlobal_fp.glsl +++ b/src/engine/renderer/glsl_source/fogGlobal_fp.glsl @@ -37,6 +37,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/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..a78216d541 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; @@ -52,7 +54,7 @@ vec4 rangeTest( vec4 diff1, vec4 diff2, vec4 deltaX, vec4 deltaY ) { // Based on AMD HDAO, adapted for lack of normals void computeOcclusionForQuad( in vec2 centerTC, in float centerDepth, - in vec2 quadOffset, + in vec2 quadOffset, in sampler2D u_DepthMap, inout vec4 occlusion, inout vec4 total ) { vec2 tc1 = centerTC + quadOffset * pixelScale; vec2 tc2 = centerTC - quadOffset * pixelScale; @@ -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 ); @@ -107,7 +111,7 @@ void main() } else { of = offsets[i].zw; } - computeOcclusionForQuad( st, center, spread * of, + computeOcclusionForQuad( st, center, spread * of, u_DepthMap, occlusion, total ); } diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 6669164ad9..5c6d9d7b35 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -2789,6 +2789,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(); +} + /* ============================================================================ @@ -3787,6 +3822,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 7da251d6b0..b3c179d86a 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -4641,6 +4641,59 @@ 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_SRGB( tr.worldLinearizeTexture ); + + 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 @@ -4796,6 +4849,10 @@ void RE_LoadWorldMap( const char *name ) tr.loadingMap = ""; GLSL_InitWorldShaders(); + if ( glConfig.pushBufferAvailable ) { + SetConstUniforms(); + } + if ( glConfig.reflectionMappingAvailable ) { tr.cubeProbeSpacing = r_cubeProbeSpacing.Get(); From 6d86201821a92439bf04aa3cf09e3c31b317db80 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Tue, 24 Jun 2025 20:47:00 +0300 Subject: [PATCH 07/16] Fix global fog texture with PushBuffer --- src/engine/renderer/gl_shader.cpp | 2 +- src/engine/renderer/glsl_source/fogGlobal_fp.glsl | 4 +++- src/engine/renderer/glsl_source/fogQuake3_fp.glsl | 2 -- src/engine/renderer/glsl_source/material_fp.glsl | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 368dfaf000..4090196a3e 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -2730,7 +2730,7 @@ GLShader_fogGlobal::GLShader_fogGlobal() : void GLShader_fogGlobal::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_FogMap" ), 0 ); glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } diff --git a/src/engine/renderer/glsl_source/fogGlobal_fp.glsl b/src/engine/renderer/glsl_source/fogGlobal_fp.glsl index c7669638b4..6f3fb21533 100644 --- a/src/engine/renderer/glsl_source/fogGlobal_fp.glsl +++ b/src/engine/renderer/glsl_source/fogGlobal_fp.glsl @@ -25,7 +25,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert common #insert fogEquation_fp -uniform sampler2D u_DepthMap; +#define DEPTHMAP_GLSL + +uniform sampler2D u_DepthMap; uniform colorPack u_Color; diff --git a/src/engine/renderer/glsl_source/fogQuake3_fp.glsl b/src/engine/renderer/glsl_source/fogQuake3_fp.glsl index ccc3258af4..dbf9f45737 100644 --- a/src/engine/renderer/glsl_source/fogQuake3_fp.glsl +++ b/src/engine/renderer/glsl_source/fogQuake3_fp.glsl @@ -24,8 +24,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert fogEquation_fp -#define FOGQUAKE3_GLSL - uniform float u_FogEyeT; IN(smooth) float var_FogPlaneDistance; diff --git a/src/engine/renderer/glsl_source/material_fp.glsl b/src/engine/renderer/glsl_source/material_fp.glsl index ac6d8c83e9..a43cca4835 100644 --- a/src/engine/renderer/glsl_source/material_fp.glsl +++ b/src/engine/renderer/glsl_source/material_fp.glsl @@ -52,9 +52,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sampler3D u_ColorMap3D = sampler3D( u_ColorMap3D_initial ); #endif // !CAMERAEFFECTS_GLSL - #if defined(FOGQUAKE3_GLSL) + #if defined(FOGMAP_GLSL) sampler2D u_FogMap = sampler2D( u_FogMap_initial ); - #endif // !FOGQUAKE3_GLSL + #endif // !FOGMAP_GLSL #if defined(LIQUID_GLSL) sampler2D u_PortalMap = sampler2D( u_PortalMap_initial ); From 4ae549c6fb454450af1aed60ff0e4158b6cccd57 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sat, 2 Aug 2025 01:48:12 +0300 Subject: [PATCH 08/16] Fix quake3 fog with material system --- src/engine/renderer/gl_shader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 7a5925f3aa..1db702e5fc 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -2227,7 +2227,7 @@ class u_ColorGlobal_Uint : GLUniform1ui { public: u_ColorGlobal_Uint( GLShader* shader ) : - GLUniform1ui( shader, "u_ColorGlobal", MATERIAL_OR_PUSH ) { + GLUniform1ui( shader, "u_ColorGlobal", PUSH ) { } void SetUniform_ColorGlobal_Uint( const Color::Color& color ) { From ead312d27dbc11e92364d4ed80dc593001cf272d Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sat, 2 Aug 2025 01:57:52 +0300 Subject: [PATCH 09/16] Fix wrong refdef/viewParms being used in PushBuffer --- src/engine/renderer/tr_backend.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 5c6d9d7b35..1b1071bbd9 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -2799,10 +2799,10 @@ static void SetFrameUniforms() { uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::FRAME ); - globalUBOProxy->SetUniform_blurVec( backEnd.refdef.blurVec ); - globalUBOProxy->SetUniform_numLights( backEnd.refdef.numLights ); + globalUBOProxy->SetUniform_blurVec( tr.refdef.blurVec ); + globalUBOProxy->SetUniform_numLights( tr.refdef.numLights ); - globalUBOProxy->SetUniform_ColorModulate( backEnd.viewParms.gradingWeights ); + globalUBOProxy->SetUniform_ColorModulate( tr.viewParms.gradingWeights ); globalUBOProxy->SetUniform_InverseGamma( 1.0f / r_gamma->value ); const bool tonemap = r_toneMapping.Get() && r_highPrecisionRendering.Get() && glConfig2.textureFloatAvailable; From 3e49947b7cb27bf21c8d4e86e47b3caa97b7c70d Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sat, 30 Aug 2025 15:38:04 +0300 Subject: [PATCH 10/16] Fix glconfig2 occurences --- src/engine/renderer/tr_backend.cpp | 6 +++--- src/engine/renderer/tr_bsp.cpp | 8 ++++---- src/engine/renderer/tr_vbo.cpp | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 1b1071bbd9..761aa21068 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -2805,7 +2805,7 @@ static void SetFrameUniforms() { globalUBOProxy->SetUniform_ColorModulate( tr.viewParms.gradingWeights ); globalUBOProxy->SetUniform_InverseGamma( 1.0f / r_gamma->value ); - const bool tonemap = r_toneMapping.Get() && r_highPrecisionRendering.Get() && glConfig2.textureFloatAvailable; + const bool tonemap = r_toneMapping.Get() && r_highPrecisionRendering.Get() && glConfig.textureFloatAvailable; if ( tonemap ) { vec4_t tonemapParms{ r_toneMappingContrast.Get(), r_toneMappingHighlightsCompressionSpeed.Get() }; ComputeTonemapParams( tonemapParms[0], tonemapParms[1], r_toneMappingHDRMax.Get(), @@ -2815,7 +2815,7 @@ static void SetFrameUniforms() { } globalUBOProxy->SetUniform_Tonemap( tonemap ); - if ( glConfig2.usingMaterialSystem ) { + if ( glConfig.usingMaterialSystem ) { materialSystem.SetFrameUniforms(); } @@ -3823,7 +3823,7 @@ void RB_ExecuteRenderCommands( const void *data ) materialSystem.frameStart = true; - if ( glConfig2.pushBufferAvailable ) { + if ( glConfig.pushBufferAvailable ) { SetFrameUniforms(); } diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index b3c179d86a..de7a21811d 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -4654,8 +4654,8 @@ static void SetConstUniforms() { globalUBOProxy->SetUniform_ProfilerZero(); - if ( glConfig2.usingBindlessTextures ) { - if ( glConfig2.colorGrading ) { + if ( glConfig.usingBindlessTextures ) { + if ( glConfig.colorGrading ) { globalUBOProxy->SetUniform_ColorMap3DBindless( GL_BindToTMU( 3, tr.colorGradeImage ) ); } @@ -4667,7 +4667,7 @@ static void SetConstUniforms() { GL_BindToTMU( 0, tr.fogImage ) ); - if ( glConfig2.realtimeLighting ) { + if ( glConfig.realtimeLighting ) { globalUBOProxy->SetUniform_DepthTile1Bindless( GL_BindToTMU( 0, tr.depthtile1RenderImage ) ); @@ -4685,7 +4685,7 @@ static void SetConstUniforms() { globalUBOProxy->SetUniform_LightGrid2Bindless( GL_BindToTMU( BIND_LIGHTGRID2, tr.lightGrid2Image ) ); } - if ( glConfig2.usingMaterialSystem ) { + if ( glConfig.usingMaterialSystem ) { materialSystem.SetConstUniforms(); } diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index 035ca58aed..6db30d4003 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -760,7 +760,7 @@ void R_InitVBOs() stagingBuffer.InitGLBuffer(); } - if ( glConfig2.pushBufferAvailable ) { + if ( glConfig.pushBufferAvailable ) { pushBuffer.InitGLBuffers(); } @@ -841,7 +841,7 @@ void R_ShutdownVBOs() stagingBuffer.FreeGLBuffer(); } - if ( glConfig2.pushBufferAvailable ) { + if ( glConfig.pushBufferAvailable ) { pushBuffer.FreeGLBuffers(); } From 16fb7296b3d8425ad9d9fd169f773922afd7c758 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 5 Sep 2025 20:15:35 +0300 Subject: [PATCH 11/16] Rebase clean-up --- src/engine/renderer/gl_shader.cpp | 54 +++++++++++++------------------ src/engine/renderer/gl_shader.h | 11 +++++-- 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 4090196a3e..51c347fe27 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1536,9 +1536,9 @@ std::string GLShaderManager::RemoveUniformsFromShaderText( const std::string& sh return shaderMain; } -void GLShaderManager::GenerateUniformStructDefinesText( const std::vector& uniforms, - const std::string& definesName, std::string& uniformStruct, std::string& uniformDefines ) { - int pad = 0; +uint32_t GLShaderManager::GenerateUniformStructDefinesText( const std::vector& uniforms, + const std::string& definesName, const uint32_t offset, std::string& uniformStruct, std::string& uniformDefines ) { + int pad = offset; for ( GLUniform* uniform : uniforms ) { uniformStruct += " " + ( uniform->_isTexture ? "uvec2" : uniform->_type ) + " " + uniform->_name; @@ -1565,6 +1565,8 @@ void GLShaderManager::GenerateUniformStructDefinesText( const std::vector* uniforms = &( ( GLShader* ) globalUBOProxy )->_uniforms; std::vector constUniforms = - ProcessUniforms( GLUniform::CONST, GLUniform::CONST, !glConfig.usingBindlessTextures, *uniforms, size, padding ); - - GenerateUniformStructDefinesText( constUniforms, padding, 0, "globalUniforms", uniformStruct, uniformDefines ); + ProcessUniforms( GLUniform::CONST, GLUniform::CONST, !glConfig.usingBindlessTextures, *uniforms, size ); - uint32_t paddingCount = padding; + const uint32_t padding = GenerateUniformStructDefinesText( constUniforms, "globalUniforms", 0, uniformStruct, uniformDefines ); - pushBuffer.constUniformsSize = size + padding; + pushBuffer.constUniformsSize = size; std::vector frameUniforms = - ProcessUniforms( GLUniform::FRAME, GLUniform::FRAME, !glConfig.usingBindlessTextures, *uniforms, size, padding ); + ProcessUniforms( GLUniform::FRAME, GLUniform::FRAME, !glConfig.usingBindlessTextures, *uniforms, size ); - GenerateUniformStructDefinesText( frameUniforms, padding, paddingCount, "globalUniforms", uniformStruct, uniformDefines ); + GenerateUniformStructDefinesText( frameUniforms, "globalUniforms", padding, uniformStruct, uniformDefines ); - pushBuffer.frameUniformsSize = size + padding; + pushBuffer.frameUniformsSize = size; uniformStruct += "};\n\n"; @@ -1682,7 +1681,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str std::string materialStruct = "\nstruct Material {\n"; std::string materialDefines; GenerateUniformStructDefinesText( shader->_materialSystemUniforms, - "materials[baseInstance & 0xFFF]", materialStruct, materialDefines ); + "materials[baseInstance & 0xFFF]", 0, materialStruct, materialDefines ); materialStruct += "};\n\n"; @@ -2157,12 +2156,7 @@ static auto FindUniformForOffset( std::vector& uniforms, const GLuin // Note: using the std430 uniform size will give the wrong result for matrix types where // the number of rows is not 4 GLuint GLShaderManager::SortUniforms( std::vector& uniforms ) { - std::vector uniformQueue; - for ( GLUniform* uniform : _uniforms ) { - if ( !uniform->_global ) { - uniformQueue.emplace_back( uniform ); - } - } + std::vector uniformQueue = uniforms; std::stable_sort( uniformQueue.begin(), uniformQueue.end(), []( const GLUniform* lhs, const GLUniform* rhs ) { @@ -2174,32 +2168,33 @@ GLuint GLShaderManager::SortUniforms( std::vector& uniforms ) { GLuint align = 4; // mininum alignment since this will be used as an std140 array element GLuint structSize = 0; uniforms.clear(); - while ( !uniformQueue.empty() || std140Size & ( align - 1 ) ) { - auto iterNext = FindUniformForOffset( uniformQueue, std140Size ); + while ( !uniformQueue.empty() || structSize & ( align - 1 ) ) { + auto iterNext = FindUniformForOffset( uniformQueue, structSize ); if ( iterNext == uniformQueue.end() ) { // add 1 unit of padding ASSERT( !_materialSystemUniforms.back()->_components); // array WriteToBuffer impls don't handle padding correctly - ++std140Size; + ++structSize; ++uniforms.back()->_std430Size; } else { ( *iterNext )->_std430Size = ( *iterNext )->_std430BaseSize; if ( ( *iterNext )->_components ) { ASSERT_GE( ( *iterNext )->_std430Alignment, 4u ); // these would need extra padding in a std130 array - std140Size += ( *iterNext )->_std430Size * ( *iterNext )->_components; + structSize += ( *iterNext )->_std430Size * ( *iterNext )->_components; } else { - std140Size += ( *iterNext )->_std430Size; + structSize += ( *iterNext )->_std430Size; } align = std::max( align, ( *iterNext )->_std430Alignment ); uniforms.push_back( *iterNext ); uniformQueue.erase( iterNext ); } } + 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& uniforms, GLuint& structSize ) { std::vector tmp; tmp.reserve( uniforms.size() ); @@ -2212,24 +2207,19 @@ std::vector GLShaderManager::ProcessUniforms( const GLUniform::Updat 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; } void GLShader::PostProcessUniforms() { if ( _useMaterialSystem ) { _materialSystemUniforms = gl_shaderManager.ProcessUniforms( GLUniform::MATERIAL_OR_PUSH, GLUniform::MATERIAL_OR_PUSH, - true, _uniforms, std430Size, padding ); + true, _uniforms, std140Size ); } if ( glConfig.pushBufferAvailable && !pushSkip ) { GLuint unused; _pushUniforms = gl_shaderManager.ProcessUniforms( GLUniform::CONST, GLUniform::FRAME, - !glConfig.usingBindlessTextures, _uniforms, unused, unused ); + !glConfig.usingBindlessTextures, _uniforms, unused ); } } diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 1db702e5fc..e1d7c83567 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -422,7 +422,7 @@ class GLShaderManager { 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 ); + const bool skipTextures, std::vector& uniforms, GLuint& structSize ); template void LoadShader( T*& shader ) { @@ -497,8 +497,8 @@ class GLShaderManager { ShaderProgramDescriptor* out ); void SaveShaderBinary( ShaderProgramDescriptor* descriptor ); - void GenerateUniformStructDefinesText( - const std::vector& uniforms, const std::string& definesName, + uint32_t GenerateUniformStructDefinesText( + const std::vector& uniforms, const std::string& definesName, const uint32_t offset, 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 ); @@ -729,6 +729,11 @@ class GLUniform1Bool : protected GLUniform { return sizeof( int ); } + uint32_t* WriteToBuffer( uint32_t* buffer ) override { + memcpy( buffer, ¤tValue, sizeof( int ) ); + return buffer + _std430Size; + } + private: int currentValue = 0; }; From 6c4ff4b78a10628da3042f27d54fa37c08667c36 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 5 Sep 2025 20:59:11 +0300 Subject: [PATCH 12/16] MaterialSystem: use SetUniform_DepthMapBindless() --- src/engine/renderer/Material.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index ca9f4a16ef..fe4a077529 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1639,8 +1639,10 @@ void MaterialSystem::DepthReduction() { uint32_t globalWorkgroupX = ( width + 7 ) / 8; uint32_t globalWorkgroupY = ( height + 7 ) / 8; - // FIXME: u_DepthMap object on the shader is not actually used - GL_Bind( tr.currentDepthImage ); + gl_depthReductionShader->SetUniform_DepthMapBindless( + GL_BindToTMU( 0, tr.currentDepthImage ) + ); + glBindImageTexture( 2, depthImage->texnum, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32F ); gl_depthReductionShader->SetUniform_InitialDepthLevel( true ); From c0bda3c989673d2876e4c6fff2b57db8d01e5067 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 5 Sep 2025 20:59:34 +0300 Subject: [PATCH 13/16] Add a workaround for AMD/Mesa driver bug with bindless on depth target --- src/engine/renderer/gl_shader.cpp | 19 ++++++++++++++++++ src/engine/renderer/gl_shader.h | 20 +++++++++++++------ .../glsl_source/depthReduction_cp.glsl | 2 +- .../renderer/glsl_source/material_fp.glsl | 2 +- src/engine/renderer/tr_backend.cpp | 2 +- src/engine/renderer/tr_image.cpp | 11 +++++++++- src/engine/renderer/tr_local.h | 5 ++++- src/engine/sys/sdl_glimp.cpp | 4 ++++ 8 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 51c347fe27..3e39d79c29 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -562,6 +562,10 @@ static std::string GenVertexHeader() { "#define OUT(mode) varying\n"; } + if ( glConfig.driverVendor == glDriverVendor_t::ATI || glConfig.driverVendor == glDriverVendor_t::MESA ) { + AddDefine( str, "DRIVER_AMD_MESA", 1 ); + } + if ( glConfig.shaderDrawParametersAvailable ) { str += "OUT(flat) int in_drawID;\n"; str += "OUT(flat) int in_baseInstance;\n"; @@ -599,6 +603,10 @@ static std::string GenFragmentHeader() { "#define DECLARE_OUTPUT(type) /* empty*/\n"; } + if ( glConfig.driverVendor == glDriverVendor_t::ATI || glConfig.driverVendor == glDriverVendor_t::MESA ) { + AddDefine( str, "DRIVER_AMD_MESA", 1 ); + } + if ( glConfig.usingBindlessTextures ) { str += "layout(bindless_sampler) uniform;\n"; } @@ -627,6 +635,10 @@ static std::string GenFragmentHeader() { static std::string GenComputeHeader() { std::string str; + if ( glConfig.driverVendor == glDriverVendor_t::ATI || glConfig.driverVendor == glDriverVendor_t::MESA ) { + AddDefine( str, "DRIVER_AMD_MESA", 1 ); + } + // Compute shader compatibility defines if ( glConfig.usingMaterialSystem ) { AddDefine( str, "MAX_VIEWS", MAX_VIEWS ); @@ -2201,6 +2213,13 @@ std::vector GLShaderManager::ProcessUniforms( const GLUniform::Updat for ( GLUniform* uniform : uniforms ) { if ( uniform->_updateType >= minType && uniform->_updateType <= maxType && ( !uniform->_isTexture || !skipTextures ) ) { + + if ( uniform->_isTexture && uniform->_AMDSkipBindless + && ( glConfig.driverVendor == glDriverVendor_t::ATI || glConfig.driverVendor == glDriverVendor_t::MESA ) + && workaround_glDriver_amd_mesa_skipBindlessDepthTarget.Get() ){ + continue; + } + tmp.emplace_back( uniform ); } } diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index e1d7c83567..06fc727237 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -347,6 +347,7 @@ class GLUniform { const UpdateType _updateType; const int _components; const bool _isTexture; + const bool _AMDSkipBindless; protected: GLShader* _shader; @@ -355,7 +356,7 @@ class GLUniform { GLUniform( GLShader* shader, const char* name, const char* type, const GLuint std430Size, const GLuint std430Alignment, const UpdateType updateType, const int components = 0, - const bool isTexture = false ) : + const bool isTexture = false, const bool AMDSkipBindless = false ) : _name( name ), _type( type ), _std430BaseSize( std430Size ), @@ -364,6 +365,7 @@ class GLUniform { _updateType( updateType ), _components( components ), _isTexture( isTexture ), + _AMDSkipBindless( AMDSkipBindless ), _shader( shader ) { _shader->RegisterUniform( this ); } @@ -522,9 +524,9 @@ class GLShaderManager { class GLUniformSampler : protected GLUniform { protected: - GLUniformSampler( GLShader* shader, const char* name, const char* type, const UpdateType updateType ) : + GLUniformSampler( GLShader* shader, const char* name, const char* type, const UpdateType updateType, const bool AMDSkipBindless = false ) : GLUniform( shader, name, type, glConfig.bindlessTexturesAvailable ? 2 : 1, - glConfig.bindlessTexturesAvailable ? 2 : 1, updateType, 0, true ) { + glConfig.bindlessTexturesAvailable ? 2 : 1, updateType, 0, true, AMDSkipBindless ) { } inline GLint GetLocation() { @@ -550,6 +552,12 @@ class GLUniformSampler : protected GLUniform { currentValueBindless = value; if ( glConfig.usingBindlessTextures ) { + if ( _AMDSkipBindless + && ( glConfig.driverVendor == glDriverVendor_t::ATI || glConfig.driverVendor == glDriverVendor_t::MESA ) + && workaround_glDriver_amd_mesa_skipBindlessDepthTarget.Get() ) { + return; + } + if ( _shader->UseMaterialSystem() && _updateType == TEXDATA_OR_PUSH ) { return; } @@ -579,8 +587,8 @@ class GLUniformSampler : protected GLUniform { class GLUniformSampler2D : protected GLUniformSampler { protected: - GLUniformSampler2D( GLShader* shader, const char* name, const UpdateType updateType ) : - GLUniformSampler( shader, name, "sampler2D", updateType ) { + GLUniformSampler2D( GLShader* shader, const char* name, const UpdateType updateType, const bool AMDSkipBindless = false ) : + GLUniformSampler( shader, name, "sampler2D", updateType, AMDSkipBindless ) { } }; @@ -1743,7 +1751,7 @@ class u_DepthMap : GLUniformSampler2D { public: u_DepthMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthMap", CONST ) { + GLUniformSampler2D( shader, "u_DepthMap", CONST, true ) { } void SetUniform_DepthMapBindless( GLuint64 bindlessHandle ) { diff --git a/src/engine/renderer/glsl_source/depthReduction_cp.glsl b/src/engine/renderer/glsl_source/depthReduction_cp.glsl index d6501ca4b5..eb9c9263c8 100644 --- a/src/engine/renderer/glsl_source/depthReduction_cp.glsl +++ b/src/engine/renderer/glsl_source/depthReduction_cp.glsl @@ -41,7 +41,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 u_DepthMap; +uniform sampler2D u_DepthMap; layout(r32f, binding = 1) uniform readonly image2D depthImageIn; layout(r32f, binding = 2) uniform writeonly image2D depthImageOut; diff --git a/src/engine/renderer/glsl_source/material_fp.glsl b/src/engine/renderer/glsl_source/material_fp.glsl index a43cca4835..d436a617e6 100644 --- a/src/engine/renderer/glsl_source/material_fp.glsl +++ b/src/engine/renderer/glsl_source/material_fp.glsl @@ -60,7 +60,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sampler2D u_PortalMap = sampler2D( u_PortalMap_initial ); #endif // !LIQUID_GLSL - #if defined(DEPTHMAP_GLSL) + #if defined(DEPTHMAP_GLSL) && !defined(DRIVER_AMD_MESA) sampler2D u_DepthMap = sampler2D( u_DepthMap_initial ); #endif // !DEPTHMAP_GLSL diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 761aa21068..5003eb3941 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -178,7 +178,7 @@ GLuint64 GL_BindToTMU( int unit, image_t *image ) image = tr.defaultImage; } - if ( glConfig.usingBindlessTextures ) { + if ( glConfig.usingBindlessTextures && !( image->bits & IF_AMD_SKIP_BINDLESS ) ) { return tr.textureManager.BindTexture( 0, image->texture ); } diff --git a/src/engine/renderer/tr_image.cpp b/src/engine/renderer/tr_image.cpp index bdbe237f89..d4e34357da 100644 --- a/src/engine/renderer/tr_image.cpp +++ b/src/engine/renderer/tr_image.cpp @@ -1471,6 +1471,15 @@ image_t *R_CreateImage( const char *name, const byte **pic, int width, int heigh image->height = height; image->bits = imageParams.bits; + + const bool skipAMDBindless = + ( glConfig.driverVendor == glDriverVendor_t::ATI || glConfig.driverVendor == glDriverVendor_t::MESA ) + && workaround_glDriver_amd_mesa_skipBindlessDepthTarget.Get(); + + if ( !skipAMDBindless ) { + image->bits &= ~IF_AMD_SKIP_BINDLESS; + } + image->filterType = imageParams.filterType; image->wrapType = imageParams.wrapType; @@ -2460,7 +2469,7 @@ static void R_CreateCurrentRenderImage() tr.currentRenderImage[1] = R_CreateImage( "_currentRender[1]", nullptr, width, height, 1, imageParams ); imageParams = {}; - imageParams.bits = IF_NOPICMIP | IF_PACKED_DEPTH24_STENCIL8; + imageParams.bits = IF_NOPICMIP | IF_PACKED_DEPTH24_STENCIL8 | IF_AMD_SKIP_BINDLESS; imageParams.filterType = filterType_t::FT_NEAREST; imageParams.wrapType = wrapTypeEnum_t::WT_CLAMP; diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 231015c716..31c6bd428d 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -498,7 +498,8 @@ enum class ssaoMode { IF_BC4 = BIT( 22 ), IF_BC5 = BIT( 23 ), IF_RGBA32UI = BIT( 24 ), - IF_HOMEPATH = BIT( 25 ) + IF_HOMEPATH = BIT( 25 ), + IF_AMD_SKIP_BINDLESS = BIT( 26 ) }; enum class filterType_t @@ -2774,6 +2775,8 @@ enum extern cvar_t *r_evsmPostProcess; + extern Cvar::Cvar workaround_glDriver_amd_mesa_skipBindlessDepthTarget; + //==================================================================== /* r_checkGLErrors values: diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index 16fa8f6243..1a558019f7 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -137,6 +137,10 @@ static Cvar::Cvar workaround_glDriver_amd_oglp_disableBindlessTexture( "workaround.glDriver.amd.oglp.disableBindlessTexture", "Disable ARB_bindless_texture on AMD OGLP driver", Cvar::NONE, true ); +Cvar::Cvar workaround_glDriver_amd_mesa_skipBindlessDepthTarget( + "workaround.glDriver.amd.mesa.skipBindlessDepthTarget", + "Disable bindless depth target on AMD and Mesa drivers", + Cvar::NONE, true ); static Cvar::Cvar workaround_glDriver_mesa_ati_rv300_useFloatVertex( "workaround.glDriver.mesa.ati.rv300.useFloatVertex", "Use float vertex instead of supported-but-slower half-float vertex on Mesa driver on ATI RV300 hardware", From fdb7f2a4737d52e870cfdcc738de40c77b5dab25 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 23 Jun 2025 14:39:52 +0300 Subject: [PATCH 14/16] Only update PushBuffer if any uniform has actually changed Also mutualises `uniformFirewall` and `currentValue` and removes a bunch of unneeded code. --- src/engine/renderer/gl_shader.cpp | 30 +- src/engine/renderer/gl_shader.h | 448 +++++++---------------------- src/engine/renderer/tr_backend.cpp | 7 +- src/engine/renderer/tr_bsp.cpp | 7 +- 4 files changed, 134 insertions(+), 358 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 3e39d79c29..4bf08540ff 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -218,6 +218,12 @@ GLShaderManager::~GLShaderManager() = default; void GLShaderManager::FreeAll() { + for ( const std::unique_ptr& shader : _shaders ) { + if ( shader.get()->uniformStorage ) { + Z_Free( shader.get()->uniformStorage ); + } + } + _shaders.clear(); deformShaderCount = 0; @@ -236,8 +242,8 @@ void GLShaderManager::FreeAll() { Z_Free( program.uniformBlockIndexes ); } - if ( program.uniformFirewall ) { - Z_Free( program.uniformFirewall ); + if ( program.uniformStorage ) { + Z_Free( program.uniformStorage ); } } @@ -266,7 +272,7 @@ void GLShaderManager::UpdateShaderProgramUniformLocations( GLShader* shader, Sha shaderProgram->uniformLocations = ( GLint* ) Z_Malloc( sizeof( GLint ) * numUniforms ); // create buffer for uniform firewall - shaderProgram->uniformFirewall = ( byte* ) Z_Malloc( uniformSize ); + shaderProgram->uniformStorage = ( uint32_t* ) Z_Malloc( uniformSize ); // update uniforms for (GLUniform *uniform : shader->_uniforms) @@ -1278,10 +1284,16 @@ void GLShaderManager::InitShader( GLShader* shader ) { for ( std::size_t i = 0; i < shader->_uniforms.size(); i++ ) { GLUniform* uniform = shader->_uniforms[i]; uniform->SetLocationIndex( i ); - uniform->SetFirewallIndex( shader->_uniformStorageSize ); - shader->_uniformStorageSize += uniform->GetSize(); + uniform->SetUniformStorageOffset( shader->_uniformStorageSize ); + + const uint32_t size = uniform->_components ? uniform->_std430Size * uniform->_components : uniform->_std430Size; + shader->_uniformStorageSize += size; } + shader->_uniformStorageSize *= sizeof( uint32_t ); + + shader->uniformStorage = ( uint32_t* ) Z_Malloc( shader->_uniformStorageSize ); + for ( std::size_t i = 0; i < shader->_uniformBlocks.size(); i++ ) { GLUniformBlock* uniformBlock = shader->_uniformBlocks[i]; uniformBlock->SetLocationIndex( i ); @@ -2141,10 +2153,6 @@ bool GLCompileMacro_USE_BSP_SURFACE::HasConflictingMacros(size_t permutation, co return false; } -uint32_t* GLUniform::WriteToBuffer( uint32_t * ) { - Sys::Error( "WriteToBuffer not implemented for GLUniform '%s'", _name ); -} - void GLShader::RegisterUniform( GLUniform* uniform ) { _uniforms.push_back( uniform ); } @@ -2184,7 +2192,7 @@ GLuint GLShaderManager::SortUniforms( std::vector& uniforms ) { auto iterNext = FindUniformForOffset( uniformQueue, structSize ); if ( iterNext == uniformQueue.end() ) { // add 1 unit of padding - ASSERT( !_materialSystemUniforms.back()->_components); // array WriteToBuffer impls don't handle padding correctly + ASSERT( !uniforms.back()->_components ); // array WriteToBuffer impls don't handle padding correctly ++structSize; ++uniforms.back()->_std430Size; } else { @@ -2440,6 +2448,8 @@ void GLShader::WriteUniformsToBuffer( uint32_t* buffer, const Mode mode, const i bufPtr = uniform->WriteToBuffer( bufPtr ); } } + + uniformsUpdated = false; } GLShader_generic::GLShader_generic() : diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 06fc727237..9c03b5b3ab 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -28,8 +28,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "GLUtils.h" #include -#define USE_UNIFORM_FIREWALL 1 - // *INDENT-OFF* static const unsigned int MAX_SHADER_MACROS = 10; static const unsigned int GL_SHADER_VERSION = 6; @@ -128,7 +126,7 @@ struct ShaderProgramDescriptor { GLint* uniformLocations; GLuint* uniformBlockIndexes = nullptr; - byte* uniformFirewall; + uint32_t* uniformStorage; uint32_t checkSum; @@ -202,6 +200,7 @@ class GLShader { std::vector computeShaderDescriptors; size_t _uniformStorageSize; + std::vector _uniforms; std::vector _pushUniforms; std::vector _materialSystemUniforms; @@ -279,6 +278,9 @@ class GLShader { PUSH }; + uint32_t* uniformStorage = nullptr; + bool uniformsUpdated = true; + void MarkProgramForBuilding( int deformIndex ); GLuint GetProgram( int deformIndex, const bool buildOneShader ); void BindProgram( int deformIndex ); @@ -343,6 +345,7 @@ class GLUniform { const GLuint _std430BaseSize; GLuint _std430Size; // includes padding that depends on the other uniforms in the struct const GLuint _std430Alignment; + GLuint _nextUniformOffset; const UpdateType _updateType; const int _components; @@ -351,8 +354,8 @@ class GLUniform { protected: GLShader* _shader; - size_t _firewallIndex; size_t _locationIndex; + size_t _uniformStorageOffset; GLUniform( GLShader* shader, const char* name, const char* type, const GLuint std430Size, const GLuint std430Alignment, const UpdateType updateType, const int components = 0, @@ -362,6 +365,7 @@ class GLUniform { _std430BaseSize( std430Size ), _std430Size( std430Size ), _std430Alignment( std430Alignment ), + _nextUniformOffset( components ? components * 4 : std430Size ), _updateType( updateType ), _components( components ), _isTexture( isTexture ), @@ -370,19 +374,61 @@ class GLUniform { _shader->RegisterUniform( this ); } - public: - virtual ~GLUniform() = default; + bool CacheValue( void* value ) { + uint32_t* currentValue; + + const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ); + + if ( bufferUniform ) { + currentValue = _shader->uniformStorage + _uniformStorageOffset; + } else { + ShaderProgramDescriptor* p = _shader->GetProgram(); + ASSERT_EQ( p, glState.currentProgram ); + + currentValue = p->uniformStorage + _uniformStorageOffset; + } + + const uint32_t size = _components ? _std430Size * _components : _std430Size; + const bool updated = memcmp( currentValue, value, size * sizeof( uint32_t ) ); - void SetFirewallIndex( size_t offSetValue ) { - _firewallIndex = offSetValue; + if ( updated ) { + memcpy( currentValue, value, size * sizeof( uint32_t ) ); + _shader->uniformsUpdated = true; + } + + return updated && !bufferUniform; } + public: + virtual ~GLUniform() = default; + void SetLocationIndex( size_t index ) { _locationIndex = index; } + void SetUniformStorageOffset( size_t index ) { + _uniformStorageOffset = index; + } + // This should return a pointer to the memory right after the one this uniform wrote to - virtual uint32_t* WriteToBuffer( uint32_t* buffer ); + uint32_t* WriteToBuffer( uint32_t* buffer ) { + uint32_t* currentValue; + + const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ); + + if ( bufferUniform ) { + currentValue = _shader->uniformStorage + _uniformStorageOffset; + } else { + return buffer; + } + + const uint32_t size = _components ? _std430Size * _components : _std430Size; + memcpy( buffer, currentValue, size * sizeof( uint32_t ) ); + + return buffer + _nextUniformOffset; + } void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, _name.c_str() ); @@ -532,10 +578,6 @@ class GLUniformSampler : protected GLUniform { inline GLint GetLocation() { ShaderProgramDescriptor* p = _shader->GetProgram(); - if ( !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); - } - return p->uniformLocations[_locationIndex]; } @@ -545,44 +587,22 @@ class GLUniformSampler : protected GLUniform { } void SetValue( GLuint value ) { - currentValue = value; + if ( !CacheValue( &value ) ) { + return; + } } - void SetValueBindless( GLint64 value ) { - currentValueBindless = value; - - if ( glConfig.usingBindlessTextures ) { - if ( _AMDSkipBindless - && ( glConfig.driverVendor == glDriverVendor_t::ATI || glConfig.driverVendor == glDriverVendor_t::MESA ) - && workaround_glDriver_amd_mesa_skipBindlessDepthTarget.Get() ) { - return; - } - - if ( _shader->UseMaterialSystem() && _updateType == TEXDATA_OR_PUSH ) { - return; - } - - if ( glConfig.pushBufferAvailable && _updateType <= FRAME ) { - return; - } - - glUniformHandleui64ARB( GetLocation(), currentValueBindless ); + void SetValueBindless( GLuint64 value ) { + if ( !glConfig.usingBindlessTextures ) { + return; } - } - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - if ( glConfig.usingBindlessTextures ) { - memcpy( buffer, ¤tValueBindless, sizeof( GLuint64 ) ); - } else { - memcpy( buffer, ¤tValue, sizeof( GLint ) ); + if ( !CacheValue( &value ) ) { + return; } - return buffer + _std430Size; + glUniformHandleui64ARB( GetLocation(), value ); } - - private: - GLuint64 currentValueBindless = 0; - GLuint currentValue = 0; }; class GLUniformSampler2D : protected GLUniformSampler { @@ -617,32 +637,16 @@ class GLUniform1i : protected GLUniform { protected: GLUniform1i( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "int", 1, 1, updateType ) - { + GLUniform( shader, name, "int", 1, 1, updateType ) { } inline void SetValue( int value ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - currentValue = value; + if ( !CacheValue( &value ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - int *firewall = ( int * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( *firewall == value ) - { - return; - } - - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1i( p->uniformLocations[ _locationIndex ], value ); } public: @@ -650,14 +654,6 @@ class GLUniform1i : protected GLUniform { return sizeof( int ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( int ) ); - return buffer + _std430Size; - } - - private: - int currentValue = 0; }; class GLUniform1ui : protected GLUniform { @@ -667,39 +663,17 @@ class GLUniform1ui : protected GLUniform { } inline void SetValue( uint value ) { - ShaderProgramDescriptor* p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - currentValue = value; + if ( !CacheValue( &value ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - uint* firewall = ( uint* ) &p->uniformFirewall[_firewallIndex]; - - if ( *firewall == value ) { - return; - } - - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1ui( p->uniformLocations[_locationIndex], value ); } public: size_t GetSize() override { return sizeof( uint ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( uint ) ); - return buffer + _std430Size; - } - - private: - uint currentValue = 0; }; class GLUniform1Bool : protected GLUniform { @@ -710,25 +684,11 @@ class GLUniform1Bool : protected GLUniform { } inline void SetValue( int value ) { - ShaderProgramDescriptor* p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - currentValue = value; + if ( !CacheValue( &value ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - int* firewall = ( int* ) &p->uniformFirewall[_firewallIndex]; - - if ( *firewall == value ) { - return; - } - - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1i( p->uniformLocations[_locationIndex], value ); } @@ -736,46 +696,22 @@ class GLUniform1Bool : protected GLUniform { size_t GetSize() override { return sizeof( int ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( int ) ); - return buffer + _std430Size; - } - - private: - int currentValue = 0; }; class GLUniform1f : protected GLUniform { protected: GLUniform1f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "float", 1, 1, updateType ) - { + GLUniform( shader, name, "float", 1, 1, updateType ) { } inline void SetValue( float value ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - currentValue = value; + if ( !CacheValue( &value ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - float *firewall = ( float * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( *firewall == value ) - { - return; - } - - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1f( p->uniformLocations[ _locationIndex ], value ); } public: @@ -783,77 +719,40 @@ class GLUniform1f : protected GLUniform { return sizeof( float ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( float ) ); - return buffer + _std430Size; - } - - private: - float currentValue = 0; }; class GLUniform1fv : protected GLUniform { protected: GLUniform1fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : - GLUniform( shader, name, "float", 1, 1, updateType, size ) - { - currentValue.reserve( size ); + GLUniform( shader, name, "float", 1, 1, updateType, size ) { } inline void SetValue( int numFloats, float *f ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue.data(), f, numFloats * sizeof( float ) ); + if ( !CacheValue( f ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - - glUniform1fv( p->uniformLocations[ _locationIndex ], numFloats, f ); + ShaderProgramDescriptor* p = _shader->GetProgram(); + glUniform1fv( p->uniformLocations[_locationIndex], numFloats, f ); } - - private: - std::vector currentValue; }; class GLUniform2f : protected GLUniform { protected: GLUniform2f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "vec2", 2, 2, updateType ) - { - currentValue[0] = 0.0; - currentValue[1] = 0.0; + GLUniform( shader, name, "vec2", 2, 2, updateType ) { } inline void SetValue( const vec2_t v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - Vector2Copy( v, currentValue ); + if ( !CacheValue( ( void* ) v ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - vec2_t *firewall = ( vec2_t * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( ( *firewall )[ 0 ] == v[ 0 ] && ( *firewall )[ 1 ] == v[ 1 ] ) - { - return; - } - - ( *firewall )[ 0 ] = v[ 0 ]; - ( *firewall )[ 1 ] = v[ 1 ]; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform2f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ] ); } @@ -861,49 +760,22 @@ class GLUniform2f : protected GLUniform { return sizeof( vec2_t ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( vec2_t ) ); - return buffer + _std430Size; - } - - private: - vec2_t currentValue; }; class GLUniform3f : protected GLUniform { protected: GLUniform3f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "vec3", 3, 4, updateType ) - { - currentValue[0] = 0.0; - currentValue[1] = 0.0; - currentValue[2] = 0.0; + GLUniform( shader, name, "vec3", 3, 4, updateType ) { } inline void SetValue( const vec3_t v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - VectorCopy( v, currentValue ); + if ( !CacheValue( ( void* ) v ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - vec3_t *firewall = ( vec3_t * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( VectorCompare( *firewall, v ) ) - { - return; - } - - VectorCopy( v, *firewall ); -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform3f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ] ); } public: @@ -911,50 +783,22 @@ class GLUniform3f : protected GLUniform { return sizeof( vec3_t ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( vec3_t ) ); - return buffer + _std430Size; - } - - private: - vec3_t currentValue; }; class GLUniform4f : protected GLUniform { protected: GLUniform4f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "vec4", 4, 4, updateType ) - { - currentValue[0] = 0.0; - currentValue[1] = 0.0; - currentValue[2] = 0.0; - currentValue[3] = 0.0; + GLUniform( shader, name, "vec4", 4, 4, updateType ) { } inline void SetValue( const vec4_t v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - Vector4Copy( v, currentValue ); + if ( !CacheValue( ( void* ) v ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - vec4_t *firewall = ( vec4_t * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( !memcmp( *firewall, v, sizeof( *firewall ) ) ) - { - return; - } - - Vector4Copy( v, *firewall ); -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform4f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); } public: @@ -962,81 +806,40 @@ class GLUniform4f : protected GLUniform { return sizeof( vec4_t ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( vec4_t ) ); - return buffer + _std430Size; - } - - private: - vec4_t currentValue; }; class GLUniform4fv : protected GLUniform { protected: GLUniform4fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : - GLUniform( shader, name, "vec4", 4, 4, updateType, size ) - { - currentValue.reserve( size ); + GLUniform( shader, name, "vec4", 4, 4, updateType, size ) { } inline void SetValue( int numV, vec4_t *v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue.data(), v, numV * sizeof( vec4_t ) ); + if ( !CacheValue( v ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform4fv( p->uniformLocations[ _locationIndex ], numV, &v[ 0 ][ 0 ] ); } - - public: - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, currentValue.data(), currentValue.size() * sizeof( float ) ); - return buffer + _std430Size * _components; - } - - private: - std::vector currentValue; }; class GLUniformMatrix4f : protected GLUniform { protected: GLUniformMatrix4f( GLShader *shader, const char *name, const UpdateType updateType ) : - GLUniform( shader, name, "mat4", 16, 4, updateType ) - { - MatrixIdentity( currentValue ); + GLUniform( shader, name, "mat4", 16, 4, updateType ) { } inline void SetValue( GLboolean transpose, const matrix_t m ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - MatrixCopy( m, currentValue ); + if ( !CacheValue( ( void* ) m ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - -#if defined( USE_UNIFORM_FIREWALL ) - matrix_t *firewall = ( matrix_t * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( MatrixCompare( m, *firewall ) ) - { - return; - } - - MatrixCopy( m, *firewall ); -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix4fv( p->uniformLocations[ _locationIndex ], 1, transpose, m ); } public: @@ -1044,14 +847,6 @@ class GLUniformMatrix4f : protected GLUniform { return sizeof( matrix_t ); } - - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, ¤tValue, sizeof( matrix_t ) ); - return buffer + _std430Size; - } - - private: - matrix_t currentValue; }; class GLUniformMatrix32f : protected GLUniform { @@ -1061,59 +856,38 @@ class GLUniformMatrix32f : protected GLUniform { } inline void SetValue( GLboolean transpose, const vec_t* m ) { - ShaderProgramDescriptor* p = _shader->GetProgram(); + vec_t value[12] {}; + memcpy( value, m, 6 * sizeof( vec_t ) ); - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue, m, 6 * sizeof( float ) ); + if ( !CacheValue( value ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix3x2fv( p->uniformLocations[_locationIndex], 1, transpose, m ); } public: size_t GetSize() override { return 6 * sizeof( float ); } - - private: - vec_t currentValue[6] {}; }; class GLUniformMatrix4fv : protected GLUniform { protected: GLUniformMatrix4fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : - GLUniform( shader, name, "mat4", 16, 4, updateType, size ) - { - currentValue.reserve( size * 16 ); + GLUniform( shader, name, "mat4", 16, 4, updateType, size ) { } inline void SetValue( int numMatrices, GLboolean transpose, const matrix_t *m ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue.data(), m, numMatrices * sizeof( matrix_t ) ); + if ( !CacheValue( ( void* ) m ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix4fv( p->uniformLocations[ _locationIndex ], numMatrices, transpose, &m[ 0 ][ 0 ] ); } - - public: - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, currentValue.data(), currentValue.size() * sizeof( float ) ); - return buffer + _std430Size * _components; - } - - private: - std::vector currentValue; }; class GLUniformMatrix34fv : protected GLUniform @@ -1126,27 +900,13 @@ class GLUniformMatrix34fv : protected GLUniform inline void SetValue( int numMatrices, GLboolean transpose, const float *m ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) - || ( glConfig.pushBufferAvailable && _updateType <= FRAME ) ) { - memcpy( currentValue.data(), m, numMatrices * sizeof( matrix_t ) ); + if ( !CacheValue( ( void* ) m ) ) { return; } - ASSERT_EQ( p, glState.currentProgram ); - - glUniformMatrix3x4fv( p->uniformLocations[ _locationIndex ], numMatrices, transpose, m ); - } - - public: - uint32_t* WriteToBuffer( uint32_t* buffer ) override { - memcpy( buffer, currentValue.data(), currentValue.size() * sizeof( float ) ); - return buffer + _std430Size * _components; + ShaderProgramDescriptor* p = _shader->GetProgram(); + glUniformMatrix3x4fv( p->uniformLocations[_locationIndex], numMatrices, transpose, m ); } - - private: - std::vector currentValue; }; class GLUniformBlock @@ -2612,7 +2372,7 @@ class u_Bones : { public: u_Bones( GLShader *shader ) : - GLUniform4fv( shader, "u_Bones", MAX_BONES, PUSH ) + GLUniform4fv( shader, "u_Bones", MAX_BONES * 2, PUSH ) { } diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 5003eb3941..8b5959a254 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -2797,8 +2797,6 @@ static void SetFrameUniforms() { GLIMP_LOGCOMMENT( "--- SetFrameUniforms ---" ); - uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::FRAME ); - globalUBOProxy->SetUniform_blurVec( tr.refdef.blurVec ); globalUBOProxy->SetUniform_numLights( tr.refdef.numLights ); @@ -2819,6 +2817,11 @@ static void SetFrameUniforms() { materialSystem.SetFrameUniforms(); } + if ( !globalUBOProxy->uniformsUpdated ) { + return; + } + + uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::FRAME ); globalUBOProxy->WriteUniformsToBuffer( data, GLShader::PUSH, GLUniform::FRAME ); pushBuffer.PushGlobalUniforms(); diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index de7a21811d..287f0d410e 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -4644,8 +4644,6 @@ 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 ); @@ -4689,6 +4687,11 @@ static void SetConstUniforms() { materialSystem.SetConstUniforms(); } + if ( !globalUBOProxy->uniformsUpdated ) { + return; + } + + uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::CONST ); globalUBOProxy->WriteUniformsToBuffer( data, GLShader::PUSH, GLUniform::CONST ); pushBuffer.PushGlobalUniforms(); From 9220f6fd8cccd90b38b2d5153f2940b49cdbde44 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 25 Jun 2025 08:55:28 +0300 Subject: [PATCH 15/16] NUKE unused GLUniform.GetSize() --- src/engine/renderer/gl_shader.h | 54 +-------------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 9c03b5b3ab..83a2004bcb 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -343,7 +343,6 @@ class GLUniform { // In multiples of 4 bytes // FIXME: the uniform structs are actually std140 so it would be more relevant to provide std140 info const GLuint _std430BaseSize; - GLuint _std430Size; // includes padding that depends on the other uniforms in the struct const GLuint _std430Alignment; GLuint _nextUniformOffset; @@ -374,7 +373,7 @@ class GLUniform { _shader->RegisterUniform( this ); } - bool CacheValue( void* value ) { + bool CacheValue( const void* value ) { uint32_t* currentValue; const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) @@ -433,10 +432,6 @@ class GLUniform { void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, _name.c_str() ); } - - virtual size_t GetSize() { - return 0; - } }; class GLShaderManager { @@ -582,10 +577,6 @@ class GLUniformSampler : protected GLUniform { } public: - size_t GetSize() override { - return sizeof( GLuint64 ); - } - void SetValue( GLuint value ) { if ( !CacheValue( &value ) ) { return; @@ -649,11 +640,6 @@ class GLUniform1i : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1i( p->uniformLocations[ _locationIndex ], value ); } -public: - size_t GetSize() override - { - return sizeof( int ); - } }; class GLUniform1ui : protected GLUniform { @@ -670,10 +656,6 @@ class GLUniform1ui : protected GLUniform { ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1ui( p->uniformLocations[_locationIndex], value ); } - public: - size_t GetSize() override { - return sizeof( uint ); - } }; class GLUniform1Bool : protected GLUniform { @@ -691,11 +673,6 @@ class GLUniform1Bool : protected GLUniform { ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1i( p->uniformLocations[_locationIndex], value ); } - - public: - size_t GetSize() override { - return sizeof( int ); - } }; class GLUniform1f : protected GLUniform @@ -714,11 +691,6 @@ class GLUniform1f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1f( p->uniformLocations[ _locationIndex ], value ); } -public: - size_t GetSize() override - { - return sizeof( float ); - } }; class GLUniform1fv : protected GLUniform @@ -755,11 +727,6 @@ class GLUniform2f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform2f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ] ); } - - size_t GetSize() override - { - return sizeof( vec2_t ); - } }; class GLUniform3f : protected GLUniform @@ -778,11 +745,6 @@ class GLUniform3f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform3f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ] ); } -public: - size_t GetSize() override - { - return sizeof( vec3_t ); - } }; class GLUniform4f : protected GLUniform @@ -801,11 +763,6 @@ class GLUniform4f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform4f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); } -public: - size_t GetSize() override - { - return sizeof( vec4_t ); - } }; class GLUniform4fv : protected GLUniform @@ -842,11 +799,6 @@ class GLUniformMatrix4f : protected GLUniform ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix4fv( p->uniformLocations[ _locationIndex ], 1, transpose, m ); } -public: - size_t GetSize() override - { - return sizeof( matrix_t ); - } }; class GLUniformMatrix32f : protected GLUniform { @@ -866,10 +818,6 @@ class GLUniformMatrix32f : protected GLUniform { ShaderProgramDescriptor* p = _shader->GetProgram(); glUniformMatrix3x2fv( p->uniformLocations[_locationIndex], 1, transpose, m ); } - public: - size_t GetSize() override { - return 6 * sizeof( float ); - } }; class GLUniformMatrix4fv : protected GLUniform From 2b38e3fdfbb79da85bf04ac242aa89abcf2d9546 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 25 Jun 2025 08:58:40 +0300 Subject: [PATCH 16/16] Add GLUniform.bufferSize as a shorthand for _std430Size * max( 1, _components ) --- src/engine/renderer/gl_shader.cpp | 3 +-- src/engine/renderer/gl_shader.h | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 4bf08540ff..7361d27519 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1286,8 +1286,7 @@ void GLShaderManager::InitShader( GLShader* shader ) { uniform->SetLocationIndex( i ); uniform->SetUniformStorageOffset( shader->_uniformStorageSize ); - const uint32_t size = uniform->_components ? uniform->_std430Size * uniform->_components : uniform->_std430Size; - shader->_uniformStorageSize += size; + shader->_uniformStorageSize += uniform->_bufferSize; } shader->_uniformStorageSize *= sizeof( uint32_t ); diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 83a2004bcb..91232eee99 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -344,6 +344,7 @@ class GLUniform { // FIXME: the uniform structs are actually std140 so it would be more relevant to provide std140 info const GLuint _std430BaseSize; const GLuint _std430Alignment; + const GLuint _bufferSize; GLuint _nextUniformOffset; const UpdateType _updateType; @@ -364,6 +365,7 @@ class GLUniform { _std430BaseSize( std430Size ), _std430Size( std430Size ), _std430Alignment( std430Alignment ), + _bufferSize( components ? components * 4 : std430Size ), _nextUniformOffset( components ? components * 4 : std430Size ), _updateType( updateType ), _components( components ), @@ -388,11 +390,10 @@ class GLUniform { currentValue = p->uniformStorage + _uniformStorageOffset; } - const uint32_t size = _components ? _std430Size * _components : _std430Size; - const bool updated = memcmp( currentValue, value, size * sizeof( uint32_t ) ); + const bool updated = memcmp( currentValue, value, _bufferSize * sizeof( uint32_t ) ); if ( updated ) { - memcpy( currentValue, value, size * sizeof( uint32_t ) ); + memcpy( currentValue, value, _bufferSize * sizeof( uint32_t ) ); _shader->uniformsUpdated = true; } @@ -423,8 +424,7 @@ class GLUniform { return buffer; } - const uint32_t size = _components ? _std430Size * _components : _std430Size; - memcpy( buffer, currentValue, size * sizeof( uint32_t ) ); + memcpy( buffer, currentValue, _bufferSize * sizeof( uint32_t ) ); return buffer + _nextUniformOffset; }