From d636984c4dd9aecd27d2a90e5869fc29e86aad76 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Tue, 25 Feb 2025 12:22:27 +0300 Subject: [PATCH 1/6] Add debug info for shader compilation/link time Also make sure to display the full shader name rather than just the main shader. --- src/engine/renderer/gl_shader.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 6ef7a0a48b..9044f484d9 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1321,9 +1321,11 @@ void GLShaderManager::CompileGPUShaders( GLShader *shader, shaderProgram_t *prog } Log::Debug( "building %s shader permutation with macro: %s", - shader->GetMainShaderName(), + shader->GetName(), compileMacros.empty() ? "none" : compileMacros ); + const int start = Sys::Milliseconds(); + // add them std::string vertexShaderTextWithMacros = macrosString + shader->_vertexShaderText; std::string fragmentShaderTextWithMacros = macrosString + shader->_fragmentShaderText; @@ -1356,6 +1358,8 @@ void GLShaderManager::CompileGPUShaders( GLShader *shader, shaderProgram_t *prog &GLWorldHeader }, GL_COMPUTE_SHADER ); } + + Log::Debug( "Compilation: %i ms", Sys::Milliseconds() - start ); } void GLShaderManager::CompileAndLinkGPUShaderProgram( GLShader *shader, shaderProgram_t *program, @@ -1375,8 +1379,11 @@ void GLShaderManager::CompileAndLinkGPUShaderProgram( GLShader *shader, shaderPr glAttachShader( program->program, program->CS ); } + const int start = Sys::Milliseconds(); BindAttribLocations( program->program ); LinkProgram( program->program ); + + Log::Debug( "Link: %i ms", Sys::Milliseconds() - start ); } // This will generate all the extra code for material system shaders From 819ddd0ab92648b7ff3fe3e134b045c5cf09d8b5 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Thu, 27 Feb 2025 04:21:46 +0300 Subject: [PATCH 2/6] Improve shader building Previously, the GLSL shader building was done in the following manner: 1. When the renderer is started, some of the shader source was initialised/processed. This included the main shader text, #insert's, and material system post-processing. 2. When `buildAll()` was called, all permutations with empty deform shaders were built. The deform shaders themselves are loaded either at the start (for the default, empty one), or when the map itself is being loaded. These permutations included adding macros to shaders in the form of `#ifndef #define #endif`, and attaching the default deform shader. When possible, shader program binaries were saved/loaded to/from disk. 3. UI shader and non-0 deform shaders were built on-demand. There were multiple issues with that system: 1. Shader caches were unreliable. This is likely because the checksum was calculated *before* macros and such were added to the shader text. 2. Every shader permutation was always compiled and linked every time. 3. Shader programs with non-0 deformVertexes were never cached. This commit changes the underlying system to use an `std::vector` of shader program descriptors, and another one for shader descriptors. The initialisation/building of shaders is now more generic for each type, and as a result each unique shader is only compiled once. The permutations are still linked each time (unless downloaded from cache), but this change lays the foundation to easily add shader pipelines, which would solve this problem. Shader cache binaries are now identified by each shader compiled into the corresponding shader program, which allows caching non-0 deformVertexes too. This also fixes the incorrect #line numbers emitted by #insert due to macros and such being added after #insert is processed. Also adds more information into how many shader/shader programs were built and how much time it took (there's currently a small discrepancy, because the output is shown at the end of `BuildAll()`, but is gathered every time `BuildPermutation()` or `InitShader()` is called). --- src/engine/renderer/gl_shader.cpp | 1238 +++++++++-------- src/engine/renderer/gl_shader.h | 525 ++++--- src/engine/renderer/glsl_source/cull_cp.glsl | 5 + .../renderer/glsl_source/fogQuake3_vp.glsl | 6 +- .../renderer/glsl_source/generic_vp.glsl | 10 +- .../renderer/glsl_source/lightMapping_vp.glsl | 4 +- .../renderer/glsl_source/material_cp.glsl | 4 +- src/engine/renderer/tr_backend.cpp | 6 +- src/engine/renderer/tr_bsp.cpp | 2 + src/engine/renderer/tr_init.cpp | 4 +- src/engine/renderer/tr_local.h | 18 +- src/engine/renderer/tr_main.cpp | 2 +- src/engine/renderer/tr_shade.cpp | 82 +- src/engine/renderer/tr_shader.cpp | 2 +- 14 files changed, 1072 insertions(+), 836 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 9044f484d9..aaf2fc59cd 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -231,33 +231,56 @@ std::string GetShaderPath() GLShaderManager::~GLShaderManager() = default; -void GLShaderManager::freeAll() -{ +void GLShaderManager::FreeAll() { _shaders.clear(); - for ( GLint sh : _deformShaders ) - glDeleteShader( sh ); - - _deformShaders.clear(); + deformShaderCount = 0; _deformShaderLookup.clear(); + for ( const ShaderProgramDescriptor& program : shaderProgramDescriptors ) { + if ( program.id ) { + glDeleteProgram( program.id ); + } + + if ( program.uniformLocations ) { + Z_Free( program.uniformLocations ); + } + + if ( program.uniformBlockIndexes ) { + Z_Free( program.uniformBlockIndexes ); + } + + if ( program.uniformFirewall ) { + Z_Free( program.uniformFirewall ); + } + } + + shaderProgramDescriptors.clear(); + + for ( const ShaderDescriptor& shader : shaderDescriptors ) { + if ( shader.id ) { + glDeleteShader( shader.id ); + } + } + + shaderDescriptors.clear(); + while ( !_shaderBuildQueue.empty() ) { _shaderBuildQueue.pop(); } } -void GLShaderManager::UpdateShaderProgramUniformLocations( GLShader *shader, shaderProgram_t *shaderProgram ) const -{ +void GLShaderManager::UpdateShaderProgramUniformLocations( GLShader* shader, ShaderProgramDescriptor* shaderProgram ) const { size_t uniformSize = shader->_uniformStorageSize; size_t numUniforms = shader->_uniforms.size(); size_t numUniformBlocks = shader->_uniformBlocks.size(); // create buffer for storing uniform locations - shaderProgram->uniformLocations = ( GLint * ) Z_Malloc( sizeof( GLint ) * numUniforms ); + shaderProgram->uniformLocations = ( GLint* ) Z_Malloc( sizeof( GLint ) * numUniforms ); // create buffer for uniform firewall - shaderProgram->uniformFirewall = ( byte * ) Z_Malloc( uniformSize ); + shaderProgram->uniformFirewall = ( byte* ) Z_Malloc( uniformSize ); // update uniforms for (GLUniform *uniform : shader->_uniforms) @@ -267,7 +290,7 @@ void GLShaderManager::UpdateShaderProgramUniformLocations( GLShader *shader, sha if( glConfig2.uniformBufferObjectAvailable ) { // create buffer for storing uniform block indexes - shaderProgram->uniformBlockIndexes = ( GLuint * ) Z_Malloc( sizeof( GLuint ) * numUniformBlocks ); + shaderProgram->uniformBlockIndexes = ( GLuint* ) Z_Malloc( sizeof( GLuint ) * numUniformBlocks ); // update uniform blocks for (GLUniformBlock *uniformBlock : shader->_uniformBlocks) @@ -868,36 +891,39 @@ void GLShaderManager::GenerateWorldHeaders() { GLWorldHeader = GLHeader( "GLWorldHeader", GenWorldHeader(), this ); } -std::string GLShaderManager::BuildDeformShaderText( const std::string& steps ) -{ +std::string GLShaderManager::GetDeformShaderName( const int index ) { + if ( ( !tr.world && !tr.loadingMap.size() ) || !index ) { + return Str::Format( "deformVertexes_%i", index ); + } + + if ( !tr.world ) { + return Str::Format( "deformVertexes_%s_%i", tr.loadingMap, index ); + } + + return Str::Format( "deformVertexes_%s_%i", tr.world->baseName, index ); +} + +std::string GLShaderManager::BuildDeformShaderText( const std::string& steps ) { std::string shaderText; shaderText = steps + "\n"; + shaderText += GetShaderText( "deformVertexes_vp.glsl" ); - // We added a lot of stuff but if we do something bad - // in the GLSL shaders then we want the proper line - // so we have to reset the line counting. - shaderText += "#line 0\n"; - shaderText += GetShaderText("deformVertexes_vp.glsl"); return shaderText; } -int GLShaderManager::getDeformShaderIndex( deformStage_t *deforms, int numDeforms ) -{ +int GLShaderManager::GetDeformShaderIndex( deformStage_t *deforms, int numDeforms ) { std::string steps = BuildDeformSteps( deforms, numDeforms ); - int index = _deformShaderLookup[ steps ] - 1; + uint32_t index = _deformShaderLookup[steps]; - if( index < 0 ) - { - // compile new deform shader + if( !index ) { std::string shaderText = GLShaderManager::BuildDeformShaderText( steps ); - _deformShaders.push_back(CompileShader( "deformVertexes", - shaderText, - { &GLVersionDeclaration, - &GLVertexHeader }, - GL_VERTEX_SHADER ) ); - index = _deformShaders.size(); - _deformShaderLookup[ steps ] = index--; + index = deformShaderCount; + FindShader( GetDeformShaderName( index ), shaderText, GL_VERTEX_SHADER, + std::vector { &GLVersionDeclaration, &GLVertexHeader } ); + + deformShaderCount++; + _deformShaderLookup[steps] = deformShaderCount; } return index; @@ -940,102 +966,257 @@ static bool IsUnusedPermutation( const char *compileMacros ) return false; } -// returns whether something was really built (using a cached one counts) -bool GLShaderManager::buildPermutation( GLShader *shader, int macroIndex, int deformIndex ) -{ - std::string compileMacros; +void GLShaderManager::BuildShader( ShaderDescriptor* descriptor ) { + if ( descriptor->id ) { + return; + } + + const int start = Sys::Milliseconds(); + + const GLchar* text[1] = { descriptor->shaderSource.data() }; + GLint length[1] = { ( GLint ) descriptor->shaderSource.size() }; + + GLuint shader = glCreateShader( descriptor->type ); + GL_CheckErrors(); + + glShaderSource( shader, 1, text, length ); + glCompileShader( shader ); + + GL_CheckErrors(); + + GLint compiled; + glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); + + if ( !compiled ) { + std::string log = GetInfoLog( shader ); + std::vector infoLog = ParseInfoLog( log ); + PrintShaderSource( descriptor->name, shader, infoLog ); + + Log::Warn( "Compile log:\n%s", log ); + + switch ( descriptor->type ) { + case GL_VERTEX_SHADER: + ThrowShaderError( Str::Format( "Couldn't compile vertex shader: %s", descriptor->name ) ); + case GL_FRAGMENT_SHADER: + ThrowShaderError( Str::Format( "Couldn't compile fragment shader: %s", descriptor->name ) ); + case GL_COMPUTE_SHADER: + ThrowShaderError( Str::Format( "Couldn't compile compute shader: %s", descriptor->name ) ); + default: + break; + } + } + + descriptor->id = shader; + + const int time = Sys::Milliseconds() - start; + compileTime += time; + compileCount++; + Log::Debug( "Compilation: %i", time ); +} + +void GLShaderManager::BuildShaderProgram( ShaderProgramDescriptor* descriptor ) { + if ( descriptor->id ) { + return; + } + + const int start = Sys::Milliseconds(); + + GLuint program = glCreateProgram(); + GL_CheckErrors(); + + for ( const GLuint& shader : descriptor->shaders ) { + if ( shader ) { + glAttachShader( program, shader ); + } else { + break; + } + } + GL_CheckErrors(); + + BindAttribLocations( program ); + + if ( glConfig2.getProgramBinaryAvailable ) { + glProgramParameteri( program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE ); + } + + GLint linked; + glLinkProgram( program ); + + glGetProgramiv( program, GL_LINK_STATUS, &linked ); + + if ( !linked ) { + Log::Warn( "Link log:" ); + Log::Warn( GetInfoLog( program ) ); + ThrowShaderError( "Shader program failed to link!" ); + } + + descriptor->id = program; + + const int time = Sys::Milliseconds() - start; + linkTime += time; + linkCount++; + Log::Debug( "Program creation + linking: %i", time ); +} + +ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vector& shaders, const std::string& mainShader ) { + std::vector::iterator it = std::find_if( shaderProgramDescriptors.begin(), shaderProgramDescriptors.end(), + [&]( const ShaderProgramDescriptor& program ) { + for ( const ShaderEntry& shader : shaders ) { + if ( std::find( program.shaderNames, program.shaderNames + program.shaderCount, shader ) + == program.shaderNames + program.shaderCount ) { + return false; + } + } + + return true; + } + ); + + if ( it == shaderProgramDescriptors.end() ) { + std::sort( shaders.begin(), shaders.end(), + []( const ShaderEntry& lhs, const ShaderEntry& rhs ) { + return lhs.name < rhs.name; + } + ); + + ShaderProgramDescriptor desc; + std::string combinedShaderText; + std::vector buildQueue; + buildQueue.reserve( shaders.size() ); + + for ( const ShaderEntry& shader : shaders ) { + std::vector::iterator shaderIt = std::find_if( shaderDescriptors.begin(), shaderDescriptors.end(), + [&]( const ShaderDescriptor& other ) { + return shader.type == other.type && shader.macro == other.macro && shader.name == other.name; + } + ); + + if ( shaderIt == shaderDescriptors.end() ) { + ThrowShaderError( Str::Format( "Shader not found: %s %u", shader.name, shader.macro ) ); + } + + buildQueue.emplace_back( &*shaderIt ); + + combinedShaderText += shaderIt->shaderSource; + } + + desc.checkSum = Com_BlockChecksum( combinedShaderText.c_str(), combinedShaderText.length() ); + + if ( !LoadShaderBinary( shaders, mainShader, &desc ) ) { + for ( ShaderDescriptor* shader : buildQueue ) { + BuildShader( shader ); + desc.AttachShader( &*shader ); + } + BuildShaderProgram( &desc ); + SaveShaderBinary( &desc ); + } + + shaderProgramDescriptors.emplace_back( desc ); + + return &shaderProgramDescriptors[shaderProgramDescriptors.size() - 1]; + } + + return &*it; +} + +bool GLShaderManager::BuildPermutation( GLShader* shader, int macroIndex, int deformIndex ) { size_t i = macroIndex + ( deformIndex << shader->_compileMacros.size() ); - // program already exists - if ( i < shader->_shaderPrograms.size() && - shader->_shaderPrograms[ i ].program ) - { + std::string compileMacros; + if ( !shader->GetCompileMacrosString( i, compileMacros, GLCompileMacro::VERTEX | GLCompileMacro::FRAGMENT ) ) { return false; } - if ( !shader->GetCompileMacrosString( macroIndex, compileMacros ) ) - { + if ( IsUnusedPermutation( compileMacros.c_str() ) ) { return false; } - shader->BuildShaderCompileMacros( compileMacros ); - - if ( IsUnusedPermutation( compileMacros.c_str() ) ) + // Program already exists + if ( i < shader->shaderPrograms.size() && + shader->shaderPrograms[i].id ) { return false; + } + + Log::Debug( "Building %s shader permutation with macro: %s", + shader->GetName(), + compileMacros.empty() ? "none" : compileMacros ); - if ( i >= shader->_shaderPrograms.size() ) - shader->_shaderPrograms.resize( (deformIndex + 1) << shader->_compileMacros.size() ); + const int start = Sys::Milliseconds(); - shaderProgram_t *shaderProgram = &shader->_shaderPrograms[ i ]; - shaderProgram->attribs = shader->_vertexAttribsRequired; // | _vertexAttribsOptional; + if ( i >= shader->shaderPrograms.size() ) { + shader->shaderPrograms.resize( ( deformIndex + 1 ) << shader->_compileMacros.size() ); + } - if ( deformIndex > 0 ) - { - shaderProgram_t *baseShader = &shader->_shaderPrograms[ macroIndex ]; - if ( ( !baseShader->VS && shader->_hasVertexShader ) || ( !baseShader->FS && shader->_hasFragmentShader ) ) - CompileGPUShaders( shader, baseShader, compileMacros ); - - shaderProgram->program = glCreateProgram(); - if ( shader->_hasVertexShader ) { - glAttachShader( shaderProgram->program, baseShader->VS ); - glAttachShader( shaderProgram->program, _deformShaders[deformIndex] ); - } - if ( shader->_hasFragmentShader ) { - glAttachShader( shaderProgram->program, baseShader->FS ); - } + ShaderProgramDescriptor* program; - BindAttribLocations( shaderProgram->program ); - LinkProgram( shaderProgram->program ); + std::vector shaders; + if ( shader->_hasVertexShader ) { + const uint32_t macros = shader->GetUniqueCompileMacros( macroIndex, GLCompileMacro::VERTEX ); + shaders.emplace_back( ShaderEntry{ shader->_name, macros, GL_VERTEX_SHADER } ); + shaders.emplace_back( ShaderEntry{ GetDeformShaderName( deformIndex ), 0, GL_VERTEX_SHADER } ); } - else if ( !LoadShaderBinary( shader, i ) ) - { - CompileAndLinkGPUShaderProgram( shader, shaderProgram, compileMacros, deformIndex ); - SaveShaderBinary( shader, i ); + if ( shader->_hasFragmentShader ) { + const uint32_t macros = shader->GetUniqueCompileMacros( macroIndex, GLCompileMacro::FRAGMENT ); + shaders.emplace_back( ShaderEntry{ shader->_name, macros, GL_FRAGMENT_SHADER } ); } + if ( shader->_hasComputeShader ) { + shaders.emplace_back( ShaderEntry{ shader->_name, 0, GL_COMPUTE_SHADER } ); + } + + program = FindShaderProgram( shaders, shader->_name ); - UpdateShaderProgramUniformLocations( shader, shaderProgram ); - GL_BindProgram( shaderProgram ); - shader->SetShaderProgramUniforms( shaderProgram ); - GL_BindProgram( nullptr ); + UpdateShaderProgramUniformLocations( shader, program ); + GL_BindProgram( program ); + shader->SetShaderProgramUniforms( program ); + GL_BindNullProgram(); + + // Copy this for a fast look-up, but the values held in program aren't supposed to change after + shader->shaderPrograms[i] = *program; GL_CheckErrors(); + Log::Debug( "Built in: %i ms", Sys::Milliseconds() - start ); + return true; } -void GLShaderManager::buildAll() -{ +void GLShaderManager::BuildAll() { int startTime = Sys::Milliseconds(); int count = 0; + compileTime = 0; + compileCount = 0; + linkTime = 0; + linkCount = 0; - while ( !_shaderBuildQueue.empty() ) - { - GLShader& shader = *_shaderBuildQueue.front(); + while ( !_shaderBuildQueue.empty() ) { + GLShader* shader = _shaderBuildQueue.front(); - std::string shaderName = shader.GetMainShaderName(); + std::string shaderName = shader->GetMainShaderName(); - size_t numPermutations = static_cast(1) << shader.GetNumOfCompiledMacros(); - size_t i; + size_t numPermutations = static_cast( 1 ) << shader->GetNumOfCompiledMacros(); - for( i = 0; i < numPermutations; i++ ) - { - count += +buildPermutation( &shader, i, 0 ); + for( size_t i = 0; i < numPermutations; i++ ) { + count += +BuildPermutation( shader, i, 0 ); } _shaderBuildQueue.pop(); } // doesn't include deform vertex shaders, those are built elsewhere! - Log::Notice( "built %d glsl shaders in %d msec", count, Sys::Milliseconds() - startTime ); + Log::Notice( "Built %u glsl shader programs in %i ms (compile: %u in %i ms, link: %u in %i ms, init: %u in %i ms;" + " cache: loaded %u in %i ms, saved %u in %i ms)", + count, Sys::Milliseconds() - startTime, + compileCount, compileTime, linkCount, linkTime, initCount, initTime, + cacheLoadCount, cacheLoadTime, cacheSaveCount, cacheSaveTime ); } -std::string GLShaderManager::ProcessInserts( const std::string& shaderText, const uint32_t offset ) const { +std::string GLShaderManager::ProcessInserts( const std::string& shaderText ) const { std::string out; std::istringstream shaderTextStream( shaderText ); std::string line; int insertCount = 0; - int lineCount = offset; + int lineCount = 0; while ( std::getline( shaderTextStream, line, '\n' ) ) { ++lineCount; @@ -1059,8 +1240,64 @@ std::string GLShaderManager::ProcessInserts( const std::string& shaderText, cons return out; } +ShaderDescriptor* GLShaderManager::FindShader( const std::string& name, const std::string& mainText, + const GLenum type, const std::vector& headers, + const uint32_t macro, const std::string& compileMacros, const bool main ) { + + ShaderDescriptor desc{ name, compileMacros, macro, type, main }; + const std::vector::iterator it = std::find_if( shaderDescriptors.begin(), shaderDescriptors.end(), + [&]( const ShaderDescriptor& other ) { + return desc.type == other.type && desc.macro == other.macro && desc.name == other.name; + } + ); + + if ( it != shaderDescriptors.end() ) { + return nullptr; + } + + std::string combinedShaderText = BuildShaderText( mainText, headers, compileMacros ); + combinedShaderText = ProcessInserts( combinedShaderText ); + + desc.shaderSource = combinedShaderText; + + shaderDescriptors.emplace_back( desc ); + + return &shaderDescriptors.back(); +} + +std::string GLShaderManager::BuildShaderText( const std::string& mainShaderText, const std::vector& headers, + const std::string& macros ) { + std::string combinedText; + + uint32_t count = 0; + for ( GLHeader* header : headers ) { + count += header->getText().size(); + } + + combinedText.reserve( count ); + + for ( GLHeader* header : headers ) { + combinedText += header->getText(); + } + + const char* compileMacrosP = macros.c_str(); + while ( true ) { + const char* token = COM_ParseExt2( &compileMacrosP, false ); + + if ( !token[0] ) { + break; + } + + combinedText += Str::Format( "#ifndef %s\n#define %s 1\n#endif\n", token, token ); + } + + combinedText += mainShaderText; + + return combinedText; +} + void GLShaderManager::InitShader( GLShader* shader ) { - shader->_shaderPrograms = std::vector( static_cast< size_t >( 1 ) << shader->_compileMacros.size() ); + const int start = Sys::Milliseconds(); shader->PostProcessUniforms(); @@ -1077,317 +1314,244 @@ void GLShaderManager::InitShader( GLShader* shader ) { uniformBlock->SetLocationIndex( i ); } + struct ShaderType { + bool enabled; + int type; + GLenum GLType; + + const char* postfix; + uint32_t offset; + std::vector headers; + + std::string path; + std::string mainText; + }; + + ShaderType shaderTypes[] = { + { shader->_hasVertexShader, GLCompileMacro::VERTEX, GL_VERTEX_SHADER, "_vp", + GLVersionDeclaration.getText().size(), + { &GLVersionDeclaration, &GLCompatHeader, &GLEngineConstants, &GLVertexHeader } }, + { shader->_hasFragmentShader, GLCompileMacro::FRAGMENT, GL_FRAGMENT_SHADER, "_fp", + GLVersionDeclaration.getText().size(), + { &GLVersionDeclaration, &GLCompatHeader, &GLEngineConstants, &GLFragmentHeader } }, + { shader->_hasComputeShader, GLCompileMacro::COMPUTE, GL_COMPUTE_SHADER, "_cp", + 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 ( uint32_t i = 0; i < BIT( shader->GetNumOfCompiledMacros() ); i++ ) { + for ( ShaderType& shaderType : shaderTypes ) { + if ( !shaderType.enabled ) { + continue; + } - if ( shader->_hasVertexShader ) { - combinedShaderText += shader->_vertexShaderText; - } - if ( shader->_hasFragmentShader ) { - combinedShaderText += shader->_fragmentShaderText; - } - if ( shader->_hasComputeShader ) { - combinedShaderText += shader->_computeShaderText; + std::string compileMacros; + if ( !shader->GetCompileMacrosString( i, compileMacros, shaderType.type ) ) { + continue; + } + + if ( IsUnusedPermutation( compileMacros.c_str() ) ) { + continue; + } + + shader->BuildShaderCompileMacros( compileMacros ); + + const uint32_t uniqueMacros = shader->GetUniqueCompileMacros( i, shaderType.type ); + + ShaderDescriptor* desc = FindShader( shader->_name, shaderType.mainText, shaderType.GLType, shaderType.headers, + uniqueMacros, compileMacros, true ); + + if ( desc && glConfig2.usingMaterialSystem && shader->_useMaterialSystem ) { + desc->shaderSource = ShaderPostProcess( shader, desc->shaderSource, shaderType.offset ); + } + + initCount++; + } } - shader->_checkSum = Com_BlockChecksum( combinedShaderText.c_str(), combinedShaderText.length() ); + initTime += Sys::Milliseconds() - start; } -bool GLShaderManager::LoadShaderBinary( GLShader *shader, size_t programNum ) -{ -#ifdef GL_ARB_get_program_binary - GLint success; - const byte *binaryptr; - GLBinaryHeader shaderHeader; - - if ( !r_glslCache.Get() ) +bool GLShaderManager::LoadShaderBinary( const std::vector& shaders, const std::string& mainShader, + ShaderProgramDescriptor* descriptor ) { + if ( !r_glslCache.Get() ) { return false; + } - if (!GetShaderPath().empty()) + if ( !GetShaderPath().empty() ) { return false; + } - // don't even try if the necessary functions aren't available - if( !glConfig2.getProgramBinaryAvailable ) + // Don't even try if the necessary functions aren't available + if ( !glConfig2.getProgramBinaryAvailable ) { return false; + } - if (_shaderBinaryCacheInvalidated) + if ( _shaderBinaryCacheInvalidated ) { return false; + } + + const int start = Sys::Milliseconds(); std::error_code err; - std::string shaderFilename = Str::Format("glsl/%s/%s_%u.bin", shader->GetName(), shader->GetName(), (unsigned int)programNum); - FS::File shaderFile = FS::HomePath::OpenRead(shaderFilename, err); - if (err) + std::string secondaryName; + for ( const ShaderEntry& shader : shaders ) { + if ( shader.name != mainShader ) { + secondaryName += Str::Format( "%s_%u_%u", shader.name, shader.macro, shader.type ); + } else { + secondaryName += Str::Format( "%u_%u_", shader.macro, shader.type ); + } + } + + std::string shaderFilename = Str::Format( "glsl/%s/%s.bin", mainShader, secondaryName ); + FS::File shaderFile = FS::HomePath::OpenRead( shaderFilename, err ); + if ( err ) { return false; + } - std::string shaderData = shaderFile.ReadAll(err); - if (err) + GLint success; + const byte *binaryptr; + GLBinaryHeader shaderHeader; + std::string shaderData = shaderFile.ReadAll( err ); + if ( err ) { return false; + } - if (shaderData.size() < sizeof(shaderHeader)) + if ( shaderData.size() < sizeof( shaderHeader ) ) { return false; + } - binaryptr = reinterpret_cast(shaderData.data()); + binaryptr = reinterpret_cast( shaderData.data() ); - // get the shader header from the file + // Get the shader header from the file memcpy( &shaderHeader, binaryptr, sizeof( shaderHeader ) ); binaryptr += sizeof( shaderHeader ); - // check if the header struct is the correct format - // and the binary was produced by the same gl driver - if (shaderHeader.version != GL_SHADER_VERSION || shaderHeader.driverVersionHash != _driverVersionHash) - { - // These two fields should be the same for all shaders. So if there is a mismatch, - // don't bother opening any of the remaining files. - Log::Notice("Invalidating shader binary cache"); + /* Check if the header struct is the correct format + and the binary was produced by the same GL driver */ + if ( shaderHeader.version != GL_SHADER_VERSION /* || shaderHeader.driverVersionHash != _driverVersionHash */ ) { + /* These two fields should be the same for all shaders. So if there is a mismatch, + don't bother opening any of the remaining files. + I've disabled the cache invalidation on driver version change, because we now also cache shader programs that use + non-empty deformVertexes. This would mean that after updating the driver, any time you load a new map with + deformVertexes, it would cause the rebuild of *all* shaders */ + Log::Notice( "Invalidating shader binary cache" ); _shaderBinaryCacheInvalidated = true; return false; } - // make sure this shader uses the same number of macros - if ( shaderHeader.numMacros != shader->GetNumOfCompiledMacros() ) + // Make sure the checksums for the source code match + if ( shaderHeader.checkSum != descriptor->checkSum ) { return false; - - // make sure this shader uses the same macros - for ( unsigned int i = 0; i < shaderHeader.numMacros; i++ ) - { - if ( shader->_compileMacros[ i ]->GetType() != shaderHeader.macros[ i ] ) - return false; } - // make sure the checksums for the source code match - if ( shaderHeader.checkSum != shader->_checkSum ) - return false; - - if ( shaderHeader.binaryLength != shaderData.size() - sizeof( shaderHeader ) ) - { + if ( shaderHeader.binaryLength != shaderData.size() - sizeof( shaderHeader ) ) { Log::Warn( "Shader cache %s has wrong size", shaderFilename ); return false; } - // load the shader - shaderProgram_t *shaderProgram = &shader->_shaderPrograms[ programNum ]; - shaderProgram->program = glCreateProgram(); - glProgramBinary( shaderProgram->program, shaderHeader.binaryFormat, binaryptr, shaderHeader.binaryLength ); - glGetProgramiv( shaderProgram->program, GL_LINK_STATUS, &success ); + // Load the shader program + descriptor->id = glCreateProgram(); + glProgramBinary( descriptor->id, shaderHeader.binaryFormat, binaryptr, shaderHeader.binaryLength ); + glGetProgramiv( descriptor->id, GL_LINK_STATUS, &success ); - if ( !success ) + if ( !success ) { return false; + } + + for ( const ShaderEntry& shader : shaders ) { + descriptor->shaderNames[descriptor->shaderCount] = shader; + descriptor->shaderCount++; + } + + cacheLoadTime += Sys::Milliseconds() - start; + cacheLoadCount++; return true; -#else - return false; -#endif } -void GLShaderManager::SaveShaderBinary( GLShader *shader, size_t programNum ) -{ -#ifdef GL_ARB_get_program_binary - GLint binaryLength; - GLuint binarySize = 0; - byte *binary; - byte *binaryptr; - GLBinaryHeader shaderHeader{}; // Zero init. - shaderProgram_t *shaderProgram; - - if ( !r_glslCache.Get() ) + +void GLShaderManager::SaveShaderBinary( ShaderProgramDescriptor* descriptor ) { + if ( !r_glslCache.Get() ) { return; + } - if (!GetShaderPath().empty()) + if ( !GetShaderPath().empty() ) { return; + } - // don't even try if the necessary functions aren't available - if( !glConfig2.getProgramBinaryAvailable ) - { + // Don't even try if the necessary functions aren't available + if( !glConfig2.getProgramBinaryAvailable ) { return; } - shaderProgram = &shader->_shaderPrograms[ programNum ]; + const int start = Sys::Milliseconds(); - // find output size - binarySize += sizeof( shaderHeader ); - glGetProgramiv( shaderProgram->program, GL_PROGRAM_BINARY_LENGTH, &binaryLength ); + // Find output size + GLBinaryHeader shaderHeader{}; + GLuint binarySize = sizeof( shaderHeader ); + GLint binaryLength; + glGetProgramiv( descriptor->id, GL_PROGRAM_BINARY_LENGTH, &binaryLength ); // The binary length may be 0 if there is an error. - if ( binaryLength <= 0 ) - { + if ( binaryLength <= 0 ) { return; } binarySize += binaryLength; + byte* binary; + byte* binaryptr; binaryptr = binary = ( byte* )ri.Hunk_AllocateTempMemory( binarySize ); - // reserve space for the header + // Reserve space for the header binaryptr += sizeof( shaderHeader ); - // get the program binary and write it to the buffer - glGetProgramBinary( shaderProgram->program, binaryLength, nullptr, &shaderHeader.binaryFormat, binaryptr ); + // Get the program binary and write it to the buffer + glGetProgramBinary( descriptor->id, binaryLength, nullptr, &shaderHeader.binaryFormat, binaryptr ); - // set the header + // Set the header shaderHeader.version = GL_SHADER_VERSION; - shaderHeader.numMacros = shader->_compileMacros.size(); - - for ( unsigned int i = 0; i < shaderHeader.numMacros; i++ ) - { - shaderHeader.macros[ i ] = shader->_compileMacros[ i ]->GetType(); - } shaderHeader.binaryLength = binaryLength; - shaderHeader.checkSum = shader->_checkSum; + shaderHeader.checkSum = descriptor->checkSum; shaderHeader.driverVersionHash = _driverVersionHash; - // write the header to the buffer - memcpy(binary, &shaderHeader, sizeof( shaderHeader ) ); - - auto fileName = Str::Format("glsl/%s/%s_%u.bin", shader->GetName(), shader->GetName(), (unsigned int)programNum); - ri.FS_WriteFile(fileName.c_str(), binary, binarySize); - - ri.Hunk_FreeTempMemory( binary ); -#endif -} - -void GLShaderManager::CompileGPUShaders( GLShader *shader, shaderProgram_t *program, - const std::string &compileMacros ) -{ - // permutation macros - std::string macrosString; - - const char* compileMacrosP = compileMacros.c_str(); - while ( true ) - { - const char *token = COM_ParseExt2( &compileMacrosP, false ); + // Write the header to the buffer + memcpy( binary, &shaderHeader, sizeof( shaderHeader ) ); - if ( !token[ 0 ] ) - { - break; + std::string secondaryName; + for ( uint32_t i = 0; i < descriptor->shaderCount; i++ ) { + const ShaderEntry& shader = descriptor->shaderNames[i]; + if ( shader.name != descriptor->mainShader || !descriptor->hasMain ) { + secondaryName += Str::Format( "%s_%u_%u", shader.name, shader.macro, shader.type ); + } else { + secondaryName += Str::Format( "%u_%u_", shader.macro, shader.type ); } - - macrosString += Str::Format( "#ifndef %s\n#define %s 1\n#endif\n", token, token ); - } - - Log::Debug( "building %s shader permutation with macro: %s", - shader->GetName(), - compileMacros.empty() ? "none" : compileMacros ); - - const int start = Sys::Milliseconds(); - - // add them - std::string vertexShaderTextWithMacros = macrosString + shader->_vertexShaderText; - std::string fragmentShaderTextWithMacros = macrosString + shader->_fragmentShaderText; - std::string computeShaderTextWithMacros = macrosString + shader->_computeShaderText; - if( shader->_hasVertexShader ) { - program->VS = CompileShader( shader->GetName(), - vertexShaderTextWithMacros, - { &GLVersionDeclaration, - &GLCompatHeader, - &GLEngineConstants, - &GLVertexHeader }, - GL_VERTEX_SHADER ); - } - if ( shader->_hasFragmentShader ) { - program->FS = CompileShader( shader->GetName(), - fragmentShaderTextWithMacros, - { &GLVersionDeclaration, - &GLCompatHeader, - &GLEngineConstants, - &GLFragmentHeader }, - GL_FRAGMENT_SHADER ); } - if ( shader->_hasComputeShader ) { - program->CS = CompileShader( shader->GetName(), - computeShaderTextWithMacros, - { &GLComputeVersionDeclaration, - &GLCompatHeader, - &GLComputeHeader, - &GLEngineConstants, - &GLWorldHeader }, - GL_COMPUTE_SHADER ); - } - - Log::Debug( "Compilation: %i ms", Sys::Milliseconds() - start ); -} - -void GLShaderManager::CompileAndLinkGPUShaderProgram( GLShader *shader, shaderProgram_t *program, - Str::StringRef compileMacros, int deformIndex ) -{ - GLShaderManager::CompileGPUShaders( shader, program, compileMacros ); - program->program = glCreateProgram(); - if ( shader->_hasVertexShader ) { - glAttachShader( program->program, program->VS ); - glAttachShader( program->program, _deformShaders[ deformIndex ] ); - } - if ( shader->_hasFragmentShader ) { - glAttachShader( program->program, program->FS ); - } - if ( shader->_hasComputeShader ) { - glAttachShader( program->program, program->CS ); - } + std::string name = descriptor->hasMain ? descriptor->mainShader : "unknown"; + auto fileName = Str::Format( "glsl/%s/%s.bin", name, secondaryName ); + ri.FS_WriteFile( fileName.c_str(), binary, binarySize ); - const int start = Sys::Milliseconds(); - BindAttribLocations( program->program ); - LinkProgram( program->program ); + ri.Hunk_FreeTempMemory( binary ); - Log::Debug( "Link: %i ms", Sys::Milliseconds() - start ); + cacheSaveTime += Sys::Milliseconds() - start; + cacheSaveCount++; } // This will generate all the extra code for material system shaders -std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::string& shaderText ) { +std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::string& shaderText, const uint32_t offset ) { if ( !shader->std430Size ) { return shaderText; } @@ -1537,64 +1701,9 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str materialDefines += "\n"; - newShaderText = "#define USE_MATERIAL_SYSTEM\n" + materialStruct + materialBlock + texDataBlock + materialDefines + shaderMain; - return newShaderText; -} - -GLuint GLShaderManager::CompileShader( Str::StringRef programName, - Str::StringRef shaderText, - std::initializer_list headers, - GLenum shaderType ) const -{ - GLuint shader = glCreateShader( shaderType ); - std::vector texts(headers.size() + 1); - std::vector lengths(headers.size() + 1); - int i; - - i = 0; - for(const GLHeader *hdr : headers) { - texts[i++] = hdr->getText().data(); - } - texts[i++] = shaderText.data(); - - i = 0; - for(const GLHeader *hdr : headers) { - lengths[i++] = (GLint)hdr->getText().size(); - } - lengths[i++] = (GLint)shaderText.size(); - - GL_CheckErrors(); - - glShaderSource( shader, i, texts.data(), lengths.data() ); - - // compile shader - glCompileShader( shader ); - - GL_CheckErrors(); - - // check if shader compiled - GLint compiled; - glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); - - if ( !compiled ) - { - std::string log = GetInfoLog( shader ); - std::vector infoLog = ParseInfoLog( log ); - PrintShaderSource( programName, shader, infoLog ); - Log::Warn( "Compile log:\n%s", log ); - switch ( shaderType ) { - case GL_VERTEX_SHADER: - ThrowShaderError( Str::Format( "Couldn't compile vertex shader: %s", programName ) ); - case GL_FRAGMENT_SHADER: - ThrowShaderError( Str::Format( "Couldn't compile fragment shader: %s", programName ) ); - case GL_COMPUTE_SHADER: - ThrowShaderError( Str::Format( "Couldn't compile compute shader: %s", programName ) ); - default: - break; - } - } - - return shader; + newShaderText = "#define USE_MATERIAL_SYSTEM\n" + materialStruct + materialBlock + texDataBlock + materialDefines; // + shaderMain; + shaderMain.insert( offset, newShaderText ); + return shaderMain; } void GLShaderManager::PrintShaderSource( Str::StringRef programName, GLuint object, std::vector& infoLog ) const @@ -2044,8 +2153,8 @@ void GLShader::RegisterUniform( GLUniform* uniform ) { } GLint GLShader::GetUniformLocation( const GLchar *uniformName ) const { - shaderProgram_t* p = GetProgram(); - return glGetUniformLocation( p->program, uniformName ); + ShaderProgramDescriptor* p = GetProgram(); + return glGetUniformLocation( p->id, uniformName ); } // Compute std430 size/alignment and sort uniforms from highest to lowest alignment @@ -2107,22 +2216,45 @@ void GLShader::PostProcessUniforms() { } } -bool GLShader::GetCompileMacrosString( size_t permutation, std::string &compileMacrosOut ) const -{ +uint32_t GLShader::GetUniqueCompileMacros( size_t permutation, const int type ) const { + uint32_t macroOut = 0; + for ( const GLCompileMacro* macro : _compileMacros ) { + if ( permutation & macro->GetBit() ) { + if ( macro->HasConflictingMacros( permutation, _compileMacros ) ) { + continue; + } + + if ( macro->MissesRequiredMacros( permutation, _compileMacros ) ) { + continue; + } + + if ( !( macro->GetShaderTypes() & type ) ) { + continue; + } + + macroOut |= BIT( macro->GetType() ); + } + } + + return macroOut; +} + +bool GLShader::GetCompileMacrosString( size_t permutation, std::string &compileMacrosOut, const int type ) const { compileMacrosOut.clear(); - for (const GLCompileMacro* macro : _compileMacros) - { - if ( permutation & macro->GetBit() ) - { - if ( macro->HasConflictingMacros( permutation, _compileMacros ) ) - { - //Log::Notice("conflicting macro! canceling '%s'", macro->GetName()); + for ( const GLCompileMacro* macro : _compileMacros ) { + if ( permutation & macro->GetBit() ) { + if ( macro->HasConflictingMacros( permutation, _compileMacros ) ) { + return false; + } + + if ( macro->MissesRequiredMacros( permutation, _compileMacros ) ) { return false; } - if ( macro->MissesRequiredMacros( permutation, _compileMacros ) ) + if ( !( macro->GetShaderTypes() & type ) ) { return false; + } compileMacrosOut += macro->GetName(); compileMacrosOut += " "; @@ -2155,12 +2287,12 @@ GLuint GLShader::GetProgram( int deformIndex ) { // program may not be loaded yet because the shader manager hasn't yet gotten to it // so try to load it now - if ( index >= _shaderPrograms.size() || !_shaderPrograms[index].program ) { - _shaderManager->buildPermutation( this, macroIndex, deformIndex ); + if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { + _shaderManager->BuildPermutation( this, macroIndex, deformIndex ); } // program is still not loaded - if ( index >= _shaderPrograms.size() || !_shaderPrograms[index].program ) { + if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { std::string activeMacros; size_t numMacros = _compileMacros.size(); @@ -2178,23 +2310,22 @@ GLuint GLShader::GetProgram( int deformIndex ) { ThrowShaderError( Str::Format( "Invalid shader configuration: shader = '%s', macros = '%s'", _name, activeMacros ) ); } - return _shaderPrograms[index].program; + return shaderPrograms[index].id; } -void GLShader::BindProgram( int deformIndex ) -{ +void GLShader::BindProgram( int deformIndex ) { int macroIndex = SelectProgram(); size_t index = macroIndex + ( size_t(deformIndex) << _compileMacros.size() ); // program may not be loaded yet because the shader manager hasn't yet gotten to it // so try to load it now - if ( index >= _shaderPrograms.size() || !_shaderPrograms[ index ].program ) + if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { - _shaderManager->buildPermutation( this, macroIndex, deformIndex ); + _shaderManager->BuildPermutation( this, macroIndex, deformIndex ); } // program is still not loaded - if ( index >= _shaderPrograms.size() || !_shaderPrograms[ index ].program ) + if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { std::string activeMacros; @@ -2210,29 +2341,28 @@ void GLShader::BindProgram( int deformIndex ) ThrowShaderError(Str::Format("Invalid shader configuration: shader = '%s', macros = '%s'", _name, activeMacros )); } - _currentProgram = &_shaderPrograms[ index ]; + currentProgram = &shaderPrograms[index]; - if ( r_logFile->integer ) - { + if ( r_logFile->integer ) { std::string macros; - this->GetCompileMacrosString( index, macros ); + GetCompileMacrosString( index, macros, GLCompileMacro::VERTEX | GLCompileMacro::FRAGMENT ); - auto msg = Str::Format("--- GL_BindProgram( name = '%s', macros = '%s' ) ---\n", this->GetName(), macros); - GLimp_LogComment(msg.c_str()); + auto msg = Str::Format( "--- GL_BindProgram( name = '%s', macros = '%s' ) ---\n", this->GetName(), macros ); + GLimp_LogComment( msg.c_str() ); } - GL_BindProgram( _currentProgram ); + GL_BindProgram( &shaderPrograms[index] ); } void GLShader::DispatchCompute( const GLuint globalWorkgroupX, const GLuint globalWorkgroupY, const GLuint globalWorkgroupZ ) { - ASSERT_EQ( _currentProgram, glState.currentProgram ); + ASSERT_EQ( currentProgram, glState.currentProgram ); ASSERT( _hasComputeShader ); glDispatchCompute( globalWorkgroupX, globalWorkgroupY, globalWorkgroupZ ); } void GLShader::DispatchComputeIndirect( const GLintptr indirectBuffer ) { - ASSERT_EQ( _currentProgram, glState.currentProgram ); + ASSERT_EQ( currentProgram, glState.currentProgram ); ASSERT( _hasComputeShader ); glDispatchComputeIndirect( indirectBuffer ); } @@ -2288,10 +2418,10 @@ GLShader_generic::GLShader_generic( GLShaderManager *manager ) : { } -void GLShader_generic::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_generic::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_genericMaterial::GLShader_genericMaterial( GLShaderManager* manager ) : @@ -2317,9 +2447,9 @@ GLShader_genericMaterial::GLShader_genericMaterial( GLShaderManager* manager ) : GLCompileMacro_USE_DEPTH_FADE( this ) { } -void GLShader_genericMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 1 ); +void GLShader_genericMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : @@ -2371,22 +2501,22 @@ GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : { } -void GLShader_lightMapping::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_lightMapping::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), BIND_NORMALMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), BIND_HEIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), BIND_MATERIALMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightMap" ), BIND_LIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid1" ), BIND_LIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DeluxeMap" ), BIND_DELUXEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid2" ), BIND_DELUXEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_GlowMap" ), BIND_GLOWMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), BIND_LIGHTTILES ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), BIND_NORMALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), BIND_HEIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), BIND_MATERIALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightMap" ), BIND_LIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid1" ), BIND_LIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DeluxeMap" ), BIND_DELUXEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightGrid2" ), BIND_DELUXEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_GlowMap" ), BIND_GLOWMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightTiles" ), BIND_LIGHTTILES ); if( !glConfig2.uniformBufferObjectAvailable ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), BIND_LIGHTS ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_Lights" ), BIND_LIGHTS ); } } @@ -2436,19 +2566,19 @@ GLShader_lightMappingMaterial::GLShader_lightMappingMaterial( GLShaderManager* m GLCompileMacro_USE_PHYSICAL_MAPPING( this ) { } -void GLShader_lightMappingMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), BIND_NORMALMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), BIND_HEIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), BIND_MATERIALMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightMap" ), BIND_LIGHTMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DeluxeMap" ), BIND_DELUXEMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_GlowMap" ), BIND_GLOWMAP ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), BIND_LIGHTTILES ); +void GLShader_lightMappingMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), BIND_NORMALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), BIND_HEIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), BIND_MATERIALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightMap" ), BIND_LIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DeluxeMap" ), BIND_DELUXEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_GlowMap" ), BIND_GLOWMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_LightTiles" ), BIND_LIGHTTILES ); if ( !glConfig2.uniformBufferObjectAvailable ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), BIND_LIGHTS ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_Lights" ), BIND_LIGHTS ); } } @@ -2492,17 +2622,17 @@ GLShader_forwardLighting_omniXYZ::GLShader_forwardLighting_omniXYZ( GLShaderMana { } -void GLShader_forwardLighting_omniXYZ::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_forwardLighting_omniXYZ::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), 2 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_AttenuationMapXY" ), 3 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_AttenuationMapZ" ), 4 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap" ), 5 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_RandomMap" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), 2 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_AttenuationMapXY" ), 3 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_AttenuationMapZ" ), 4 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap" ), 5 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_RandomMap" ), 6 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_forwardLighting_projXYZ::GLShader_forwardLighting_projXYZ( GLShaderManager *manager ): @@ -2551,17 +2681,17 @@ void GLShader_forwardLighting_projXYZ::BuildShaderCompileMacros( std::string& co compileMacros += "LIGHT_PROJ "; } -void GLShader_forwardLighting_projXYZ::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_forwardLighting_projXYZ::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), 2 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_AttenuationMapXY" ), 3 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_AttenuationMapZ" ), 4 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap0" ), 5 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_RandomMap" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap0" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), 2 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_AttenuationMapXY" ), 3 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_AttenuationMapZ" ), 4 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap0" ), 5 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_RandomMap" ), 6 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap0" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_forwardLighting_directionalSun::GLShader_forwardLighting_directionalSun( GLShaderManager *manager ): @@ -2617,24 +2747,24 @@ void GLShader_forwardLighting_directionalSun::BuildShaderCompileMacros( std::str compileMacros += "LIGHT_DIRECTIONAL "; } -void GLShader_forwardLighting_directionalSun::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_forwardLighting_directionalSun::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), 2 ); - //glUniform1i(glGetUniformLocation( shaderProgram->program, "u_AttenuationMapXY" ), 3); - //glUniform1i(glGetUniformLocation( shaderProgram->program, "u_AttenuationMapZ" ), 4); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap0" ), 5 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap1" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap2" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap3" ), 8 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap4" ), 9 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap0" ), 10 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap1" ), 11 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap2" ), 12 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap3" ), 13 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap4" ), 14 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), 2 ); + //glUniform1i(glGetUniformLocation( shaderProgram->id, "u_AttenuationMapXY" ), 3); + //glUniform1i(glGetUniformLocation( shaderProgram->id, "u_AttenuationMapZ" ), 4); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap0" ), 5 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap1" ), 6 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap2" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap3" ), 8 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowMap4" ), 9 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap0" ), 10 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap1" ), 11 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap2" ), 12 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap3" ), 13 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ShadowClipMap4" ), 14 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_shadowFill::GLShader_shadowFill( GLShaderManager *manager ) : @@ -2656,9 +2786,9 @@ GLShader_shadowFill::GLShader_shadowFill( GLShaderManager *manager ) : { } -void GLShader_shadowFill::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_shadowFill::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); } GLShader_reflection::GLShader_reflection( GLShaderManager *manager ): @@ -2684,11 +2814,11 @@ GLShader_reflection::GLShader_reflection( GLShaderManager *manager ): { } -void GLShader_reflection::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_reflection::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_reflectionMaterial::GLShader_reflectionMaterial( GLShaderManager* manager ) : @@ -2709,10 +2839,10 @@ GLShader_reflectionMaterial::GLShader_reflectionMaterial( GLShaderManager* manag GLCompileMacro_USE_RELIEF_MAPPING( this ) { } -void GLShader_reflectionMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); +void GLShader_reflectionMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_skybox::GLShader_skybox( GLShaderManager *manager ) : @@ -2727,10 +2857,10 @@ GLShader_skybox::GLShader_skybox( GLShaderManager *manager ) : { } -void GLShader_skybox::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_skybox::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMapCube" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CloudMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMapCube" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CloudMap" ), 1 ); } GLShader_skyboxMaterial::GLShader_skyboxMaterial( GLShaderManager* manager ) : @@ -2744,9 +2874,9 @@ GLShader_skyboxMaterial::GLShader_skyboxMaterial( GLShaderManager* manager ) : u_ModelViewProjectionMatrix( this ) {} -void GLShader_skyboxMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CloudMap" ), 1 ); +void GLShader_skyboxMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CloudMap" ), 1 ); } GLShader_fogQuake3::GLShader_fogQuake3( GLShaderManager *manager ) : @@ -2766,9 +2896,9 @@ GLShader_fogQuake3::GLShader_fogQuake3( GLShaderManager *manager ) : { } -void GLShader_fogQuake3::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_fogQuake3::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_FogMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_FogMap" ), 0 ); } GLShader_fogQuake3Material::GLShader_fogQuake3Material( GLShaderManager* manager ) : @@ -2783,8 +2913,8 @@ GLShader_fogQuake3Material::GLShader_fogQuake3Material( GLShaderManager* manager GLDeformStage( this ) { } -void GLShader_fogQuake3Material::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_FogMap" ), 0 ); +void GLShader_fogQuake3Material::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_FogMap" ), 0 ); } GLShader_fogGlobal::GLShader_fogGlobal( GLShaderManager *manager ) : @@ -2798,10 +2928,10 @@ GLShader_fogGlobal::GLShader_fogGlobal( GLShaderManager *manager ) : { } -void GLShader_fogGlobal::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_fogGlobal::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_heatHaze::GLShader_heatHaze( GLShaderManager *manager ) : @@ -2823,11 +2953,11 @@ GLShader_heatHaze::GLShader_heatHaze( GLShaderManager *manager ) : { } -void GLShader_heatHaze::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_heatHaze::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_heatHazeMaterial::GLShader_heatHazeMaterial( GLShaderManager* manager ) : @@ -2846,10 +2976,10 @@ GLShader_heatHazeMaterial::GLShader_heatHazeMaterial( GLShaderManager* manager ) { } -void GLShader_heatHazeMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); +void GLShader_heatHazeMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_screen::GLShader_screen( GLShaderManager *manager ) : @@ -2859,9 +2989,9 @@ GLShader_screen::GLShader_screen( GLShaderManager *manager ) : { } -void GLShader_screen::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_screen::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_screenMaterial::GLShader_screenMaterial( GLShaderManager* manager ) : @@ -2870,8 +3000,8 @@ GLShader_screenMaterial::GLShader_screenMaterial( GLShaderManager* manager ) : u_ModelViewProjectionMatrix( this ) { } -void GLShader_screenMaterial::SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); +void GLShader_screenMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_portal::GLShader_portal( GLShaderManager *manager ) : @@ -2883,9 +3013,9 @@ GLShader_portal::GLShader_portal( GLShaderManager *manager ) : { } -void GLShader_portal::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_portal::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_contrast::GLShader_contrast( GLShaderManager *manager ) : @@ -2895,9 +3025,9 @@ GLShader_contrast::GLShader_contrast( GLShaderManager *manager ) : { } -void GLShader_contrast::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_contrast::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); + glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); } GLShader_cameraEffects::GLShader_cameraEffects( GLShaderManager *manager ) : @@ -2914,10 +3044,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 ) : @@ -2930,9 +3060,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 ) : @@ -2942,9 +3072,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 ) : @@ -2980,14 +3110,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 ) : @@ -3023,15 +3153,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 ) : @@ -3043,10 +3173,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 ) : @@ -3058,9 +3188,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 ) : @@ -3071,9 +3201,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 ) : @@ -3083,9 +3213,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 ) : @@ -3099,12 +3229,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 ); } } @@ -3115,9 +3245,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 ) : @@ -3146,8 +3276,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 e53b8119a2..0a44a2a4d7 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // *INDENT-OFF* static const unsigned int MAX_SHADER_MACROS = 10; -static const unsigned int GL_SHADER_VERSION = 5; +static const unsigned int GL_SHADER_VERSION = 6; class ShaderException : public std::runtime_error { @@ -47,14 +47,13 @@ enum class ShaderKind }; // Header for saved shader binaries -struct GLBinaryHeader -{ - unsigned int version; - unsigned int checkSum; // checksum of shader source this was built from - unsigned int driverVersionHash; // detect if the graphics driver was different +struct GLBinaryHeader { + uint32_t version; + uint32_t checkSum; // checksum of shader source this was built from + uint32_t driverVersionHash; // detect if the graphics driver was different - unsigned int macros[ MAX_SHADER_MACROS ]; // macros the shader uses ( may or may not be enabled ) - unsigned int numMacros; + GLuint type; + uint32_t macro; // Bitmask of macros the shader uses ( may or may not be enabled ) GLenum binaryFormat; // argument to glProgramBinary uint32_t binaryLength; // argument to glProgramBinary @@ -68,14 +67,12 @@ class GLShaderManager; // represents a piece of GLSL code that can be copied verbatim into // GLShaders, like a .h file in C++ -class GLHeader -{ +class GLHeader { private: - - std::string _name; - std::string _text; + std::string _name; + std::string _text; uint32_t _lineCount; - GLShaderManager *_shaderManager; + GLShaderManager *_shaderManager; public: GLHeader() : _name(), _text(), _lineCount(), _shaderManager( nullptr ) @@ -85,8 +82,7 @@ class GLHeader _name( name ), _text( text ), _lineCount( std::count( text.begin(), text.end(), '\n' ) ), - _shaderManager( manager ) - { + _shaderManager( manager ) { } const std::string &getName() const { return _name; } @@ -95,44 +91,39 @@ class GLHeader const GLShaderManager *getManager() const { return _shaderManager; } }; -class GLShader -{ +class GLShader { friend class GLShaderManager; private: GLShader( const GLShader & ) = delete; - GLShader &operator = ( const GLShader & ) = delete; + GLShader &operator = ( const GLShader & ) = delete; - std::string _name; - std::string _mainShaderName; + std::string _name; + std::string _mainShaderName; const bool _useMaterialSystem; GLuint std430Size = 0; uint padding = 0; uint textureCount = 0; protected: - int _activeMacros; - unsigned int _checkSum; - shaderProgram_t *_currentProgram; - const uint32_t _vertexAttribsRequired; - uint32_t _vertexAttribs; // can be set by uniforms - GLShaderManager *_shaderManager; - - bool _hasVertexShader; - std::string _vertexShaderText; - bool _hasFragmentShader; - std::string _fragmentShaderText; - bool _hasComputeShader; - std::string _computeShaderText; - std::vector< shaderProgram_t > _shaderPrograms; - - - size_t _uniformStorageSize; - std::vector< GLUniform * > _uniforms; - std::vector< GLUniformBlock * > _uniformBlocks; - std::vector< GLCompileMacro * > _compileMacros; - - - - + int _activeMacros; + unsigned int _checkSum; + ShaderProgramDescriptor* currentProgram; + const uint32_t _vertexAttribsRequired; + uint32_t _vertexAttribs; // can be set by uniforms + GLShaderManager *_shaderManager; + + bool _hasVertexShader; + bool _hasFragmentShader; + bool _hasComputeShader; + std::vector shaderPrograms; + + std::vector vertexShaderDescriptors; + std::vector fragmentShaderDescriptors; + std::vector computeShaderDescriptors; + + size_t _uniformStorageSize; + std::vector _uniforms; + std::vector _uniformBlocks; + std::vector _compileMacros; GLShader( const std::string &name, uint32_t vertexAttribsRequired, GLShaderManager *manager, const bool hasVertexShader = true, const bool hasFragmentShader = true, const bool hasComputeShader = false ) : @@ -141,15 +132,13 @@ class GLShader _useMaterialSystem( false ), _activeMacros( 0 ), _checkSum( 0 ), - _currentProgram( nullptr ), _vertexAttribsRequired( vertexAttribsRequired ), _vertexAttribs( 0 ), _shaderManager( manager ), _hasVertexShader( hasVertexShader ), _hasFragmentShader( hasFragmentShader ), _hasComputeShader( hasComputeShader ), - _uniformStorageSize( 0 ) - { + _uniformStorageSize( 0 ) { } GLShader( const std::string &name, const std::string &mainShaderName, uint32_t vertexAttribsRequired, GLShaderManager *manager, @@ -159,15 +148,13 @@ class GLShader _useMaterialSystem( false ), _activeMacros( 0 ), _checkSum( 0 ), - _currentProgram( nullptr ), _vertexAttribsRequired( vertexAttribsRequired ), _vertexAttribs( 0 ), _shaderManager( manager ), _hasVertexShader( hasVertexShader ), _hasFragmentShader( hasFragmentShader ), _hasComputeShader( hasComputeShader ), - _uniformStorageSize( 0 ) - { + _uniformStorageSize( 0 ) { } GLShader( const std::string& name, const std::string& mainShaderName, const bool useMaterialSystem, uint32_t vertexAttribsRequired, @@ -178,7 +165,6 @@ class GLShader _useMaterialSystem( useMaterialSystem ), _activeMacros( 0 ), _checkSum( 0 ), - _currentProgram( nullptr ), _vertexAttribsRequired( vertexAttribsRequired ), _vertexAttribs( 0 ), _shaderManager( manager ), @@ -189,57 +175,16 @@ class GLShader } public: - virtual ~GLShader() - { - for ( std::size_t i = 0; i < _shaderPrograms.size(); i++ ) - { - shaderProgram_t *p = &_shaderPrograms[ i ]; - - if ( p->program ) - { - glDeleteProgram( p->program ); - } - - if ( p->VS ) - { - glDeleteShader( p->VS ); - } - - if ( p->FS ) - { - glDeleteShader( p->FS ); - } - - if ( p->CS ) { - glDeleteShader( p->CS ); - } - - if ( p->uniformFirewall ) - { - Z_Free( p->uniformFirewall ); - } - - if ( p->uniformLocations ) - { - Z_Free( p->uniformLocations ); - } - - if ( p->uniformBlockIndexes ) - { - Z_Free( p->uniformBlockIndexes ); - } - } + virtual ~GLShader() { } void RegisterUniform( GLUniform* uniform ); - void RegisterUniformBlock( GLUniformBlock *uniformBlock ) - { + void RegisterUniformBlock( GLUniformBlock *uniformBlock ) { _uniformBlocks.push_back( uniformBlock ); } - void RegisterCompileMacro( GLCompileMacro *compileMacro ) - { + void RegisterCompileMacro( GLCompileMacro *compileMacro ) { if ( _compileMacros.size() >= MAX_SHADER_MACROS ) { Sys::Drop( "Can't register more than %u compile macros for a single shader", MAX_SHADER_MACROS ); @@ -248,34 +193,31 @@ class GLShader _compileMacros.push_back( compileMacro ); } - size_t GetNumOfCompiledMacros() const - { + size_t GetNumOfCompiledMacros() const { return _compileMacros.size(); } GLint GetUniformLocation( const GLchar *uniformName ) const; - shaderProgram_t *GetProgram() const - { - return _currentProgram; + ShaderProgramDescriptor* GetProgram() const { + return currentProgram; } - const std::string &GetName() const - { + const std::string &GetName() const { return _name; } - const std::string &GetMainShaderName() const - { + const std::string &GetMainShaderName() const { return _mainShaderName; } protected: - void PostProcessUniforms(); - bool GetCompileMacrosString( size_t permutation, std::string &compileMacrosOut ) const; + void PostProcessUniforms(); + uint32_t GetUniqueCompileMacros( size_t permutation, const int type ) const; + bool GetCompileMacrosString( size_t permutation, std::string &compileMacrosOut, const int type ) const; virtual void BuildShaderCompileMacros( std::string& /*vertexInlines*/ ) { }; - virtual void SetShaderProgramUniforms( shaderProgram_t* /*shaderProgram*/ ) { }; - int SelectProgram(); + virtual void SetShaderProgramUniforms( ShaderProgramDescriptor* /*shaderProgram*/ ) { }; + int SelectProgram(); public: GLuint GetProgram( int deformIndex ); void BindProgram( int deformIndex ); @@ -283,33 +225,27 @@ class GLShader void DispatchComputeIndirect( const GLintptr indirectBuffer ); void SetRequiredVertexPointers(); - bool IsMacroSet( int bit ) - { + bool IsMacroSet( int bit ) { return ( _activeMacros & bit ) != 0; } - void AddMacroBit( int bit ) - { + void AddMacroBit( int bit ) { _activeMacros |= bit; } - void DelMacroBit( int bit ) - { + void DelMacroBit( int bit ) { _activeMacros &= ~bit; } - bool IsVertexAttribSet( int bit ) - { + bool IsVertexAttribSet( int bit ) { return ( _vertexAttribs & bit ) != 0; } - void AddVertexAttribBit( int bit ) - { + void AddVertexAttribBit( int bit ) { _vertexAttribs |= bit; } - void DelVertexAttribBit( int bit ) - { + void DelVertexAttribBit( int bit ) { _vertexAttribs &= ~bit; } @@ -336,12 +272,102 @@ class GLShader void WriteUniformsToBuffer( uint32_t* buffer ); }; -class GLShaderManager -{ - std::queue< GLShader* > _shaderBuildQueue; - std::vector< std::unique_ptr< GLShader > > _shaders; - std::unordered_map< std::string, int > _deformShaderLookup; - std::vector< GLint > _deformShaders; +struct ShaderEntry { + std::string name; + uint32_t macro; + GLuint type; + + bool operator==( const ShaderEntry& other ) const { + return name == other.name && macro == other.macro && type == other.type; + } + + bool operator!=( const ShaderEntry& other ) const { + return !( *this == other ); + } +}; + +struct ShaderDescriptor { + std::string name; + + std::string macros; + uint32_t macro; + + GLenum type; + bool main = false; + + GLuint id = 0; + + std::string shaderSource; +}; + +static const uint32_t MAX_SHADER_PROGRAM_SHADERS = 16; + +struct ShaderProgramDescriptor { + GLuint id = 0; + + bool hasMain = false; + GLuint type; + + uint32_t macro = 0; + + GLuint shaders[MAX_SHADER_PROGRAM_SHADERS] {}; + ShaderEntry shaderNames[MAX_SHADER_PROGRAM_SHADERS] {}; + std::string mainShader; + uint32_t shaderCount = 0; + + GLint* uniformLocations; + GLuint* uniformBlockIndexes; + byte* uniformFirewall; + + uint32_t checkSum; + + void AttachShader( ShaderDescriptor* descriptor ) { + if ( shaderCount == MAX_SHADER_PROGRAM_SHADERS ) { + Log::Warn( "Tried to attach too many shaders to program: skipping shader %s %s", descriptor->name, descriptor->macros ); + return; + } + + if ( !shaderCount ) { + type = descriptor->type; + } else if ( type != descriptor->type ) { + type = 0; + } + + if ( descriptor->main ) { + if ( hasMain && mainShader != descriptor->name ) { + Log::Warn( "More than one shader specified as main, current: %s, new: %s, using current", + mainShader, descriptor->name ); + } else { + mainShader = descriptor->name; + hasMain = true; + } + } + + shaders[shaderCount] = descriptor->id; + + shaderNames[shaderCount].name = descriptor->name; + shaderNames[shaderCount].macro = descriptor->macro; + shaderNames[shaderCount].type = descriptor->type; + + macro |= descriptor->macro; + + /* std::sort( shaderNames, shaderNames + shaderCount, + []( const ShaderEntry& lhs, const ShaderEntry& rhs ) { + return lhs.name < rhs.name; + } + ); */ + + shaderCount++; + }; +}; + +class GLShaderManager { + std::queue _shaderBuildQueue; + std::vector> _shaders; + + uint32_t deformShaderCount = 0; + std::unordered_map _deformShaderLookup; + unsigned int _driverVersionHash; // For cache invalidation if hardware changes bool _shaderBinaryCacheInvalidated; @@ -363,11 +389,12 @@ class GLShaderManager void GenerateBuiltinHeaders(); void GenerateWorldHeaders(); - template< class T > - void load( T *& shader ) - { - if( _deformShaders.size() == 0 ) { - Q_UNUSED(getDeformShaderIndex( nullptr, 0 )); + template + void LoadShader( T *& shader ) { + if( !deformShaderCount ) { + Q_UNUSED( GetDeformShaderIndex( nullptr, 0 ) ); + initTime = 0; + initCount = 0; } shader = new T( this ); @@ -375,12 +402,12 @@ class GLShaderManager _shaders.emplace_back( shader ); _shaderBuildQueue.push( shader ); } - void freeAll(); - int getDeformShaderIndex( deformStage_t *deforms, int numDeforms ); + int GetDeformShaderIndex( deformStage_t *deforms, int numDeforms ); - bool buildPermutation( GLShader *shader, int macroIndex, int deformIndex ); - void buildAll(); + bool BuildPermutation( GLShader* shader, int macroIndex, int deformIndex ); + void BuildAll(); + void FreeAll(); private: struct InfoLogEntry { int line; @@ -389,25 +416,44 @@ class GLShaderManager std::string error; }; - bool LoadShaderBinary( GLShader *shader, size_t permutation ); - void SaveShaderBinary( GLShader *shader, size_t permutation ); - GLuint CompileShader( Str::StringRef programName, Str::StringRef shaderText, - std::initializer_list headers, - GLenum shaderType ) const; - void CompileGPUShaders( GLShader *shader, shaderProgram_t *program, - const std::string &compileMacros ); - void CompileAndLinkGPUShaderProgram( GLShader *shader, shaderProgram_t *program, - Str::StringRef compileMacros, int deformIndex ); - std::string ShaderPostProcess( GLShader *shader, const std::string& shaderText ); + std::vector shaderDescriptors; + std::vector shaderProgramDescriptors; + + int compileTime; + uint32_t compileCount; + int linkTime; + uint32_t linkCount; + int initTime; + uint32_t initCount; + int cacheLoadTime; + uint32_t cacheLoadCount; + int cacheSaveTime; + uint32_t cacheSaveCount; + + void BuildShader( ShaderDescriptor* descriptor ); + void BuildShaderProgram( ShaderProgramDescriptor* descriptor ); + + std::string GetDeformShaderName( const int index ); + ShaderProgramDescriptor* FindShaderProgram( std::vector& shaders, const std::string& mainShader ); + + bool LoadShaderBinary( const std::vector& shaders, const std::string& mainShader, + ShaderProgramDescriptor* out ); + void SaveShaderBinary( ShaderProgramDescriptor* descriptor ); + + std::string ShaderPostProcess( GLShader *shader, const std::string& shaderText, const uint32_t offset ); std::string BuildDeformShaderText( const std::string& steps ); - std::string ProcessInserts( const std::string& shaderText, const uint32_t offset ) const; + std::string ProcessInserts( const std::string& shaderText ) const; void LinkProgram( GLuint program ) const; void BindAttribLocations( GLuint program ) const; void PrintShaderSource( Str::StringRef programName, GLuint object, std::vector& infoLogLines ) const; std::vector ParseInfoLog( const std::string& infoLog ) const; std::string GetInfoLog( GLuint object ) const; - void InitShader( GLShader *shader ); - void UpdateShaderProgramUniformLocations( GLShader *shader, shaderProgram_t *shaderProgram ) const; + std::string BuildShaderText( const std::string& mainShaderText, const std::vector& headers, const std::string& macros ); + ShaderDescriptor* FindShader( const std::string& name, const std::string& mainText, + const GLenum type, const std::vector& headers, + const uint32_t macro = 0, const std::string& compileMacros = "", const bool main = false ); + void InitShader( GLShader* shader ); + void UpdateShaderProgramUniformLocations( GLShader* shader, ShaderProgramDescriptor* shaderProgram ) const; }; class GLUniform @@ -486,9 +532,9 @@ class GLUniform // This should return a pointer to the memory right after the one this uniform wrote to virtual uint32_t* WriteToBuffer( uint32_t* buffer ); - void UpdateShaderProgramUniformLocation( shaderProgram_t *shaderProgram ) + void UpdateShaderProgramUniformLocation( ShaderProgramDescriptor* shaderProgram ) { - shaderProgram->uniformLocations[ _locationIndex ] = glGetUniformLocation( shaderProgram->program, GetName() ); + shaderProgram->uniformLocations[_locationIndex] = glGetUniformLocation( shaderProgram->id, GetName() ); } virtual size_t GetSize() @@ -505,7 +551,7 @@ class GLUniformSampler : protected GLUniform { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -559,7 +605,7 @@ class GLUniformSampler1D : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -581,7 +627,7 @@ class GLUniformSampler2D : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -603,7 +649,7 @@ class GLUniformSampler3D : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -625,7 +671,7 @@ class GLUniformUSampler3D : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -647,7 +693,7 @@ class GLUniformSamplerCube : protected GLUniformSampler { } inline GLint GetLocation() { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -672,7 +718,7 @@ class GLUniform1i : protected GLUniform inline void SetValue( int value ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -725,7 +771,7 @@ class GLUniform1ui : protected GLUniform { } inline void SetValue( uint value ) { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -776,7 +822,7 @@ class GLUniform1Bool : protected GLUniform { } inline void SetValue( int value ) { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -830,7 +876,7 @@ class GLUniform1f : protected GLUniform inline void SetValue( float value ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -887,7 +933,7 @@ class GLUniform1fv : protected GLUniform inline void SetValue( int numFloats, float *f ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -930,7 +976,7 @@ class GLUniform2f : protected GLUniform inline void SetValue( const vec2_t v ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -990,7 +1036,7 @@ class GLUniform3f : protected GLUniform inline void SetValue( const vec3_t v ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1050,7 +1096,7 @@ class GLUniform4f : protected GLUniform inline void SetValue( const vec4_t v ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1107,7 +1153,7 @@ class GLUniform4fv : protected GLUniform inline void SetValue( int numV, vec4_t *v ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1150,7 +1196,7 @@ class GLUniformMatrix4f : protected GLUniform inline void SetValue( GLboolean transpose, const matrix_t m ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1205,7 +1251,7 @@ class GLUniformMatrix32f : protected GLUniform { } inline void SetValue( GLboolean transpose, const vec_t* m ) { - shaderProgram_t* p = _shader->GetProgram(); + ShaderProgramDescriptor* p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1251,7 +1297,7 @@ class GLUniformMatrix4fv : protected GLUniform inline void SetValue( int numMatrices, GLboolean transpose, const matrix_t *m ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1293,7 +1339,7 @@ class GLUniformMatrix34fv : protected GLUniform inline void SetValue( int numMatrices, GLboolean transpose, const float *m ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { ASSERT_EQ( p, glState.currentProgram ); @@ -1351,13 +1397,13 @@ class GLUniformBlock return _name.c_str(); } - void UpdateShaderProgramUniformBlockIndex( shaderProgram_t *shaderProgram ) + void UpdateShaderProgramUniformBlockIndex( ShaderProgramDescriptor* shaderProgram ) { - shaderProgram->uniformBlockIndexes[ _locationIndex ] = glGetUniformBlockIndex( shaderProgram->program, GetName() ); + shaderProgram->uniformBlockIndexes[_locationIndex] = glGetUniformBlockIndex( shaderProgram->id, GetName() ); } void SetBuffer( GLuint buffer ) { - shaderProgram_t *p = _shader->GetProgram(); + ShaderProgramDescriptor *p = _shader->GetProgram(); GLuint blockIndex = p->uniformBlockIndexes[ _locationIndex ]; ASSERT_EQ(p, glState.currentProgram); @@ -1640,8 +1686,15 @@ class GLCompileMacro }; public: + enum ShaderType { + VERTEX = BIT( 0 ), + FRAGMENT = BIT( 1 ), + COMPUTE = BIT( 2 ) + }; + virtual const char *GetName() const = 0; virtual EGLCompileMacro GetType() const = 0; + virtual int GetShaderTypes() const = 0; virtual bool HasConflictingMacros( size_t, const std::vector& ) const { @@ -1703,6 +1756,10 @@ class GLCompileMacro_USE_BSP_SURFACE : return EGLCompileMacro::USE_BSP_SURFACE; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetBspSurface( bool enable ) { SetMacro( enable ); @@ -1728,6 +1785,10 @@ class GLCompileMacro_USE_VERTEX_SKINNING : return EGLCompileMacro::USE_VERTEX_SKINNING; } + int GetShaderTypes() const override { + return ShaderType::VERTEX; + } + bool HasConflictingMacros( size_t permutation, const std::vector< GLCompileMacro * > ¯os ) const override; bool MissesRequiredMacros( size_t permutation, const std::vector< GLCompileMacro * > ¯os ) const override; @@ -1761,6 +1822,10 @@ class GLCompileMacro_USE_VERTEX_ANIMATION : return EGLCompileMacro::USE_VERTEX_ANIMATION; } + int GetShaderTypes() const override { + return ShaderType::VERTEX; + } + bool HasConflictingMacros( size_t permutation, const std::vector< GLCompileMacro * > ¯os ) const override; uint32_t GetRequiredVertexAttributes() const override; @@ -1789,6 +1854,10 @@ class GLCompileMacro_USE_TCGEN_ENVIRONMENT : return EGLCompileMacro::USE_TCGEN_ENVIRONMENT; } + int GetShaderTypes() const override { + return ShaderType::VERTEX; + } + bool HasConflictingMacros(size_t permutation, const std::vector< GLCompileMacro * > ¯os) const override; uint32_t GetRequiredVertexAttributes() const override { @@ -1821,6 +1890,10 @@ class GLCompileMacro_USE_TCGEN_LIGHTMAP : return EGLCompileMacro::USE_TCGEN_LIGHTMAP; } + int GetShaderTypes() const override { + return ShaderType::VERTEX; + } + void SetTCGenLightmap( bool enable ) { SetMacro( enable ); @@ -1848,6 +1921,10 @@ class GLCompileMacro_USE_GRID_LIGHTING : return EGLCompileMacro::USE_GRID_LIGHTING; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetGridLighting( bool enable ) { SetMacro( enable ); @@ -1875,6 +1952,10 @@ class GLCompileMacro_USE_DELUXE_MAPPING : return EGLCompileMacro::USE_DELUXE_MAPPING; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetDeluxeMapping( bool enable ) { SetMacro( enable ); @@ -1902,6 +1983,10 @@ class GLCompileMacro_USE_GRID_DELUXE_MAPPING : return EGLCompileMacro::USE_GRID_DELUXE_MAPPING; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetGridDeluxeMapping( bool enable ) { SetMacro( enable ); @@ -1927,6 +2012,10 @@ class GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP : return EGLCompileMacro::USE_HEIGHTMAP_IN_NORMALMAP; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetHeightMapInNormalMap( bool enable ) { SetMacro( enable ); @@ -1952,6 +2041,10 @@ class GLCompileMacro_USE_RELIEF_MAPPING : return EGLCompileMacro::USE_RELIEF_MAPPING; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetReliefMapping( bool enable ) { SetMacro( enable ); @@ -1979,6 +2072,10 @@ class GLCompileMacro_USE_REFLECTIVE_SPECULAR : return EGLCompileMacro::USE_REFLECTIVE_SPECULAR; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetReflectiveSpecular( bool enable ) { SetMacro( enable ); @@ -2004,6 +2101,10 @@ class GLCompileMacro_LIGHT_DIRECTIONAL : return EGLCompileMacro::LIGHT_DIRECTIONAL; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetMacro_LIGHT_DIRECTIONAL( bool enable ) { SetMacro( enable ); @@ -2029,6 +2130,10 @@ class GLCompileMacro_USE_SHADOWING : return EGLCompileMacro::USE_SHADOWING; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetShadowing( bool enable ) { SetMacro( enable ); @@ -2054,6 +2159,10 @@ class GLCompileMacro_USE_DEPTH_FADE : return EGLCompileMacro::USE_DEPTH_FADE; } + int GetShaderTypes() const override { + return ShaderType::VERTEX | ShaderType::FRAGMENT; + } + void SetDepthFade( bool enable ) { SetMacro( enable ); @@ -2079,6 +2188,10 @@ class GLCompileMacro_USE_PHYSICAL_MAPPING : return USE_PHYSICAL_MAPPING; } + int GetShaderTypes() const override { + return ShaderType::FRAGMENT; + } + void SetPhysicalShading( bool enable ) { SetMacro( enable ); @@ -3958,7 +4071,7 @@ class GLShader_generic : { public: GLShader_generic( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_genericMaterial : @@ -3984,7 +4097,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 : @@ -4035,7 +4148,7 @@ class GLShader_lightMapping : { public: GLShader_lightMapping( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_lightMappingMaterial : @@ -4083,7 +4196,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 : @@ -4126,7 +4239,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 : @@ -4171,7 +4284,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 : @@ -4223,7 +4336,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 : @@ -4245,7 +4358,7 @@ class GLShader_shadowFill : { public: GLShader_shadowFill( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_reflection : @@ -4271,7 +4384,7 @@ class GLShader_reflection : { public: GLShader_reflection( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_reflectionMaterial : @@ -4292,7 +4405,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 : @@ -4307,7 +4420,7 @@ class GLShader_skybox : { public: GLShader_skybox( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_skyboxMaterial : @@ -4321,7 +4434,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 : @@ -4341,7 +4454,7 @@ class GLShader_fogQuake3 : { public: GLShader_fogQuake3( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_fogQuake3Material : @@ -4356,7 +4469,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 : @@ -4370,7 +4483,7 @@ class GLShader_fogGlobal : { public: GLShader_fogGlobal( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_heatHaze : @@ -4392,7 +4505,7 @@ class GLShader_heatHaze : { public: GLShader_heatHaze( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_heatHazeMaterial : @@ -4411,7 +4524,7 @@ class GLShader_heatHazeMaterial : { public: GLShader_heatHazeMaterial( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_screen : @@ -4421,7 +4534,7 @@ class GLShader_screen : { public: GLShader_screen( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_screenMaterial : @@ -4430,7 +4543,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 : @@ -4442,7 +4555,7 @@ class GLShader_portal : { public: GLShader_portal( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_contrast : @@ -4452,7 +4565,7 @@ class GLShader_contrast : { public: GLShader_contrast( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_cameraEffects : @@ -4469,7 +4582,7 @@ class GLShader_cameraEffects : { public: GLShader_cameraEffects( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_blur : @@ -4482,7 +4595,7 @@ class GLShader_blur : { public: GLShader_blur( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_debugShadowMap : @@ -4492,7 +4605,7 @@ class GLShader_debugShadowMap : { public: GLShader_debugShadowMap( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_liquid : @@ -4528,7 +4641,7 @@ class GLShader_liquid : { public: GLShader_liquid( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_liquidMaterial : @@ -4564,7 +4677,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 : @@ -4576,7 +4689,7 @@ class GLShader_motionblur : { public: GLShader_motionblur( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_ssao : @@ -4588,7 +4701,7 @@ class GLShader_ssao : { public: GLShader_ssao( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_depthtile1 : @@ -4599,7 +4712,7 @@ class GLShader_depthtile1 : { public: GLShader_depthtile1( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_depthtile2 : @@ -4609,7 +4722,7 @@ class GLShader_depthtile2 : { public: GLShader_depthtile2( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_lighttile : @@ -4623,7 +4736,7 @@ class GLShader_lighttile : { public: GLShader_lighttile( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_fxaa : @@ -4633,7 +4746,7 @@ class GLShader_fxaa : { public: GLShader_fxaa( GLShaderManager *manager ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) override; }; class GLShader_cull : @@ -4664,7 +4777,7 @@ class GLShader_depthReduction : public u_InitialDepthLevel { public: GLShader_depthReduction( GLShaderManager* manager ); - void SetShaderProgramUniforms( shaderProgram_t* shaderProgram ) override; + void SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) override; }; class GLShader_clearSurfaces : diff --git a/src/engine/renderer/glsl_source/cull_cp.glsl b/src/engine/renderer/glsl_source/cull_cp.glsl index 1e210e21fc..201cdc2844 100644 --- a/src/engine/renderer/glsl_source/cull_cp.glsl +++ b/src/engine/renderer/glsl_source/cull_cp.glsl @@ -42,6 +42,11 @@ layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in; layout(binding = 0) uniform sampler2D depthImage; +struct SurfaceDescriptor { + BoundingSphere boundingSphere; + uint surfaceCommandIDs[MAX_SURFACE_COMMANDS]; +}; + layout(std430, binding = BIND_SURFACE_DESCRIPTORS) readonly restrict buffer surfaceDescriptorsSSBO { SurfaceDescriptor surfaces[]; }; diff --git a/src/engine/renderer/glsl_source/fogQuake3_vp.glsl b/src/engine/renderer/glsl_source/fogQuake3_vp.glsl index 35123a2d5d..1101a3ad77 100644 --- a/src/engine/renderer/glsl_source/fogQuake3_vp.glsl +++ b/src/engine/renderer/glsl_source/fogQuake3_vp.glsl @@ -44,9 +44,9 @@ void DeformVertex( inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, - in float time); + in float time ); -void main() +void main() { #insert material_vp @@ -63,7 +63,7 @@ void main() LB.normal, texCoord, color, - u_Time); + u_Time ); // transform vertex position into homogenous clip-space gl_Position = u_ModelViewProjectionMatrix * position; diff --git a/src/engine/renderer/glsl_source/generic_vp.glsl b/src/engine/renderer/glsl_source/generic_vp.glsl index 3affc9a91d..a13740611c 100644 --- a/src/engine/renderer/glsl_source/generic_vp.glsl +++ b/src/engine/renderer/glsl_source/generic_vp.glsl @@ -55,9 +55,9 @@ void DeformVertex( inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, - in float time); + in float time ); -void main() +void main() { #insert material_vp @@ -72,11 +72,7 @@ void main() color = color * ColorModulateToColor( u_ColorModulateColorGen, lightFactor ) + unpackUnorm4x8( u_Color ) * vec4( lightFactor, lightFactor, lightFactor, 1.0 ); - DeformVertex( position, - LB.normal, - texCoord, - color, - u_Time); + DeformVertex( position, LB.normal, texCoord, color, u_Time ); // transform vertex position into homogenous clip-space gl_Position = u_ModelViewProjectionMatrix * position; diff --git a/src/engine/renderer/glsl_source/lightMapping_vp.glsl b/src/engine/renderer/glsl_source/lightMapping_vp.glsl index 49bee16a28..8e6bf7e30c 100644 --- a/src/engine/renderer/glsl_source/lightMapping_vp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_vp.glsl @@ -64,7 +64,7 @@ OUT(smooth) vec3 var_Normal; OUT(smooth) vec4 var_Color; -void DeformVertex(inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, in float time); +void DeformVertex( inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, in float time ); void main() { @@ -78,7 +78,7 @@ void main() color = color * ColorModulateToColor( u_ColorModulateColorGen ) + unpackUnorm4x8( u_Color ); - DeformVertex(position, LB.normal, texCoord, color, u_Time); + DeformVertex( position, LB.normal, texCoord, color, u_Time ); // transform vertex position into homogenous clip-space gl_Position = u_ModelViewProjectionMatrix * position; diff --git a/src/engine/renderer/glsl_source/material_cp.glsl b/src/engine/renderer/glsl_source/material_cp.glsl index 8156273bd8..159b314988 100644 --- a/src/engine/renderer/glsl_source/material_cp.glsl +++ b/src/engine/renderer/glsl_source/material_cp.glsl @@ -39,10 +39,10 @@ struct BoundingSphere { float radius; }; -struct SurfaceDescriptor { +/* struct SurfaceDescriptor { BoundingSphere boundingSphere; uint surfaceCommandIDs[MAX_SURFACE_COMMANDS]; -}; +}; */ struct PortalSurface { BoundingSphere boundingSphere; diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 133f2dfba6..09f52e08c6 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 ad2cf25bfa..5db68cc36b 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -5081,6 +5081,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 ); @@ -5239,6 +5240,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 7156dcf52d..446a7d05f6 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -874,7 +874,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 ); @@ -1137,7 +1137,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 ed59f14404..7522d6fd03 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; @@ -3240,7 +3230,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 19dd45a2fc..3536d27b75 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 eeac8658df..65a215295c 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -5229,7 +5229,7 @@ static void FinishStages() GroupActiveStages(); int deformIndex = shader.numDeforms > 0 - ? gl_shaderManager.getDeformShaderIndex( shader.deforms, shader.numDeforms ) + ? gl_shaderManager.GetDeformShaderIndex( shader.deforms, shader.numDeforms ) : 0; for ( size_t s = 0; s < numStages; s++ ) From 95f8d62538108517f953eed3d71883280fe5499e Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sun, 9 Mar 2025 22:48:57 +0300 Subject: [PATCH 3/6] . --- src/engine/renderer/gl_shader.cpp | 33 ++++++------------------------- src/engine/renderer/gl_shader.h | 20 ++++++++++--------- src/engine/renderer/tr_public.h | 1 + src/engine/sys/sdl_glimp.cpp | 10 ++++++++-- 4 files changed, 26 insertions(+), 38 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index aaf2fc59cd..82ff6ebbfe 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1039,6 +1039,10 @@ void GLShaderManager::BuildShaderProgram( ShaderProgramDescriptor* descriptor ) glProgramParameteri( program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE ); } + if ( glConfig2.separateShaderObjectsAvailable ) { + glProgramParameteri( program, GL_PROGRAM_SEPARABLE, GL_TRUE ); + } + GLint linked; glLinkProgram( program ); @@ -1968,33 +1972,8 @@ std::string GLShaderManager::GetInfoLog( GLuint object ) const return out; } -void GLShaderManager::LinkProgram( GLuint program ) const -{ - GLint linked; - -#ifdef GL_ARB_get_program_binary - // Apparently, this is necessary to get the binary program via glGetProgramBinary - if( glConfig2.getProgramBinaryAvailable ) - { - glProgramParameteri( program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE ); - } -#endif - glLinkProgram( program ); - - glGetProgramiv( program, GL_LINK_STATUS, &linked ); - - if ( !linked ) - { - Log::Warn( "Link log:" ); - Log::Warn( GetInfoLog( program ) ); - ThrowShaderError( "Shaders failed to link!" ); - } -} - -void GLShaderManager::BindAttribLocations( GLuint program ) const -{ - for ( uint32_t i = 0; i < ATTR_INDEX_MAX; i++ ) - { +void GLShaderManager::BindAttribLocations( GLuint program ) const { + for ( uint32_t i = 0; i < ATTR_INDEX_MAX; i++ ) { glBindAttribLocation( program, i, attributeNames[ i ] ); } } diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 0a44a2a4d7..dde2aeb295 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -430,30 +430,32 @@ class GLShaderManager { int cacheSaveTime; uint32_t cacheSaveCount; - void BuildShader( ShaderDescriptor* descriptor ); - void BuildShaderProgram( ShaderProgramDescriptor* descriptor ); + std::string BuildDeformShaderText( const std::string& steps ); std::string GetDeformShaderName( const int index ); + + void BuildShader( ShaderDescriptor* descriptor ); + void BuildShaderProgram( ShaderProgramDescriptor* descriptor ); ShaderProgramDescriptor* FindShaderProgram( std::vector& shaders, const std::string& mainShader ); + void BindAttribLocations( GLuint program ) const; + void UpdateShaderProgramUniformLocations( GLShader* shader, ShaderProgramDescriptor* shaderProgram ) const; + 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; - void LinkProgram( GLuint program ) const; - void BindAttribLocations( GLuint program ) const; void PrintShaderSource( Str::StringRef programName, GLuint object, std::vector& infoLogLines ) const; std::vector ParseInfoLog( const std::string& infoLog ) const; std::string GetInfoLog( GLuint object ) const; - std::string BuildShaderText( const std::string& mainShaderText, const std::vector& headers, const std::string& macros ); + + std::string ProcessInserts( const std::string& shaderText ) const; 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 ); + std::string BuildShaderText( const std::string& mainShaderText, const std::vector& headers, const std::string& macros ); void InitShader( GLShader* shader ); - void UpdateShaderProgramUniformLocations( GLShader* shader, ShaderProgramDescriptor* shaderProgram ) const; + std::string ShaderPostProcess( GLShader *shader, const std::string& shaderText, const uint32_t offset ); }; class GLUniform diff --git a/src/engine/renderer/tr_public.h b/src/engine/renderer/tr_public.h index e417473e89..4559fabc76 100644 --- a/src/engine/renderer/tr_public.h +++ b/src/engine/renderer/tr_public.h @@ -93,6 +93,7 @@ struct glconfig2_t int textureRGBA16BlendAvailable; bool textureIntegerAvailable; bool textureRGAvailable; + bool separateShaderObjectsAvailable; bool computeShaderAvailable; bool bindlessTexturesAvailable; // do the driver/hardware support it bool usingBindlessTextures; // are we using them right now diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index feae888678..88c77f82ed 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -90,12 +90,14 @@ static Cvar::Cvar r_arb_map_buffer_range( "r_arb_map_buffer_range", "Use GL_ARB_map_buffer_range if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_multi_draw_indirect( "r_arb_multi_draw_indirect", "Use GL_ARB_multi_draw_indirect if available", Cvar::NONE, true ); -static Cvar::Cvar r_arb_shader_draw_parameters( "r_arb_shader_draw_parameters", - "Use GL_ARB_shader_draw_parameters if available", Cvar::NONE, true ); +static Cvar::Cvar r_arb_separate_shader_objects( "r_arb_separate_shader_objects", + "Use GL_ARB_separate_shader_objects if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_shader_atomic_counters( "r_arb_shader_atomic_counters", "Use GL_ARB_shader_atomic_counters if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_shader_atomic_counter_ops( "r_arb_shader_atomic_counter_ops", "Use GL_ARB_shader_atomic_counter_ops if available", Cvar::NONE, true ); +static Cvar::Cvar r_arb_shader_draw_parameters( "r_arb_shader_draw_parameters", + "Use GL_ARB_shader_draw_parameters if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_shader_image_load_store( "r_arb_shader_image_load_store", "Use GL_ARB_shader_image_load_store if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_shader_storage_buffer_object( "r_arb_shader_storage_buffer_object", @@ -1993,6 +1995,7 @@ static void GLimp_InitExtensions() Cvar::Latch( r_arb_internalformat_query2 ); Cvar::Latch( r_arb_map_buffer_range ); Cvar::Latch( r_arb_multi_draw_indirect ); + Cvar::Latch( r_arb_separate_shader_objects ); Cvar::Latch( r_arb_shader_atomic_counters ); Cvar::Latch( r_arb_shader_atomic_counter_ops ); Cvar::Latch( r_arb_shader_draw_parameters ); @@ -2571,6 +2574,9 @@ static void GLimp_InitExtensions() // made required in OpenGL 4.3 glConfig2.vertexAttribBindingAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_NONE, ARB_vertex_attrib_binding, r_arb_vertex_attrib_binding.Get() ); + // made required in OpenGL 4.1 + glConfig2.separateShaderObjectsAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_NONE, ARB_separate_shader_objects, r_arb_separate_shader_objects.Get() ); + glConfig2.geometryCacheAvailable = glConfig2.vertexAttribBindingAvailable && glConfig2.directStateAccessAvailable; glConfig2.materialSystemAvailable = glConfig2.shaderDrawParametersAvailable && glConfig2.SSBOAvailable From 70a00a78db1d7b36c5dce9846b92625271ebb3e1 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sun, 9 Mar 2025 23:42:31 +0300 Subject: [PATCH 4/6] . --- src/engine/renderer/gl_shader.cpp | 75 ++++++++++++++++++++++++++---- src/engine/renderer/gl_shader.h | 38 +++++++++++---- src/engine/renderer/tr_backend.cpp | 47 ++++++++++++++----- src/engine/renderer/tr_local.h | 6 ++- 4 files changed, 133 insertions(+), 33 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 82ff6ebbfe..805db7d772 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1062,7 +1062,7 @@ void GLShaderManager::BuildShaderProgram( ShaderProgramDescriptor* descriptor ) Log::Debug( "Program creation + linking: %i", time ); } -ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vector& shaders, const std::string& mainShader ) { +ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vector& shaders, GLShader* mainShader ) { std::vector::iterator it = std::find_if( shaderProgramDescriptors.begin(), shaderProgramDescriptors.end(), [&]( const ShaderProgramDescriptor& program ) { for ( const ShaderEntry& shader : shaders ) { @@ -1106,7 +1106,7 @@ ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vector_name, &desc ) ) { for ( ShaderDescriptor* shader : buildQueue ) { BuildShader( shader ); desc.AttachShader( &*shader ); @@ -1115,6 +1115,11 @@ ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vectorSetShaderProgramUniforms( &desc ); + GL_BindNullProgram(); + shaderProgramDescriptors.emplace_back( desc ); return &shaderProgramDescriptors[shaderProgramDescriptors.size() - 1]; @@ -1123,6 +1128,61 @@ ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vector& vertexShaders, std::vector& fragmentShaders, + std::vector& computeShaders, + GLShader* mainShader ) { + std::vector::iterator it = std::find_if( shaderPipelineDescriptors.begin(), shaderPipelineDescriptors.end(), + [&]( const ShaderPipelineDescriptor& pipeline ) { + for ( const ShaderEntry& shader : vertexShaders ) { + if ( std::find( pipeline.shaderNames, pipeline.shaderNames + pipeline.shaderCount, shader ) + == pipeline.shaderNames + pipeline.shaderCount ) { + return false; + } + } + + for ( const ShaderEntry& shader : fragmentShaders ) { + if ( std::find( pipeline.shaderNames, pipeline.shaderNames + pipeline.shaderCount, shader ) + == pipeline.shaderNames + pipeline.shaderCount ) { + return false; + } + } + + for ( const ShaderEntry& shader : computeShaders ) { + if ( std::find( pipeline.shaderNames, pipeline.shaderNames + pipeline.shaderCount, shader ) + == pipeline.shaderNames + pipeline.shaderCount ) { + return false; + } + } + + return true; + } + ); + + if ( it == shaderPipelineDescriptors.end() ) { + ShaderPipelineDescriptor descriptor; + glGenProgramPipelines( 1, &descriptor.id ); + + if ( vertexShaders.size() ) { + ShaderProgramDescriptor* program = FindShaderProgram( vertexShaders, mainShader ); + descriptor.AttachProgram( program ); + } + if ( fragmentShaders.size() ) { + ShaderProgramDescriptor* program = FindShaderProgram( fragmentShaders, mainShader ); + descriptor.AttachProgram( program ); + } + if ( computeShaders.size() ) { + ShaderProgramDescriptor* program = FindShaderProgram( computeShaders, mainShader ); + descriptor.AttachProgram( program ); + } + + shaderPipelineDescriptors.emplace_back( descriptor ); + return &shaderPipelineDescriptors.back(); + } + + return &*it; +} + bool GLShaderManager::BuildPermutation( GLShader* shader, int macroIndex, int deformIndex ) { size_t i = macroIndex + ( deformIndex << shader->_compileMacros.size() ); @@ -1167,12 +1227,7 @@ bool GLShaderManager::BuildPermutation( GLShader* shader, int macroIndex, int de shaders.emplace_back( ShaderEntry{ shader->_name, 0, GL_COMPUTE_SHADER } ); } - program = FindShaderProgram( shaders, shader->_name ); - - UpdateShaderProgramUniformLocations( shader, program ); - GL_BindProgram( program ); - shader->SetShaderProgramUniforms( program ); - GL_BindNullProgram(); + program = FindShaderProgram( shaders, shader ); // Copy this for a fast look-up, but the values held in program aren't supposed to change after shader->shaderPrograms[i] = *program; @@ -2273,12 +2328,12 @@ GLuint GLShader::GetProgram( int deformIndex ) { // program is still not loaded if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { std::string activeMacros; - size_t numMacros = _compileMacros.size(); + size_t numMacros = _compileMacros.size(); for ( size_t j = 0; j < numMacros; j++ ) { GLCompileMacro* macro = _compileMacros[j]; - int bit = macro->GetBit(); + int bit = macro->GetBit(); if ( IsMacroSet( bit ) ) { activeMacros += macro->GetName(); diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index dde2aeb295..9df1fc4823 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -115,6 +115,7 @@ class GLShader { bool _hasFragmentShader; bool _hasComputeShader; std::vector shaderPrograms; + std::vector shaderPipelines; std::vector vertexShaderDescriptors; std::vector fragmentShaderDescriptors; @@ -351,16 +352,29 @@ struct ShaderProgramDescriptor { macro |= descriptor->macro; - /* std::sort( shaderNames, shaderNames + shaderCount, - []( const ShaderEntry& lhs, const ShaderEntry& rhs ) { - return lhs.name < rhs.name; - } - ); */ - shaderCount++; }; }; +struct ShaderPipelineDescriptor { + GLuint id; + + GLuint VSProgram = 0; + GLuint FSProgram = 0; + GLuint CSProgram = 0; + + uint32_t shaderCount = 0; + ShaderEntry shaderNames[MAX_SHADER_PROGRAM_SHADERS * 3] {}; + + void AttachProgram( ShaderProgramDescriptor* descriptor ) { + ASSERT_LE( shaderCount, MAX_SHADER_PROGRAM_SHADERS ); + + for ( ; shaderCount < descriptor->shaderCount; shaderCount++ ) { + shaderNames[shaderCount] = descriptor->shaderNames[shaderCount]; + } + }; +}; + class GLShaderManager { std::queue _shaderBuildQueue; std::vector> _shaders; @@ -418,6 +432,7 @@ class GLShaderManager { std::vector shaderDescriptors; std::vector shaderProgramDescriptors; + std::vector shaderPipelineDescriptors; int compileTime; uint32_t compileCount; @@ -430,13 +445,16 @@ class GLShaderManager { int cacheSaveTime; uint32_t cacheSaveCount; - std::string BuildDeformShaderText( const std::string& steps ); std::string GetDeformShaderName( const int index ); void BuildShader( ShaderDescriptor* descriptor ); void BuildShaderProgram( ShaderProgramDescriptor* descriptor ); - ShaderProgramDescriptor* FindShaderProgram( std::vector& shaders, const std::string& mainShader ); + ShaderProgramDescriptor* FindShaderProgram( std::vector& shaders, GLShader* mainShader ); + ShaderPipelineDescriptor* FindShaderPipelines( + std::vector& vertexShaders, std::vector& fragmentShaders, + std::vector& computeShaders, + GLShader* mainShader ); void BindAttribLocations( GLuint program ) const; void UpdateShaderProgramUniformLocations( GLShader* shader, ShaderProgramDescriptor* shaderProgram ) const; @@ -445,9 +463,9 @@ class GLShaderManager { ShaderProgramDescriptor* out ); void SaveShaderBinary( ShaderProgramDescriptor* descriptor ); - void PrintShaderSource( Str::StringRef programName, GLuint object, std::vector& infoLogLines ) const; - std::vector ParseInfoLog( const std::string& infoLog ) const; std::string GetInfoLog( GLuint object ) const; + std::vector ParseInfoLog( const std::string& infoLog ) const; + void PrintShaderSource( Str::StringRef programName, GLuint object, std::vector& infoLogLines ) const; std::string ProcessInserts( const std::string& shaderText ) const; ShaderDescriptor* FindShader( const std::string& name, const std::string& mainText, diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 09f52e08c6..87f562a2df 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -120,35 +120,58 @@ GLuint64 BindAnimatedImage( int unit, const textureBundle_t *bundle ) return GL_BindToTMU( unit, bundle->image[ index ] ); } -void GL_BindProgram( ShaderProgramDescriptor* program ) -{ - if ( !program ) - { +void GL_BindProgram( ShaderProgramDescriptor* program ) { + if ( !program ) { GL_BindNullProgram(); return; } - if ( glState.currentProgram != program ) - { + if ( glState.currentProgram != program ) { glUseProgram( program->id ); glState.currentProgram = program; } } -void GL_BindNullProgram() -{ - if ( r_logFile->integer ) - { +void GL_BindNullProgram() { + if ( r_logFile->integer ) { GLimp_LogComment( "--- GL_BindNullProgram ---\n" ); } - if ( glState.currentProgram ) - { + if ( glState.currentProgram ) { glUseProgram( 0 ); glState.currentProgram = nullptr; } } +void GL_BindProgramPipeline( ShaderPipelineDescriptor* pipeline ) { + if ( !pipeline ) { + GL_BindNullProgramPipeline(); + return; + } + + if ( glState.currentProgram ) { + Log::Warn( "A GL program is still bound, program pipeline bind is ignored " + "(current program: %u, current pipeline: %u, new pipeline: %u", + glState.currentProgram->id, glState.currentPipeline->id, pipeline->id ); + } + + if ( glState.currentPipeline != pipeline ) { + glBindProgramPipeline( pipeline->id ); + glState.currentPipeline = pipeline; + } +} + +void GL_BindNullProgramPipeline() { + if ( r_logFile->integer ) { + GLimp_LogComment( "--- GL_BindNullProgramPipeline ---\n" ); + } + + if ( glState.currentPipeline ) { + glBindProgramPipeline( 0 ); + glState.currentPipeline = nullptr; + } +} + void GL_SelectTexture( int unit ) { diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 7522d6fd03..1374c276d7 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1416,6 +1416,7 @@ enum class shaderProfilerRenderSubGroupsMode { // *INDENT-ON* struct ShaderProgramDescriptor; + struct ShaderPipelineDescriptor; // trRefdef_t holds everything that comes in refdef_t, // as well as the locally generated scene information @@ -2429,6 +2430,7 @@ enum class shaderProfilerRenderSubGroupsMode { uint32_t vertexAttribsNewFrame; // offset for VBO vertex animations uint32_t vertexAttribsOldFrame; // offset for VBO vertex animations ShaderProgramDescriptor* currentProgram; + ShaderPipelineDescriptor* currentPipeline; FBO_t *currentFBO; VBO_t *currentVBO; IBO_t *currentIBO; @@ -3229,10 +3231,12 @@ inline bool checkGLErrors() void GL_BindNearestCubeMap( int unit, const vec3_t xyz ); void GL_Unbind( image_t *image ); GLuint64 BindAnimatedImage( int unit, const textureBundle_t *bundle ); + GLuint64 GL_BindToTMU( int unit, image_t *image ); void GL_TextureFilter( image_t *image, filterType_t filterType ); void GL_BindProgram( ShaderProgramDescriptor* program ); - GLuint64 GL_BindToTMU( int unit, image_t *image ); void GL_BindNullProgram(); + void GL_BindProgramPipeline( ShaderPipelineDescriptor* program ); + void GL_BindNullProgramPipeline(); void GL_SetDefaultState(); void GL_SelectTexture( int unit ); void GL_TextureMode( const char *string ); From e2a926f136a7a1428bfc033da54664417f66087b Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 10 Mar 2025 00:05:13 +0300 Subject: [PATCH 5/6] . --- src/engine/renderer/gl_shader.cpp | 56 ++++++++++++++++++++++++------- src/engine/renderer/gl_shader.h | 8 ++--- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 805db7d772..24e2454712 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -237,6 +237,14 @@ void GLShaderManager::FreeAll() { deformShaderCount = 0; _deformShaderLookup.clear(); + for ( const ShaderPipelineDescriptor& pipeline : shaderPipelineDescriptors ) { + if ( pipeline.id ) { + glDeleteProgramPipelines( 1, &pipeline.id ); + } + } + + shaderPipelineDescriptors.clear(); + for ( const ShaderProgramDescriptor& program : shaderProgramDescriptors ) { if ( program.id ) { glDeleteProgram( program.id ); @@ -1166,14 +1174,17 @@ ShaderPipelineDescriptor* GLShaderManager::FindShaderPipelines( if ( vertexShaders.size() ) { ShaderProgramDescriptor* program = FindShaderProgram( vertexShaders, mainShader ); descriptor.AttachProgram( program ); + descriptor.VSProgram = *program; } if ( fragmentShaders.size() ) { ShaderProgramDescriptor* program = FindShaderProgram( fragmentShaders, mainShader ); descriptor.AttachProgram( program ); + descriptor.FSProgram = *program; } if ( computeShaders.size() ) { ShaderProgramDescriptor* program = FindShaderProgram( computeShaders, mainShader ); descriptor.AttachProgram( program ); + descriptor.CSProgram = *program; } shaderPipelineDescriptors.emplace_back( descriptor ); @@ -1196,7 +1207,12 @@ bool GLShaderManager::BuildPermutation( GLShader* shader, int macroIndex, int de } // Program already exists - if ( i < shader->shaderPrograms.size() && + if ( glConfig2.separateShaderObjectsAvailable ) { + if ( i < shader->shaderPipelines.size() && + shader->shaderPipelines[i].id ) { + return false; + } + } else if ( i < shader->shaderPrograms.size() && shader->shaderPrograms[i].id ) { return false; } @@ -1207,30 +1223,46 @@ bool GLShaderManager::BuildPermutation( GLShader* shader, int macroIndex, int de const int start = Sys::Milliseconds(); - if ( i >= shader->shaderPrograms.size() ) { + if ( glConfig2.separateShaderObjectsAvailable ) { + if ( i >= shader->shaderPipelines.size() ) { + shader->shaderPipelines.resize( ( deformIndex + 1 ) << shader->_compileMacros.size() ); + } + } else if ( i >= shader->shaderPrograms.size() ) { shader->shaderPrograms.resize( ( deformIndex + 1 ) << shader->_compileMacros.size() ); } - ShaderProgramDescriptor* program; - - std::vector shaders; + std::vector vertexShaders; + std::vector fragmentShaders; + std::vector computeShaders; 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 } ); + vertexShaders.emplace_back( ShaderEntry{ shader->_name, macros, GL_VERTEX_SHADER } ); + vertexShaders.emplace_back( ShaderEntry{ GetDeformShaderName( deformIndex ), 0, GL_VERTEX_SHADER } ); } if ( shader->_hasFragmentShader ) { const uint32_t macros = shader->GetUniqueCompileMacros( macroIndex, GLCompileMacro::FRAGMENT ); - shaders.emplace_back( ShaderEntry{ shader->_name, macros, GL_FRAGMENT_SHADER } ); + fragmentShaders.emplace_back( ShaderEntry{ shader->_name, macros, GL_FRAGMENT_SHADER } ); } if ( shader->_hasComputeShader ) { - shaders.emplace_back( ShaderEntry{ shader->_name, 0, GL_COMPUTE_SHADER } ); + computeShaders.emplace_back( ShaderEntry{ shader->_name, 0, GL_COMPUTE_SHADER } ); } - program = FindShaderProgram( shaders, shader ); + if ( glConfig2.separateShaderObjectsAvailable ) { + ShaderPipelineDescriptor* pipeline = FindShaderPipelines( vertexShaders, fragmentShaders, computeShaders, shader ); + + // Copy this for a fast look-up, but the values held in program aren't supposed to change after + shader->shaderPipelines[i] = *pipeline; + } else { + std::vector shaders; + shaders.reserve( vertexShaders.size() + fragmentShaders.size() + computeShaders.size() ); + shaders.insert( shaders.end(), vertexShaders.begin(), vertexShaders.end() ); + shaders.insert( shaders.end(), fragmentShaders.begin(), fragmentShaders.end() ); + shaders.insert( shaders.end(), computeShaders.begin(), computeShaders.end() ); + ShaderProgramDescriptor* program = FindShaderProgram( shaders, shader ); - // Copy this for a fast look-up, but the values held in program aren't supposed to change after - shader->shaderPrograms[i] = *program; + // 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(); diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 9df1fc4823..976060877d 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -357,11 +357,11 @@ struct ShaderProgramDescriptor { }; struct ShaderPipelineDescriptor { - GLuint id; + GLuint id = 0; - GLuint VSProgram = 0; - GLuint FSProgram = 0; - GLuint CSProgram = 0; + ShaderProgramDescriptor VSProgram; + ShaderProgramDescriptor FSProgram; + ShaderProgramDescriptor CSProgram; uint32_t shaderCount = 0; ShaderEntry shaderNames[MAX_SHADER_PROGRAM_SHADERS * 3] {}; From 5d6700716b2123b2ad9b33837e68fb3763d028ea Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 10 Mar 2025 10:11:41 +0300 Subject: [PATCH 6/6] . --- src/engine/renderer/gl_shader.cpp | 287 +++++++++------ src/engine/renderer/gl_shader.h | 569 ++++++++++++++++++++--------- src/engine/renderer/tr_backend.cpp | 53 +-- src/engine/renderer/tr_local.h | 9 +- 4 files changed, 595 insertions(+), 323 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 24e2454712..fb51e75d6d 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1070,7 +1070,8 @@ void GLShaderManager::BuildShaderProgram( ShaderProgramDescriptor* descriptor ) Log::Debug( "Program creation + linking: %i", time ); } -ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vector& shaders, GLShader* mainShader ) { +ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vector& shaders, GLShader* mainShader, + GLShader::UniformData* uniformData ) { std::vector::iterator it = std::find_if( shaderProgramDescriptors.begin(), shaderProgramDescriptors.end(), [&]( const ShaderProgramDescriptor& program ) { for ( const ShaderEntry& shader : shaders ) { @@ -1124,9 +1125,12 @@ ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vectoruniformLocations = desc.uniformLocations; + uniformData->uniformBlockIndexes = desc.uniformBlockIndexes; + uniformData->uniformFirewall = desc.uniformFirewall; + GL_BindProgram( desc.id, true ); mainShader->SetShaderProgramUniforms( &desc ); - GL_BindNullProgram(); + GL_BindNullProgram( true ); shaderProgramDescriptors.emplace_back( desc ); @@ -1139,7 +1143,7 @@ ShaderProgramDescriptor* GLShaderManager::FindShaderProgram( std::vector& vertexShaders, std::vector& fragmentShaders, std::vector& computeShaders, - GLShader* mainShader ) { + GLShader* mainShader, uint32_t permutation ) { std::vector::iterator it = std::find_if( shaderPipelineDescriptors.begin(), shaderPipelineDescriptors.end(), [&]( const ShaderPipelineDescriptor& pipeline ) { for ( const ShaderEntry& shader : vertexShaders ) { @@ -1171,26 +1175,75 @@ ShaderPipelineDescriptor* GLShaderManager::FindShaderPipelines( ShaderPipelineDescriptor descriptor; glGenProgramPipelines( 1, &descriptor.id ); + GL_CheckErrors(); if ( vertexShaders.size() ) { - ShaderProgramDescriptor* program = FindShaderProgram( vertexShaders, mainShader ); + ShaderProgramDescriptor* program = + FindShaderProgram( vertexShaders, mainShader, &mainShader->uniformsData[permutation * 3] ); + mainShader->uniformsData[permutation * 3].program = program->id; + mainShader->uniformsData[permutation * 3].uniformLocations = program->uniformLocations; + mainShader->uniformsData[permutation * 3].uniformBlockIndexes = program->uniformBlockIndexes; + mainShader->uniformsData[permutation * 3].uniformFirewall = program->uniformFirewall; descriptor.AttachProgram( program ); descriptor.VSProgram = *program; + + GL_CheckErrors(); + + glUseProgramStages( descriptor.id, GL_VERTEX_SHADER_BIT, program->id ); + GL_CheckErrors(); } if ( fragmentShaders.size() ) { - ShaderProgramDescriptor* program = FindShaderProgram( fragmentShaders, mainShader ); + ShaderProgramDescriptor* program = + FindShaderProgram( fragmentShaders, mainShader, &mainShader->uniformsData[permutation * 3 + 1] ); + mainShader->uniformsData[permutation * 3 + 1].program = program->id; + mainShader->uniformsData[permutation * 3 + 1].uniformLocations = program->uniformLocations; + mainShader->uniformsData[permutation * 3 + 1].uniformBlockIndexes = program->uniformBlockIndexes; + mainShader->uniformsData[permutation * 3 + 1].uniformFirewall = program->uniformFirewall; descriptor.AttachProgram( program ); descriptor.FSProgram = *program; + + GL_CheckErrors(); + + glUseProgramStages( descriptor.id, GL_FRAGMENT_SHADER_BIT, program->id ); + GL_CheckErrors(); } if ( computeShaders.size() ) { - ShaderProgramDescriptor* program = FindShaderProgram( computeShaders, mainShader ); + ShaderProgramDescriptor* program = + FindShaderProgram( computeShaders, mainShader, &mainShader->uniformsData[permutation * 3 + 2] ); + mainShader->uniformsData[permutation * 3 + 2].program = program->id; + mainShader->uniformsData[permutation * 3 + 2].uniformLocations = program->uniformLocations; + mainShader->uniformsData[permutation * 3 + 2].uniformBlockIndexes = program->uniformBlockIndexes; + mainShader->uniformsData[permutation * 3 + 2].uniformFirewall = program->uniformFirewall; descriptor.AttachProgram( program ); descriptor.CSProgram = *program; + + GL_CheckErrors(); + + glUseProgramStages( descriptor.id, GL_COMPUTE_SHADER_BIT, program->id ); + GL_CheckErrors(); } shaderPipelineDescriptors.emplace_back( descriptor ); return &shaderPipelineDescriptors.back(); } + if ( it->VSProgram.id ) { + mainShader->uniformsData[permutation * 3].program = it->VSProgram.id; + mainShader->uniformsData[permutation * 3].uniformLocations = it->VSProgram.uniformLocations; + mainShader->uniformsData[permutation * 3].uniformBlockIndexes = it->VSProgram.uniformBlockIndexes; + mainShader->uniformsData[permutation * 3].uniformFirewall = it->VSProgram.uniformFirewall; + } + if ( it->FSProgram.id ) { + mainShader->uniformsData[permutation * 3 + 1].program = it->FSProgram.id; + mainShader->uniformsData[permutation * 3 + 1].uniformLocations = it->FSProgram.uniformLocations; + mainShader->uniformsData[permutation * 3 + 1].uniformBlockIndexes = it->FSProgram.uniformBlockIndexes; + mainShader->uniformsData[permutation * 3 + 1].uniformFirewall = it->FSProgram.uniformFirewall; + } + if ( it->CSProgram.id ) { + mainShader->uniformsData[permutation * 3 + 2].program = it->CSProgram.id; + mainShader->uniformsData[permutation * 3 + 2].uniformLocations = it->CSProgram.uniformLocations; + mainShader->uniformsData[permutation * 3 + 2].uniformBlockIndexes = it->CSProgram.uniformBlockIndexes; + mainShader->uniformsData[permutation * 3 + 2].uniformFirewall = it->CSProgram.uniformFirewall; + } return &*it; } @@ -1207,13 +1260,8 @@ bool GLShaderManager::BuildPermutation( GLShader* shader, int macroIndex, int de } // Program already exists - if ( glConfig2.separateShaderObjectsAvailable ) { - if ( i < shader->shaderPipelines.size() && - shader->shaderPipelines[i].id ) { - return false; - } - } else if ( i < shader->shaderPrograms.size() && - shader->shaderPrograms[i].id ) { + if ( i < shader->shaderPipelines.size() && + shader->shaderPipelines[i] ) { return false; } @@ -1223,12 +1271,9 @@ bool GLShaderManager::BuildPermutation( GLShader* shader, int macroIndex, int de const int start = Sys::Milliseconds(); - if ( glConfig2.separateShaderObjectsAvailable ) { - if ( i >= shader->shaderPipelines.size() ) { - shader->shaderPipelines.resize( ( deformIndex + 1 ) << shader->_compileMacros.size() ); - } - } else if ( i >= shader->shaderPrograms.size() ) { - shader->shaderPrograms.resize( ( deformIndex + 1 ) << shader->_compileMacros.size() ); + if ( i >= shader->shaderPipelines.size() ) { + shader->shaderPipelines.resize( ( deformIndex + 1 ) << shader->_compileMacros.size() ); + shader->uniformsData.resize( ( ( deformIndex + 1 ) << shader->_compileMacros.size() ) * 3 ); } std::vector vertexShaders; @@ -1247,21 +1292,22 @@ bool GLShaderManager::BuildPermutation( GLShader* shader, int macroIndex, int de computeShaders.emplace_back( ShaderEntry{ shader->_name, 0, GL_COMPUTE_SHADER } ); } + GL_CheckErrors(); if ( glConfig2.separateShaderObjectsAvailable ) { - ShaderPipelineDescriptor* pipeline = FindShaderPipelines( vertexShaders, fragmentShaders, computeShaders, shader ); + ShaderPipelineDescriptor* pipeline = FindShaderPipelines( vertexShaders, fragmentShaders, computeShaders, shader, + i ); - // Copy this for a fast look-up, but the values held in program aren't supposed to change after - shader->shaderPipelines[i] = *pipeline; + shader->shaderPipelines[i] = pipeline->id; } else { std::vector shaders; shaders.reserve( vertexShaders.size() + fragmentShaders.size() + computeShaders.size() ); shaders.insert( shaders.end(), vertexShaders.begin(), vertexShaders.end() ); shaders.insert( shaders.end(), fragmentShaders.begin(), fragmentShaders.end() ); shaders.insert( shaders.end(), computeShaders.begin(), computeShaders.end() ); - ShaderProgramDescriptor* program = FindShaderProgram( shaders, shader ); - // Copy this for a fast look-up, but the values held in program aren't supposed to change after - shader->shaderPrograms[i] = *program; + ShaderProgramDescriptor* program = FindShaderProgram( shaders, shader, &shader->uniformsData[i * 3] ); + + shader->shaderPipelines[i] = program->id; } GL_CheckErrors(); @@ -1547,6 +1593,10 @@ bool GLShaderManager::LoadShaderBinary( const std::vector& shaders, return false; } + if ( glConfig2.separateShaderObjectsAvailable && !shaderHeader.separateProgram ) { + return false; + } + if ( shaderHeader.binaryLength != shaderData.size() - sizeof( shaderHeader ) ) { Log::Warn( "Shader cache %s has wrong size", shaderFilename ); return false; @@ -1618,6 +1668,8 @@ void GLShaderManager::SaveShaderBinary( ShaderProgramDescriptor* descriptor ) { shaderHeader.checkSum = descriptor->checkSum; shaderHeader.driverVersionHash = _driverVersionHash; + shaderHeader.separateProgram = glConfig2.separateShaderObjectsAvailable; + // Write the header to the buffer memcpy( binary, &shaderHeader, sizeof( shaderHeader ) ); @@ -2219,8 +2271,8 @@ void GLShader::RegisterUniform( GLUniform* uniform ) { } GLint GLShader::GetUniformLocation( const GLchar *uniformName ) const { - ShaderProgramDescriptor* p = GetProgram(); - return glGetUniformLocation( p->id, uniformName ); + GLuint p = GetProgram(); + return glGetUniformLocation( p, uniformName ); } // Compute std430 size/alignment and sort uniforms from highest to lowest alignment @@ -2353,12 +2405,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].id ) { + if ( index >= shaderPipelines.size() || !shaderPipelines[index] ) { _shaderManager->BuildPermutation( this, macroIndex, deformIndex ); } // program is still not loaded - if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) { + if ( index >= shaderPipelines.size() || !shaderPipelines[index] ) { std::string activeMacros; size_t numMacros = _compileMacros.size(); @@ -2376,7 +2428,7 @@ GLuint GLShader::GetProgram( int deformIndex ) { ThrowShaderError( Str::Format( "Invalid shader configuration: shader = '%s', macros = '%s'", _name, activeMacros ) ); } - return shaderPrograms[index].id; + return shaderPipelines[index]; } void GLShader::BindProgram( int deformIndex ) { @@ -2385,13 +2437,13 @@ void GLShader::BindProgram( 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].id ) + if ( index >= shaderPipelines.size() || !shaderPipelines[index] ) { _shaderManager->BuildPermutation( this, macroIndex, deformIndex ); } // program is still not loaded - if ( index >= shaderPrograms.size() || !shaderPrograms[index].id ) + if ( index >= shaderPipelines.size() || !shaderPipelines[index] ) { std::string activeMacros; @@ -2407,7 +2459,8 @@ void GLShader::BindProgram( int deformIndex ) { ThrowShaderError(Str::Format("Invalid shader configuration: shader = '%s', macros = '%s'", _name, activeMacros )); } - currentProgram = &shaderPrograms[index]; + currentPipeline = shaderPipelines[index]; + currentIndex = index; if ( r_logFile->integer ) { std::string macros; @@ -2418,17 +2471,17 @@ void GLShader::BindProgram( int deformIndex ) { GLimp_LogComment( msg.c_str() ); } - GL_BindProgram( &shaderPrograms[index] ); + GL_BindProgram( currentPipeline ); } void GLShader::DispatchCompute( const GLuint globalWorkgroupX, const GLuint globalWorkgroupY, const GLuint globalWorkgroupZ ) { - ASSERT_EQ( currentProgram, glState.currentProgram ); + ASSERT_EQ( currentPipeline, glState.currentPipeline ); ASSERT( _hasComputeShader ); glDispatchCompute( globalWorkgroupX, globalWorkgroupY, globalWorkgroupZ ); } void GLShader::DispatchComputeIndirect( const GLintptr indirectBuffer ) { - ASSERT_EQ( currentProgram, glState.currentProgram ); + ASSERT_EQ( currentPipeline, glState.currentPipeline ); ASSERT( _hasComputeShader ); glDispatchComputeIndirect( indirectBuffer ); } @@ -2458,6 +2511,14 @@ void GLShader::WriteUniformsToBuffer( uint32_t* buffer ) { } } +void TextureUniform( GLuint program, GLint location, GLint value ) { + if ( glConfig2.separateShaderObjectsAvailable ) { + glProgramUniform1i( program, location, value ); + } else { + glUniform1i( location, value ); + } +} + GLShader_generic::GLShader_generic( GLShaderManager *manager ) : GLShader( "generic", ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_COLOR, manager ), u_ColorMap( this ), @@ -2486,8 +2547,8 @@ GLShader_generic::GLShader_generic( GLShaderManager *manager ) : void GLShader_generic::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_genericMaterial::GLShader_genericMaterial( GLShaderManager* manager ) : @@ -2514,8 +2575,8 @@ GLShader_genericMaterial::GLShader_genericMaterial( GLShaderManager* manager ) : } void GLShader_genericMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : @@ -2569,18 +2630,18 @@ GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : void GLShader_lightMapping::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_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 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), BIND_NORMALMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), BIND_HEIGHTMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), BIND_MATERIALMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightMap" ), BIND_LIGHTMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightGrid1" ), BIND_LIGHTMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DeluxeMap" ), BIND_DELUXEMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightGrid2" ), BIND_DELUXEMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_GlowMap" ), BIND_GLOWMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightTiles" ), BIND_LIGHTTILES ); if( !glConfig2.uniformBufferObjectAvailable ) { glUniform1i( glGetUniformLocation( shaderProgram->id, "u_Lights" ), BIND_LIGHTS ); } @@ -2633,16 +2694,16 @@ GLShader_lightMappingMaterial::GLShader_lightMappingMaterial( GLShaderManager* m } 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 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), BIND_NORMALMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), BIND_HEIGHTMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_MaterialMap" ), BIND_MATERIALMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightMap" ), BIND_LIGHTMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DeluxeMap" ), BIND_DELUXEMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_GlowMap" ), BIND_GLOWMAP ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightTiles" ), BIND_LIGHTTILES ); if ( !glConfig2.uniformBufferObjectAvailable ) { glUniform1i( glGetUniformLocation( shaderProgram->id, "u_Lights" ), BIND_LIGHTS ); } @@ -2882,9 +2943,9 @@ GLShader_reflection::GLShader_reflection( GLShaderManager *manager ): void GLShader_reflection::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_reflectionMaterial::GLShader_reflectionMaterial( GLShaderManager* manager ) : @@ -2906,9 +2967,9 @@ GLShader_reflectionMaterial::GLShader_reflectionMaterial( GLShaderManager* manag } 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 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_skybox::GLShader_skybox( GLShaderManager *manager ) : @@ -2925,8 +2986,8 @@ GLShader_skybox::GLShader_skybox( GLShaderManager *manager ) : void GLShader_skybox::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMapCube" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CloudMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMapCube" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CloudMap" ), 1 ); } GLShader_skyboxMaterial::GLShader_skyboxMaterial( GLShaderManager* manager ) : @@ -2941,8 +3002,8 @@ GLShader_skyboxMaterial::GLShader_skyboxMaterial( GLShaderManager* manager ) : {} void GLShader_skyboxMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CloudMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CloudMap" ), 1 ); } GLShader_fogQuake3::GLShader_fogQuake3( GLShaderManager *manager ) : @@ -2964,7 +3025,7 @@ GLShader_fogQuake3::GLShader_fogQuake3( GLShaderManager *manager ) : void GLShader_fogQuake3::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_FogMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_FogMap" ), 0 ); } GLShader_fogQuake3Material::GLShader_fogQuake3Material( GLShaderManager* manager ) : @@ -2980,7 +3041,7 @@ GLShader_fogQuake3Material::GLShader_fogQuake3Material( GLShaderManager* manager } void GLShader_fogQuake3Material::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_FogMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_FogMap" ), 0 ); } GLShader_fogGlobal::GLShader_fogGlobal( GLShaderManager *manager ) : @@ -2996,8 +3057,8 @@ GLShader_fogGlobal::GLShader_fogGlobal( GLShaderManager *manager ) : void GLShader_fogGlobal::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_heatHaze::GLShader_heatHaze( GLShaderManager *manager ) : @@ -3021,9 +3082,9 @@ GLShader_heatHaze::GLShader_heatHaze( GLShaderManager *manager ) : void GLShader_heatHaze::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_heatHazeMaterial::GLShader_heatHazeMaterial( GLShaderManager* manager ) : @@ -3043,9 +3104,9 @@ GLShader_heatHazeMaterial::GLShader_heatHazeMaterial( GLShaderManager* manager ) } 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 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_screen::GLShader_screen( GLShaderManager *manager ) : @@ -3057,7 +3118,7 @@ GLShader_screen::GLShader_screen( GLShaderManager *manager ) : void GLShader_screen::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_screenMaterial::GLShader_screenMaterial( GLShaderManager* manager ) : @@ -3067,7 +3128,7 @@ GLShader_screenMaterial::GLShader_screenMaterial( GLShaderManager* manager ) : } void GLShader_screenMaterial::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_portal::GLShader_portal( GLShaderManager *manager ) : @@ -3081,7 +3142,7 @@ GLShader_portal::GLShader_portal( GLShaderManager *manager ) : void GLShader_portal::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_contrast::GLShader_contrast( GLShaderManager *manager ) : @@ -3093,7 +3154,7 @@ GLShader_contrast::GLShader_contrast( GLShaderManager *manager ) : void GLShader_contrast::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); } GLShader_cameraEffects::GLShader_cameraEffects( GLShaderManager *manager ) : @@ -3112,8 +3173,8 @@ GLShader_cameraEffects::GLShader_cameraEffects( GLShaderManager *manager ) : void GLShader_cameraEffects::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap3D" ), 3 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap3D" ), 3 ); } GLShader_blur::GLShader_blur( GLShaderManager *manager ) : @@ -3128,7 +3189,7 @@ GLShader_blur::GLShader_blur( GLShaderManager *manager ) : void GLShader_blur::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); } GLShader_debugShadowMap::GLShader_debugShadowMap( GLShaderManager *manager ) : @@ -3140,7 +3201,7 @@ GLShader_debugShadowMap::GLShader_debugShadowMap( GLShaderManager *manager ) : void GLShader_debugShadowMap::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); } GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) : @@ -3177,13 +3238,13 @@ GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) : } 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 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_PortalMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 2 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 3 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightGrid1" ), 6 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightGrid2" ), 7 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_liquidMaterial::GLShader_liquidMaterial( GLShaderManager* manager ) : @@ -3221,13 +3282,13 @@ GLShader_liquidMaterial::GLShader_liquidMaterial( GLShaderManager* manager ) : void GLShader_liquidMaterial::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 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_CurrentMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_PortalMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 2 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_NormalMap" ), 3 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightGrid1" ), 6 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_LightGrid2" ), 7 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_HeightMap" ), 15 ); } GLShader_motionblur::GLShader_motionblur( GLShaderManager *manager ) : @@ -3241,8 +3302,8 @@ GLShader_motionblur::GLShader_motionblur( GLShaderManager *manager ) : void GLShader_motionblur::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 1 ); } GLShader_ssao::GLShader_ssao( GLShaderManager *manager ) : @@ -3256,7 +3317,7 @@ GLShader_ssao::GLShader_ssao( GLShaderManager *manager ) : void GLShader_ssao::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); } GLShader_depthtile1::GLShader_depthtile1( GLShaderManager *manager ) : @@ -3269,7 +3330,7 @@ GLShader_depthtile1::GLShader_depthtile1( GLShaderManager *manager ) : void GLShader_depthtile1::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); } GLShader_depthtile2::GLShader_depthtile2( GLShaderManager *manager ) : @@ -3281,7 +3342,7 @@ GLShader_depthtile2::GLShader_depthtile2( GLShaderManager *manager ) : void GLShader_depthtile2::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); } GLShader_lighttile::GLShader_lighttile( GLShaderManager *manager ) : @@ -3297,7 +3358,7 @@ GLShader_lighttile::GLShader_lighttile( GLShaderManager *manager ) : void GLShader_lighttile::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_DepthMap" ), 0 ); if( !glConfig2.uniformBufferObjectAvailable ) { glUniform1i( glGetUniformLocation( shaderProgram->id, "u_Lights" ), 1 ); @@ -3313,7 +3374,7 @@ GLShader_fxaa::GLShader_fxaa( GLShaderManager *manager ) : void GLShader_fxaa::SetShaderProgramUniforms( ShaderProgramDescriptor *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); + TextureUniform( shaderProgram->id, glGetUniformLocation( shaderProgram->id, "u_ColorMap" ), 0 ); } GLShader_cull::GLShader_cull( GLShaderManager* manager ) : @@ -3343,7 +3404,7 @@ GLShader_depthReduction::GLShader_depthReduction( GLShaderManager* manager ) : } void GLShader_depthReduction::SetShaderProgramUniforms( ShaderProgramDescriptor* shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->id, "depthTextureInitial" ), 0 ); + TextureUniform( shaderProgram->id, 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 976060877d..3ee7179551 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -52,6 +52,8 @@ struct GLBinaryHeader { uint32_t checkSum; // checksum of shader source this was built from uint32_t driverVersionHash; // detect if the graphics driver was different + uint32_t separateProgram; + GLuint type; uint32_t macro; // Bitmask of macros the shader uses ( may or may not be enabled ) @@ -93,6 +95,13 @@ class GLHeader { class GLShader { friend class GLShaderManager; + public: + struct UniformData { + GLuint program = 0; + GLint* uniformLocations; + GLuint* uniformBlockIndexes; + byte* uniformFirewall; + }; private: GLShader( const GLShader & ) = delete; GLShader &operator = ( const GLShader & ) = delete; @@ -106,7 +115,8 @@ class GLShader { protected: int _activeMacros; unsigned int _checkSum; - ShaderProgramDescriptor* currentProgram; + GLuint currentPipeline; + uint32_t currentIndex; const uint32_t _vertexAttribsRequired; uint32_t _vertexAttribs; // can be set by uniforms GLShaderManager *_shaderManager; @@ -114,8 +124,9 @@ class GLShader { bool _hasVertexShader; bool _hasFragmentShader; bool _hasComputeShader; - std::vector shaderPrograms; - std::vector shaderPipelines; + // std::vector shaderPrograms; + std::vector shaderPipelines; + std::vector uniformsData; std::vector vertexShaderDescriptors; std::vector fragmentShaderDescriptors; @@ -198,10 +209,14 @@ class GLShader { return _compileMacros.size(); } + UniformData* GetUniformData( int offset = 0 ) { + return &uniformsData[currentIndex * 3 + offset]; + } + GLint GetUniformLocation( const GLchar *uniformName ) const; - ShaderProgramDescriptor* GetProgram() const { - return currentProgram; + GLuint GetProgram() const { + return currentPipeline; } const std::string &GetName() const { @@ -450,11 +465,12 @@ class GLShaderManager { void BuildShader( ShaderDescriptor* descriptor ); void BuildShaderProgram( ShaderProgramDescriptor* descriptor ); - ShaderProgramDescriptor* FindShaderProgram( std::vector& shaders, GLShader* mainShader ); + ShaderProgramDescriptor* FindShaderProgram( std::vector& shaders, GLShader* mainShader, + GLShader::UniformData* uniformData ); ShaderPipelineDescriptor* FindShaderPipelines( std::vector& vertexShaders, std::vector& fragmentShaders, std::vector& computeShaders, - GLShader* mainShader ); + GLShader* mainShader, uint32_t permutation ); void BindAttribLocations( GLuint program ) const; void UpdateShaderProgramUniformLocations( GLShader* shader, ShaderProgramDescriptor* shaderProgram ) const; @@ -571,13 +587,15 @@ class GLUniformSampler : protected GLUniform { } inline GLint GetLocation() { - ShaderProgramDescriptor* p = _shader->GetProgram(); + GLuint p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + ASSERT_EQ( p, glState.currentPipeline ); } - return p->uniformLocations[_locationIndex]; + GLShader::UniformData* FSData = _shader->GetUniformData( 1 ); + GLShader::UniformData* CSData = _shader->GetUniformData( 2 ); + return FSData->program ? FSData->uniformLocations[_locationIndex] : CSData->uniformLocations[_locationIndex]; } inline size_t GetFirewallIndex() const { @@ -597,7 +615,10 @@ class GLUniformSampler : protected GLUniform { currentValueBindless = value; if ( glConfig2.usingBindlessTextures && ( !_shader->UseMaterialSystem() || _global ) ) { - glUniformHandleui64ARB( GetLocation(), currentValueBindless ); + GLShader::UniformData* FSData = _shader->GetUniformData( 1 ); + GLShader::UniformData* CSData = _shader->GetUniformData( 2 ); + GLuint program = FSData->program ? FSData->program : CSData->program; + glProgramUniformHandleui64ARB( program, GetLocation(), currentValueBindless ); } } @@ -625,13 +646,15 @@ class GLUniformSampler1D : protected GLUniformSampler { } inline GLint GetLocation() { - ShaderProgramDescriptor* p = _shader->GetProgram(); + GLuint p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + ASSERT_EQ( p, glState.currentPipeline ); } - return p->uniformLocations[_locationIndex]; + GLShader::UniformData* FSData = _shader->GetUniformData( 1 ); + GLShader::UniformData* CSData = _shader->GetUniformData( 2 ); + return FSData->program ? FSData->uniformLocations[_locationIndex] : CSData->uniformLocations[_locationIndex]; } public: @@ -647,13 +670,15 @@ class GLUniformSampler2D : protected GLUniformSampler { } inline GLint GetLocation() { - ShaderProgramDescriptor* p = _shader->GetProgram(); + GLuint p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + ASSERT_EQ( p, glState.currentPipeline ); } - return p->uniformLocations[_locationIndex]; + GLShader::UniformData* FSData = _shader->GetUniformData( 1 ); + GLShader::UniformData* CSData = _shader->GetUniformData( 2 ); + return FSData->program ? FSData->uniformLocations[_locationIndex] : CSData->uniformLocations[_locationIndex]; } public: @@ -669,13 +694,15 @@ class GLUniformSampler3D : protected GLUniformSampler { } inline GLint GetLocation() { - ShaderProgramDescriptor* p = _shader->GetProgram(); + GLuint p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + ASSERT_EQ( p, glState.currentPipeline ); } - return p->uniformLocations[_locationIndex]; + GLShader::UniformData* FSData = _shader->GetUniformData( 1 ); + GLShader::UniformData* CSData = _shader->GetUniformData( 2 ); + return FSData->program ? FSData->uniformLocations[_locationIndex] : CSData->uniformLocations[_locationIndex]; } public: @@ -691,13 +718,15 @@ class GLUniformUSampler3D : protected GLUniformSampler { } inline GLint GetLocation() { - ShaderProgramDescriptor* p = _shader->GetProgram(); + GLuint p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + ASSERT_EQ( p, glState.currentPipeline ); } - return p->uniformLocations[_locationIndex]; + GLShader::UniformData* FSData = _shader->GetUniformData( 1 ); + GLShader::UniformData* CSData = _shader->GetUniformData( 2 ); + return FSData->program ? FSData->uniformLocations[_locationIndex] : CSData->uniformLocations[_locationIndex]; } public: @@ -713,13 +742,15 @@ class GLUniformSamplerCube : protected GLUniformSampler { } inline GLint GetLocation() { - ShaderProgramDescriptor* p = _shader->GetProgram(); + GLuint p = _shader->GetProgram(); if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + ASSERT_EQ( p, glState.currentPipeline ); } - return p->uniformLocations[_locationIndex]; + GLShader::UniformData* FSData = _shader->GetUniformData( 1 ); + GLShader::UniformData* CSData = _shader->GetUniformData( 2 ); + return FSData->program ? FSData->uniformLocations[_locationIndex] : CSData->uniformLocations[_locationIndex]; } public: @@ -732,16 +763,14 @@ class GLUniform1i : protected GLUniform { protected: GLUniform1i( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "int", 1, 1, global ) - { + GLUniform( shader, name, "int", 1, 1, global ) { } - inline void SetValue( int value ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( int value ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -757,17 +786,37 @@ class GLUniform1i : protected GLUniform return; } + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + #if defined( USE_UNIFORM_FIREWALL ) - int *firewall = ( int * ) &p->uniformFirewall[ _firewallIndex ]; + int* firewall = ( int* ) &p->uniformFirewall[_firewallIndex]; - if ( *firewall == value ) - { - return; - } + if ( *firewall == value ) { + continue; + } + + *firewall = value; +#endif + glProgramUniform1i( p->program, p->uniformLocations[_locationIndex], value ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); +#if defined( USE_UNIFORM_FIREWALL ) + int* firewall = ( int* ) &p->uniformFirewall[_firewallIndex]; + + if ( *firewall == value ) { + return; + } - *firewall = value; + *firewall = value; #endif - glUniform1i( p->uniformLocations[ _locationIndex ], value ); + glUniform1i( p->uniformLocations[_locationIndex], value ); + } } public: size_t GetSize() override @@ -791,10 +840,10 @@ class GLUniform1ui : protected GLUniform { } inline void SetValue( uint value ) { - ShaderProgramDescriptor* p = _shader->GetProgram(); + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -809,16 +858,38 @@ class GLUniform1ui : protected GLUniform { return; } + + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + #if defined( USE_UNIFORM_FIREWALL ) - uint* firewall = ( uint* ) &p->uniformFirewall[_firewallIndex]; + uint* firewall = ( uint* ) &p->uniformFirewall[_firewallIndex]; - if ( *firewall == value ) { - return; - } + if ( *firewall == value ) { + continue; + } + + *firewall = value; +#endif + glProgramUniform1ui( p->program, p->uniformLocations[_locationIndex], value ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); +#if defined( USE_UNIFORM_FIREWALL ) + uint* firewall = ( uint* ) &p->uniformFirewall[_firewallIndex]; + + if ( *firewall == value ) { + return; + } - *firewall = value; + *firewall = value; #endif - glUniform1ui( p->uniformLocations[_locationIndex], value ); + glUniform1ui( p->uniformLocations[_locationIndex], value ); + } } public: size_t GetSize() override { @@ -842,10 +913,10 @@ class GLUniform1Bool : protected GLUniform { } inline void SetValue( int value ) { - ShaderProgramDescriptor* p = _shader->GetProgram(); + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -860,16 +931,38 @@ class GLUniform1Bool : protected GLUniform { return; } + + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + #if defined( USE_UNIFORM_FIREWALL ) - int* firewall = ( int* ) &p->uniformFirewall[_firewallIndex]; + int* firewall = ( int* ) &p->uniformFirewall[_firewallIndex]; - if ( *firewall == value ) { - return; - } + if ( *firewall == value ) { + continue; + } - *firewall = value; + *firewall = value; #endif - glUniform1i( p->uniformLocations[_locationIndex], value ); + glProgramUniform1i( p->program, p->uniformLocations[_locationIndex], value ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); +#if defined( USE_UNIFORM_FIREWALL ) + int* firewall = ( int* ) &p->uniformFirewall[_firewallIndex]; + + if ( *firewall == value ) { + return; + } + + *firewall = value; +#endif + glUniform1i( p->uniformLocations[_locationIndex], value ); + } } public: @@ -890,16 +983,14 @@ class GLUniform1f : protected GLUniform { protected: GLUniform1f( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "float", 1, 1, global ) - { + GLUniform( shader, name, "float", 1, 1, global ) { } - inline void SetValue( float value ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( float value ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -915,17 +1006,37 @@ class GLUniform1f : protected GLUniform return; } + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + #if defined( USE_UNIFORM_FIREWALL ) - float *firewall = ( float * ) &p->uniformFirewall[ _firewallIndex ]; + float* firewall = ( float* ) &p->uniformFirewall[_firewallIndex]; - if ( *firewall == value ) - { - return; - } + if ( *firewall == value ) { + continue; + } - *firewall = value; + *firewall = value; #endif - glUniform1f( p->uniformLocations[ _locationIndex ], value ); + glProgramUniform1f( p->program, p->uniformLocations[_locationIndex], value ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); +#if defined( USE_UNIFORM_FIREWALL ) + float* firewall = ( float* ) &p->uniformFirewall[_firewallIndex]; + + if ( *firewall == value ) { + return; + } + + *firewall = value; +#endif + glUniform1f( p->uniformLocations[_locationIndex], value ); + } } public: size_t GetSize() override @@ -946,17 +1057,15 @@ class GLUniform1fv : protected GLUniform { protected: GLUniform1fv( GLShader *shader, const char *name, const int size ) : - GLUniform( shader, name, "float", 1, 1, false, size ) - { + GLUniform( shader, name, "float", 1, 1, false, size ) { currentValue.reserve( size ); } - inline void SetValue( int numFloats, float *f ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( int numFloats, float *f ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -972,7 +1081,19 @@ class GLUniform1fv : protected GLUniform return; } - glUniform1fv( p->uniformLocations[ _locationIndex ], numFloats, f ); + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + + glProgramUniform1fv( p->program, p->uniformLocations[_locationIndex], numFloats, f ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); + glUniform1fv( p->uniformLocations[_locationIndex], numFloats, f ); + } } uint32_t* WriteToBuffer( uint32_t* buffer ) override { @@ -988,18 +1109,16 @@ class GLUniform2f : protected GLUniform { protected: GLUniform2f( GLShader *shader, const char *name ) : - GLUniform( shader, name, "vec2", 2, 2, false ) - { + GLUniform( shader, name, "vec2", 2, 2, false ) { currentValue[0] = 0.0; currentValue[1] = 0.0; } - inline void SetValue( const vec2_t v ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( const vec2_t v ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -1015,18 +1134,39 @@ class GLUniform2f : protected GLUniform return; } + + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } #if defined( USE_UNIFORM_FIREWALL ) - vec2_t *firewall = ( vec2_t * ) &p->uniformFirewall[ _firewallIndex ]; + vec2_t* firewall = ( vec2_t* ) &p->uniformFirewall[_firewallIndex]; - if ( ( *firewall )[ 0 ] == v[ 0 ] && ( *firewall )[ 1 ] == v[ 1 ] ) - { - return; - } + if ( ( *firewall )[0] == v[0] && ( *firewall )[1] == v[1] ) { + continue; + } - ( *firewall )[ 0 ] = v[ 0 ]; - ( *firewall )[ 1 ] = v[ 1 ]; + ( *firewall )[0] = v[0]; + ( *firewall )[1] = v[1]; #endif - glUniform2f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ] ); + glProgramUniform2f( p->program, p->uniformLocations[_locationIndex], v[0], v[1] ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); +#if defined( USE_UNIFORM_FIREWALL ) + vec2_t* firewall = ( vec2_t* ) &p->uniformFirewall[_firewallIndex]; + + if ( ( *firewall )[0] == v[0] && ( *firewall )[1] == v[1] ) { + return; + } + + ( *firewall )[0] = v[0]; + ( *firewall )[1] = v[1]; +#endif + glUniform2f( p->uniformLocations[_locationIndex], v[0], v[1] ); + } } size_t GetSize() override @@ -1047,19 +1187,17 @@ class GLUniform3f : protected GLUniform { protected: GLUniform3f( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "vec3", 3, 4, global ) - { + GLUniform( shader, name, "vec3", 3, 4, global ) { currentValue[0] = 0.0; currentValue[1] = 0.0; currentValue[2] = 0.0; } - inline void SetValue( const vec3_t v ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( const vec3_t v ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -1075,17 +1213,37 @@ class GLUniform3f : protected GLUniform return; } + + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } #if defined( USE_UNIFORM_FIREWALL ) - vec3_t *firewall = ( vec3_t * ) &p->uniformFirewall[ _firewallIndex ]; + vec3_t* firewall = ( vec3_t* ) &p->uniformFirewall[_firewallIndex]; - if ( VectorCompare( *firewall, v ) ) - { - return; - } + if ( VectorCompare( *firewall, v ) ) { + continue; + } - VectorCopy( v, *firewall ); + VectorCopy( v, *firewall ); #endif - glUniform3f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ] ); + glProgramUniform3f( p->program, p->uniformLocations[_locationIndex], v[0], v[1], v[2] ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); +#if defined( USE_UNIFORM_FIREWALL ) + vec3_t* firewall = ( vec3_t* ) &p->uniformFirewall[_firewallIndex]; + + if ( VectorCompare( *firewall, v ) ) { + return; + } + + VectorCopy( v, *firewall ); +#endif + glUniform3f( p->uniformLocations[_locationIndex], v[0], v[1], v[2] ); + } } public: size_t GetSize() override @@ -1106,20 +1264,18 @@ class GLUniform4f : protected GLUniform { protected: GLUniform4f( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "vec4", 4, 4, global ) - { + GLUniform( shader, name, "vec4", 4, 4, global ) { currentValue[0] = 0.0; currentValue[1] = 0.0; currentValue[2] = 0.0; currentValue[3] = 0.0; } - inline void SetValue( const vec4_t v ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( const vec4_t v ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -1135,17 +1291,38 @@ class GLUniform4f : protected GLUniform return; } + + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + #if defined( USE_UNIFORM_FIREWALL ) - vec4_t *firewall = ( vec4_t * ) &p->uniformFirewall[ _firewallIndex ]; + vec4_t* firewall = ( vec4_t* ) &p->uniformFirewall[_firewallIndex]; - if ( !memcmp( *firewall, v, sizeof( *firewall ) ) ) - { - return; - } + if ( !memcmp( *firewall, v, sizeof( *firewall ) ) ) { + continue; + } + + Vector4Copy( v, *firewall ); +#endif + glProgramUniform4f( p->program, p->uniformLocations[_locationIndex], v[0], v[1], v[2], v[3] ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); +#if defined( USE_UNIFORM_FIREWALL ) + vec4_t* firewall = ( vec4_t* ) &p->uniformFirewall[_firewallIndex]; - Vector4Copy( v, *firewall ); + if ( !memcmp( *firewall, v, sizeof( *firewall ) ) ) { + return; + } + + Vector4Copy( v, *firewall ); #endif - glUniform4f( p->uniformLocations[ _locationIndex ], v[ 0 ], v[ 1 ], v[ 2 ], v[ 3 ] ); + glUniform4f( p->uniformLocations[_locationIndex], v[0], v[1], v[2], v[3] ); + } } public: size_t GetSize() override @@ -1166,17 +1343,15 @@ class GLUniform4fv : protected GLUniform { protected: GLUniform4fv( GLShader *shader, const char *name, const int size ) : - GLUniform( shader, name, "vec4", 4, 4, false, size ) - { + GLUniform( shader, name, "vec4", 4, 4, false, size ) { currentValue.reserve( size ); } - inline void SetValue( int numV, vec4_t *v ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( int numV, vec4_t *v ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -1192,7 +1367,18 @@ class GLUniform4fv : protected GLUniform return; } - glUniform4fv( p->uniformLocations[ _locationIndex ], numV, &v[ 0 ][ 0 ] ); + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + glProgramUniform4fv( p->program, p->uniformLocations[_locationIndex], numV, &v[0][0] ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); + glUniform4fv( p->uniformLocations[_locationIndex], numV, &v[0][0] ); + } } public: @@ -1209,17 +1395,15 @@ class GLUniformMatrix4f : protected GLUniform { protected: GLUniformMatrix4f( GLShader *shader, const char *name, const bool global = false ) : - GLUniform( shader, name, "mat4", 16, 4, global ) - { + GLUniform( shader, name, "mat4", 16, 4, global ) { MatrixIdentity( currentValue ); } - inline void SetValue( GLboolean transpose, const matrix_t m ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( GLboolean transpose, const matrix_t m ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -1237,17 +1421,37 @@ class GLUniformMatrix4f : protected GLUniform return; } + + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } #if defined( USE_UNIFORM_FIREWALL ) - matrix_t *firewall = ( matrix_t * ) &p->uniformFirewall[ _firewallIndex ]; + matrix_t* firewall = ( matrix_t* ) &p->uniformFirewall[_firewallIndex]; - if ( MatrixCompare( m, *firewall ) ) - { - return; - } + if ( MatrixCompare( m, *firewall ) ) { + continue; + } - MatrixCopy( m, *firewall ); + MatrixCopy( m, *firewall ); #endif - glUniformMatrix4fv( p->uniformLocations[ _locationIndex ], 1, transpose, m ); + glProgramUniformMatrix4fv( p->program, p->uniformLocations[_locationIndex], 1, transpose, m ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); +#if defined( USE_UNIFORM_FIREWALL ) + matrix_t* firewall = ( matrix_t* ) &p->uniformFirewall[_firewallIndex]; + + if ( MatrixCompare( m, *firewall ) ) { + return; + } + + MatrixCopy( m, *firewall ); +#endif + glUniformMatrix4fv( p->uniformLocations[_locationIndex], 1, transpose, m ); + } } public: size_t GetSize() override @@ -1271,10 +1475,10 @@ class GLUniformMatrix32f : protected GLUniform { } inline void SetValue( GLboolean transpose, const vec_t* m ) { - ShaderProgramDescriptor* p = _shader->GetProgram(); + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -1290,7 +1494,18 @@ class GLUniformMatrix32f : protected GLUniform { return; } - glUniformMatrix3x2fv( p->uniformLocations[_locationIndex], 1, transpose, m ); + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + glProgramUniformMatrix3x2fv( p->program, p->uniformLocations[_locationIndex], 1, transpose, m ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); + glUniformMatrix3x2fv( p->uniformLocations[_locationIndex], 1, transpose, m ); + } } public: size_t GetSize() override { @@ -1310,17 +1525,15 @@ class GLUniformMatrix4fv : protected GLUniform { protected: GLUniformMatrix4fv( GLShader *shader, const char *name, const int size ) : - GLUniform( shader, name, "mat4", 16, 4, false, size ) - { + GLUniform( shader, name, "mat4", 16, 4, false, size ) { currentValue.reserve( size * 16 ); } - inline void SetValue( int numMatrices, GLboolean transpose, const matrix_t *m ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( int numMatrices, GLboolean transpose, const matrix_t *m ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -1336,7 +1549,18 @@ class GLUniformMatrix4fv : protected GLUniform return; } - glUniformMatrix4fv( p->uniformLocations[ _locationIndex ], numMatrices, transpose, &m[ 0 ][ 0 ] ); + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + glProgramUniformMatrix4fv( p->program, p->uniformLocations[_locationIndex], numMatrices, transpose, &m[0][0] ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); + glUniformMatrix4fv( p->uniformLocations[_locationIndex], numMatrices, transpose, &m[0][0] ); + } } public: @@ -1353,16 +1577,14 @@ class GLUniformMatrix34fv : protected GLUniform { protected: GLUniformMatrix34fv( GLShader *shader, const char *name, const int size ) : - GLUniform( shader, name, "mat3x4", 12, 4, false, size ) - { + GLUniform( shader, name, "mat3x4", 12, 4, false, size ) { } - inline void SetValue( int numMatrices, GLboolean transpose, const float *m ) - { - ShaderProgramDescriptor *p = _shader->GetProgram(); + inline void SetValue( int numMatrices, GLboolean transpose, const float *m ) { + GLuint program = _shader->GetProgram(); - if ( _global || !_shader->UseMaterialSystem() ) { - ASSERT_EQ( p, glState.currentProgram ); + if ( !glConfig2.separateShaderObjectsAvailable && ( _global || !_shader->UseMaterialSystem() ) ) { + ASSERT_EQ( program, glState.currentPipeline ); } #if defined( LOG_GLSL_UNIFORMS ) @@ -1378,7 +1600,18 @@ class GLUniformMatrix34fv : protected GLUniform return; } - glUniformMatrix3x4fv( p->uniformLocations[ _locationIndex ], numMatrices, transpose, m ); + if ( glConfig2.separateShaderObjectsAvailable ) { + for ( int i = 0; i < 3; i++ ) { + GLShader::UniformData* p = _shader->GetUniformData( i ); + if ( !p->program ) { + continue; + } + glProgramUniformMatrix3x4fv( p->program, p->uniformLocations[_locationIndex], numMatrices, transpose, m ); + } + } else { + GLShader::UniformData* p = _shader->GetUniformData(); + glUniformMatrix3x4fv( p->uniformLocations[_locationIndex], numMatrices, transpose, m ); + } } public: @@ -1423,10 +1656,10 @@ class GLUniformBlock } void SetBuffer( GLuint buffer ) { - ShaderProgramDescriptor *p = _shader->GetProgram(); - GLuint blockIndex = p->uniformBlockIndexes[ _locationIndex ]; + GLuint p = _shader->GetProgram(); + GLuint blockIndex = _shader->GetUniformData( 1 )->uniformBlockIndexes[_locationIndex]; - ASSERT_EQ(p, glState.currentProgram); + // ASSERT_EQ( p, glState.currentPipeline ); if( blockIndex != GL_INVALID_INDEX ) { glBindBufferBase( GL_UNIFORM_BUFFER, blockIndex, buffer ); diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 87f562a2df..d0f882a4b8 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -120,55 +120,36 @@ GLuint64 BindAnimatedImage( int unit, const textureBundle_t *bundle ) return GL_BindToTMU( unit, bundle->image[ index ] ); } -void GL_BindProgram( ShaderProgramDescriptor* program ) { - if ( !program ) { - GL_BindNullProgram(); - return; - } - - if ( glState.currentProgram != program ) { - glUseProgram( program->id ); - glState.currentProgram = program; - } -} - -void GL_BindNullProgram() { - if ( r_logFile->integer ) { - GLimp_LogComment( "--- GL_BindNullProgram ---\n" ); - } - - if ( glState.currentProgram ) { - glUseProgram( 0 ); - glState.currentProgram = nullptr; - } -} - -void GL_BindProgramPipeline( ShaderPipelineDescriptor* pipeline ) { +void GL_BindProgram( GLuint pipeline, bool override ) { if ( !pipeline ) { - GL_BindNullProgramPipeline(); + GL_BindNullProgram(); return; } - if ( glState.currentProgram ) { - Log::Warn( "A GL program is still bound, program pipeline bind is ignored " - "(current program: %u, current pipeline: %u, new pipeline: %u", - glState.currentProgram->id, glState.currentPipeline->id, pipeline->id ); - } - if ( glState.currentPipeline != pipeline ) { - glBindProgramPipeline( pipeline->id ); + if ( glConfig2.separateShaderObjectsAvailable && !override ) { + glBindProgramPipeline( pipeline ); + } else { + glUseProgram( pipeline ); + } + glState.currentPipeline = pipeline; } } -void GL_BindNullProgramPipeline() { +void GL_BindNullProgram( bool override ) { if ( r_logFile->integer ) { - GLimp_LogComment( "--- GL_BindNullProgramPipeline ---\n" ); + GLimp_LogComment( "--- GL_BindNullProgram ---\n" ); } if ( glState.currentPipeline ) { - glBindProgramPipeline( 0 ); - glState.currentPipeline = nullptr; + if ( glConfig2.separateShaderObjectsAvailable && !override ) { + glBindProgramPipeline( 0 ); + } else { + glUseProgram( 0 ); + } + + glState.currentPipeline = 0; } } diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 1374c276d7..4f1c5232f1 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -2429,8 +2429,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 - ShaderProgramDescriptor* currentProgram; - ShaderPipelineDescriptor* currentPipeline; + GLuint currentPipeline; FBO_t *currentFBO; VBO_t *currentVBO; IBO_t *currentIBO; @@ -3233,10 +3232,8 @@ inline bool checkGLErrors() GLuint64 BindAnimatedImage( int unit, const textureBundle_t *bundle ); GLuint64 GL_BindToTMU( int unit, image_t *image ); void GL_TextureFilter( image_t *image, filterType_t filterType ); - void GL_BindProgram( ShaderProgramDescriptor* program ); - void GL_BindNullProgram(); - void GL_BindProgramPipeline( ShaderPipelineDescriptor* program ); - void GL_BindNullProgramPipeline(); + void GL_BindProgram( GLuint pipeline, bool override = false ); + void GL_BindNullProgram( bool override = false); void GL_SetDefaultState(); void GL_SelectTexture( int unit ); void GL_TextureMode( const char *string );