From ef863cfc35eb1b2eb720486a9ba347b00b4a534a Mon Sep 17 00:00:00 2001 From: VReaperV Date: Tue, 25 Feb 2025 12:22:27 +0300 Subject: [PATCH 1/6] Add debug info for shader compilation/link time Also make sure to display the full shader name rather than just the main shader. --- src/engine/renderer/gl_shader.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 1508b6bb6d..676e14081b 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1321,9 +1321,11 @@ void GLShaderManager::CompileGPUShaders( GLShader *shader, shaderProgram_t *prog } Log::Debug( "building %s shader permutation with macro: %s", - shader->GetMainShaderName(), + shader->GetName(), compileMacros.empty() ? "none" : compileMacros ); + const int start = Sys::Milliseconds(); + // add them std::string vertexShaderTextWithMacros = macrosString + shader->_vertexShaderText; std::string fragmentShaderTextWithMacros = macrosString + shader->_fragmentShaderText; @@ -1356,6 +1358,8 @@ void GLShaderManager::CompileGPUShaders( GLShader *shader, shaderProgram_t *prog &GLWorldHeader }, GL_COMPUTE_SHADER ); } + + Log::Debug( "Compilation: %i ms", Sys::Milliseconds() - start ); } void GLShaderManager::CompileAndLinkGPUShaderProgram( GLShader *shader, shaderProgram_t *program, @@ -1375,8 +1379,11 @@ void GLShaderManager::CompileAndLinkGPUShaderProgram( GLShader *shader, shaderPr glAttachShader( program->program, program->CS ); } + const int start = Sys::Milliseconds(); BindAttribLocations( program->program ); LinkProgram( program->program ); + + Log::Debug( "Link: %i ms", Sys::Milliseconds() - start ); } // This will generate all the extra code for material system shaders From ffefe5233c8c703f4f635bc0519ca3080e1789a1 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Thu, 27 Feb 2025 04:21:46 +0300 Subject: [PATCH 2/6] Improve shader building Previously, the GLSL shader building was done in the following manner: 1. When the renderer is started, some of the shader source was initialised/processed. This included the main shader text, #insert's, and material system post-processing. 2. When `buildAll()` was called, all permutations with empty deform shaders were built. The deform shaders themselves are loaded either at the start (for the default, empty one), or when the map itself is being loaded. These permutations included adding macros to shaders in the form of `#ifndef #define #endif`, and attaching the default deform shader. When possible, shader program binaries were saved/loaded to/from disk. 3. UI shader and non-0 deform shaders were built on-demand. There were multiple issues with that system: 1. Shader caches were unreliable. This is likely because the checksum was calculated *before* macros and such were added to the shader text. 2. Every shader permutation was always compiled and linked every time. 3. Shader programs with non-0 deformVertexes were never cached. This commit changes the underlying system to use an `std::vector` of shader program descriptors, and another one for shader descriptors. The initialisation/building of shaders is now more generic for each type, and as a result each unique shader is only compiled once. The permutations are still linked each time (unless downloaded from cache), but this change lays the foundation to easily add shader pipelines, which would solve this problem. Shader cache binaries are now identified by each shader compiled into the corresponding shader program, which allows caching non-0 deformVertexes too. This also fixes the incorrect #line numbers emitted by #insert due to macros and such being added after #insert is processed. Also adds more information into how many shader/shader programs were built and how much time it took (there's currently a small discrepancy, because the output is shown at the end of `BuildAll()`, but is gathered every time `BuildPermutation()` or `InitShader()` is called). --- src/engine/renderer/gl_shader.cpp | 1238 +++++++++-------- src/engine/renderer/gl_shader.h | 525 ++++--- src/engine/renderer/glsl_source/cull_cp.glsl | 5 + .../renderer/glsl_source/fogQuake3_vp.glsl | 6 +- .../renderer/glsl_source/generic_vp.glsl | 10 +- .../renderer/glsl_source/lightMapping_vp.glsl | 4 +- .../renderer/glsl_source/material_cp.glsl | 4 +- src/engine/renderer/tr_backend.cpp | 6 +- src/engine/renderer/tr_bsp.cpp | 2 + src/engine/renderer/tr_init.cpp | 4 +- src/engine/renderer/tr_local.h | 18 +- src/engine/renderer/tr_main.cpp | 2 +- src/engine/renderer/tr_shade.cpp | 82 +- src/engine/renderer/tr_shader.cpp | 2 +- 14 files changed, 1072 insertions(+), 836 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 676e14081b..88acd065e9 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -231,33 +231,56 @@ std::string GetShaderPath() GLShaderManager::~GLShaderManager() = default; -void GLShaderManager::freeAll() -{ +void GLShaderManager::FreeAll() { _shaders.clear(); - for ( GLint sh : _deformShaders ) - glDeleteShader( sh ); - - _deformShaders.clear(); + deformShaderCount = 0; _deformShaderLookup.clear(); + for ( const ShaderProgramDescriptor& program : shaderProgramDescriptors ) { + if ( program.id ) { + glDeleteProgram( program.id ); + } + + if ( program.uniformLocations ) { + Z_Free( program.uniformLocations ); + } + + if ( program.uniformBlockIndexes ) { + Z_Free( program.uniformBlockIndexes ); + } + + if ( program.uniformFirewall ) { + Z_Free( program.uniformFirewall ); + } + } + + shaderProgramDescriptors.clear(); + + for ( const ShaderDescriptor& shader : shaderDescriptors ) { + if ( shader.id ) { + glDeleteShader( shader.id ); + } + } + + shaderDescriptors.clear(); + while ( !_shaderBuildQueue.empty() ) { _shaderBuildQueue.pop(); } } -void GLShaderManager::UpdateShaderProgramUniformLocations( GLShader *shader, shaderProgram_t *shaderProgram ) const -{ +void GLShaderManager::UpdateShaderProgramUniformLocations( GLShader* shader, ShaderProgramDescriptor* shaderProgram ) const { size_t uniformSize = shader->_uniformStorageSize; size_t numUniforms = shader->_uniforms.size(); size_t numUniformBlocks = shader->_uniformBlocks.size(); // create buffer for storing uniform locations - shaderProgram->uniformLocations = ( GLint * ) Z_Malloc( sizeof( GLint ) * numUniforms ); + shaderProgram->uniformLocations = ( GLint* ) Z_Malloc( sizeof( GLint ) * numUniforms ); // create buffer for uniform firewall - shaderProgram->uniformFirewall = ( byte * ) Z_Malloc( uniformSize ); + shaderProgram->uniformFirewall = ( byte* ) Z_Malloc( uniformSize ); // update uniforms for (GLUniform *uniform : shader->_uniforms) @@ -267,7 +290,7 @@ void GLShaderManager::UpdateShaderProgramUniformLocations( GLShader *shader, sha if( glConfig2.uniformBufferObjectAvailable ) { // create buffer for storing uniform block indexes - shaderProgram->uniformBlockIndexes = ( GLuint * ) Z_Malloc( sizeof( GLuint ) * numUniformBlocks ); + shaderProgram->uniformBlockIndexes = ( GLuint* ) Z_Malloc( sizeof( GLuint ) * numUniformBlocks ); // update uniform blocks for (GLUniformBlock *uniformBlock : shader->_uniformBlocks) @@ -868,36 +891,39 @@ void GLShaderManager::GenerateWorldHeaders() { GLWorldHeader = GLHeader( "GLWorldHeader", GenWorldHeader(), this ); } -std::string GLShaderManager::BuildDeformShaderText( const std::string& steps ) -{ +std::string GLShaderManager::GetDeformShaderName( const int index ) { + if ( ( !tr.world && !tr.loadingMap.size() ) || !index ) { + return Str::Format( "deformVertexes_%i", index ); + } + + if ( !tr.world ) { + return Str::Format( "deformVertexes_%s_%i", tr.loadingMap, index ); + } + + return Str::Format( "deformVertexes_%s_%i", tr.world->baseName, index ); +} + +std::string GLShaderManager::BuildDeformShaderText( const std::string& steps ) { std::string shaderText; shaderText = steps + "\n"; + shaderText += GetShaderText( "deformVertexes_vp.glsl" ); - // We added a lot of stuff but if we do something bad - // in the GLSL shaders then we want the proper line - // so we have to reset the line counting. - shaderText += "#line 0\n"; - shaderText += GetShaderText("deformVertexes_vp.glsl"); return shaderText; } -int GLShaderManager::getDeformShaderIndex( deformStage_t *deforms, int numDeforms ) -{ +int GLShaderManager::GetDeformShaderIndex( deformStage_t *deforms, int numDeforms ) { std::string steps = BuildDeformSteps( deforms, numDeforms ); - int index = _deformShaderLookup[ steps ] - 1; + uint32_t index = _deformShaderLookup[steps]; - if( index < 0 ) - { - // compile new deform shader + if( !index ) { std::string shaderText = GLShaderManager::BuildDeformShaderText( steps ); - _deformShaders.push_back(CompileShader( "deformVertexes", - shaderText, - { &GLVersionDeclaration, - &GLVertexHeader }, - GL_VERTEX_SHADER ) ); - index = _deformShaders.size(); - _deformShaderLookup[ steps ] = index--; + index = deformShaderCount; + FindShader( GetDeformShaderName( index ), shaderText, GL_VERTEX_SHADER, + std::vector { &GLVersionDeclaration, &GLVertexHeader } ); + + deformShaderCount++; + _deformShaderLookup[steps] = deformShaderCount; } return index; @@ -940,102 +966,257 @@ static bool IsUnusedPermutation( const char *compileMacros ) return false; } -// returns whether something was really built (using a cached one counts) -bool GLShaderManager::buildPermutation( GLShader *shader, int macroIndex, int deformIndex ) -{ - std::string compileMacros; +void GLShaderManager::BuildShader( ShaderDescriptor* descriptor ) { + if ( descriptor->id ) { + return; + } + + const int start = Sys::Milliseconds(); + + const GLchar* text[1] = { descriptor->shaderSource.data() }; + GLint length[1] = { ( GLint ) descriptor->shaderSource.size() }; + + GLuint shader = glCreateShader( descriptor->type ); + GL_CheckErrors(); + + glShaderSource( shader, 1, text, length ); + glCompileShader( shader ); + + GL_CheckErrors(); + + GLint compiled; + glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); + + if ( !compiled ) { + std::string log = GetInfoLog( shader ); + std::vector infoLog = ParseInfoLog( log ); + PrintShaderSource( descriptor->name, shader, infoLog ); + + Log::Warn( "Compile log:\n%s", log ); + + switch ( descriptor->type ) { + case GL_VERTEX_SHADER: + ThrowShaderError( Str::Format( "Couldn't compile vertex shader: %s", descriptor->name ) ); + case GL_FRAGMENT_SHADER: + ThrowShaderError( Str::Format( "Couldn't compile fragment shader: %s", descriptor->name ) ); + case GL_COMPUTE_SHADER: + ThrowShaderError( Str::Format( "Couldn't compile compute shader: %s", descriptor->name ) ); + default: + break; + } + } + + descriptor->id = shader; + + const int time = Sys::Milliseconds() - start; + compileTime += time; + compileCount++; + Log::Debug( "Compilation: %i", time ); +} + +void GLShaderManager::BuildShaderProgram( ShaderProgramDescriptor* descriptor ) { + if ( descriptor->id ) { + return; + } + + const int start = Sys::Milliseconds(); + + GLuint program = glCreateProgram(); + GL_CheckErrors(); + + for ( const GLuint& shader : descriptor->shaders ) { + if ( shader ) { + glAttachShader( program, shader ); + } else { + break; + } + } + GL_CheckErrors(); + + BindAttribLocations( program ); + + if ( glConfig2.getProgramBinaryAvailable ) { + glProgramParameteri( program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE ); + } + + GLint linked; + glLinkProgram( program ); + + glGetProgramiv( program, GL_LINK_STATUS, &linked ); + + if ( !linked ) { + Log::Warn( "Link log:" ); + Log::Warn( GetInfoLog( program ) ); + ThrowShaderError( "Shader program failed to link!" ); + } + + descriptor->id = program; + + const int time = Sys::Milliseconds() - start; + linkTime += time; + linkCount++; + Log::Debug( "Program creation + linking: %i", time ); +} + +ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vector& shaders, const std::string& mainShader ) { + std::vector::iterator it = std::find_if( shaderProgramDescriptors.begin(), shaderProgramDescriptors.end(), + [&]( const ShaderProgramDescriptor& program ) { + for ( const ShaderEntry& shader : shaders ) { + if ( std::find( program.shaderNames, program.shaderNames + program.shaderCount, shader ) + == program.shaderNames + program.shaderCount ) { + return false; + } + } + + return true; + } + ); + + if ( it == shaderProgramDescriptors.end() ) { + std::sort( shaders.begin(), shaders.end(), + []( const ShaderEntry& lhs, const ShaderEntry& rhs ) { + return lhs.name < rhs.name; + } + ); + + ShaderProgramDescriptor desc; + std::string combinedShaderText; + std::vector buildQueue; + buildQueue.reserve( shaders.size() ); + + for ( const ShaderEntry& shader : shaders ) { + std::vector::iterator shaderIt = std::find_if( shaderDescriptors.begin(), shaderDescriptors.end(), + [&]( const ShaderDescriptor& other ) { + return shader.type == other.type && shader.macro == other.macro && shader.name == other.name; + } + ); + + if ( shaderIt == shaderDescriptors.end() ) { + ThrowShaderError( Str::Format( "Shader not found: %s %u", shader.name, shader.macro ) ); + } + + buildQueue.emplace_back( &*shaderIt ); + + combinedShaderText += shaderIt->shaderSource; + } + + desc.checkSum = Com_BlockChecksum( combinedShaderText.c_str(), combinedShaderText.length() ); + + if ( !LoadShaderBinary( shaders, mainShader, &desc ) ) { + for ( ShaderDescriptor* shader : buildQueue ) { + BuildShader( shader ); + desc.AttachShader( &*shader ); + } + BuildShaderProgram( &desc ); + SaveShaderBinary( &desc ); + } + + shaderProgramDescriptors.emplace_back( desc ); + + return &shaderProgramDescriptors[shaderProgramDescriptors.size() - 1]; + } + + return &*it; +} + +bool GLShaderManager::BuildPermutation( GLShader* shader, int macroIndex, int deformIndex ) { size_t i = macroIndex + ( deformIndex << shader->_compileMacros.size() ); - // program already exists - if ( i < shader->_shaderPrograms.size() && - shader->_shaderPrograms[ i ].program ) - { + std::string compileMacros; + if ( !shader->GetCompileMacrosString( i, compileMacros, GLCompileMacro::VERTEX | GLCompileMacro::FRAGMENT ) ) { return false; } - if ( !shader->GetCompileMacrosString( macroIndex, compileMacros ) ) - { + if ( IsUnusedPermutation( compileMacros.c_str() ) ) { return false; } - shader->BuildShaderCompileMacros( compileMacros ); - - if ( IsUnusedPermutation( compileMacros.c_str() ) ) + // Program already exists + if ( i < shader->shaderPrograms.size() && + shader->shaderPrograms[i].id ) { return false; + } + + Log::Debug( "Building %s shader permutation with macro: %s", + shader->GetName(), + compileMacros.empty() ? "none" : compileMacros ); - if ( i >= shader->_shaderPrograms.size() ) - shader->_shaderPrograms.resize( (deformIndex + 1) << shader->_compileMacros.size() ); + const int start = Sys::Milliseconds(); - shaderProgram_t *shaderProgram = &shader->_shaderPrograms[ i ]; - shaderProgram->attribs = shader->_vertexAttribsRequired; // | _vertexAttribsOptional; + if ( i >= shader->shaderPrograms.size() ) { + shader->shaderPrograms.resize( ( deformIndex + 1 ) << shader->_compileMacros.size() ); + } - if ( deformIndex > 0 ) - { - shaderProgram_t *baseShader = &shader->_shaderPrograms[ macroIndex ]; - if ( ( !baseShader->VS && shader->_hasVertexShader ) || ( !baseShader->FS && shader->_hasFragmentShader ) ) - CompileGPUShaders( shader, baseShader, compileMacros ); - - shaderProgram->program = glCreateProgram(); - if ( shader->_hasVertexShader ) { - glAttachShader( shaderProgram->program, baseShader->VS ); - glAttachShader( shaderProgram->program, _deformShaders[deformIndex] ); - } - if ( shader->_hasFragmentShader ) { - glAttachShader( shaderProgram->program, baseShader->FS ); - } + ShaderProgramDescriptor* program; - BindAttribLocations( shaderProgram->program ); - LinkProgram( shaderProgram->program ); + std::vector shaders; + if ( shader->_hasVertexShader ) { + const uint32_t macros = shader->GetUniqueCompileMacros( macroIndex, GLCompileMacro::VERTEX ); + shaders.emplace_back( ShaderEntry{ shader->_name, macros, GL_VERTEX_SHADER } ); + shaders.emplace_back( ShaderEntry{ GetDeformShaderName( deformIndex ), 0, GL_VERTEX_SHADER } ); } - else if ( !LoadShaderBinary( shader, i ) ) - { - CompileAndLinkGPUShaderProgram( shader, shaderProgram, compileMacros, deformIndex ); - SaveShaderBinary( shader, i ); + if ( shader->_hasFragmentShader ) { + const uint32_t macros = shader->GetUniqueCompileMacros( macroIndex, GLCompileMacro::FRAGMENT ); + shaders.emplace_back( ShaderEntry{ shader->_name, macros, GL_FRAGMENT_SHADER } ); } + if ( shader->_hasComputeShader ) { + shaders.emplace_back( ShaderEntry{ shader->_name, 0, GL_COMPUTE_SHADER } ); + } + + program = FindShaderProgram( shaders, shader->_name ); - UpdateShaderProgramUniformLocations( shader, shaderProgram ); - GL_BindProgram( shaderProgram ); - shader->SetShaderProgramUniforms( shaderProgram ); - GL_BindProgram( nullptr ); + UpdateShaderProgramUniformLocations( shader, program ); + GL_BindProgram( program ); + shader->SetShaderProgramUniforms( program ); + GL_BindNullProgram(); + + // Copy this for a fast look-up, but the values held in program aren't supposed to change after + shader->shaderPrograms[i] = *program; GL_CheckErrors(); + Log::Debug( "Built in: %i ms", Sys::Milliseconds() - start ); + return true; } -void GLShaderManager::buildAll() -{ +void GLShaderManager::BuildAll() { int startTime = Sys::Milliseconds(); int count = 0; + compileTime = 0; + compileCount = 0; + linkTime = 0; + linkCount = 0; - while ( !_shaderBuildQueue.empty() ) - { - GLShader& shader = *_shaderBuildQueue.front(); + while ( !_shaderBuildQueue.empty() ) { + GLShader* shader = _shaderBuildQueue.front(); - std::string shaderName = shader.GetMainShaderName(); + std::string shaderName = shader->GetMainShaderName(); - size_t numPermutations = static_cast(1) << shader.GetNumOfCompiledMacros(); - size_t i; + size_t numPermutations = static_cast( 1 ) << shader->GetNumOfCompiledMacros(); - for( i = 0; i < numPermutations; i++ ) - { - count += +buildPermutation( &shader, i, 0 ); + for( size_t i = 0; i < numPermutations; i++ ) { + count += +BuildPermutation( shader, i, 0 ); } _shaderBuildQueue.pop(); } // doesn't include deform vertex shaders, those are built elsewhere! - Log::Notice( "built %d glsl shaders in %d msec", count, Sys::Milliseconds() - startTime ); + Log::Notice( "Built %u glsl shader programs in %i ms (compile: %u in %i ms, link: %u in %i ms, init: %u in %i ms;" + " cache: loaded %u in %i ms, saved %u in %i ms)", + count, Sys::Milliseconds() - startTime, + compileCount, compileTime, linkCount, linkTime, initCount, initTime, + cacheLoadCount, cacheLoadTime, cacheSaveCount, cacheSaveTime ); } -std::string GLShaderManager::ProcessInserts( const std::string& shaderText, const uint32_t offset ) const { +std::string GLShaderManager::ProcessInserts( const std::string& shaderText ) const { std::string out; std::istringstream shaderTextStream( shaderText ); std::string line; int insertCount = 0; - int lineCount = offset; + int lineCount = 0; while ( std::getline( shaderTextStream, line, '\n' ) ) { ++lineCount; @@ -1059,8 +1240,64 @@ std::string GLShaderManager::ProcessInserts( const std::string& shaderText, cons return out; } +ShaderDescriptor* GLShaderManager::FindShader( const std::string& name, const std::string& mainText, + const GLenum type, const std::vector& headers, + const uint32_t macro, const std::string& compileMacros, const bool main ) { + + ShaderDescriptor desc{ name, compileMacros, macro, type, main }; + const std::vector::iterator it = std::find_if( shaderDescriptors.begin(), shaderDescriptors.end(), + [&]( const ShaderDescriptor& other ) { + return desc.type == other.type && desc.macro == other.macro && desc.name == other.name; + } + ); + + if ( it != shaderDescriptors.end() ) { + return nullptr; + } + + std::string combinedShaderText = BuildShaderText( mainText, headers, compileMacros ); + combinedShaderText = ProcessInserts( combinedShaderText ); + + desc.shaderSource = combinedShaderText; + + shaderDescriptors.emplace_back( desc ); + + return &shaderDescriptors.back(); +} + +std::string GLShaderManager::BuildShaderText( const std::string& mainShaderText, const std::vector& headers, + const std::string& macros ) { + std::string combinedText; + + uint32_t count = 0; + for ( GLHeader* header : headers ) { + count += header->getText().size(); + } + + combinedText.reserve( count ); + + for ( GLHeader* header : headers ) { + combinedText += header->getText(); + } + + const char* compileMacrosP = macros.c_str(); + while ( true ) { + const char* token = COM_ParseExt2( &compileMacrosP, false ); + + if ( !token[0] ) { + break; + } + + combinedText += Str::Format( "#ifndef %s\n#define %s 1\n#endif\n", token, token ); + } + + combinedText += mainShaderText; + + return combinedText; +} + void GLShaderManager::InitShader( GLShader* shader ) { - shader->_shaderPrograms = std::vector( static_cast< size_t >( 1 ) << shader->_compileMacros.size() ); + const int start = Sys::Milliseconds(); shader->PostProcessUniforms(); @@ -1077,317 +1314,244 @@ void GLShaderManager::InitShader( GLShader* shader ) { uniformBlock->SetLocationIndex( i ); } + struct ShaderType { + bool enabled; + int type; + GLenum GLType; + + const char* postfix; + uint32_t offset; + std::vector headers; + + std::string path = ""; + std::string mainText = ""; + }; + + ShaderType shaderTypes[] = { + { shader->_hasVertexShader, GLCompileMacro::VERTEX, GL_VERTEX_SHADER, "_vp", + uint32_t( GLVersionDeclaration.getText().size() ), + { &GLVersionDeclaration, &GLCompatHeader, &GLEngineConstants, &GLVertexHeader } }, + { shader->_hasFragmentShader, GLCompileMacro::FRAGMENT, GL_FRAGMENT_SHADER, "_fp", + uint32_t( GLVersionDeclaration.getText().size() ), + { &GLVersionDeclaration, &GLCompatHeader, &GLEngineConstants, &GLFragmentHeader } }, + { shader->_hasComputeShader, GLCompileMacro::COMPUTE, GL_COMPUTE_SHADER, "_cp", + uint32_t( GLComputeVersionDeclaration.getText().size() ), + { &GLComputeVersionDeclaration, &GLCompatHeader, &GLEngineConstants, &GLComputeHeader, &GLWorldHeader } } + }; + char filename[MAX_QPATH]; - if ( shader->_hasVertexShader ) { - Com_sprintf( filename, sizeof( filename ), "%s_vp.glsl", shader->GetMainShaderName().c_str() ); - shader->_vertexShaderText = GetShaderText( filename ); + for ( ShaderType& shaderType : shaderTypes ) { + if ( shaderType.enabled ) { + Com_sprintf( filename, sizeof( filename ), "%s%s.glsl", shader->GetMainShaderName().c_str(), shaderType.postfix ); - const uint32_t offset = - GLVersionDeclaration.getLineCount() - + GLCompatHeader.getLineCount() - + GLEngineConstants.getLineCount() - + GLVertexHeader.getLineCount(); - shader->_vertexShaderText = ProcessInserts( shader->_vertexShaderText, offset ); + shaderType.path = filename; + shaderType.mainText = GetShaderText( filename ); + } } - if ( shader->_hasFragmentShader ) { - Com_sprintf( filename, sizeof( filename ), "%s_fp.glsl", shader->GetMainShaderName().c_str() ); - shader->_fragmentShaderText = GetShaderText( filename ); - const uint32_t offset = - GLVersionDeclaration.getLineCount() - + GLCompatHeader.getLineCount() - + GLEngineConstants.getLineCount() - + GLFragmentHeader.getLineCount(); - shader->_fragmentShaderText = ProcessInserts( shader->_fragmentShaderText, offset ); - } - if ( shader->_hasComputeShader ) { - Com_sprintf( filename, sizeof( filename ), "%s_cp.glsl", shader->GetMainShaderName().c_str() ); - shader->_computeShaderText = GetShaderText( filename ); - - const uint32_t offset = - GLComputeVersionDeclaration.getLineCount() - + GLCompatHeader.getLineCount() - + GLEngineConstants.getLineCount() - + GLComputeHeader.getLineCount() - + GLWorldHeader.getLineCount(); - shader->_computeShaderText = ProcessInserts( shader->_computeShaderText, offset ); - } - - if ( glConfig2.usingMaterialSystem && shader->_useMaterialSystem ) { - shader->_vertexShaderText = ShaderPostProcess( shader, shader->_vertexShaderText ); - shader->_fragmentShaderText = ShaderPostProcess( shader, shader->_fragmentShaderText ); - } - - std::string combinedShaderText; - if ( shader->_hasVertexShader || shader->_hasFragmentShader ) { - combinedShaderText = - GLVersionDeclaration.getText() - + GLCompatHeader.getText() - + GLEngineConstants.getText() - + GLVertexHeader.getText() - + GLFragmentHeader.getText(); - } else if ( shader->_hasComputeShader ) { - combinedShaderText = - GLComputeVersionDeclaration.getText() - + GLCompatHeader.getText() - + GLEngineConstants.getText() - + GLComputeHeader.getText() - + GLWorldHeader.getText(); - } + for ( int i = 0; i < BIT( shader->GetNumOfCompiledMacros() ); i++ ) { + for ( ShaderType& shaderType : shaderTypes ) { + if ( !shaderType.enabled ) { + continue; + } - if ( shader->_hasVertexShader ) { - combinedShaderText += shader->_vertexShaderText; - } - if ( shader->_hasFragmentShader ) { - combinedShaderText += shader->_fragmentShaderText; - } - if ( shader->_hasComputeShader ) { - combinedShaderText += shader->_computeShaderText; + std::string compileMacros; + if ( !shader->GetCompileMacrosString( i, compileMacros, shaderType.type ) ) { + continue; + } + + if ( IsUnusedPermutation( compileMacros.c_str() ) ) { + continue; + } + + shader->BuildShaderCompileMacros( compileMacros ); + + const uint32_t uniqueMacros = shader->GetUniqueCompileMacros( i, shaderType.type ); + + ShaderDescriptor* desc = FindShader( shader->_name, shaderType.mainText, shaderType.GLType, shaderType.headers, + uniqueMacros, compileMacros, true ); + + if ( desc && glConfig2.usingMaterialSystem && shader->_useMaterialSystem ) { + desc->shaderSource = ShaderPostProcess( shader, desc->shaderSource, shaderType.offset ); + } + + initCount++; + } } - shader->_checkSum = Com_BlockChecksum( combinedShaderText.c_str(), combinedShaderText.length() ); + initTime += Sys::Milliseconds() - start; } -bool GLShaderManager::LoadShaderBinary( GLShader *shader, size_t programNum ) -{ -#ifdef GL_ARB_get_program_binary - GLint success; - const byte *binaryptr; - GLBinaryHeader shaderHeader; - - if ( !r_glslCache.Get() ) +bool GLShaderManager::LoadShaderBinary( const std::vector& shaders, const std::string& mainShader, + ShaderProgramDescriptor* descriptor ) { + if ( !r_glslCache.Get() ) { return false; + } - if (!GetShaderPath().empty()) + if ( !GetShaderPath().empty() ) { return false; + } - // don't even try if the necessary functions aren't available - if( !glConfig2.getProgramBinaryAvailable ) + // Don't even try if the necessary functions aren't available + if ( !glConfig2.getProgramBinaryAvailable ) { return false; + } - if (_shaderBinaryCacheInvalidated) + if ( _shaderBinaryCacheInvalidated ) { return false; + } + + const int start = Sys::Milliseconds(); std::error_code err; - std::string shaderFilename = Str::Format("glsl/%s/%s_%u.bin", shader->GetName(), shader->GetName(), (unsigned int)programNum); - FS::File shaderFile = FS::HomePath::OpenRead(shaderFilename, err); - if (err) + std::string secondaryName; + for ( const ShaderEntry& shader : shaders ) { + if ( shader.name != mainShader ) { + secondaryName += Str::Format( "%s_%u_%u", shader.name, shader.macro, shader.type ); + } else { + secondaryName += Str::Format( "%u_%u_", shader.macro, shader.type ); + } + } + + std::string shaderFilename = Str::Format( "glsl/%s/%s.bin", mainShader, secondaryName ); + FS::File shaderFile = FS::HomePath::OpenRead( shaderFilename, err ); + if ( err ) { return false; + } - std::string shaderData = shaderFile.ReadAll(err); - if (err) + GLint success; + const byte *binaryptr; + GLBinaryHeader shaderHeader; + std::string shaderData = shaderFile.ReadAll( err ); + if ( err ) { return false; + } - if (shaderData.size() < sizeof(shaderHeader)) + if ( shaderData.size() < sizeof( shaderHeader ) ) { return false; + } - binaryptr = reinterpret_cast(shaderData.data()); + binaryptr = reinterpret_cast( shaderData.data() ); - // get the shader header from the file + // Get the shader header from the file memcpy( &shaderHeader, binaryptr, sizeof( shaderHeader ) ); binaryptr += sizeof( shaderHeader ); - // check if the header struct is the correct format - // and the binary was produced by the same gl driver - if (shaderHeader.version != GL_SHADER_VERSION || shaderHeader.driverVersionHash != _driverVersionHash) - { - // These two fields should be the same for all shaders. So if there is a mismatch, - // don't bother opening any of the remaining files. - Log::Notice("Invalidating shader binary cache"); + /* Check if the header struct is the correct format + and the binary was produced by the same GL driver */ + if ( shaderHeader.version != GL_SHADER_VERSION /* || shaderHeader.driverVersionHash != _driverVersionHash */ ) { + /* These two fields should be the same for all shaders. So if there is a mismatch, + don't bother opening any of the remaining files. + I've disabled the cache invalidation on driver version change, because we now also cache shader programs that use + non-empty deformVertexes. This would mean that after updating the driver, any time you load a new map with + deformVertexes, it would cause the rebuild of *all* shaders */ + Log::Notice( "Invalidating shader binary cache" ); _shaderBinaryCacheInvalidated = true; return false; } - // make sure this shader uses the same number of macros - if ( shaderHeader.numMacros != shader->GetNumOfCompiledMacros() ) + // Make sure the checksums for the source code match + if ( shaderHeader.checkSum != descriptor->checkSum ) { return false; - - // make sure this shader uses the same macros - for ( unsigned int i = 0; i < shaderHeader.numMacros; i++ ) - { - if ( shader->_compileMacros[ i ]->GetType() != shaderHeader.macros[ i ] ) - return false; } - // make sure the checksums for the source code match - if ( shaderHeader.checkSum != shader->_checkSum ) - return false; - - if ( shaderHeader.binaryLength != shaderData.size() - sizeof( shaderHeader ) ) - { + if ( shaderHeader.binaryLength != shaderData.size() - sizeof( shaderHeader ) ) { Log::Warn( "Shader cache %s has wrong size", shaderFilename ); return false; } - // load the shader - shaderProgram_t *shaderProgram = &shader->_shaderPrograms[ programNum ]; - shaderProgram->program = glCreateProgram(); - glProgramBinary( shaderProgram->program, shaderHeader.binaryFormat, binaryptr, shaderHeader.binaryLength ); - glGetProgramiv( shaderProgram->program, GL_LINK_STATUS, &success ); + // Load the shader program + descriptor->id = glCreateProgram(); + glProgramBinary( descriptor->id, shaderHeader.binaryFormat, binaryptr, shaderHeader.binaryLength ); + glGetProgramiv( descriptor->id, GL_LINK_STATUS, &success ); - if ( !success ) + if ( !success ) { return false; + } + + for ( const ShaderEntry& shader : shaders ) { + descriptor->shaderNames[descriptor->shaderCount] = shader; + descriptor->shaderCount++; + } + + cacheLoadTime += Sys::Milliseconds() - start; + cacheLoadCount++; return true; -#else - return false; -#endif } -void GLShaderManager::SaveShaderBinary( GLShader *shader, size_t programNum ) -{ -#ifdef GL_ARB_get_program_binary - GLint binaryLength; - GLuint binarySize = 0; - byte *binary; - byte *binaryptr; - GLBinaryHeader shaderHeader{}; // Zero init. - shaderProgram_t *shaderProgram; - - if ( !r_glslCache.Get() ) + +void GLShaderManager::SaveShaderBinary( ShaderProgramDescriptor* descriptor ) { + if ( !r_glslCache.Get() ) { return; + } - if (!GetShaderPath().empty()) + if ( !GetShaderPath().empty() ) { return; + } - // don't even try if the necessary functions aren't available - if( !glConfig2.getProgramBinaryAvailable ) - { + // Don't even try if the necessary functions aren't available + if( !glConfig2.getProgramBinaryAvailable ) { return; } - shaderProgram = &shader->_shaderPrograms[ programNum ]; + const int start = Sys::Milliseconds(); - // find output size - binarySize += sizeof( shaderHeader ); - glGetProgramiv( shaderProgram->program, GL_PROGRAM_BINARY_LENGTH, &binaryLength ); + // Find output size + GLBinaryHeader shaderHeader{}; + GLuint binarySize = sizeof( shaderHeader ); + GLint binaryLength; + glGetProgramiv( descriptor->id, GL_PROGRAM_BINARY_LENGTH, &binaryLength ); // The binary length may be 0 if there is an error. - if ( binaryLength <= 0 ) - { + if ( binaryLength <= 0 ) { return; } binarySize += binaryLength; + byte* binary; + byte* binaryptr; binaryptr = binary = ( byte* )ri.Hunk_AllocateTempMemory( binarySize ); - // reserve space for the header + // Reserve space for the header binaryptr += sizeof( shaderHeader ); - // get the program binary and write it to the buffer - glGetProgramBinary( shaderProgram->program, binaryLength, nullptr, &shaderHeader.binaryFormat, binaryptr ); + // Get the program binary and write it to the buffer + glGetProgramBinary( descriptor->id, binaryLength, nullptr, &shaderHeader.binaryFormat, binaryptr ); - // set the header + // Set the header shaderHeader.version = GL_SHADER_VERSION; - shaderHeader.numMacros = shader->_compileMacros.size(); - - for ( unsigned int i = 0; i < shaderHeader.numMacros; i++ ) - { - shaderHeader.macros[ i ] = shader->_compileMacros[ i ]->GetType(); - } shaderHeader.binaryLength = binaryLength; - shaderHeader.checkSum = shader->_checkSum; + shaderHeader.checkSum = descriptor->checkSum; shaderHeader.driverVersionHash = _driverVersionHash; - // write the header to the buffer - memcpy(binary, &shaderHeader, sizeof( shaderHeader ) ); - - auto fileName = Str::Format("glsl/%s/%s_%u.bin", shader->GetName(), shader->GetName(), (unsigned int)programNum); - ri.FS_WriteFile(fileName.c_str(), binary, binarySize); - - ri.Hunk_FreeTempMemory( binary ); -#endif -} - -void GLShaderManager::CompileGPUShaders( GLShader *shader, shaderProgram_t *program, - const std::string &compileMacros ) -{ - // permutation macros - std::string macrosString; - - const char* compileMacrosP = compileMacros.c_str(); - while ( true ) - { - const char *token = COM_ParseExt2( &compileMacrosP, false ); + // Write the header to the buffer + memcpy( binary, &shaderHeader, sizeof( shaderHeader ) ); - if ( !token[ 0 ] ) - { - break; + std::string secondaryName; + for ( uint32_t i = 0; i < descriptor->shaderCount; i++ ) { + const ShaderEntry& shader = descriptor->shaderNames[i]; + if ( shader.name != descriptor->mainShader || !descriptor->hasMain ) { + secondaryName += Str::Format( "%s_%u_%u", shader.name, shader.macro, shader.type ); + } else { + secondaryName += Str::Format( "%u_%u_", shader.macro, shader.type ); } - - macrosString += Str::Format( "#ifndef %s\n#define %s 1\n#endif\n", token, token ); - } - - Log::Debug( "building %s shader permutation with macro: %s", - shader->GetName(), - compileMacros.empty() ? "none" : compileMacros ); - - const int start = Sys::Milliseconds(); - - // add them - std::string vertexShaderTextWithMacros = macrosString + shader->_vertexShaderText; - std::string fragmentShaderTextWithMacros = macrosString + shader->_fragmentShaderText; - std::string computeShaderTextWithMacros = macrosString + shader->_computeShaderText; - if( shader->_hasVertexShader ) { - program->VS = CompileShader( shader->GetName(), - vertexShaderTextWithMacros, - { &GLVersionDeclaration, - &GLCompatHeader, - &GLEngineConstants, - &GLVertexHeader }, - GL_VERTEX_SHADER ); - } - if ( shader->_hasFragmentShader ) { - program->FS = CompileShader( shader->GetName(), - fragmentShaderTextWithMacros, - { &GLVersionDeclaration, - &GLCompatHeader, - &GLEngineConstants, - &GLFragmentHeader }, - GL_FRAGMENT_SHADER ); } - if ( shader->_hasComputeShader ) { - program->CS = CompileShader( shader->GetName(), - computeShaderTextWithMacros, - { &GLComputeVersionDeclaration, - &GLCompatHeader, - &GLComputeHeader, - &GLEngineConstants, - &GLWorldHeader }, - GL_COMPUTE_SHADER ); - } - - Log::Debug( "Compilation: %i ms", Sys::Milliseconds() - start ); -} - -void GLShaderManager::CompileAndLinkGPUShaderProgram( GLShader *shader, shaderProgram_t *program, - Str::StringRef compileMacros, int deformIndex ) -{ - GLShaderManager::CompileGPUShaders( shader, program, compileMacros ); - program->program = glCreateProgram(); - if ( shader->_hasVertexShader ) { - glAttachShader( program->program, program->VS ); - glAttachShader( program->program, _deformShaders[ deformIndex ] ); - } - if ( shader->_hasFragmentShader ) { - glAttachShader( program->program, program->FS ); - } - if ( shader->_hasComputeShader ) { - glAttachShader( program->program, program->CS ); - } + std::string name = descriptor->hasMain ? descriptor->mainShader : "unknown"; + auto fileName = Str::Format( "glsl/%s/%s.bin", name, secondaryName ); + ri.FS_WriteFile( fileName.c_str(), binary, binarySize ); - const int start = Sys::Milliseconds(); - BindAttribLocations( program->program ); - LinkProgram( program->program ); + ri.Hunk_FreeTempMemory( binary ); - Log::Debug( "Link: %i ms", Sys::Milliseconds() - start ); + cacheSaveTime += Sys::Milliseconds() - start; + cacheSaveCount++; } // This will generate all the extra code for material system shaders -std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::string& shaderText ) { +std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::string& shaderText, const uint32_t offset ) { if ( !shader->std430Size ) { return shaderText; } @@ -1537,64 +1701,9 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str materialDefines += "\n"; - newShaderText = "#define USE_MATERIAL_SYSTEM\n" + materialStruct + materialBlock + texDataBlock + materialDefines + shaderMain; - return newShaderText; -} - -GLuint GLShaderManager::CompileShader( Str::StringRef programName, - Str::StringRef shaderText, - std::initializer_list headers, - GLenum shaderType ) const -{ - GLuint shader = glCreateShader( shaderType ); - std::vector texts(headers.size() + 1); - std::vector lengths(headers.size() + 1); - int i; - - i = 0; - for(const GLHeader *hdr : headers) { - texts[i++] = hdr->getText().data(); - } - texts[i++] = shaderText.data(); - - i = 0; - for(const GLHeader *hdr : headers) { - lengths[i++] = (GLint)hdr->getText().size(); - } - lengths[i++] = (GLint)shaderText.size(); - - GL_CheckErrors(); - - glShaderSource( shader, i, texts.data(), lengths.data() ); - - // compile shader - glCompileShader( shader ); - - GL_CheckErrors(); - - // check if shader compiled - GLint compiled; - glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); - - if ( !compiled ) - { - std::string log = GetInfoLog( shader ); - std::vector infoLog = ParseInfoLog( log ); - PrintShaderSource( programName, shader, infoLog ); - Log::Warn( "Compile log:\n%s", log ); - switch ( shaderType ) { - case GL_VERTEX_SHADER: - ThrowShaderError( Str::Format( "Couldn't compile vertex shader: %s", programName ) ); - case GL_FRAGMENT_SHADER: - ThrowShaderError( Str::Format( "Couldn't compile fragment shader: %s", programName ) ); - case GL_COMPUTE_SHADER: - ThrowShaderError( Str::Format( "Couldn't compile compute shader: %s", programName ) ); - default: - break; - } - } - - return shader; + newShaderText = "#define USE_MATERIAL_SYSTEM\n" + materialStruct + materialBlock + texDataBlock + materialDefines; // + shaderMain; + shaderMain.insert( offset, newShaderText ); + return shaderMain; } void GLShaderManager::PrintShaderSource( Str::StringRef programName, GLuint object, std::vector& infoLog ) const @@ -2044,8 +2153,8 @@ void GLShader::RegisterUniform( GLUniform* uniform ) { } GLint GLShader::GetUniformLocation( const GLchar *uniformName ) const { - shaderProgram_t* p = GetProgram(); - return glGetUniformLocation( p->program, uniformName ); + ShaderProgramDescriptor* p = GetProgram(); + return glGetUniformLocation( p->id, uniformName ); } // Compute std430 size/alignment and sort uniforms from highest to lowest alignment @@ -2107,22 +2216,45 @@ void GLShader::PostProcessUniforms() { } } -bool GLShader::GetCompileMacrosString( size_t permutation, std::string &compileMacrosOut ) const -{ +uint32_t GLShader::GetUniqueCompileMacros( size_t permutation, const int type ) const { + uint32_t macroOut = 0; + for ( const GLCompileMacro* macro : _compileMacros ) { + if ( permutation & macro->GetBit() ) { + if ( macro->HasConflictingMacros( permutation, _compileMacros ) ) { + continue; + } + + if ( macro->MissesRequiredMacros( permutation, _compileMacros ) ) { + continue; + } + + if ( !( macro->GetShaderTypes() & type ) ) { + continue; + } + + macroOut |= BIT( macro->GetType() ); + } + } + + return macroOut; +} + +bool GLShader::GetCompileMacrosString( size_t permutation, std::string &compileMacrosOut, const int type ) const { compileMacrosOut.clear(); - for (const GLCompileMacro* macro : _compileMacros) - { - if ( permutation & macro->GetBit() ) - { - if ( macro->HasConflictingMacros( permutation, _compileMacros ) ) - { - //Log::Notice("conflicting macro! canceling '%s'", macro->GetName()); + for ( const GLCompileMacro* macro : _compileMacros ) { + if ( permutation & macro->GetBit() ) { + if ( macro->HasConflictingMacros( permutation, _compileMacros ) ) { + return false; + } + + if ( macro->MissesRequiredMacros( permutation, _compileMacros ) ) { return false; } - if ( macro->MissesRequiredMacros( permutation, _compileMacros ) ) + if ( !( macro->GetShaderTypes() & type ) ) { return false; + } compileMacrosOut += macro->GetName(); compileMacrosOut += " "; @@ -2155,12 +2287,12 @@ GLuint GLShader::GetProgram( int deformIndex ) { // program may not be loaded yet because the shader manager hasn't yet gotten to it // so try to load it now - if ( index >= _shaderPrograms.size() || !_shaderPrograms[index].program ) { - _shaderManager->buildPermutation( this, macroIndex, deformIndex ); + if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { + _shaderManager->BuildPermutation( this, macroIndex, deformIndex ); } // program is still not loaded - if ( index >= _shaderPrograms.size() || !_shaderPrograms[index].program ) { + if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { std::string activeMacros; size_t numMacros = _compileMacros.size(); @@ -2178,23 +2310,22 @@ GLuint GLShader::GetProgram( int deformIndex ) { ThrowShaderError( Str::Format( "Invalid shader configuration: shader = '%s', macros = '%s'", _name, activeMacros ) ); } - return _shaderPrograms[index].program; + return shaderPrograms[index].id; } -void GLShader::BindProgram( int deformIndex ) -{ +void GLShader::BindProgram( int deformIndex ) { int macroIndex = SelectProgram(); size_t index = macroIndex + ( size_t(deformIndex) << _compileMacros.size() ); // program may not be loaded yet because the shader manager hasn't yet gotten to it // so try to load it now - if ( index >= _shaderPrograms.size() || !_shaderPrograms[ index ].program ) + if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { - _shaderManager->buildPermutation( this, macroIndex, deformIndex ); + _shaderManager->BuildPermutation( this, macroIndex, deformIndex ); } // program is still not loaded - if ( index >= _shaderPrograms.size() || !_shaderPrograms[ index ].program ) + if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { std::string activeMacros; @@ -2210,29 +2341,28 @@ void GLShader::BindProgram( int deformIndex ) ThrowShaderError(Str::Format("Invalid shader configuration: shader = '%s', macros = '%s'", _name, activeMacros )); } - _currentProgram = &_shaderPrograms[ index ]; + currentProgram = &shaderPrograms[index]; - if ( r_logFile->integer ) - { + if ( r_logFile->integer ) { std::string macros; - this->GetCompileMacrosString( index, macros ); + GetCompileMacrosString( index, macros, GLCompileMacro::VERTEX | GLCompileMacro::FRAGMENT ); - auto msg = Str::Format("--- GL_BindProgram( name = '%s', macros = '%s' ) ---\n", this->GetName(), macros); - GLimp_LogComment(msg.c_str()); + auto msg = Str::Format( "--- GL_BindProgram( name = '%s', macros = '%s' ) ---\n", this->GetName(), macros ); + GLimp_LogComment( msg.c_str() ); } - GL_BindProgram( _currentProgram ); + GL_BindProgram( &shaderPrograms[index] ); } void GLShader::DispatchCompute( const GLuint globalWorkgroupX, const GLuint globalWorkgroupY, const GLuint globalWorkgroupZ ) { - ASSERT_EQ( _currentProgram, glState.currentProgram ); + ASSERT_EQ( currentProgram, glState.currentProgram ); ASSERT( _hasComputeShader ); glDispatchCompute( globalWorkgroupX, globalWorkgroupY, globalWorkgroupZ ); } void GLShader::DispatchComputeIndirect( const GLintptr indirectBuffer ) { - ASSERT_EQ( _currentProgram, glState.currentProgram ); + ASSERT_EQ( currentProgram, glState.currentProgram ); ASSERT( _hasComputeShader ); glDispatchComputeIndirect( indirectBuffer ); } @@ -2288,10 +2418,10 @@ GLShader_generic::GLShader_generic( GLShaderManager *manager ) : { } -void GLShader_generic::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_generic::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_genericMaterial::GLShader_genericMaterial( GLShaderManager* manager ) : @@ -2317,9 +2447,9 @@ GLShader_genericMaterial::GLShader_genericMaterial( GLShaderManager* manager ) : GLCompileMacro_USE_DEPTH_FADE( this ) { } -void GLShader_genericMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 1 ); +void GLShader_genericMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : @@ -2371,22 +2501,22 @@ GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : { } -void GLShader_lightMapping::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_lightMapping::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), BIND_NORMALMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), BIND_HEIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), BIND_MATERIALMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightMap" ), BIND_LIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid1" ), BIND_LIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DeluxeMap" ), BIND_DELUXEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid2" ), BIND_DELUXEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_GlowMap" ), BIND_GLOWMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), BIND_LIGHTTILES ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), BIND_NORMALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), BIND_HEIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), BIND_MATERIALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightMap" ), BIND_LIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid1" ), BIND_LIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DeluxeMap" ), BIND_DELUXEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid2" ), BIND_DELUXEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_GlowMap" ), BIND_GLOWMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightTiles" ), BIND_LIGHTTILES ); if( !glConfig2.uniformBufferObjectAvailable ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), BIND_LIGHTS ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_Lights" ), BIND_LIGHTS ); } } @@ -2436,19 +2566,19 @@ GLShader_lightMappingMaterial::GLShader_lightMappingMaterial( GLShaderManager* m GLCompileMacro_USE_PHYSICAL_MAPPING( this ) { } -void GLShader_lightMappingMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), BIND_NORMALMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), BIND_HEIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), BIND_MATERIALMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightMap" ), BIND_LIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DeluxeMap" ), BIND_DELUXEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_GlowMap" ), BIND_GLOWMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), BIND_LIGHTTILES ); +void GLShader_lightMappingMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), BIND_NORMALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), BIND_HEIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), BIND_MATERIALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightMap" ), BIND_LIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DeluxeMap" ), BIND_DELUXEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_GlowMap" ), BIND_GLOWMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightTiles" ), BIND_LIGHTTILES ); if ( !glConfig2.uniformBufferObjectAvailable ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), BIND_LIGHTS ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_Lights" ), BIND_LIGHTS ); } } @@ -2492,17 +2622,17 @@ GLShader_forwardLighting_omniXYZ::GLShader_forwardLighting_omniXYZ( GLShaderMana { } -void GLShader_forwardLighting_omniXYZ::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_forwardLighting_omniXYZ::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), 2 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_AttenuationMapXY" ), 3 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_AttenuationMapZ" ), 4 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap" ), 5 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_RandomMap" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), 2 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_AttenuationMapXY" ), 3 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_AttenuationMapZ" ), 4 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap" ), 5 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_RandomMap" ), 6 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_forwardLighting_projXYZ::GLShader_forwardLighting_projXYZ( GLShaderManager *manager ): @@ -2551,17 +2681,17 @@ void GLShader_forwardLighting_projXYZ::BuildShaderCompileMacros( std::string& co compileMacros += "LIGHT_PROJ "; } -void GLShader_forwardLighting_projXYZ::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_forwardLighting_projXYZ::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), 2 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_AttenuationMapXY" ), 3 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_AttenuationMapZ" ), 4 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap0" ), 5 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_RandomMap" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap0" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), 2 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_AttenuationMapXY" ), 3 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_AttenuationMapZ" ), 4 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap0" ), 5 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_RandomMap" ), 6 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap0" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_forwardLighting_directionalSun::GLShader_forwardLighting_directionalSun( GLShaderManager *manager ): @@ -2617,24 +2747,24 @@ void GLShader_forwardLighting_directionalSun::BuildShaderCompileMacros( std::str compileMacros += "LIGHT_DIRECTIONAL "; } -void GLShader_forwardLighting_directionalSun::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_forwardLighting_directionalSun::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), 2 ); - //glUniform1i(glGetUniformLocation( shaderProgram->program, "u_AttenuationMapXY" ), 3); - //glUniform1i(glGetUniformLocation( shaderProgram->program, "u_AttenuationMapZ" ), 4); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap0" ), 5 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap1" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap2" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap3" ), 8 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap4" ), 9 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap0" ), 10 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap1" ), 11 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap2" ), 12 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap3" ), 13 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap4" ), 14 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), 2 ); + //glUniform1i(glGetUniformLocation( shaderProgram->id, "u_AttenuationMapXY" ), 3); + //glUniform1i(glGetUniformLocation( shaderProgram->id, "u_AttenuationMapZ" ), 4); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap0" ), 5 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap1" ), 6 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap2" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap3" ), 8 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap4" ), 9 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap0" ), 10 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap1" ), 11 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap2" ), 12 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap3" ), 13 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap4" ), 14 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_shadowFill::GLShader_shadowFill( GLShaderManager *manager ) : @@ -2656,9 +2786,9 @@ GLShader_shadowFill::GLShader_shadowFill( GLShaderManager *manager ) : { } -void GLShader_shadowFill::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_shadowFill::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); } GLShader_reflection::GLShader_reflection( GLShaderManager *manager ): @@ -2684,11 +2814,11 @@ GLShader_reflection::GLShader_reflection( GLShaderManager *manager ): { } -void GLShader_reflection::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_reflection::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_reflectionMaterial::GLShader_reflectionMaterial( GLShaderManager* manager ) : @@ -2709,10 +2839,10 @@ GLShader_reflectionMaterial::GLShader_reflectionMaterial( GLShaderManager* manag GLCompileMacro_USE_RELIEF_MAPPING( this ) { } -void GLShader_reflectionMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); +void GLShader_reflectionMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_skybox::GLShader_skybox( GLShaderManager *manager ) : @@ -2727,10 +2857,10 @@ GLShader_skybox::GLShader_skybox( GLShaderManager *manager ) : { } -void GLShader_skybox::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_skybox::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMapCube" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CloudMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMapCube" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CloudMap" ), 1 ); } GLShader_skyboxMaterial::GLShader_skyboxMaterial( GLShaderManager* manager ) : @@ -2744,9 +2874,9 @@ GLShader_skyboxMaterial::GLShader_skyboxMaterial( GLShaderManager* manager ) : u_ModelViewProjectionMatrix( this ) {} -void GLShader_skyboxMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CloudMap" ), 1 ); +void GLShader_skyboxMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CloudMap" ), 1 ); } GLShader_fogQuake3::GLShader_fogQuake3( GLShaderManager *manager ) : @@ -2766,9 +2896,9 @@ GLShader_fogQuake3::GLShader_fogQuake3( GLShaderManager *manager ) : { } -void GLShader_fogQuake3::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_fogQuake3::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_FogMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_FogMap" ), 0 ); } GLShader_fogQuake3Material::GLShader_fogQuake3Material( GLShaderManager* manager ) : @@ -2783,8 +2913,8 @@ GLShader_fogQuake3Material::GLShader_fogQuake3Material( GLShaderManager* manager GLDeformStage( this ) { } -void GLShader_fogQuake3Material::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_FogMap" ), 0 ); +void GLShader_fogQuake3Material::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_FogMap" ), 0 ); } GLShader_fogGlobal::GLShader_fogGlobal( GLShaderManager *manager ) : @@ -2798,10 +2928,10 @@ GLShader_fogGlobal::GLShader_fogGlobal( GLShaderManager *manager ) : { } -void GLShader_fogGlobal::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_fogGlobal::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_heatHaze::GLShader_heatHaze( GLShaderManager *manager ) : @@ -2823,11 +2953,11 @@ GLShader_heatHaze::GLShader_heatHaze( GLShaderManager *manager ) : { } -void GLShader_heatHaze::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_heatHaze::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_heatHazeMaterial::GLShader_heatHazeMaterial( GLShaderManager* manager ) : @@ -2846,10 +2976,10 @@ GLShader_heatHazeMaterial::GLShader_heatHazeMaterial( GLShaderManager* manager ) { } -void GLShader_heatHazeMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); +void GLShader_heatHazeMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_screen::GLShader_screen( GLShaderManager *manager ) : @@ -2859,9 +2989,9 @@ GLShader_screen::GLShader_screen( GLShaderManager *manager ) : { } -void GLShader_screen::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_screen::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_screenMaterial::GLShader_screenMaterial( GLShaderManager* manager ) : @@ -2870,8 +3000,8 @@ GLShader_screenMaterial::GLShader_screenMaterial( GLShaderManager* manager ) : u_ModelViewProjectionMatrix( this ) { } -void GLShader_screenMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); +void GLShader_screenMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_portal::GLShader_portal( GLShaderManager *manager ) : @@ -2883,9 +3013,9 @@ GLShader_portal::GLShader_portal( GLShaderManager *manager ) : { } -void GLShader_portal::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_portal::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_contrast::GLShader_contrast( GLShaderManager *manager ) : @@ -2895,9 +3025,9 @@ GLShader_contrast::GLShader_contrast( GLShaderManager *manager ) : { } -void GLShader_contrast::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_contrast::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); } GLShader_cameraEffects::GLShader_cameraEffects( GLShaderManager *manager ) : @@ -2915,10 +3045,10 @@ GLShader_cameraEffects::GLShader_cameraEffects( GLShaderManager *manager ) : { } -void GLShader_cameraEffects::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_cameraEffects::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap3D" ), 3 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap3D" ), 3 ); } GLShader_blur::GLShader_blur( GLShaderManager *manager ) : @@ -2931,9 +3061,9 @@ GLShader_blur::GLShader_blur( GLShaderManager *manager ) : { } -void GLShader_blur::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_blur::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); } GLShader_debugShadowMap::GLShader_debugShadowMap( GLShaderManager *manager ) : @@ -2943,9 +3073,9 @@ GLShader_debugShadowMap::GLShader_debugShadowMap( GLShaderManager *manager ) : { } -void GLShader_debugShadowMap::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_debugShadowMap::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) : @@ -2981,14 +3111,14 @@ GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) : { } -void GLShader_liquid::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_PortalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 2 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 3 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid1" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid2" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); +void GLShader_liquid::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_PortalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 2 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 3 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid1" ), 6 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid2" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_liquidMaterial::GLShader_liquidMaterial( GLShaderManager* manager ) : @@ -3024,15 +3154,15 @@ GLShader_liquidMaterial::GLShader_liquidMaterial( GLShaderManager* manager ) : GLCompileMacro_USE_RELIEF_MAPPING( this ) { } -void GLShader_liquidMaterial::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_liquidMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_PortalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 2 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 3 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid1" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid2" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_PortalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 2 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 3 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid1" ), 6 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid2" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_motionblur::GLShader_motionblur( GLShaderManager *manager ) : @@ -3044,10 +3174,10 @@ GLShader_motionblur::GLShader_motionblur( GLShaderManager *manager ) : { } -void GLShader_motionblur::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_motionblur::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_ssao::GLShader_ssao( GLShaderManager *manager ) : @@ -3059,9 +3189,9 @@ GLShader_ssao::GLShader_ssao( GLShaderManager *manager ) : { } -void GLShader_ssao::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_ssao::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); } GLShader_depthtile1::GLShader_depthtile1( GLShaderManager *manager ) : @@ -3072,9 +3202,9 @@ GLShader_depthtile1::GLShader_depthtile1( GLShaderManager *manager ) : { } -void GLShader_depthtile1::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_depthtile1::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); } GLShader_depthtile2::GLShader_depthtile2( GLShaderManager *manager ) : @@ -3084,9 +3214,9 @@ GLShader_depthtile2::GLShader_depthtile2( GLShaderManager *manager ) : { } -void GLShader_depthtile2::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_depthtile2::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); } GLShader_lighttile::GLShader_lighttile( GLShaderManager *manager ) : @@ -3100,12 +3230,12 @@ GLShader_lighttile::GLShader_lighttile( GLShaderManager *manager ) : { } -void GLShader_lighttile::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_lighttile::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); if( !glConfig2.uniformBufferObjectAvailable ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_Lights" ), 1 ); } } @@ -3116,9 +3246,9 @@ GLShader_fxaa::GLShader_fxaa( GLShaderManager *manager ) : { } -void GLShader_fxaa::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_fxaa::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); } GLShader_cull::GLShader_cull( GLShaderManager* manager ) : @@ -3147,8 +3277,8 @@ GLShader_depthReduction::GLShader_depthReduction( GLShaderManager* manager ) : u_InitialDepthLevel( this ) { } -void GLShader_depthReduction::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "depthTextureInitial" ), 0 ); +void GLShader_depthReduction::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "depthTextureInitial" ), 0 ); } GLShader_clearSurfaces::GLShader_clearSurfaces( GLShaderManager* manager ) : diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 80c5054a67..7490a70a90 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // *INDENT-OFF* static const unsigned int MAX_SHADER_MACROS = 10; -static const unsigned int GL_SHADER_VERSION = 5; +static const unsigned int GL_SHADER_VERSION = 6; class ShaderException : public std::runtime_error { @@ -47,14 +47,13 @@ enum class ShaderKind }; // Header for saved shader binaries -struct GLBinaryHeader -{ - unsigned int version; - unsigned int checkSum; // checksum of shader source this was built from - unsigned int driverVersionHash; // detect if the graphics driver was different +struct GLBinaryHeader { + uint32_t version; + uint32_t checkSum; // checksum of shader source this was built from + uint32_t driverVersionHash; // detect if the graphics driver was different - unsigned int macros[ MAX_SHADER_MACROS ]; // macros the shader uses ( may or may not be enabled ) - unsigned int numMacros; + GLuint type; + uint32_t macro; // Bitmask of macros the shader uses ( may or may not be enabled ) GLenum binaryFormat; // argument to glProgramBinary uint32_t binaryLength; // argument to glProgramBinary @@ -68,14 +67,12 @@ class GLShaderManager; // represents a piece of GLSL code that can be copied verbatim into // GLShaders, like a .h file in C++ -class GLHeader -{ +class GLHeader { private: - - std::string _name; - std::string _text; + std::string _name; + std::string _text; uint32_t _lineCount; - GLShaderManager *_shaderManager; + GLShaderManager *_shaderManager; public: GLHeader() : _name(), _text(), _lineCount(), _shaderManager( nullptr ) @@ -85,8 +82,7 @@ class GLHeader _name( name ), _text( text ), _lineCount( std::count( text.begin(), text.end(), '\n' ) ), - _shaderManager( manager ) - { + _shaderManager( manager ) { } const std::string &getName() const { return _name; } @@ -95,44 +91,39 @@ class GLHeader const GLShaderManager *getManager() const { return _shaderManager; } }; -class GLShader -{ +class GLShader { friend class GLShaderManager; private: GLShader( const GLShader & ) = delete; - GLShader &operator = ( const GLShader & ) = delete; + GLShader &operator = ( const GLShader & ) = delete; - std::string _name; - std::string _mainShaderName; + std::string _name; + std::string _mainShaderName; const bool _useMaterialSystem; GLuint std430Size = 0; uint padding = 0; uint textureCount = 0; protected: - int _activeMacros; - unsigned int _checkSum; - shaderProgram_t *_currentProgram; - const uint32_t _vertexAttribsRequired; - uint32_t _vertexAttribs; // can be set by uniforms - GLShaderManager *_shaderManager; - - bool _hasVertexShader; - std::string _vertexShaderText; - bool _hasFragmentShader; - std::string _fragmentShaderText; - bool _hasComputeShader; - std::string _computeShaderText; - std::vector< shaderProgram_t > _shaderPrograms; - - - size_t _uniformStorageSize; - std::vector< GLUniform * > _uniforms; - std::vector< GLUniformBlock * > _uniformBlocks; - std::vector< GLCompileMacro * > _compileMacros; - - - - + int _activeMacros; + unsigned int _checkSum; + ShaderProgramDescriptor* currentProgram; + const uint32_t _vertexAttribsRequired; + uint32_t _vertexAttribs; // can be set by uniforms + GLShaderManager *_shaderManager; + + bool _hasVertexShader; + bool _hasFragmentShader; + bool _hasComputeShader; + std::vector shaderPrograms; + + std::vector vertexShaderDescriptors; + std::vector fragmentShaderDescriptors; + std::vector computeShaderDescriptors; + + size_t _uniformStorageSize; + std::vector _uniforms; + std::vector _uniformBlocks; + std::vector _compileMacros; GLShader( const std::string &name, uint32_t vertexAttribsRequired, GLShaderManager *manager, const bool hasVertexShader = true, const bool hasFragmentShader = true, const bool hasComputeShader = false ) : @@ -141,15 +132,13 @@ class GLShader _useMaterialSystem( false ), _activeMacros( 0 ), _checkSum( 0 ), - _currentProgram( nullptr ), _vertexAttribsRequired( vertexAttribsRequired ), _vertexAttribs( 0 ), _shaderManager( manager ), _hasVertexShader( hasVertexShader ), _hasFragmentShader( hasFragmentShader ), _hasComputeShader( hasComputeShader ), - _uniformStorageSize( 0 ) - { + _uniformStorageSize( 0 ) { } GLShader( const std::string &name, const std::string &mainShaderName, uint32_t vertexAttribsRequired, GLShaderManager *manager, @@ -159,15 +148,13 @@ class GLShader _useMaterialSystem( false ), _activeMacros( 0 ), _checkSum( 0 ), - _currentProgram( nullptr ), _vertexAttribsRequired( vertexAttribsRequired ), _vertexAttribs( 0 ), _shaderManager( manager ), _hasVertexShader( hasVertexShader ), _hasFragmentShader( hasFragmentShader ), _hasComputeShader( hasComputeShader ), - _uniformStorageSize( 0 ) - { + _uniformStorageSize( 0 ) { } GLShader( const std::string& name, const std::string& mainShaderName, const bool useMaterialSystem, uint32_t vertexAttribsRequired, @@ -178,7 +165,6 @@ class GLShader _useMaterialSystem( useMaterialSystem ), _activeMacros( 0 ), _checkSum( 0 ), - _currentProgram( nullptr ), _vertexAttribsRequired( vertexAttribsRequired ), _vertexAttribs( 0 ), _shaderManager( manager ), @@ -189,57 +175,16 @@ class GLShader } public: - virtual ~GLShader() - { - for ( std::size_t i = 0; i < _shaderPrograms.size(); i++ ) - { - shaderProgram_t *p = &_shaderPrograms[ i ]; - - if ( p->program ) - { - glDeleteProgram( p->program ); - } - - if ( p->VS ) - { - glDeleteShader( p->VS ); - } - - if ( p->FS ) - { - glDeleteShader( p->FS ); - } - - if ( p->CS ) { - glDeleteShader( p->CS ); - } - - if ( p->uniformFirewall ) - { - Z_Free( p->uniformFirewall ); - } - - if ( p->uniformLocations ) - { - Z_Free( p->uniformLocations ); - } - - if ( p->uniformBlockIndexes ) - { - Z_Free( p->uniformBlockIndexes ); - } - } + virtual ~GLShader() { } void RegisterUniform( GLUniform* uniform ); - void RegisterUniformBlock( GLUniformBlock *uniformBlock ) - { + void RegisterUniformBlock( GLUniformBlock *uniformBlock ) { _uniformBlocks.push_back( uniformBlock ); } - void RegisterCompileMacro( GLCompileMacro *compileMacro ) - { + void RegisterCompileMacro( GLCompileMacro *compileMacro ) { if ( _compileMacros.size() >= MAX_SHADER_MACROS ) { Sys::Drop( "Can't register more than %u compile macros for a single shader", MAX_SHADER_MACROS ); @@ -248,34 +193,31 @@ class GLShader _compileMacros.push_back( compileMacro ); } - size_t GetNumOfCompiledMacros() const - { + size_t GetNumOfCompiledMacros() const { return _compileMacros.size(); } GLint GetUniformLocation( const GLchar *uniformName ) const; - shaderProgram_t *GetProgram() const - { - return _currentProgram; + ShaderProgramDescriptor* GetProgram() const { + return currentProgram; } - const std::string &GetName() const - { + const std::string &GetName() const { return _name; } - const std::string &GetMainShaderName() const - { + const std::string &GetMainShaderName() const { return _mainShaderName; } protected: - void PostProcessUniforms(); - bool GetCompileMacrosString( size_t permutation, std::string &compileMacrosOut ) const; + void PostProcessUniforms(); + uint32_t GetUniqueCompileMacros( size_t permutation, const int type ) const; + bool GetCompileMacrosString( size_t permutation, std::string &compileMacrosOut, const int type ) const; virtual void BuildShaderCompileMacros( std::string& /*vertexInlines*/ ) { }; - virtual void SetShaderProgramUniforms( shaderProgram_t* /*shaderProgram*/ ) { }; - int SelectProgram(); + virtual void SetShaderProgramUniforms( ShaderProgramDescriptor* /*shaderProgram*/ ) { }; + int SelectProgram(); public: GLuint GetProgram( int deformIndex ); void BindProgram( int deformIndex ); @@ -283,33 +225,27 @@ class GLShader void DispatchComputeIndirect( const GLintptr indirectBuffer ); void SetRequiredVertexPointers(); - bool IsMacroSet( int bit ) - { + bool IsMacroSet( int bit ) { return ( _activeMacros & bit ) != 0; } - void AddMacroBit( int bit ) - { + void AddMacroBit( int bit ) { _activeMacros |= bit; } - void DelMacroBit( int bit ) - { + void DelMacroBit( int bit ) { _activeMacros &= ~bit; } - bool IsVertexAttribSet( int bit ) - { + bool IsVertexAttribSet( int bit ) { return ( _vertexAttribs & bit ) != 0; } - void AddVertexAttribBit( int bit ) - { + void AddVertexAttribBit( int bit ) { _vertexAttribs |= bit; } - void DelVertexAttribBit( int bit ) - { + void DelVertexAttribBit( int bit ) { _vertexAttribs &= ~bit; } @@ -336,12 +272,102 @@ class GLShader void WriteUniformsToBuffer( uint32_t* buffer ); }; -class GLShaderManager -{ - std::queue< GLShader* > _shaderBuildQueue; - std::vector< std::unique_ptr< GLShader > > _shaders; - std::unordered_map< std::string, int > _deformShaderLookup; - std::vector< GLint > _deformShaders; +struct ShaderEntry { + std::string name; + uint32_t macro; + GLuint type; + + bool operator==( const ShaderEntry& other ) const { + return name == other.name && macro == other.macro && type == other.type; + } + + bool operator!=( const ShaderEntry& other ) const { + return !( *this == other ); + } +}; + +struct ShaderDescriptor { + std::string name; + + std::string macros; + uint32_t macro; + + GLenum type; + bool main = false; + + GLuint id = 0; + + std::string shaderSource; +}; + +static const uint32_t MAX_SHADER_PROGRAM_SHADERS = 16; + +struct ShaderProgramDescriptor { + GLuint id = 0; + + bool hasMain = false; + GLuint type; + + uint32_t macro = 0; + + GLuint shaders[MAX_SHADER_PROGRAM_SHADERS] {}; + ShaderEntry shaderNames[MAX_SHADER_PROGRAM_SHADERS] {}; + std::string mainShader; + uint32_t shaderCount = 0; + + GLint* uniformLocations; + GLuint* uniformBlockIndexes; + byte* uniformFirewall; + + uint32_t checkSum; + + void AttachShader( ShaderDescriptor* descriptor ) { + if ( shaderCount == MAX_SHADER_PROGRAM_SHADERS ) { + Log::Warn( "Tried to attach too many shaders to program: skipping shader %s %s", descriptor->name, descriptor->macros ); + return; + } + + if ( !shaderCount ) { + type = descriptor->type; + } else if ( type != descriptor->type ) { + type = 0; + } + + if ( descriptor->main ) { + if ( hasMain && mainShader != descriptor->name ) { + Log::Warn( "More than one shader specified as main, current: %s, new: %s, using current", + mainShader, descriptor->name ); + } else { + mainShader = descriptor->name; + hasMain = true; + } + } + + shaders[shaderCount] = descriptor->id; + + shaderNames[shaderCount].name = descriptor->name; + shaderNames[shaderCount].macro = descriptor->macro; + shaderNames[shaderCount].type = descriptor->type; + + macro |= descriptor->macro; + + /* std::sort( shaderNames, shaderNames + shaderCount, + []( const ShaderEntry& lhs, const ShaderEntry& rhs ) { + return lhs.name < rhs.name; + } + ); */ + + shaderCount++; + }; +}; + +class GLShaderManager { + std::queue _shaderBuildQueue; + std::vector> _shaders; + + uint32_t deformShaderCount = 0; + std::unordered_map _deformShaderLookup; + unsigned int _driverVersionHash; // For cache invalidation if hardware changes bool _shaderBinaryCacheInvalidated; @@ -363,11 +389,12 @@ class GLShaderManager void GenerateBuiltinHeaders(); void GenerateWorldHeaders(); - template< class T > - void load( T *& shader ) - { - if( _deformShaders.size() == 0 ) { - Q_UNUSED(getDeformShaderIndex( nullptr, 0 )); + template + void LoadShader( T *& shader ) { + if( !deformShaderCount ) { + Q_UNUSED( GetDeformShaderIndex( nullptr, 0 ) ); + initTime = 0; + initCount = 0; } shader = new T( this ); @@ -375,12 +402,12 @@ class GLShaderManager _shaders.emplace_back( shader ); _shaderBuildQueue.push( shader ); } - void freeAll(); - int getDeformShaderIndex( deformStage_t *deforms, int numDeforms ); + int GetDeformShaderIndex( deformStage_t *deforms, int numDeforms ); - bool buildPermutation( GLShader *shader, int macroIndex, int deformIndex ); - void buildAll(); + bool BuildPermutation( GLShader* shader, int macroIndex, int deformIndex ); + void BuildAll(); + void FreeAll(); private: struct InfoLogEntry { int line; @@ -389,25 +416,44 @@ class GLShaderManager std::string error; }; - bool LoadShaderBinary( GLShader *shader, size_t permutation ); - void SaveShaderBinary( GLShader *shader, size_t permutation ); - GLuint CompileShader( Str::StringRef programName, Str::StringRef shaderText, - std::initializer_list headers, - GLenum shaderType ) const; - void CompileGPUShaders( GLShader *shader, shaderProgram_t *program, - const std::string &compileMacros ); - void CompileAndLinkGPUShaderProgram( GLShader *shader, shaderProgram_t *program, - Str::StringRef compileMacros, int deformIndex ); - std::string ShaderPostProcess( GLShader *shader, const std::string& shaderText ); + std::vector shaderDescriptors; + std::vector shaderProgramDescriptors; + + int compileTime; + uint32_t compileCount; + int linkTime; + uint32_t linkCount; + int initTime; + uint32_t initCount; + int cacheLoadTime; + uint32_t cacheLoadCount; + int cacheSaveTime; + uint32_t cacheSaveCount; + + void BuildShader( ShaderDescriptor* descriptor ); + void BuildShaderProgram( ShaderProgramDescriptor* descriptor ); + + std::string GetDeformShaderName( const int index ); + ShaderProgramDescriptor* FindShaderProgram( std::vector& shaders, const std::string& mainShader ); + + bool LoadShaderBinary( const std::vector& shaders, const std::string& mainShader, + ShaderProgramDescriptor* out ); + void SaveShaderBinary( ShaderProgramDescriptor* descriptor ); + + std::string ShaderPostProcess( GLShader *shader, const std::string& shaderText, const uint32_t offset ); std::string BuildDeformShaderText( const std::string& steps ); - std::string ProcessInserts( const std::string& shaderText, const uint32_t offset ) const; + std::string ProcessInserts( const std::string& shaderText ) const; void LinkProgram( GLuint program ) const; void BindAttribLocations( GLuint program ) const; void PrintShaderSource( Str::StringRef programName, GLuint object, std::vector& infoLogLines ) const; std::vector ParseInfoLog( const std::string& infoLog ) const; std::string GetInfoLog( GLuint object ) const; - void InitShader( GLShader *shader ); - void UpdateShaderProgramUniformLocations( GLShader *shader, shaderProgram_t *shaderProgram ) const; + std::string BuildShaderText( const std::string& mainShaderText, const std::vector& headers, const std::string& macros ); + ShaderDescriptor* FindShader( const std::string& name, const std::string& mainText, + const GLenum type, const std::vector& headers, + const uint32_t macro = 0, const std::string& compileMacros = "", const bool main = false ); + void InitShader( GLShader* shader ); + void UpdateShaderProgramUniformLocations( GLShader* shader, ShaderProgramDescriptor* shaderProgram ) const; }; class GLUniform @@ -486,9 +532,9 @@ class GLUniform // This should return a pointer to the memory right after the one this uniform wrote to virtual uint32_t* WriteToBuffer( uint32_t* buffer ); - void UpdateShaderProgramUniformLocation( shaderProgram_t *shaderProgram ) + void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { - shaderProgram->uniformLocations[ _locationIndex ] = glGetUniformLocation( shaderProgram->program, GetName() ); + shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, GetName() ); } virtual size_t GetSize() @@ -505,7 +551,7 @@ class GLUniformSampler : protected GLUniform { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -559,7 +605,7 @@ class GLUniformSampler1D : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -581,7 +627,7 @@ class GLUniformSampler2D : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -603,7 +649,7 @@ class GLUniformSampler3D : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -625,7 +671,7 @@ class GLUniformUSampler3D : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -647,7 +693,7 @@ class GLUniformSamplerCube : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -672,7 +718,7 @@ class GLUniform1i : protected GLUniform inline void SetValue( int value ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -725,7 +771,7 @@ class GLUniform1ui : protected GLUniform { } inline void SetValue( uint value ) { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -776,7 +822,7 @@ class GLUniform1Bool : protected GLUniform { } inline void SetValue( int value ) { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -830,7 +876,7 @@ class GLUniform1f : protected GLUniform inline void SetValue( float value ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -887,7 +933,7 @@ class GLUniform1fv : protected GLUniform inline void SetValue( int numFloats, float *f ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -930,7 +976,7 @@ class GLUniform2f : protected GLUniform inline void SetValue( const vec2_t v ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -990,7 +1036,7 @@ class GLUniform3f : protected GLUniform inline void SetValue( const vec3_t v ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1050,7 +1096,7 @@ class GLUniform4f : protected GLUniform inline void SetValue( const vec4_t v ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1107,7 +1153,7 @@ class GLUniform4fv : protected GLUniform inline void SetValue( int numV, vec4_t *v ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1150,7 +1196,7 @@ class GLUniformMatrix4f : protected GLUniform inline void SetValue( GLboolean transpose, const matrix_t m ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1205,7 +1251,7 @@ class GLUniformMatrix32f : protected GLUniform { } inline void SetValue( GLboolean transpose, const vec_t* m ) { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1251,7 +1297,7 @@ class GLUniformMatrix4fv : protected GLUniform inline void SetValue( int numMatrices, GLboolean transpose, const matrix_t *m ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1293,7 +1339,7 @@ class GLUniformMatrix34fv : protected GLUniform inline void SetValue( int numMatrices, GLboolean transpose, const float *m ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1351,13 +1397,13 @@ class GLUniformBlock return _name.c_str(); } - void UpdateShaderProgramUniformBlockIndex( shaderProgram_t *shaderProgram ) + void UpdateShaderProgramUniformBlockIndex( ShaderProgramDescriptor* shaderProgram ) { - shaderProgram->uniformBlockIndexes[ _locationIndex ] = glGetUniformBlockIndex( shaderProgram->program, GetName() ); + shaderProgram->uniformBlockIndexes[_locationIndex] = glGetUniformBlockIndex( shaderProgram->id, GetName() ); } void SetBuffer( GLuint buffer ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); GLuint blockIndex = p->uniformBlockIndexes[ _locationIndex ]; ASSERT_EQ(p, glState.currentProgram); @@ -1640,8 +1686,15 @@ class GLCompileMacro }; public: + enum ShaderType { + VERTEX = BIT( 0 ), + FRAGMENT = BIT( 1 ), + COMPUTE = BIT( 2 ) + }; + virtual const char *GetName() const = 0; virtual EGLCompileMacro GetType() const = 0; + virtual int GetShaderTypes() const = 0; virtual bool HasConflictingMacros( size_t, const std::vector& ) const { @@ -1703,6 +1756,10 @@ class GLCompileMacro_USE_BSP_SURFACE : return EGLCompileMacro::USE_BSP_SURFACE; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetBspSurface( bool enable ) { SetMacro( enable ); @@ -1728,6 +1785,10 @@ class GLCompileMacro_USE_VERTEX_SKINNING : return EGLCompileMacro::USE_VERTEX_SKINNING; } + int GetShaderTypes() const override { + return ShaderType::VERTEX; + } + bool HasConflictingMacros( size_t permutation, const std::vector< GLCompileMacro * > ¯os ) const override; bool MissesRequiredMacros( size_t permutation, const std::vector< GLCompileMacro * > ¯os ) const override; @@ -1761,6 +1822,10 @@ class GLCompileMacro_USE_VERTEX_ANIMATION : return EGLCompileMacro::USE_VERTEX_ANIMATION; } + int GetShaderTypes() const override { + return ShaderType::VERTEX; + } + bool HasConflictingMacros( size_t permutation, const std::vector< GLCompileMacro * > ¯os ) const override; uint32_t GetRequiredVertexAttributes() const override; @@ -1789,6 +1854,10 @@ class GLCompileMacro_USE_TCGEN_ENVIRONMENT : return EGLCompileMacro::USE_TCGEN_ENVIRONMENT; } + int GetShaderTypes() const override { + return ShaderType::VERTEX; + } + bool HasConflictingMacros(size_t permutation, const std::vector< GLCompileMacro * > ¯os) const override; uint32_t GetRequiredVertexAttributes() const override { @@ -1821,6 +1890,10 @@ class GLCompileMacro_USE_TCGEN_LIGHTMAP : return EGLCompileMacro::USE_TCGEN_LIGHTMAP; } + int GetShaderTypes() const override { + return ShaderType::VERTEX; + } + void SetTCGenLightmap( bool enable ) { SetMacro( enable ); @@ -1848,6 +1921,10 @@ class GLCompileMacro_USE_GRID_LIGHTING : return EGLCompileMacro::USE_GRID_LIGHTING; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetGridLighting( bool enable ) { SetMacro( enable ); @@ -1875,6 +1952,10 @@ class GLCompileMacro_USE_DELUXE_MAPPING : return EGLCompileMacro::USE_DELUXE_MAPPING; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetDeluxeMapping( bool enable ) { SetMacro( enable ); @@ -1902,6 +1983,10 @@ class GLCompileMacro_USE_GRID_DELUXE_MAPPING : return EGLCompileMacro::USE_GRID_DELUXE_MAPPING; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetGridDeluxeMapping( bool enable ) { SetMacro( enable ); @@ -1927,6 +2012,10 @@ class GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP : return EGLCompileMacro::USE_HEIGHTMAP_IN_NORMALMAP; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetHeightMapInNormalMap( bool enable ) { SetMacro( enable ); @@ -1952,6 +2041,10 @@ class GLCompileMacro_USE_RELIEF_MAPPING : return EGLCompileMacro::USE_RELIEF_MAPPING; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetReliefMapping( bool enable ) { SetMacro( enable ); @@ -1979,6 +2072,10 @@ class GLCompileMacro_USE_REFLECTIVE_SPECULAR : return EGLCompileMacro::USE_REFLECTIVE_SPECULAR; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetReflectiveSpecular( bool enable ) { SetMacro( enable ); @@ -2004,6 +2101,10 @@ class GLCompileMacro_LIGHT_DIRECTIONAL : return EGLCompileMacro::LIGHT_DIRECTIONAL; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetMacro_LIGHT_DIRECTIONAL( bool enable ) { SetMacro( enable ); @@ -2029,6 +2130,10 @@ class GLCompileMacro_USE_SHADOWING : return EGLCompileMacro::USE_SHADOWING; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetShadowing( bool enable ) { SetMacro( enable ); @@ -2054,6 +2159,10 @@ class GLCompileMacro_USE_DEPTH_FADE : return EGLCompileMacro::USE_DEPTH_FADE; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetDepthFade( bool enable ) { SetMacro( enable ); @@ -2079,6 +2188,10 @@ class GLCompileMacro_USE_PHYSICAL_MAPPING : return USE_PHYSICAL_MAPPING; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetPhysicalShading( bool enable ) { SetMacro( enable ); @@ -3973,7 +4086,7 @@ class GLShader_generic : { public: GLShader_generic( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_genericMaterial : @@ -3999,7 +4112,7 @@ class GLShader_genericMaterial : public GLCompileMacro_USE_DEPTH_FADE { public: GLShader_genericMaterial( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_lightMapping : @@ -4050,7 +4163,7 @@ class GLShader_lightMapping : { public: GLShader_lightMapping( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_lightMappingMaterial : @@ -4098,7 +4211,7 @@ class GLShader_lightMappingMaterial : public GLCompileMacro_USE_PHYSICAL_MAPPING { public: GLShader_lightMappingMaterial( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_forwardLighting_omniXYZ : @@ -4141,7 +4254,7 @@ class GLShader_forwardLighting_omniXYZ : { public: GLShader_forwardLighting_omniXYZ( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_forwardLighting_projXYZ : @@ -4186,7 +4299,7 @@ class GLShader_forwardLighting_projXYZ : public: GLShader_forwardLighting_projXYZ( GLShaderManager *manager ); void BuildShaderCompileMacros( std::string& compileMacros ) override; - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_forwardLighting_directionalSun : @@ -4238,7 +4351,7 @@ class GLShader_forwardLighting_directionalSun : public: GLShader_forwardLighting_directionalSun( GLShaderManager *manager ); void BuildShaderCompileMacros( std::string& compileMacros ) override; - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_shadowFill : @@ -4260,7 +4373,7 @@ class GLShader_shadowFill : { public: GLShader_shadowFill( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_reflection : @@ -4286,7 +4399,7 @@ class GLShader_reflection : { public: GLShader_reflection( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_reflectionMaterial : @@ -4307,7 +4420,7 @@ class GLShader_reflectionMaterial : public GLCompileMacro_USE_RELIEF_MAPPING { public: GLShader_reflectionMaterial( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_skybox : @@ -4322,7 +4435,7 @@ class GLShader_skybox : { public: GLShader_skybox( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_skyboxMaterial : @@ -4336,7 +4449,7 @@ class GLShader_skyboxMaterial : public u_ModelViewProjectionMatrix { public: GLShader_skyboxMaterial( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_fogQuake3 : @@ -4356,7 +4469,7 @@ class GLShader_fogQuake3 : { public: GLShader_fogQuake3( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_fogQuake3Material : @@ -4371,7 +4484,7 @@ class GLShader_fogQuake3Material : public GLDeformStage { public: GLShader_fogQuake3Material( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_fogGlobal : @@ -4385,7 +4498,7 @@ class GLShader_fogGlobal : { public: GLShader_fogGlobal( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_heatHaze : @@ -4407,7 +4520,7 @@ class GLShader_heatHaze : { public: GLShader_heatHaze( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_heatHazeMaterial : @@ -4426,7 +4539,7 @@ class GLShader_heatHazeMaterial : { public: GLShader_heatHazeMaterial( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_screen : @@ -4436,7 +4549,7 @@ class GLShader_screen : { public: GLShader_screen( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_screenMaterial : @@ -4445,7 +4558,7 @@ class GLShader_screenMaterial : public u_ModelViewProjectionMatrix { public: GLShader_screenMaterial( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_portal : @@ -4457,7 +4570,7 @@ class GLShader_portal : { public: GLShader_portal( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_contrast : @@ -4467,7 +4580,7 @@ class GLShader_contrast : { public: GLShader_contrast( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_cameraEffects : @@ -4485,7 +4598,7 @@ class GLShader_cameraEffects : { public: GLShader_cameraEffects( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_blur : @@ -4498,7 +4611,7 @@ class GLShader_blur : { public: GLShader_blur( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_debugShadowMap : @@ -4508,7 +4621,7 @@ class GLShader_debugShadowMap : { public: GLShader_debugShadowMap( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_liquid : @@ -4544,7 +4657,7 @@ class GLShader_liquid : { public: GLShader_liquid( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_liquidMaterial : @@ -4580,7 +4693,7 @@ class GLShader_liquidMaterial : public GLCompileMacro_USE_RELIEF_MAPPING { public: GLShader_liquidMaterial( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_motionblur : @@ -4592,7 +4705,7 @@ class GLShader_motionblur : { public: GLShader_motionblur( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_ssao : @@ -4604,7 +4717,7 @@ class GLShader_ssao : { public: GLShader_ssao( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_depthtile1 : @@ -4615,7 +4728,7 @@ class GLShader_depthtile1 : { public: GLShader_depthtile1( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_depthtile2 : @@ -4625,7 +4738,7 @@ class GLShader_depthtile2 : { public: GLShader_depthtile2( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_lighttile : @@ -4639,7 +4752,7 @@ class GLShader_lighttile : { public: GLShader_lighttile( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_fxaa : @@ -4649,7 +4762,7 @@ class GLShader_fxaa : { public: GLShader_fxaa( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_cull : @@ -4680,7 +4793,7 @@ class GLShader_depthReduction : public u_InitialDepthLevel { public: GLShader_depthReduction( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_clearSurfaces : diff --git a/src/engine/renderer/glsl_source/cull_cp.glsl b/src/engine/renderer/glsl_source/cull_cp.glsl index 1e210e21fc..201cdc2844 100644 --- a/src/engine/renderer/glsl_source/cull_cp.glsl +++ b/src/engine/renderer/glsl_source/cull_cp.glsl @@ -42,6 +42,11 @@ layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in; layout(binding = 0) uniform sampler2D depthImage; +struct SurfaceDescriptor { + BoundingSphere boundingSphere; + uint surfaceCommandIDs[MAX_SURFACE_COMMANDS]; +}; + layout(std430, binding = BIND_SURFACE_DESCRIPTORS) readonly restrict buffer surfaceDescriptorsSSBO { SurfaceDescriptor surfaces[]; }; diff --git a/src/engine/renderer/glsl_source/fogQuake3_vp.glsl b/src/engine/renderer/glsl_source/fogQuake3_vp.glsl index 35123a2d5d..1101a3ad77 100644 --- a/src/engine/renderer/glsl_source/fogQuake3_vp.glsl +++ b/src/engine/renderer/glsl_source/fogQuake3_vp.glsl @@ -44,9 +44,9 @@ void DeformVertex( inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, - in float time); + in float time ); -void main() +void main() { #insert material_vp @@ -63,7 +63,7 @@ void main() LB.normal, texCoord, color, - u_Time); + u_Time ); // transform vertex position into homogenous clip-space gl_Position = u_ModelViewProjectionMatrix * position; diff --git a/src/engine/renderer/glsl_source/generic_vp.glsl b/src/engine/renderer/glsl_source/generic_vp.glsl index 3affc9a91d..a13740611c 100644 --- a/src/engine/renderer/glsl_source/generic_vp.glsl +++ b/src/engine/renderer/glsl_source/generic_vp.glsl @@ -55,9 +55,9 @@ void DeformVertex( inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, - in float time); + in float time ); -void main() +void main() { #insert material_vp @@ -72,11 +72,7 @@ void main() color = color * ColorModulateToColor( u_ColorModulateColorGen, lightFactor ) + unpackUnorm4x8( u_Color ) * vec4( lightFactor, lightFactor, lightFactor, 1.0 ); - DeformVertex( position, - LB.normal, - texCoord, - color, - u_Time); + DeformVertex( position, LB.normal, texCoord, color, u_Time ); // transform vertex position into homogenous clip-space gl_Position = u_ModelViewProjectionMatrix * position; diff --git a/src/engine/renderer/glsl_source/lightMapping_vp.glsl b/src/engine/renderer/glsl_source/lightMapping_vp.glsl index 49bee16a28..8e6bf7e30c 100644 --- a/src/engine/renderer/glsl_source/lightMapping_vp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_vp.glsl @@ -64,7 +64,7 @@ OUT(smooth) vec3 var_Normal; OUT(smooth) vec4 var_Color; -void DeformVertex(inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, in float time); +void DeformVertex( inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, in float time ); void main() { @@ -78,7 +78,7 @@ void main() color = color * ColorModulateToColor( u_ColorModulateColorGen ) + unpackUnorm4x8( u_Color ); - DeformVertex(position, LB.normal, texCoord, color, u_Time); + DeformVertex( position, LB.normal, texCoord, color, u_Time ); // transform vertex position into homogenous clip-space gl_Position = u_ModelViewProjectionMatrix * position; diff --git a/src/engine/renderer/glsl_source/material_cp.glsl b/src/engine/renderer/glsl_source/material_cp.glsl index 8156273bd8..159b314988 100644 --- a/src/engine/renderer/glsl_source/material_cp.glsl +++ b/src/engine/renderer/glsl_source/material_cp.glsl @@ -39,10 +39,10 @@ struct BoundingSphere { float radius; }; -struct SurfaceDescriptor { +/* struct SurfaceDescriptor { BoundingSphere boundingSphere; uint surfaceCommandIDs[MAX_SURFACE_COMMANDS]; -}; +}; */ struct PortalSurface { BoundingSphere boundingSphere; diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 0e3c749abe..142146bcfd 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -120,7 +120,7 @@ GLuint64 BindAnimatedImage( int unit, const textureBundle_t *bundle ) return GL_BindToTMU( unit, bundle->image[ index ] ); } -void GL_BindProgram( shaderProgram_t *program ) +void GL_BindProgram( ShaderProgramDescriptor* program ) { if ( !program ) { @@ -130,7 +130,7 @@ void GL_BindProgram( shaderProgram_t *program ) if ( glState.currentProgram != program ) { - glUseProgram( program->program ); + glUseProgram( program->id ); glState.currentProgram = program; } } @@ -1378,7 +1378,7 @@ static void RB_SetupLightForShadowing( trRefLight_t *light, int index, bool shadowClip ) { // HACK: bring OpenGL into a safe state or strange FBO update problems will occur - GL_BindProgram( nullptr ); + GL_BindNullProgram(); GL_State( GLS_DEFAULT ); GL_Bind( tr.whiteImage ); diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index 14e9d3dd75..2d0e7135f4 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -5054,6 +5054,7 @@ void RE_LoadWorldMap( const char *name ) Q_strncpyz( s_worldData.baseName, COM_SkipPath( s_worldData.name ), sizeof( s_worldData.name ) ); COM_StripExtension3( s_worldData.baseName, s_worldData.baseName, sizeof( s_worldData.baseName ) ); + tr.loadingMap = s_worldData.baseName; startMarker = (byte*) ri.Hunk_Alloc( 0, ha_pref::h_low ); @@ -5222,6 +5223,7 @@ void RE_LoadWorldMap( const char *name ) } tr.worldLoaded = true; + tr.loadingMap = ""; GLSL_InitWorldShaders(); if ( glConfig2.reflectionMappingAvailable ) { diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index d734da5641..511e9085d9 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -878,7 +878,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p glState.vertexAttribsState = 0; glState.vertexAttribPointersSet = 0; - GL_BindProgram( nullptr ); + GL_BindNullProgram(); glBindBuffer( GL_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); @@ -1141,7 +1141,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p } int deformIndex = - gl_shaderManager.getDeformShaderIndex( shader.deforms, shader.numDeforms ); + gl_shaderManager.GetDeformShaderIndex( shader.deforms, shader.numDeforms ); for ( shaderStage_t *stage = shader.stages; stage != shader.lastStage; stage++ ) { diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 4bee0e9c9b..0fd6eff942 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1415,18 +1415,7 @@ enum class shaderProfilerRenderSubGroupsMode { }; // *INDENT-ON* - -// Tr3B - shaderProgram_t represents a pair of one -// GLSL vertex and one GLSL fragment shader - struct shaderProgram_t - { - GLuint program; - GLuint VS, FS, CS; - uint32_t attribs; // vertex array attributes - GLint *uniformLocations; - GLuint *uniformBlockIndexes; - byte *uniformFirewall; - }; + struct ShaderProgramDescriptor; // trRefdef_t holds everything that comes in refdef_t, // as well as the locally generated scene information @@ -2439,7 +2428,7 @@ enum class shaderProfilerRenderSubGroupsMode { float vertexAttribsInterpolation; // 0 = no interpolation, 1 = final position uint32_t vertexAttribsNewFrame; // offset for VBO vertex animations uint32_t vertexAttribsOldFrame; // offset for VBO vertex animations - shaderProgram_t *currentProgram; + ShaderProgramDescriptor* currentProgram; FBO_t *currentFBO; VBO_t *currentVBO; IBO_t *currentIBO; @@ -2723,6 +2712,7 @@ enum class shaderProfilerRenderSubGroupsMode { bool worldLoaded; world_t *world; + std::string loadingMap; TextureManager textureManager; @@ -3245,7 +3235,7 @@ inline bool checkGLErrors() void GL_Unbind( image_t *image ); GLuint64 BindAnimatedImage( int unit, const textureBundle_t *bundle ); void GL_TextureFilter( image_t *image, filterType_t filterType ); - void GL_BindProgram( shaderProgram_t *program ); + void GL_BindProgram( ShaderProgramDescriptor* program ); GLuint64 GL_BindToTMU( int unit, image_t *image ); void GL_BindNullProgram(); void GL_SetDefaultState(); diff --git a/src/engine/renderer/tr_main.cpp b/src/engine/renderer/tr_main.cpp index 2c8ac3d501..639226424a 100644 --- a/src/engine/renderer/tr_main.cpp +++ b/src/engine/renderer/tr_main.cpp @@ -2469,7 +2469,7 @@ static void R_DebugGraphics() // the render thread can't make callbacks to the main thread R_SyncRenderThread(); - GL_BindProgram( nullptr ); + GL_BindNullProgram(); GL_Bind( tr.whiteImage ); diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 6950c8d17c..7ab24a91ad 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -191,7 +191,7 @@ void GLSL_InitWorldShaders() { // Material system shaders that are always loaded if material system is available if ( glConfig2.usingMaterialSystem ) { - gl_shaderManager.load( gl_cullShader ); + gl_shaderManager.LoadShader( gl_cullShader ); } } @@ -211,20 +211,20 @@ static void GLSL_InitGPUShadersOrError() gl_shaderManager.GenerateBuiltinHeaders(); // single texture rendering - gl_shaderManager.load( gl_genericShader ); + gl_shaderManager.LoadShader( gl_genericShader ); // standard light mapping - gl_shaderManager.load( gl_lightMappingShader ); + gl_shaderManager.LoadShader( gl_lightMappingShader ); // Material system shaders that are always loaded if material system is available if ( glConfig2.usingMaterialSystem ) { - gl_shaderManager.load( gl_genericShaderMaterial ); - gl_shaderManager.load( gl_lightMappingShaderMaterial ); + gl_shaderManager.LoadShader( gl_genericShaderMaterial ); + gl_shaderManager.LoadShader( gl_lightMappingShaderMaterial ); - gl_shaderManager.load( gl_clearSurfacesShader ); - gl_shaderManager.load( gl_processSurfacesShader ); - gl_shaderManager.load( gl_depthReductionShader ); + gl_shaderManager.LoadShader( gl_clearSurfacesShader ); + gl_shaderManager.LoadShader( gl_processSurfacesShader ); + gl_shaderManager.LoadShader( gl_depthReductionShader ); } if ( tr.world ) // this only happens with /glsl_restart @@ -240,18 +240,18 @@ static void GLSL_InitGPUShadersOrError() { case realtimeLightingRenderer_t::LEGACY: // projective lighting ( Doom3 style ) - gl_shaderManager.load( gl_forwardLightingShader_projXYZ ); + gl_shaderManager.LoadShader( gl_forwardLightingShader_projXYZ ); // omni-directional specular bump mapping ( Doom3 style ) - gl_shaderManager.load( gl_forwardLightingShader_omniXYZ ); + gl_shaderManager.LoadShader( gl_forwardLightingShader_omniXYZ ); // directional sun lighting ( Doom3 style ) - gl_shaderManager.load( gl_forwardLightingShader_directionalSun ); + gl_shaderManager.LoadShader( gl_forwardLightingShader_directionalSun ); break; case realtimeLightingRenderer_t::TILED: - gl_shaderManager.load( gl_depthtile1Shader ); - gl_shaderManager.load( gl_depthtile2Shader ); - gl_shaderManager.load( gl_lighttileShader ); + gl_shaderManager.LoadShader( gl_depthtile1Shader ); + gl_shaderManager.LoadShader( gl_depthtile2Shader ); + gl_shaderManager.LoadShader( gl_lighttileShader ); DAEMON_FALLTHROUGH; default: /* Dynamic shadowing code also needs this shader. @@ -266,7 +266,7 @@ static void GLSL_InitGPUShadersOrError() if ( glConfig2.shadowMapping ) { // projective lighting ( Doom3 style ) - gl_shaderManager.load( gl_forwardLightingShader_projXYZ ); + gl_shaderManager.LoadShader( gl_forwardLightingShader_projXYZ ); } } } @@ -274,106 +274,106 @@ static void GLSL_InitGPUShadersOrError() if ( glConfig2.reflectionMappingAvailable ) { // bumped cubemap reflection for abitrary polygons ( EMBM ) - gl_shaderManager.load( gl_reflectionShader ); + gl_shaderManager.LoadShader( gl_reflectionShader ); if ( glConfig2.usingMaterialSystem ) { - gl_shaderManager.load( gl_reflectionShaderMaterial ); + gl_shaderManager.LoadShader( gl_reflectionShaderMaterial ); } } if ( r_drawSky.Get() ) { // skybox drawing for abitrary polygons - gl_shaderManager.load( gl_skyboxShader ); + gl_shaderManager.LoadShader( gl_skyboxShader ); if ( glConfig2.usingMaterialSystem ) { - gl_shaderManager.load( gl_skyboxShaderMaterial ); + gl_shaderManager.LoadShader( gl_skyboxShaderMaterial ); } } // Fog GLSL is always loaded and built because disabling fog is cheat. { // Q3A volumetric fog - gl_shaderManager.load( gl_fogQuake3Shader ); + gl_shaderManager.LoadShader( gl_fogQuake3Shader ); if ( glConfig2.usingMaterialSystem ) { - gl_shaderManager.load( gl_fogQuake3ShaderMaterial ); + gl_shaderManager.LoadShader( gl_fogQuake3ShaderMaterial ); } // global fog post process effect - gl_shaderManager.load( gl_fogGlobalShader ); + gl_shaderManager.LoadShader( gl_fogGlobalShader ); } if ( r_heatHaze->integer ) { // heatHaze post process effect - gl_shaderManager.load( gl_heatHazeShader ); + gl_shaderManager.LoadShader( gl_heatHazeShader ); if ( glConfig2.usingMaterialSystem ) { - gl_shaderManager.load( gl_heatHazeShaderMaterial ); + gl_shaderManager.LoadShader( gl_heatHazeShaderMaterial ); } } if ( glConfig2.bloom ) { // screen post process effect - gl_shaderManager.load( gl_screenShader ); + gl_shaderManager.LoadShader( gl_screenShader ); if ( glConfig2.usingMaterialSystem ) { - gl_shaderManager.load( gl_screenShaderMaterial ); + gl_shaderManager.LoadShader( gl_screenShaderMaterial ); } // LDR bright pass filter - gl_shaderManager.load( gl_contrastShader ); + gl_shaderManager.LoadShader( gl_contrastShader ); } // portal process effect - gl_shaderManager.load( gl_portalShader ); + gl_shaderManager.LoadShader( gl_portalShader ); // camera post process effect - gl_shaderManager.load( gl_cameraEffectsShader ); + gl_shaderManager.LoadShader( gl_cameraEffectsShader ); if ( glConfig2.bloom || glConfig2.shadowMapping ) { // gaussian blur - gl_shaderManager.load( gl_blurShader ); + gl_shaderManager.LoadShader( gl_blurShader ); } if ( glConfig2.shadowMapping ) { // shadowmap distance compression - gl_shaderManager.load( gl_shadowFillShader ); + gl_shaderManager.LoadShader( gl_shadowFillShader ); // debug utils - gl_shaderManager.load( gl_debugShadowMapShader ); + gl_shaderManager.LoadShader( gl_debugShadowMapShader ); } if ( r_liquidMapping->integer != 0 ) { - gl_shaderManager.load( gl_liquidShader ); + gl_shaderManager.LoadShader( gl_liquidShader ); if ( glConfig2.usingMaterialSystem ) { - gl_shaderManager.load( gl_liquidShaderMaterial ); + gl_shaderManager.LoadShader( gl_liquidShaderMaterial ); } } if ( glConfig2.motionBlur ) { - gl_shaderManager.load( gl_motionblurShader ); + gl_shaderManager.LoadShader( gl_motionblurShader ); } if ( r_ssao->integer ) { if ( glConfig2.textureGatherAvailable ) { - gl_shaderManager.load( gl_ssaoShader ); + gl_shaderManager.LoadShader( gl_ssaoShader ); } else { @@ -383,12 +383,12 @@ static void GLSL_InitGPUShadersOrError() if ( r_FXAA->integer != 0 ) { - gl_shaderManager.load( gl_fxaaShader ); + gl_shaderManager.LoadShader( gl_fxaaShader ); } if ( r_lazyShaders.Get() == 0 ) { - gl_shaderManager.buildAll(); + gl_shaderManager.BuildAll(); } } @@ -430,7 +430,7 @@ void GLSL_InitGPUShaders() GLSL_InitGPUShadersOrError(); if ( r_lazyShaders.Get() == 1 && tr.world != nullptr ) { - gl_shaderManager.buildAll(); + gl_shaderManager.BuildAll(); } Log::Warn("External shaders in use."); } @@ -465,7 +465,7 @@ void GLSL_ShutdownGPUShaders() { R_SyncRenderThread(); - gl_shaderManager.freeAll(); + gl_shaderManager.FreeAll(); gl_genericShader = nullptr; gl_genericShaderMaterial = nullptr; @@ -511,7 +511,7 @@ void GLSL_FinishGPUShaders() { R_SyncRenderThread(); - gl_shaderManager.buildAll(); + gl_shaderManager.BuildAll(); } /* diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index d24cb13b61..5b0b55106f 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -5229,7 +5229,7 @@ static void FinishStages() GroupActiveStages(); int deformIndex = shader.numDeforms > 0 - ? gl_shaderManager.getDeformShaderIndex( shader.deforms, shader.numDeforms ) + ? gl_shaderManager.GetDeformShaderIndex( shader.deforms, shader.numDeforms ) : 0; for ( size_t s = 0; s < numStages; s++ ) From 53c9e35f064f3c34e0f6b07d99421e565f55cd56 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 10 Mar 2025 20:29:55 +0300 Subject: [PATCH 3/6] Get rid of garbage warning --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 635eee0799..b60a091221 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -272,6 +272,7 @@ include(DaemonFlags) try_flag(WARNINGS "-Wshadow=local") try_flag(WARNINGS "-Wno-pragmas") try_flag(WARNINGS "-Wno-unknown-pragmas") +try_flag(WARNINGS "-Wno-missing-field-initializers") try_flag(WARNINGS "-W${WARNMODE}old-style-cast") try_flag(WARNINGS "-Woverloaded-virtual") try_flag(WARNINGS "-Wstrict-null-sentinel") From 4415fd4b0fbdab8b78d9cdbb3a706e9b241878ae Mon Sep 17 00:00:00 2001 From: VReaperV Date: Tue, 11 Mar 2025 20:28:11 +0300 Subject: [PATCH 4/6] NUKE some commented out code --- src/engine/renderer/glsl_source/material_cp.glsl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/engine/renderer/glsl_source/material_cp.glsl b/src/engine/renderer/glsl_source/material_cp.glsl index 159b314988..d6a7ed797f 100644 --- a/src/engine/renderer/glsl_source/material_cp.glsl +++ b/src/engine/renderer/glsl_source/material_cp.glsl @@ -39,11 +39,6 @@ struct BoundingSphere { float radius; }; -/* struct SurfaceDescriptor { - BoundingSphere boundingSphere; - uint surfaceCommandIDs[MAX_SURFACE_COMMANDS]; -}; */ - struct PortalSurface { BoundingSphere boundingSphere; From 228b400833839699cc8e8de152f99f748784ef3f Mon Sep 17 00:00:00 2001 From: VReaperV Date: Tue, 11 Mar 2025 22:07:20 +0300 Subject: [PATCH 5/6] Default nullptr uniformBlockIndexes Fixes a crash --- src/engine/renderer/gl_shader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 7490a70a90..5024ba78ea 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -316,7 +316,7 @@ struct ShaderProgramDescriptor { uint32_t shaderCount = 0; GLint* uniformLocations; - GLuint* uniformBlockIndexes; + GLuint* uniformBlockIndexes = nullptr; byte* uniformFirewall; uint32_t checkSum; From c59dcccd630b664878e7d2f649a060be892efd6d Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 12 Mar 2025 18:51:49 +0300 Subject: [PATCH 6/6] Fix-up generic_vp formatting --- .../renderer/glsl_source/generic_vp.glsl | 60 +++++++++---------- 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/engine/renderer/glsl_source/generic_vp.glsl b/src/engine/renderer/glsl_source/generic_vp.glsl index a13740611c..594c76212d 100644 --- a/src/engine/renderer/glsl_source/generic_vp.glsl +++ b/src/engine/renderer/glsl_source/generic_vp.glsl @@ -32,33 +32,29 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA uniform mat3x2 u_TextureMatrix; #endif -uniform vec3 u_ViewOrigin; +uniform vec3 u_ViewOrigin; -uniform float u_Time; +uniform float u_Time; uniform uint u_ColorModulateColorGen; uniform uint u_Color; + #if defined(USE_TCGEN_ENVIRONMENT) -uniform mat4 u_ModelMatrix; + uniform mat4 u_ModelMatrix; #endif -uniform mat4 u_ModelViewProjectionMatrix; +uniform mat4 u_ModelViewProjectionMatrix; #if defined(USE_DEPTH_FADE) -uniform float u_DepthScale; -OUT(smooth) vec2 var_FadeDepth; + uniform float u_DepthScale; + OUT(smooth) vec2 var_FadeDepth; #endif -OUT(smooth) vec2 var_TexCoords; -OUT(smooth) vec4 var_Color; +OUT(smooth) vec2 var_TexCoords; +OUT(smooth) vec4 var_Color; -void DeformVertex( inout vec4 pos, - inout vec3 normal, - inout vec2 st, - inout vec4 color, - in float time ); +void DeformVertex( inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, in float time ); -void main() -{ +void main() { #insert material_vp vec4 position; @@ -78,30 +74,28 @@ void main() gl_Position = u_ModelViewProjectionMatrix * position; // transform texcoords -#if defined(USE_TCGEN_ENVIRONMENT) - { + #if defined(USE_TCGEN_ENVIRONMENT) // TODO: Explain why only the rotational part of u_ModelMatrix is relevant - position.xyz = mat3(u_ModelMatrix) * position.xyz; + position.xyz = mat3( u_ModelMatrix ) * position.xyz; - vec3 viewer = normalize(u_ViewOrigin - position.xyz); + vec3 viewer = normalize( u_ViewOrigin - position.xyz ); - float d = dot(LB.normal, viewer); + float d = dot( LB.normal, viewer ); vec3 reflected = LB.normal * 2.0 * d - viewer; - var_TexCoords = 0.5 + vec2(0.5, -0.5) * reflected.yz; - } -#elif defined(USE_TCGEN_LIGHTMAP) - var_TexCoords = (u_TextureMatrix * vec3(lmCoord, 1.0)).xy; -#else - var_TexCoords = (u_TextureMatrix * vec3(texCoord, 1.0)).xy; -#endif - -#if defined(USE_DEPTH_FADE) - // compute z of end of fading effect - vec4 fadeDepth = u_ModelViewProjectionMatrix * (position - u_DepthScale * vec4(LB.normal, 0.0)); - var_FadeDepth = fadeDepth.zw; -#endif + var_TexCoords = 0.5 + vec2( 0.5, -0.5 ) * reflected.yz; + #elif defined(USE_TCGEN_LIGHTMAP) + var_TexCoords = ( u_TextureMatrix * vec3( lmCoord, 1.0 ) ).xy; + #else + var_TexCoords = ( u_TextureMatrix * vec3( texCoord, 1.0 ) ).xy; + #endif + + #if defined(USE_DEPTH_FADE) + // compute z of end of fading effect + vec4 fadeDepth = u_ModelViewProjectionMatrix * (position - u_DepthScale * vec4( LB.normal, 0.0 ) ); + var_FadeDepth = fadeDepth.zw; + #endif SHADER_PROFILER_SET