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") diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 1508b6bb6d..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; + } - if ( i >= shader->_shaderPrograms.size() ) - shader->_shaderPrograms.resize( (deformIndex + 1) << shader->_compileMacros.size() ); + Log::Debug( "Building %s shader permutation with macro: %s", + shader->GetName(), + compileMacros.empty() ? "none" : compileMacros ); - shaderProgram_t *shaderProgram = &shader->_shaderPrograms[ i ]; - shaderProgram->attribs = shader->_vertexAttribsRequired; // | _vertexAttribsOptional; + const int start = Sys::Milliseconds(); - 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 ); - } + if ( i >= shader->shaderPrograms.size() ) { + shader->shaderPrograms.resize( ( deformIndex + 1 ) << shader->_compileMacros.size() ); + } + + 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,310 +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 -} + // Write the header to the buffer + memcpy( binary, &shaderHeader, sizeof( shaderHeader ) ); -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 ); - - 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->GetMainShaderName(), - compileMacros.empty() ? "none" : compileMacros ); + 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 ); - // 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 ); - } -} - -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 ); - } + ri.Hunk_FreeTempMemory( binary ); - BindAttribLocations( program->program ); - LinkProgram( program->program ); + 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; } @@ -1530,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 @@ -2037,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 @@ -2100,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 ) ) + if ( macro->MissesRequiredMacros( permutation, _compileMacros ) ) { return false; + } + + if ( !( macro->GetShaderTypes() & type ) ) { + return false; + } compileMacrosOut += macro->GetName(); compileMacrosOut += " "; @@ -2148,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(); @@ -2171,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; @@ -2203,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 ); } @@ -2281,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 ) : @@ -2310,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 ) : @@ -2364,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 ); } } @@ -2429,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 ); } } @@ -2485,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 ): @@ -2544,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 ): @@ -2610,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 ) : @@ -2649,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 ): @@ -2677,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 ) : @@ -2702,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 ) : @@ -2720,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 ) : @@ -2737,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 ) : @@ -2759,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 ) : @@ -2776,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 ) : @@ -2791,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 ) : @@ -2816,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 ) : @@ -2839,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 ) : @@ -2852,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 ) : @@ -2863,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 ) : @@ -2876,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 ) : @@ -2888,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 ) : @@ -2908,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 ) : @@ -2924,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 ) : @@ -2936,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 ) : @@ -2974,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 ) : @@ -3017,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 ) : @@ -3037,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 ) : @@ -3052,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 ) : @@ -3065,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 ) : @@ -3077,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 ) : @@ -3093,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 ); } } @@ -3109,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 ) : @@ -3140,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..5024ba78ea 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 = nullptr; + 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..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; @@ -72,40 +68,34 @@ 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; // 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 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..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; 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++ )