Skip to content

Commit

Permalink
Don't needlessly write out a binary shader that was loaded from disk
Browse files Browse the repository at this point in the history
  • Loading branch information
cmf028 committed Aug 7, 2012
1 parent 5a6843e commit 814060d
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 127 deletions.
250 changes: 124 additions & 126 deletions src/engine/rendererGL/gl_shader.cpp
Expand Up @@ -821,6 +821,12 @@ bool GLShader::LoadShaderProgram( GLuint program, const char *pname, int i ) con
GLvoid *binary;
GLenum binaryFormat;

//we need to recompile the shaders
if( r_recompileShaders->integer )
{
return false;
}

// Don't even try if the necessary functions aren't available
if( !glConfig2.getProgramBinaryAvailable )
{
Expand Down Expand Up @@ -855,7 +861,6 @@ bool GLShader::LoadShaderProgram( GLuint program, const char *pname, int i ) con
}

void GLShader::CompileAndLinkGPUShaderProgram( shaderProgram_t *program,
const char *programName,
const std::string &vertexShaderText,
const std::string &fragmentShaderText,
const std::string &compileMacros, int iteration ) const
Expand All @@ -865,167 +870,144 @@ void GLShader::CompileAndLinkGPUShaderProgram( shaderProgram_t *program,
#endif

//ri.Printf(PRINT_DEVELOPER, "------- GPU shader -------\n");
// header of the glsl shader
std::string vertexHeader;
std::string fragmentHeader;

Q_strncpyz( program->name, programName, sizeof( program->name ) );
if ( glConfig.driverType == GLDRV_OPENGL3 )
{
// HACK: abuse the GLSL preprocessor to turn GLSL 1.20 shaders into 1.30 ones

#if 0
vertexHeader += "#version 130\n";
fragmentHeader += "#version 130\n";

if ( !compileMacros.empty() )
{
program->compileMacros = ( char * ) ri.Hunk_Alloc( sizeof( char ) * compileMacros.length() + 1, h_low );
Q_strncpyz( program->compileMacros, compileMacros.c_str(), compileMacros.length() + 1 );
vertexHeader += "#define attribute in\n";
vertexHeader += "#define varying out\n";

fragmentHeader += "#define varying in\n";

fragmentHeader += "out vec4 out_Color;\n";
fragmentHeader += "#define gl_FragColor out_Color\n";

vertexHeader += "#define textureCube texture\n";
fragmentHeader += "#define textureCube texture\n";
}
else
#endif
{
program->compileMacros = NULL;
vertexHeader += "#version 120\n";
fragmentHeader += "#version 120\n";
}

program->program = glCreateProgram();
program->attribs = _vertexAttribsRequired; // | _vertexAttribsOptional;
// permutation macros
std::string macrosString;

if( r_recompileShaders->integer || !LoadShaderProgram( program->program, programName, iteration ) )
if ( !compileMacros.empty() )
{
// header of the glsl shader
std::string vertexHeader;
std::string fragmentHeader;
const char *compileMacros_ = compileMacros.c_str();
char **compileMacrosP = ( char ** ) &compileMacros_;
char *token;

if ( glConfig.driverType == GLDRV_OPENGL3 )
while ( 1 )
{
// HACK: abuse the GLSL preprocessor to turn GLSL 1.20 shaders into 1.30 ones
token = COM_ParseExt2( compileMacrosP, qfalse );

vertexHeader += "#version 130\n";
fragmentHeader += "#version 130\n";
if ( !token[ 0 ] )
{
break;
}

vertexHeader += "#define attribute in\n";
vertexHeader += "#define varying out\n";
macrosString += va( "#ifndef %s\n#define %s 1\n#endif\n", token, token );
}
}

fragmentHeader += "#define varying in\n";
// add them
std::string vertexShaderTextWithMacros = vertexHeader + macrosString + vertexShaderText;
std::string fragmentShaderTextWithMacros = fragmentHeader + macrosString + fragmentShaderText;
#ifdef USE_GLSL_OPTIMIZER
if( optimize )
{
static char msgPart[ 1024 ];
int length = 0;
int i;

fragmentHeader += "out vec4 out_Color;\n";
fragmentHeader += "#define gl_FragColor out_Color\n";
const std::string version = ( glConfig.driverType == GLDRV_OPENGL3 ) ? "#version 130\n" : "#version 120\n";

vertexHeader += "#define textureCube texture\n";
fragmentHeader += "#define textureCube texture\n";
}
else
glslopt_shader *shaderOptimized = glslopt_optimize( s_glslOptimizer, kGlslOptShaderVertex, vertexShaderTextWithMacros.c_str(), 0 );
if( glslopt_get_status( shaderOptimized ) )
{
vertexHeader += "#version 120\n";
fragmentHeader += "#version 120\n";
}
vertexShaderTextWithMacros = version + glslopt_get_output( shaderOptimized );

// permutation macros
std::string macrosString;
ri.Printf( PRINT_DEVELOPER, "----------------------------------------------------------\n" );
ri.Printf( PRINT_DEVELOPER, "OPTIMIZED VERTEX shader '%s' ----------\n", programName );
ri.Printf( PRINT_DEVELOPER, " BEGIN ---------------------------------------------------\n" );

if ( !compileMacros.empty() )
{
const char *compileMacros_ = compileMacros.c_str();
char **compileMacrosP = ( char ** ) &compileMacros_;
char *token;
length = strlen( vertexShaderTextWithMacros.c_str() );

while ( 1 )
for ( i = 0; i < length; i += 1024 )
{
token = COM_ParseExt2( compileMacrosP, qfalse );

if ( !token[ 0 ] )
{
break;
}

macrosString += va( "#ifndef %s\n#define %s 1\n#endif\n", token, token );
Q_strncpyz( msgPart, vertexShaderTextWithMacros.c_str() + i, sizeof( msgPart ) );
ri.Printf( PRINT_DEVELOPER, "%s\n", msgPart );
}
}

// add them
std::string vertexShaderTextWithMacros = vertexHeader + macrosString + vertexShaderText;
std::string fragmentShaderTextWithMacros = fragmentHeader + macrosString + fragmentShaderText;
#ifdef USE_GLSL_OPTIMIZER
if( optimize )
ri.Printf( PRINT_DEVELOPER, " END-- ---------------------------------------------------\n" );
}
else
{
static char msgPart[ 1024 ];
int length = 0;
int i;
const char *errorLog = glslopt_get_log( shaderOptimized );

const std::string version = ( glConfig.driverType == GLDRV_OPENGL3 ) ? "#version 130\n" : "#version 120\n";
length = strlen( errorLog );

glslopt_shader *shaderOptimized = glslopt_optimize( s_glslOptimizer, kGlslOptShaderVertex, vertexShaderTextWithMacros.c_str(), 0 );
if( glslopt_get_status( shaderOptimized ) )
for ( i = 0; i < length; i += 1024 )
{
vertexShaderTextWithMacros = version + glslopt_get_output( shaderOptimized );

ri.Printf( PRINT_DEVELOPER, "----------------------------------------------------------\n" );
ri.Printf( PRINT_DEVELOPER, "OPTIMIZED VERTEX shader '%s' ----------\n", programName );
ri.Printf( PRINT_DEVELOPER, " BEGIN ---------------------------------------------------\n" );

length = strlen( vertexShaderTextWithMacros.c_str() );

for ( i = 0; i < length; i += 1024 )
{
Q_strncpyz( msgPart, vertexShaderTextWithMacros.c_str() + i, sizeof( msgPart ) );
ri.Printf( PRINT_DEVELOPER, "%s\n", msgPart );
}

ri.Printf( PRINT_DEVELOPER, " END-- ---------------------------------------------------\n" );
Q_strncpyz( msgPart, errorLog + i, sizeof( msgPart ) );
ri.Printf( PRINT_WARNING, "%s\n", msgPart );
}
else
{
const char *errorLog = glslopt_get_log( shaderOptimized );

length = strlen( errorLog );

for ( i = 0; i < length; i += 1024 )
{
Q_strncpyz( msgPart, errorLog + i, sizeof( msgPart ) );
ri.Printf( PRINT_WARNING, "%s\n", msgPart );
}

ri.Printf( PRINT_WARNING, "^1Couldn't optimize VERTEX shader %s\n", programName );
}
glslopt_shader_delete( shaderOptimized );
ri.Printf( PRINT_WARNING, "^1Couldn't optimize VERTEX shader %s\n", programName );
}
glslopt_shader_delete( shaderOptimized );


glslopt_shader *shaderOptimized1 = glslopt_optimize( s_glslOptimizer, kGlslOptShaderFragment, fragmentShaderTextWithMacros.c_str(), 0 );
if( glslopt_get_status( shaderOptimized1 ) )
{
fragmentShaderTextWithMacros = version + glslopt_get_output( shaderOptimized1 );
glslopt_shader *shaderOptimized1 = glslopt_optimize( s_glslOptimizer, kGlslOptShaderFragment, fragmentShaderTextWithMacros.c_str(), 0 );
if( glslopt_get_status( shaderOptimized1 ) )
{
fragmentShaderTextWithMacros = version + glslopt_get_output( shaderOptimized1 );

ri.Printf( PRINT_DEVELOPER, "----------------------------------------------------------\n" );
ri.Printf( PRINT_DEVELOPER, "OPTIMIZED FRAGMENT shader '%s' ----------\n", programName );
ri.Printf( PRINT_DEVELOPER, " BEGIN ---------------------------------------------------\n" );
ri.Printf( PRINT_DEVELOPER, "----------------------------------------------------------\n" );
ri.Printf( PRINT_DEVELOPER, "OPTIMIZED FRAGMENT shader '%s' ----------\n", programName );
ri.Printf( PRINT_DEVELOPER, " BEGIN ---------------------------------------------------\n" );

length = strlen( fragmentShaderTextWithMacros.c_str() );
length = strlen( fragmentShaderTextWithMacros.c_str() );

for ( i = 0; i < length; i += 1024 )
{
Q_strncpyz( msgPart, fragmentShaderTextWithMacros.c_str() + i, sizeof( msgPart ) );
ri.Printf( PRINT_DEVELOPER, "%s\n", msgPart );
}

ri.Printf( PRINT_DEVELOPER, " END-- ---------------------------------------------------\n" );
}
else
for ( i = 0; i < length; i += 1024 )
{
const char *errorLog = glslopt_get_log( shaderOptimized1 );
Q_strncpyz( msgPart, fragmentShaderTextWithMacros.c_str() + i, sizeof( msgPart ) );
ri.Printf( PRINT_DEVELOPER, "%s\n", msgPart );
}

length = strlen( errorLog );
ri.Printf( PRINT_DEVELOPER, " END-- ---------------------------------------------------\n" );
}
else
{
const char *errorLog = glslopt_get_log( shaderOptimized1 );

for ( i = 0; i < length; i += 1024 )
{
Q_strncpyz( msgPart, errorLog + i, sizeof( msgPart ) );
ri.Printf( PRINT_WARNING, "%s\n", msgPart );
}
length = strlen( errorLog );

ri.Printf( PRINT_WARNING, "^1Couldn't optimize FRAGMENT shader %s\n", programName );
for ( i = 0; i < length; i += 1024 )
{
Q_strncpyz( msgPart, errorLog + i, sizeof( msgPart ) );
ri.Printf( PRINT_WARNING, "%s\n", msgPart );
}
glslopt_shader_delete( shaderOptimized1 );

ri.Printf( PRINT_WARNING, "^1Couldn't optimize FRAGMENT shader %s\n", programName );
}
#endif
CompileGPUShader( program->program, programName, vertexShaderTextWithMacros.c_str(), strlen( vertexShaderTextWithMacros.c_str() ), GL_VERTEX_SHADER );
CompileGPUShader( program->program, programName, fragmentShaderTextWithMacros.c_str(), strlen( fragmentShaderTextWithMacros.c_str() ), GL_FRAGMENT_SHADER );
BindAttribLocations( program->program ); //, _vertexAttribsRequired | _vertexAttribsOptional);
LinkProgram( program->program );
glslopt_shader_delete( shaderOptimized1 );
}

#endif
CompileGPUShader( program->program, program->name, vertexShaderTextWithMacros.c_str(), strlen( vertexShaderTextWithMacros.c_str() ), GL_VERTEX_SHADER );
CompileGPUShader( program->program, program->name, fragmentShaderTextWithMacros.c_str(), strlen( fragmentShaderTextWithMacros.c_str() ), GL_FRAGMENT_SHADER );
BindAttribLocations( program->program ); //, _vertexAttribsRequired | _vertexAttribsOptional);
LinkProgram( program->program );
}
void GLShader::CompilePermutations()
{
Expand Down Expand Up @@ -1086,12 +1068,29 @@ void GLShader::CompilePermutations()
//ri.Printf(PRINT_ALL, "Compile macros: '%s'\n", compileMacros.c_str());

shaderProgram_t *shaderProgram = &_shaderPrograms[i];

Q_strncpyz( shaderProgram->name, this->GetName().c_str(), sizeof( shaderProgram->name ) );

CompileAndLinkGPUShaderProgram( shaderProgram,
this->GetName().c_str(),
vertexShaderText,
fragmentShaderText,
compileMacros, i);
#if 0
if ( !compileMacros.empty() )
{
program->compileMacros = ( char * ) ri.Hunk_Alloc( sizeof( char ) * compileMacros.length() + 1, h_low );
Q_strncpyz( program->compileMacros, compileMacros.c_str(), compileMacros.length() + 1 );
}
else
#endif
{
shaderProgram->compileMacros = NULL;
}

shaderProgram->program = glCreateProgram();
shaderProgram->attribs = _vertexAttribsRequired; // | _vertexAttribsOptional;

if( !LoadShaderProgram( shaderProgram->program, shaderProgram->name, i ) )
{
CompileAndLinkGPUShaderProgram( shaderProgram, vertexShaderText, fragmentShaderText, compileMacros, i);
SaveShaderProgram( shaderProgram->program, shaderProgram->name, i );
}

UpdateShaderProgramUniformLocations(shaderProgram);

Expand All @@ -1105,7 +1104,6 @@ void GLShader::CompilePermutations()
GL_CheckErrors();

numCompiled++;
SaveShaderProgram( shaderProgram->program, shaderProgram->name, i );
}
}

Expand Down
1 change: 0 additions & 1 deletion src/engine/rendererGL/gl_shader.h
Expand Up @@ -143,7 +143,6 @@ class GLShader
GLenum shaderType ) const;

void CompileAndLinkGPUShaderProgram( shaderProgram_t *program,
const char *programName,
const std::string &vertexShaderText,
const std::string &fragmentShaderText,
const std::string &compileMacros, int iteration ) const;
Expand Down

0 comments on commit 814060d

Please sign in to comment.