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..54a38ba26f 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, @@ -114,6 +117,10 @@ void GLStagingBuffer::FlushAll() { FlushStagingCopyQueue(); } +bool GLStagingBuffer::Active() const { + return buffer.id; +} + void GLStagingBuffer::InitGLBuffer() { buffer.GenBuffer(); @@ -130,3 +137,36 @@ void GLStagingBuffer::FreeGLBuffer() { current = 0; last = 0; } + +void PushBuffer::InitGLBuffers() { + globalUBO.GenBuffer(); + + globalUBO.BufferStorage( pushBuffer.constUniformsSize + pushBuffer.frameUniformsSize, 1, nullptr ); + + globalUBO.BindBufferBase(); +} + +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..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(); @@ -321,6 +324,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/Material.cpp b/src/engine/renderer/Material.cpp index d5e3505268..fe4a077529 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 ); } /* @@ -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(); @@ -1624,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 ); @@ -1681,15 +1698,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 +1732,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 d6ec602b7f..7361d27519 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 @@ -217,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; @@ -235,8 +242,8 @@ void GLShaderManager::FreeAll() { Z_Free( program.uniformBlockIndexes ); } - if ( program.uniformFirewall ) { - Z_Free( program.uniformFirewall ); + if ( program.uniformStorage ) { + Z_Free( program.uniformStorage ); } } @@ -265,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) @@ -561,6 +568,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"; @@ -598,6 +609,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"; } @@ -626,6 +641,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 ); @@ -1261,16 +1280,19 @@ 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]; uniform->SetLocationIndex( i ); - uniform->SetFirewallIndex( shader->_uniformStorageSize ); - shader->_uniformStorageSize += uniform->GetSize(); + uniform->SetUniformStorageOffset( shader->_uniformStorageSize ); + + shader->_uniformStorageSize += uniform->_bufferSize; } + 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 ); @@ -1333,6 +1355,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 ); } @@ -1531,9 +1559,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; @@ -1560,6 +1588,60 @@ void GLShaderManager::GenerateUniformStructDefinesText( const std::vector* uniforms = &( ( GLShader* ) globalUBOProxy )->_uniforms; + std::vector constUniforms = + ProcessUniforms( GLUniform::CONST, GLUniform::CONST, !glConfig.usingBindlessTextures, *uniforms, size ); + + const uint32_t padding = GenerateUniformStructDefinesText( constUniforms, "globalUniforms", 0, uniformStruct, uniformDefines ); + + pushBuffer.constUniformsSize = size; + + std::vector frameUniforms = + ProcessUniforms( GLUniform::FRAME, GLUniform::FRAME, !glConfig.usingBindlessTextures, *uniforms, size ); + + GenerateUniformStructDefinesText( frameUniforms, "globalUniforms", padding, uniformStruct, uniformDefines ); + + pushBuffer.frameUniformsSize = size; + + 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 @@ -1622,7 +1704,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"; @@ -2070,10 +2152,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 ); } @@ -2096,17 +2174,8 @@ 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; - } - - std::vector uniformQueue; - for ( GLUniform* uniform : _uniforms ) { - if ( !uniform->_global ) { - uniformQueue.emplace_back( uniform ); - } - } +GLuint GLShaderManager::SortUniforms( std::vector& uniforms ) { + std::vector uniformQueue = uniforms; std::stable_sort( uniformQueue.begin(), uniformQueue.end(), []( const GLUniform* lhs, const GLUniform* rhs ) { @@ -2116,28 +2185,68 @@ 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(); - while ( !uniformQueue.empty() || std140Size & ( align - 1 ) ) { - auto iterNext = FindUniformForOffset( uniformQueue, std140Size ); + GLuint structSize = 0; + uniforms.clear(); + 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; - ++_materialSystemUniforms.back()->_std430Size; + ASSERT( !uniforms.back()->_components ); // array WriteToBuffer impls don't handle padding correctly + ++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 ); - _materialSystemUniforms.push_back( *iterNext ); + 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 ) { + std::vector tmp; + + tmp.reserve( uniforms.size() ); + 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 ); + } + } + + structSize = SortUniforms( tmp ); + + return tmp; +} + +void GLShader::PostProcessUniforms() { + if ( _useMaterialSystem ) { + _materialSystemUniforms = gl_shaderManager.ProcessUniforms( GLUniform::MATERIAL_OR_PUSH, GLUniform::MATERIAL_OR_PUSH, + true, _uniforms, std140Size ); + } + + if ( glConfig.pushBufferAvailable && !pushSkip ) { + GLuint unused; + _pushUniforms = gl_shaderManager.ProcessUniforms( GLUniform::CONST, GLUniform::FRAME, + !glConfig.usingBindlessTextures, _uniforms, unused ); + } } uint32_t GLShader::GetUniqueCompileMacros( size_t permutation, const int type ) const { @@ -2319,11 +2428,27 @@ 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 ); + } } + + uniformsUpdated = false; } GLShader_generic::GLShader_generic() : @@ -2623,7 +2748,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 ); } @@ -2952,3 +3077,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 1ad4f90935..91232eee99 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; @@ -188,6 +186,7 @@ class GLShader { GLuint std140Size = 0; const bool worldShader; + const bool pushSkip; protected: int _activeMacros = 0; ShaderProgramDescriptor* currentProgram; @@ -201,14 +200,17 @@ class GLShader { std::vector computeShaderDescriptors; 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 +219,8 @@ class GLShader { hasVertexShader( true ), hasFragmentShader( true ), hasComputeShader( false ), - worldShader( false ) { + worldShader( false ), + pushSkip( newPushSkip ) { } GLShader( const std::string& name, @@ -230,7 +233,8 @@ class GLShader { hasVertexShader( false ), hasFragmentShader( false ), hasComputeShader( true ), - worldShader( newWorldShader ) { + worldShader( newWorldShader ), + pushSkip( false ) { } public: @@ -269,6 +273,14 @@ class GLShader { virtual void SetShaderProgramUniforms( ShaderProgramDescriptor* /*shaderProgram*/ ) { }; int SelectProgram(); public: + enum Mode { + MATERIAL, + PUSH + }; + + uint32_t* uniformStorage = nullptr; + bool uniformsUpdated = true; + void MarkProgramForBuilding( int deformIndex ); GLuint GetProgram( int deformIndex, const bool buildOneShader ); void BindProgram( int deformIndex ); @@ -308,64 +320,117 @@ 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; // 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; + const GLuint _bufferSize; + GLuint _nextUniformOffset; - const bool _global; // This uniform won't go into the materials UBO if true + const UpdateType _updateType; const int _components; const bool _isTexture; + const bool _AMDSkipBindless; 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 bool global, const int components = 0, - const bool isTexture = false ) : + const UpdateType updateType, const int components = 0, + const bool isTexture = false, const bool AMDSkipBindless = false ) : _name( name ), _type( type ), _std430BaseSize( std430Size ), _std430Size( std430Size ), _std430Alignment( std430Alignment ), - _global( global ), + _bufferSize( components ? components * 4 : std430Size ), + _nextUniformOffset( components ? components * 4 : std430Size ), + _updateType( updateType ), _components( components ), _isTexture( isTexture ), + _AMDSkipBindless( AMDSkipBindless ), _shader( shader ) { _shader->RegisterUniform( this ); } - public: - virtual ~GLUniform() = default; + bool CacheValue( const 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 ); - void SetFirewallIndex( size_t offSetValue ) { - _firewallIndex = offSetValue; + currentValue = p->uniformStorage + _uniformStorageOffset; + } + + const bool updated = memcmp( currentValue, value, _bufferSize * sizeof( uint32_t ) ); + + if ( updated ) { + memcpy( currentValue, value, _bufferSize * 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; - void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { - shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, _name.c_str() ); + const bool bufferUniform = ( _shader->UseMaterialSystem() && _updateType == MATERIAL_OR_PUSH ) + || ( glConfig2.pushBufferAvailable && _updateType <= FRAME ); + + if ( bufferUniform ) { + currentValue = _shader->uniformStorage + _uniformStorageOffset; + } else { + return buffer; + } + + memcpy( buffer, currentValue, _bufferSize * sizeof( uint32_t ) ); + + return buffer + _nextUniformOffset; } - virtual size_t GetSize() { - return 0; + void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { + shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, _name.c_str() ); } }; @@ -388,6 +453,8 @@ class GLShaderManager { GLHeader GLWorldHeader; GLHeader GLEngineConstants; + std::string globalUniformBlock; + GLShaderManager() {} ~GLShaderManager(); @@ -396,6 +463,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 ); + template void LoadShader( T*& shader ) { if ( !deformShaderCount ) { @@ -405,6 +476,9 @@ class GLShaderManager { } shader = new T(); + + shader->PostProcessUniforms(); + _shaders.emplace_back( shader ); _shaderBuildQueue.push( shader ); } @@ -431,6 +505,8 @@ class GLShaderManager { void BuildAll( const bool buildOnlyMarked ); void FreeAll(); + void PostProcessGlobalUniforms(); + void BindBuffers(); private: struct InfoLogEntry { @@ -464,8 +540,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 ); @@ -489,623 +565,296 @@ 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, const bool AMDSkipBindless = false ) : GLUniform( shader, name, type, glConfig.bindlessTexturesAvailable ? 2 : 1, - glConfig.bindlessTexturesAvailable ? 2 : 1, true, 0, true ) { + glConfig.bindlessTexturesAvailable ? 2 : 1, updateType, 0, true, AMDSkipBindless ) { } inline GLint GetLocation() { ShaderProgramDescriptor* p = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - return p->uniformLocations[_locationIndex]; } public: - size_t GetSize() override { - return sizeof( GLuint64 ); - } - void SetValue( GLuint value ) { - currentValue = value; + if ( !CacheValue( &value ) ) { + return; + } } - void SetValueBindless( GLint64 value ) { - currentValueBindless = value; - - if ( glConfig.usingBindlessTextures && ( !_shader->UseMaterialSystem() || _global ) ) { - 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 { protected: - GLUniformSampler2D( GLShader* shader, const char* name ) : - GLUniformSampler( shader, name, "sampler2D" ) { + GLUniformSampler2D( GLShader* shader, const char* name, const UpdateType updateType, const bool AMDSkipBindless = false ) : + GLUniformSampler( shader, name, "sampler2D", updateType, AMDSkipBindless ) { } }; 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 ) { } inline void SetValue( int value ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - currentValue = value; + if ( !CacheValue( &value ) ) { return; } -#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: - 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 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 ) { - currentValue = value; + if ( !CacheValue( &value ) ) { return; } -#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 { 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 ) { - currentValue = value; + if ( !CacheValue( &value ) ) { return; } -#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: - size_t GetSize() override { - return sizeof( int ); - } - - private: - int currentValue = 0; }; 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 ) { } inline void SetValue( float value ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - currentValue = value; - return; - } - -#if defined( USE_UNIFORM_FIREWALL ) - float *firewall = ( float * ) &p->uniformFirewall[ _firewallIndex ]; - - if ( *firewall == value ) - { + if ( !CacheValue( &value ) ) { return; } - *firewall = value; -#endif + ShaderProgramDescriptor* p = _shader->GetProgram(); glUniform1f( p->uniformLocations[ _locationIndex ], value ); } -public: - size_t GetSize() override - { - 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 ) : - GLUniform( shader, name, "float", 1, 1, false, size ) - { - currentValue.reserve( size ); + GLUniform1fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : + GLUniform( shader, name, "float", 1, 1, updateType, size ) { } inline void SetValue( int numFloats, float *f ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - memcpy( currentValue.data(), f, numFloats * sizeof( float ) ); + if ( !CacheValue( f ) ) { return; } - 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 ) : - GLUniform( shader, name, "vec2", 2, 2, false ) - { - currentValue[0] = 0.0; - currentValue[1] = 0.0; + GLUniform2f( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "vec2", 2, 2, updateType ) { } inline void SetValue( const vec2_t v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - Vector2Copy( v, currentValue ); + if ( !CacheValue( ( void* ) v ) ) { return; } -#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 ] ); } - - size_t GetSize() override - { - 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 bool global = false ) : - GLUniform( shader, name, "vec3", 3, 4, global ) - { - currentValue[0] = 0.0; - currentValue[1] = 0.0; - currentValue[2] = 0.0; + GLUniform3f( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "vec3", 3, 4, updateType ) { } inline void SetValue( const vec3_t v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - VectorCopy( v, currentValue ); + if ( !CacheValue( ( void* ) v ) ) { return; } -#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: - size_t GetSize() override - { - 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 bool global = false ) : - GLUniform( shader, name, "vec4", 4, 4, global ) - { - currentValue[0] = 0.0; - currentValue[1] = 0.0; - currentValue[2] = 0.0; - currentValue[3] = 0.0; + GLUniform4f( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "vec4", 4, 4, updateType ) { } inline void SetValue( const vec4_t v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - Vector4Copy( v, currentValue ); + if ( !CacheValue( ( void* ) v ) ) { return; } -#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: - size_t GetSize() override - { - 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 ) : - GLUniform( shader, name, "vec4", 4, 4, false, size ) - { - currentValue.reserve( size ); + GLUniform4fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : + GLUniform( shader, name, "vec4", 4, 4, updateType, size ) { } inline void SetValue( int numV, vec4_t *v ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - memcpy( currentValue.data(), v, numV * sizeof( vec4_t ) ); + if ( !CacheValue( v ) ) { return; } + 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 bool global = false ) : - GLUniform( shader, name, "mat4", 16, 4, global ) - { - MatrixIdentity( currentValue ); + GLUniformMatrix4f( GLShader *shader, const char *name, const UpdateType updateType ) : + GLUniform( shader, name, "mat4", 16, 4, updateType ) { } inline void SetValue( GLboolean transpose, const matrix_t m ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - MatrixCopy( m, currentValue ); + if ( !CacheValue( ( void* ) m ) ) { return; } -#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: - size_t GetSize() override - { - 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 { 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 ); - } + vec_t value[12] {}; + memcpy( value, m, 6 * sizeof( vec_t ) ); - if ( _shader->UseMaterialSystem() && !_global ) { - memcpy( currentValue, m, 6 * sizeof( float ) ); + if ( !CacheValue( value ) ) { return; } + 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 ) : - GLUniform( shader, name, "mat4", 16, 4, false, size ) - { - currentValue.reserve( size * 16 ); + GLUniformMatrix4fv( GLShader *shader, const char *name, const int size, const UpdateType updateType ) : + GLUniform( shader, name, "mat4", 16, 4, updateType, size ) { } inline void SetValue( int numMatrices, GLboolean transpose, const matrix_t *m ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - memcpy( currentValue.data(), m, numMatrices * sizeof( matrix_t ) ); + if ( !CacheValue( ( void* ) m ) ) { return; } + 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 { 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 ) { } inline void SetValue( int numMatrices, GLboolean transpose, const float *m ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - - if ( _global || !_shader->UseMaterialSystem() ) { - DAEMON_ASSERT_EQ( p, glState.currentProgram ); - } - - if ( _shader->UseMaterialSystem() && !_global ) { - memcpy( currentValue.data(), m, numMatrices * sizeof( matrix_t ) ); + if ( !CacheValue( ( void* ) m ) ) { return; } - 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 @@ -1674,7 +1423,7 @@ class u_ColorMap : GLUniformSampler2D { public: u_ColorMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_ColorMap" ) { + GLUniformSampler2D( shader, "u_ColorMap", PUSH ) { } void SetUniform_ColorMapBindless( GLuint64 bindlessHandle ) { @@ -1686,7 +1435,7 @@ class u_ColorMap3D : GLUniformSampler3D { public: u_ColorMap3D( GLShader* shader ) : - GLUniformSampler3D( shader, "u_ColorMap3D" ) { + GLUniformSampler3D( shader, "u_ColorMap3D", CONST ) { } void SetUniform_ColorMap3DBindless( GLuint64 bindlessHandle ) { @@ -1698,7 +1447,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 ) { @@ -1710,7 +1459,7 @@ class u_DepthMap : GLUniformSampler2D { public: u_DepthMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthMap" ) { + GLUniformSampler2D( shader, "u_DepthMap", CONST, true ) { } void SetUniform_DepthMapBindless( GLuint64 bindlessHandle ) { @@ -1722,7 +1471,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 ) { @@ -1734,7 +1483,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 ) { @@ -1746,7 +1495,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 ) { @@ -1758,7 +1507,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 ) { @@ -1770,7 +1519,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 ) { @@ -1782,7 +1531,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 ) { @@ -1794,7 +1543,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 ) { @@ -1806,7 +1555,7 @@ class u_PortalMap : GLUniformSampler2D { public: u_PortalMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_PortalMap" ) { + GLUniformSampler2D( shader, "u_PortalMap", CONST ) { } void SetUniform_PortalMapBindless( GLuint64 bindlessHandle ) { @@ -1818,7 +1567,7 @@ class u_CloudMap : GLUniformSampler2D { public: u_CloudMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_CloudMap" ) { + GLUniformSampler2D( shader, "u_CloudMap", PUSH ) { } void SetUniform_CloudMapBindless( GLuint64 bindlessHandle ) { @@ -1830,7 +1579,7 @@ class u_DepthTile1 : GLUniformSampler2D { public: u_DepthTile1( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthTile1" ) { + GLUniformSampler2D( shader, "u_DepthTile1", CONST ) { } void SetUniform_DepthTile1Bindless( GLuint64 bindlessHandle ) { @@ -1842,7 +1591,7 @@ class u_DepthTile2 : GLUniformSampler2D { public: u_DepthTile2( GLShader* shader ) : - GLUniformSampler2D( shader, "u_DepthTile2" ) { + GLUniformSampler2D( shader, "u_DepthTile2", CONST ) { } void SetUniform_DepthTile2Bindless( GLuint64 bindlessHandle ) { @@ -1854,7 +1603,7 @@ class u_LightTiles : GLUniformSampler3D { public: u_LightTiles( GLShader* shader ) : - GLUniformSampler3D( shader, "u_LightTiles" ) { + GLUniformSampler3D( shader, "u_LightTiles", CONST ) { } void SetUniform_LightTilesBindless( GLuint64 bindlessHandle ) { @@ -1866,7 +1615,7 @@ class u_LightGrid1 : GLUniformSampler3D { public: u_LightGrid1( GLShader* shader ) : - GLUniformSampler3D( shader, "u_LightGrid1" ) { + GLUniformSampler3D( shader, "u_LightGrid1", CONST ) { } void SetUniform_LightGrid1Bindless( GLuint64 bindlessHandle ) { @@ -1878,7 +1627,7 @@ class u_LightGrid2 : GLUniformSampler3D { public: u_LightGrid2( GLShader* shader ) : - GLUniformSampler3D( shader, "u_LightGrid2" ) { + GLUniformSampler3D( shader, "u_LightGrid2", CONST ) { } void SetUniform_LightGrid2Bindless( GLuint64 bindlessHandle ) { @@ -1890,7 +1639,7 @@ class u_EnvironmentMap0 : GLUniformSamplerCube { public: u_EnvironmentMap0( GLShader* shader ) : - GLUniformSamplerCube( shader, "u_EnvironmentMap0" ) { + GLUniformSamplerCube( shader, "u_EnvironmentMap0", PUSH ) { } void SetUniform_EnvironmentMap0Bindless( GLuint64 bindlessHandle ) { @@ -1902,7 +1651,7 @@ class u_EnvironmentMap1 : GLUniformSamplerCube { public: u_EnvironmentMap1( GLShader* shader ) : - GLUniformSamplerCube( shader, "u_EnvironmentMap1" ) { + GLUniformSamplerCube( shader, "u_EnvironmentMap1", PUSH ) { } void SetUniform_EnvironmentMap1Bindless( GLuint64 bindlessHandle ) { @@ -1914,7 +1663,7 @@ class u_CurrentMap : GLUniformSampler2D { public: u_CurrentMap( GLShader* shader ) : - GLUniformSampler2D( shader, "u_CurrentMap" ) { + GLUniformSampler2D( shader, "u_CurrentMap", PUSH ) { } void SetUniform_CurrentMapBindless( GLuint64 bindlessHandle ) { @@ -1927,7 +1676,7 @@ class u_TextureMatrix : { public: u_TextureMatrix( GLShader *shader ) : - GLUniformMatrix32f( shader, "u_TextureMatrix", true ) + GLUniformMatrix32f( shader, "u_TextureMatrix", TEXDATA_OR_PUSH ) { } @@ -1951,7 +1700,7 @@ class u_AlphaThreshold : { public: u_AlphaThreshold( GLShader *shader ) : - GLUniform1f( shader, "u_AlphaThreshold" ) + GLUniform1f( shader, "u_AlphaThreshold", MATERIAL_OR_PUSH ) { } @@ -2009,7 +1758,7 @@ class u_ViewOrigin : { public: u_ViewOrigin( GLShader *shader ) : - GLUniform3f( shader, "u_ViewOrigin", true ) + GLUniform3f( shader, "u_ViewOrigin", PUSH ) { } @@ -2024,7 +1773,7 @@ class u_RefractionIndex : { public: u_RefractionIndex( GLShader *shader ) : - GLUniform1f( shader, "u_RefractionIndex" ) + GLUniform1f( shader, "u_RefractionIndex", MATERIAL_OR_PUSH ) { } @@ -2039,7 +1788,7 @@ class u_FresnelPower : { public: u_FresnelPower( GLShader *shader ) : - GLUniform1f( shader, "u_FresnelPower" ) + GLUniform1f( shader, "u_FresnelPower", MATERIAL_OR_PUSH ) { } @@ -2054,7 +1803,7 @@ class u_FresnelScale : { public: u_FresnelScale( GLShader *shader ) : - GLUniform1f( shader, "u_FresnelScale" ) + GLUniform1f( shader, "u_FresnelScale", MATERIAL_OR_PUSH ) { } @@ -2069,7 +1818,7 @@ class u_FresnelBias : { public: u_FresnelBias( GLShader *shader ) : - GLUniform1f( shader, "u_FresnelBias" ) + GLUniform1f( shader, "u_FresnelBias", MATERIAL_OR_PUSH ) { } @@ -2084,7 +1833,7 @@ class u_NormalScale : { public: u_NormalScale( GLShader *shader ) : - GLUniform3f( shader, "u_NormalScale" ) + GLUniform3f( shader, "u_NormalScale", MATERIAL_OR_PUSH ) { } @@ -2100,7 +1849,7 @@ class u_FogDensity : { public: u_FogDensity( GLShader *shader ) : - GLUniform1f( shader, "u_FogDensity", true ) + GLUniform1f( shader, "u_FogDensity", PUSH ) { } @@ -2115,7 +1864,7 @@ class u_FogColor : { public: u_FogColor( GLShader *shader ) : - GLUniform3f( shader, "u_FogColor" ) + GLUniform3f( shader, "u_FogColor", MATERIAL_OR_PUSH ) { } @@ -2130,7 +1879,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 ) { @@ -2143,7 +1892,7 @@ class u_Color_Float : { public: u_Color_Float( GLShader *shader ) : - GLUniform4f( shader, "u_Color" ) + GLUniform4f( shader, "u_Color", LEGACY ) { } @@ -2158,7 +1907,7 @@ class u_Color_Uint : { public: u_Color_Uint( GLShader *shader ) : - GLUniform1ui( shader, "u_Color" ) + GLUniform1ui( shader, "u_Color", MATERIAL_OR_PUSH ) { } @@ -2185,7 +1934,7 @@ class u_ColorGlobal_Float : { public: u_ColorGlobal_Float( GLShader *shader ) : - GLUniform4f( shader, "u_ColorGlobal", true ) + GLUniform4f( shader, "u_ColorGlobal", LEGACY ) { } @@ -2199,7 +1948,7 @@ class u_ColorGlobal_Uint : GLUniform1ui { public: u_ColorGlobal_Uint( GLShader* shader ) : - GLUniform1ui( shader, "u_ColorGlobal", true ) { + GLUniform1ui( shader, "u_ColorGlobal", PUSH ) { } void SetUniform_ColorGlobal_Uint( const Color::Color& color ) { @@ -2223,7 +1972,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 ) { @@ -2235,7 +1984,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 ) { @@ -2247,7 +1996,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 ) { @@ -2259,7 +2008,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 ) { @@ -2271,7 +2020,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 ) { @@ -2283,7 +2032,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 ) { @@ -2295,7 +2044,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 ) { @@ -2307,7 +2056,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 ) { @@ -2319,7 +2068,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 ) { @@ -2331,7 +2080,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 ) { @@ -2343,7 +2092,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 ) { @@ -2355,7 +2104,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 ) { @@ -2367,7 +2116,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 ) { @@ -2379,7 +2128,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 ) { @@ -2391,7 +2140,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] ) { @@ -2403,7 +2152,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 ) { @@ -2415,7 +2164,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 ) { @@ -2429,7 +2178,7 @@ class u_ProfilerZero : GLUniform1f { public: u_ProfilerZero( GLShader* shader ) : - GLUniform1f( shader, "u_ProfilerZero", true ) { + GLUniform1f( shader, "u_ProfilerZero", CONST ) { } void SetUniform_ProfilerZero() { @@ -2441,7 +2190,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 ) { @@ -2454,7 +2203,7 @@ class u_ModelMatrix : { public: u_ModelMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelMatrix", true ) + GLUniformMatrix4f( shader, "u_ModelMatrix", PUSH ) { } @@ -2469,7 +2218,7 @@ class u_ViewMatrix : { public: u_ViewMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ViewMatrix" ) + GLUniformMatrix4f( shader, "u_ViewMatrix", PUSH ) { } @@ -2484,7 +2233,7 @@ class u_ModelViewMatrix : { public: u_ModelViewMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelViewMatrix" ) + GLUniformMatrix4f( shader, "u_ModelViewMatrix", PUSH ) { } @@ -2499,7 +2248,7 @@ class u_ModelViewMatrixTranspose : { public: u_ModelViewMatrixTranspose( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelViewMatrixTranspose", true ) + GLUniformMatrix4f( shader, "u_ModelViewMatrixTranspose", PUSH ) { } @@ -2514,7 +2263,7 @@ class u_ProjectionMatrixTranspose : { public: u_ProjectionMatrixTranspose( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ProjectionMatrixTranspose", true ) + GLUniformMatrix4f( shader, "u_ProjectionMatrixTranspose", PUSH ) { } @@ -2529,7 +2278,7 @@ class u_ModelViewProjectionMatrix : { public: u_ModelViewProjectionMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_ModelViewProjectionMatrix", true ) + GLUniformMatrix4f( shader, "u_ModelViewProjectionMatrix", PUSH ) { } @@ -2544,7 +2293,7 @@ class u_UnprojectMatrix : { public: u_UnprojectMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_UnprojectMatrix", true ) + GLUniformMatrix4f( shader, "u_UnprojectMatrix", PUSH ) { } @@ -2558,7 +2307,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 ) { @@ -2571,7 +2320,7 @@ class u_Bones : { public: u_Bones( GLShader *shader ) : - GLUniform4fv( shader, "u_Bones", MAX_BONES ) + GLUniform4fv( shader, "u_Bones", MAX_BONES * 2, PUSH ) { } @@ -2586,7 +2335,7 @@ class u_VertexInterpolation : { public: u_VertexInterpolation( GLShader *shader ) : - GLUniform1f( shader, "u_VertexInterpolation" ) + GLUniform1f( shader, "u_VertexInterpolation", PUSH ) { } @@ -2601,7 +2350,7 @@ class u_InversePortalRange : { public: u_InversePortalRange( GLShader *shader ) : - GLUniform1f( shader, "u_InversePortalRange" ) + GLUniform1f( shader, "u_InversePortalRange", PUSH ) { } @@ -2616,7 +2365,7 @@ class u_DepthScale : { public: u_DepthScale( GLShader *shader ) : - GLUniform1f( shader, "u_DepthScale" ) + GLUniform1f( shader, "u_DepthScale", MATERIAL_OR_PUSH ) { } @@ -2631,7 +2380,7 @@ class u_ReliefDepthScale : { public: u_ReliefDepthScale( GLShader *shader ) : - GLUniform1f( shader, "u_ReliefDepthScale" ) + GLUniform1f( shader, "u_ReliefDepthScale", MATERIAL_OR_PUSH ) { } @@ -2646,7 +2395,7 @@ class u_ReliefOffsetBias : { public: u_ReliefOffsetBias( GLShader *shader ) : - GLUniform1f( shader, "u_ReliefOffsetBias" ) + GLUniform1f( shader, "u_ReliefOffsetBias", MATERIAL_OR_PUSH ) { } @@ -2661,7 +2410,7 @@ class u_EnvironmentInterpolation : { public: u_EnvironmentInterpolation( GLShader *shader ) : - GLUniform1f( shader, "u_EnvironmentInterpolation", true ) + GLUniform1f( shader, "u_EnvironmentInterpolation", PUSH ) { } @@ -2676,7 +2425,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 ) { } @@ -2691,7 +2440,7 @@ class u_GlobalLightFactor : { public: u_GlobalLightFactor( GLShader *shader ) : - GLUniform1f( shader, "u_GlobalLightFactor" ) + GLUniform1f( shader, "u_GlobalLightFactor", CONST ) { } @@ -2716,7 +2465,7 @@ class u_ColorModulate : { public: u_ColorModulate( GLShader *shader ) : - GLUniform4f( shader, "u_ColorModulate" ) + GLUniform4f( shader, "u_ColorModulate", FRAME ) { } @@ -2799,7 +2548,7 @@ class u_ColorModulateColorGen_Float : { public: u_ColorModulateColorGen_Float( GLShader* shader ) : - GLUniform4f( shader, "u_ColorModulateColorGen" ) + GLUniform4f( shader, "u_ColorModulateColorGen", LEGACY ) { } @@ -2831,7 +2580,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( @@ -2905,7 +2654,7 @@ class u_FogDepthVector : { public: u_FogDepthVector( GLShader *shader ) : - GLUniform4f( shader, "u_FogDepthVector", true ) + GLUniform4f( shader, "u_FogDepthVector", PUSH ) { } @@ -2920,7 +2669,7 @@ class u_FogEyeT : { public: u_FogEyeT( GLShader *shader ) : - GLUniform1f( shader, "u_FogEyeT", true ) + GLUniform1f( shader, "u_FogEyeT", PUSH ) { } @@ -2934,7 +2683,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 ) { @@ -2947,7 +2696,7 @@ class u_DeformMagnitude : { public: u_DeformMagnitude( GLShader *shader ) : - GLUniform1f( shader, "u_DeformMagnitude" ) + GLUniform1f( shader, "u_DeformMagnitude", MATERIAL_OR_PUSH ) { } @@ -2962,7 +2711,7 @@ class u_blurVec : { public: u_blurVec( GLShader *shader ) : - GLUniform3f( shader, "u_blurVec" ) + GLUniform3f( shader, "u_blurVec", FRAME ) { } @@ -2976,7 +2725,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 ) { @@ -2989,7 +2738,7 @@ class u_TexScale : { public: u_TexScale( GLShader *shader ) : - GLUniform2f( shader, "u_TexScale" ) + GLUniform2f( shader, "u_TexScale", PUSH ) { } @@ -3004,7 +2753,7 @@ class u_SpecularExponent : { public: u_SpecularExponent( GLShader *shader ) : - GLUniform2f( shader, "u_SpecularExponent" ) + GLUniform2f( shader, "u_SpecularExponent", MATERIAL_OR_PUSH ) { } @@ -3024,7 +2773,7 @@ class u_InverseGamma : { public: u_InverseGamma( GLShader *shader ) : - GLUniform1f( shader, "u_InverseGamma" ) + GLUniform1f( shader, "u_InverseGamma", FRAME ) { } @@ -3038,7 +2787,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 ) { @@ -3050,7 +2799,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 ) { @@ -3062,7 +2811,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 ) { @@ -3074,7 +2823,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 ) { @@ -3087,7 +2836,7 @@ class u_LightGridOrigin : { public: u_LightGridOrigin( GLShader *shader ) : - GLUniform3f( shader, "u_LightGridOrigin", true ) + GLUniform3f( shader, "u_LightGridOrigin", CONST ) { } @@ -3102,7 +2851,7 @@ class u_LightGridScale : { public: u_LightGridScale( GLShader *shader ) : - GLUniform3f( shader, "u_LightGridScale", true ) + GLUniform3f( shader, "u_LightGridScale", CONST ) { } @@ -3117,7 +2866,7 @@ class u_zFar : { public: u_zFar( GLShader *shader ) : - GLUniform3f( shader, "u_zFar" ) + GLUniform3f( shader, "u_zFar", PUSH ) { } @@ -3131,7 +2880,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 ) { @@ -3144,7 +2893,7 @@ class u_numLights : { public: u_numLights( GLShader *shader ) : - GLUniform1i( shader, "u_numLights", true ) + GLUniform1i( shader, "u_numLights", FRAME ) { } @@ -3159,7 +2908,7 @@ class u_lightLayer : { public: u_lightLayer( GLShader *shader ) : - GLUniform1i( shader, "u_lightLayer" ) + GLUniform1i( shader, "u_lightLayer", PUSH ) { } @@ -3746,6 +3495,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(); @@ -3785,6 +3570,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/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..eb9c9263c8 100644 --- a/src/engine/renderer/glsl_source/depthReduction_cp.glsl +++ b/src/engine/renderer/glsl_source/depthReduction_cp.glsl @@ -34,12 +34,14 @@ 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 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; @@ -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..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; @@ -37,6 +39,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/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/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..d436a617e6 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(FOGMAP_GLSL) + sampler2D u_FogMap = sampler2D( u_FogMap_initial ); + #endif // !FOGMAP_GLSL + + #if defined(LIQUID_GLSL) + sampler2D u_PortalMap = sampler2D( u_PortalMap_initial ); + #endif // !LIQUID_GLSL + + #if defined(DEPTHMAP_GLSL) && !defined(DRIVER_AMD_MESA) + 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..8b5959a254 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 ); } @@ -2789,6 +2789,44 @@ 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 ---" ); + + globalUBOProxy->SetUniform_blurVec( tr.refdef.blurVec ); + globalUBOProxy->SetUniform_numLights( tr.refdef.numLights ); + + globalUBOProxy->SetUniform_ColorModulate( tr.viewParms.gradingWeights ); + globalUBOProxy->SetUniform_InverseGamma( 1.0f / r_gamma->value ); + + 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(), + 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 ( glConfig.usingMaterialSystem ) { + materialSystem.SetFrameUniforms(); + } + + if ( !globalUBOProxy->uniformsUpdated ) { + return; + } + + uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::FRAME ); + globalUBOProxy->WriteUniformsToBuffer( data, GLShader::PUSH, GLUniform::FRAME ); + + pushBuffer.PushGlobalUniforms(); +} + /* ============================================================================ @@ -3787,6 +3825,11 @@ void RB_ExecuteRenderCommands( const void *data ) materialSystem.frameStart = true; + + if ( glConfig.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..287f0d410e 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -4641,6 +4641,62 @@ static void SetWorldLight() { } } +static void SetConstUniforms() { + GLIMP_LOGCOMMENT( "--- SetConstUniforms ---" ); + + 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 ( glConfig.usingBindlessTextures ) { + if ( glConfig.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 ( glConfig.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 ( glConfig.usingMaterialSystem ) { + materialSystem.SetConstUniforms(); + } + + if ( !globalUBOProxy->uniformsUpdated ) { + return; + } + + uint32_t* data = pushBuffer.MapGlobalUniformData( GLUniform::CONST ); + globalUBOProxy->WriteUniformsToBuffer( data, GLShader::PUSH, GLUniform::CONST ); + + pushBuffer.PushGlobalUniforms(); +} + /* ================= RE_LoadWorldMap @@ -4796,6 +4852,10 @@ void RE_LoadWorldMap( const char *name ) tr.loadingMap = ""; GLSL_InitWorldShaders(); + if ( glConfig.pushBufferAvailable ) { + SetConstUniforms(); + } + if ( glConfig.reflectionMappingAvailable ) { tr.cubeProbeSpacing = r_cubeProbeSpacing.Get(); 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/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/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 2431c68d7e..d783650409 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 ) { @@ -380,6 +382,7 @@ static void GLSL_InitGPUShadersOrError() gl_fxaaShader->MarkProgramForBuilding( 0 ); } + gl_shaderManager.PostProcessGlobalUniforms(); gl_shaderManager.InitShaders(); if ( r_lazyShaders.Get() == 0 ) @@ -465,6 +468,7 @@ void GLSL_ShutdownGPUShaders() gl_genericShader = nullptr; gl_genericShaderMaterial = nullptr; + globalUBOProxy = nullptr; gl_cullShader = nullptr; gl_depthReductionShader = nullptr; gl_clearSurfacesShader = nullptr; diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index e68a0109c6..6db30d4003 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 ( glConfig.pushBufferAvailable ) { + pushBuffer.InitGLBuffers(); + } + GL_CheckErrors(); } @@ -837,6 +841,10 @@ void R_ShutdownVBOs() stagingBuffer.FreeGLBuffer(); } + if ( glConfig.pushBufferAvailable ) { + pushBuffer.FreeGLBuffers(); + } + tess.verts = tess.vertsBuffer = nullptr; tess.indexes = tess.indexesBuffer = nullptr; } diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index e4fc7dc59b..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", @@ -2548,6 +2552,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 +2566,7 @@ static void GLimp_InitExtensions() && glConfig.gpuShader4Available && glConfig.indirectParametersAvailable && glConfig.multiDrawIndirectAvailable + && glConfig.pushBufferAvailable && glConfig.shaderAtomicCountersAvailable && glConfig.shaderDrawParametersAvailable && glConfig.shaderImageLoadStoreAvailable