diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index bd143ca82e..7d06ad0c6f 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -490,10 +490,14 @@ static void AddConst( std::string& str, const std::string& name, float v1, float static std::string GenVersionDeclaration( const std::vector &addedExtensions ) { // Declare version. - std::string str = Str::Format( "#version %d %s\n\n", + std::string str = Str::Format( "#version %d %s\n", glConfig.shadingLanguageVersion, glConfig.shadingLanguageVersion >= 150 ? ( glConfig.glCoreProfile ? "core" : "compatibility" ) : "" ); + str += "#line 1000000000\n"; + + str += "\n"; + // Add supported GLSL extensions. for ( const auto& addedExtension : addedExtensions ) { addExtension( str, addedExtension.available, addedExtension.minGlslVersion, addedExtension.name ); @@ -840,7 +844,10 @@ std::string GLShaderManager::GetDeformShaderName( const int index ) { std::string GLShaderManager::BuildDeformShaderText( const std::string& steps ) { std::string shaderText; - shaderText = steps + "\n"; + shaderText = "\n" + steps + "\n"; + + shaderText += "#line 2000000000\n"; + shaderText += GetShaderText( "deformVertexes_vp.glsl" ); return shaderText; @@ -867,15 +874,23 @@ int GLShaderManager::GetDeformShaderIndex( deformStage_t *deforms, int numDeform static bool IsUnusedPermutation( const char *compileMacros ) { + bool hasGridLighting = false; + bool hasGridDeluxeMapping = false; + const char* token; while ( *( token = COM_ParseExt2( &compileMacros, false ) ) ) { - if ( strcmp( token, "USE_DELUXE_MAPPING" ) == 0 ) + if ( strcmp( token, "USE_GRID_LIGHTING" ) == 0 ) + { + hasGridLighting = true; + } + else if ( strcmp( token, "USE_DELUXE_MAPPING" ) == 0 ) { if ( !glConfig.deluxeMapping ) return true; } else if ( strcmp( token, "USE_GRID_DELUXE_MAPPING" ) == 0 ) { + hasGridDeluxeMapping = true; if ( !glConfig.deluxeMapping ) return true; } else if ( strcmp( token, "USE_PHYSICAL_MAPPING" ) == 0 ) @@ -899,6 +914,11 @@ static bool IsUnusedPermutation( const char *compileMacros ) } } + if ( !hasGridLighting && hasGridDeluxeMapping ) + { + return true; + } + return false; } @@ -981,7 +1001,7 @@ void GLShaderManager::BuildShaderProgram( ShaderProgramDescriptor* descriptor ) glGetProgramiv( program, GL_LINK_STATUS, &linked ); if ( !linked ) { - Log::Warn( "Link log:" ); + Log::Warn( "Link log for %s:", descriptor->mainShader ); Log::Warn( GetInfoLog( program ) ); ThrowShaderError( "Shader program failed to link!" ); } @@ -1061,6 +1081,10 @@ bool GLShaderManager::BuildPermutation( GLShader* shader, int index, const bool return false; } + if ( shader->SkipCompilation() ) { + return false; + } + if ( IsUnusedPermutation( compileMacros.c_str() ) ) { return false; } @@ -1196,6 +1220,13 @@ std::string GLShaderManager::ProcessInserts( const std::string& shaderText ) con while ( std::getline( shaderTextStream, line, '\n' ) ) { ++lineCount; + + /* The deform vertex header is prepended to the mainText and is part + of the shaderText, so we should reset line numbering after it. */ + if ( line == "#line 0" ) { + lineCount = 0; + } + const std::string::size_type position = line.find( "#insert" ); if ( position == std::string::npos || line.find_first_not_of( " \t" ) != position ) { out += line + "\n"; @@ -1326,7 +1357,9 @@ void GLShaderManager::InitShader( GLShader* shader ) { if ( shaderType.enabled ) { Com_sprintf( filename, sizeof( filename ), "%s%s.glsl", shaderType.path.c_str(), shaderType.postfix ); - shaderType.mainText = GetShaderText( filename ); + /* The deform vertex header is prepended to the mainText, + so we should reset line numbering after it. */ + shaderType.mainText = "#line 0\n" + GetShaderText( filename ); } } @@ -1980,29 +2013,6 @@ 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( glConfig.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++ ) @@ -3039,7 +3049,7 @@ GlobalUBOProxy::GlobalUBOProxy() : /* HACK: A GLShader* is required to initialise uniforms, but we don't need the GLSL shader itself, so we won't actually build it */ GLShader( "proxy", 0, - false, "screenSpace", "generic", true ), + false, "screenSpace", "generic", true, true ), // CONST u_ColorMap3D( this ), u_DepthMap( this ), @@ -3068,4 +3078,4 @@ GlobalUBOProxy::GlobalUBOProxy() : u_Tonemap( this ), u_TonemapParms( this ), u_Exposure( this ) { -} \ No newline at end of file +} diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 781438e1b5..ba4245d522 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -188,6 +188,7 @@ class GLShader { const bool worldShader; const bool pushSkip; + const bool compileSkip; protected: int _activeMacros = 0; int _deformIndex = 0; @@ -212,7 +213,7 @@ class GLShader { GLShader( const std::string& name, uint32_t vertexAttribsRequired, const bool useMaterialSystem, const std::string newVertexShaderName, const std::string newFragmentShaderName, - const bool newPushSkip = false ) : + const bool newPushSkip = false, const bool compileSkip = false ) : _name( name ), _vertexAttribsRequired( vertexAttribsRequired ), _useMaterialSystem( useMaterialSystem ), @@ -222,12 +223,14 @@ class GLShader { hasFragmentShader( true ), hasComputeShader( false ), worldShader( false ), - pushSkip( newPushSkip ) { + pushSkip( newPushSkip ), + compileSkip( compileSkip ) { } GLShader( const std::string& name, const bool useMaterialSystem, - const std::string newComputeShaderName, const bool newWorldShader = false ) : + const std::string newComputeShaderName, const bool newWorldShader = false, + const bool compileSkip = false ) : _name( name ), _vertexAttribsRequired( 0 ), _useMaterialSystem( useMaterialSystem ), @@ -236,7 +239,8 @@ class GLShader { hasFragmentShader( false ), hasComputeShader( true ), worldShader( newWorldShader ), - pushSkip( false ) { + pushSkip( false ), + compileSkip( compileSkip ) { } public: @@ -268,6 +272,10 @@ class GLShader { return currentProgram; } + bool SkipCompilation() const { + return compileSkip; + } + protected: void PostProcessUniforms(); uint32_t GetUniqueCompileMacros( size_t permutation, const int type ) const; @@ -550,7 +558,6 @@ class GLShaderManager { 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;