Skip to content

Commit

Permalink
UPBGE: Fix redundant #version shader directive.
Browse files Browse the repository at this point in the history
With the usage of GPUShader the #version directive is already
set and the user must not repeat it. Unfortunatly a lot of existing
shaders use this directive.

To fix this issue the function RAS_Shader::GetParsedProgram parse
the shader program, warn about redundant #version directive and
erase it.
  • Loading branch information
panzergame committed Jun 3, 2017
1 parent 00836b4 commit fedadad
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 25 deletions.
1 change: 0 additions & 1 deletion source/blender/gpu/GPU_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ enum {
GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV = (1 << 0),
GPU_SHADER_FLAGS_NEW_SHADING = (1 << 1),
GPU_SHADER_FLAGS_SPECIAL_INSTANCING = (1 << 2),
GPU_SHADER_FLAGS_SPECIAL_RESET_LINE = (1 << 3),
};

GPUShader *GPU_shader_create(
Expand Down
19 changes: 3 additions & 16 deletions source/blender/gpu/intern/gpu_shader.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
bool use_opensubdiv = false;
#endif
bool use_instancing = (flags & GPU_SHADER_FLAGS_SPECIAL_INSTANCING) != 0;
bool resetline = (flags & GPU_SHADER_FLAGS_SPECIAL_RESET_LINE) != 0;
GLint status;
GLchar log[5000];
GLsizei length = 0;
Expand Down Expand Up @@ -336,7 +335,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
gpu_shader_standard_extensions(standard_extensions, geocode != NULL);

if (vertexcode) {
const char *source[7];
const char *source[6];
/* custom limit, may be too small, beware */
int num_source = 0;

Expand All @@ -346,10 +345,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
source[num_source++] = datatoc_gpu_shader_lib_glsl;

if (defines) source[num_source++] = defines;
if (resetline) {
/* Print error message with the correct line number corresponding to the passed code */
source[num_source++] = "#line 0\n";
}
source[num_source++] = vertexcode;

glAttachShader(shader->program, shader->vertex);
Expand All @@ -368,7 +363,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
}

if (fragcode) {
const char *source[9];
const char *source[8];
int num_source = 0;

source[num_source++] = gpu_shader_version();
Expand All @@ -390,10 +385,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,

if (defines) source[num_source++] = defines;
if (libcode) source[num_source++] = libcode;
if (resetline) {
/* Print error message with the correct line number corresponding to the passed code */
source[num_source++] = "#line 0\n";
}
source[num_source++] = fragcode;

glAttachShader(shader->program, shader->fragment);
Expand All @@ -412,7 +403,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
}

if (geocode) {
const char *source[8];
const char *source[6];
int num_source = 0;

source[num_source++] = gpu_shader_version();
Expand All @@ -421,10 +412,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
source[num_source++] = datatoc_gpu_shader_lib_glsl;

if (defines) source[num_source++] = defines;
if (resetline) {
/* Print error message with the correct line number corresponding to the passed code */
source[num_source++] = "#line 0\n";
}
source[num_source++] = geocode;

glAttachShader(shader->program, shader->geometry);
Expand Down
37 changes: 29 additions & 8 deletions source/gameengine/Rasterizer/RAS_Shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,25 +276,46 @@ void RAS_Shader::DeleteShader()
}
}

std::string RAS_Shader::GetParsedProgram(ProgramType type) const
{
std::string prog = m_progs[type];
if (prog.empty()) {
return prog;
}

const unsigned int pos = prog.find("#version");
if (pos != -1) {
CM_Warning("found redundant #version directive in shader program, directive ignored.");
const unsigned int nline = prog.find("\n", pos);
CM_Debug(pos << ", " << nline);
prog.erase(pos, nline - pos);
}

prog.insert(0, "#line 0\n");

return prog;
}

bool RAS_Shader::LinkProgram()
{
const char *vert;
const char *frag;
const char *geom;
std::string vert;
std::string frag;
std::string geom;

if (m_error) {
goto program_error;
}

if (m_progs[VERTEX_PROGRAM].empty() || m_progs[FRAGMENT_PROGRAM].empty()) {
CM_Error("invalid GLSL sources");
CM_Error("invalid GLSL sources.");
return false;
}

vert = m_progs[VERTEX_PROGRAM].c_str();
frag = m_progs[FRAGMENT_PROGRAM].c_str();
geom = (m_progs[GEOMETRY_PROGRAM].empty()) ? nullptr : m_progs[GEOMETRY_PROGRAM].c_str();
m_shader = GPU_shader_create_ex(vert, frag, geom, nullptr, nullptr, 0, 0, 0, GPU_SHADER_FLAGS_SPECIAL_RESET_LINE);
vert = GetParsedProgram(VERTEX_PROGRAM);
frag = GetParsedProgram(FRAGMENT_PROGRAM);
geom = GetParsedProgram(GEOMETRY_PROGRAM);
m_shader = GPU_shader_create(vert.c_str(), frag.c_str(), geom.empty() ? nullptr : geom.c_str(),
nullptr, nullptr, 0, 0, 0);
if (!m_shader) {
goto program_error;
}
Expand Down
6 changes: 6 additions & 0 deletions source/gameengine/Rasterizer/RAS_Shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ class RAS_Shader
RAS_UniformVec m_uniforms;
RAS_UniformVecDef m_preDef;

/** Parse shader program to prevent redundant macro directives.
* \param type The program type to parse.
* \return The parsed program.
*/
std::string GetParsedProgram(ProgramType type) const;

// Compiles and links the shader
virtual bool LinkProgram();
void ValidateProgram();
Expand Down

2 comments on commit fedadad

@Anarchokawaii
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What version directive is GPUShader using? and how can i set it? i wanna user version directive 330

@panzergame
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GPUShader is selecting the higher safe version, for more recent compatible version see #716.

Please sign in to comment.