diff --git a/source/blender/gpu/intern/gpu_shader_log.cc b/source/blender/gpu/intern/gpu_shader_log.cc index 2ae385c108f..a7bf05e56de 100644 --- a/source/blender/gpu/intern/gpu_shader_log.cc +++ b/source/blender/gpu/intern/gpu_shader_log.cc @@ -245,19 +245,21 @@ void Shader::print_log(Span sources, log_line = line_end + 1; previous_location = log_item.cursor; } - // printf("%s", sources_combined); - MEM_freeN(sources_combined); CLG_Severity severity = error ? CLG_SEVERITY_ERROR : CLG_SEVERITY_WARN; if (((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= 0)) || (severity >= CLG_SEVERITY_WARN)) { + if (DEBUG_LOG_SHADER_SRC_ON_ERROR && error) { + CLG_log_str(LOG.type, severity, this->name, stage, sources_combined); + } const char *_str = BLI_dynstr_get_cstring(dynstr); CLG_log_str(LOG.type, severity, this->name, stage, _str); MEM_freeN((void *)_str); } + MEM_freeN(sources_combined); BLI_dynstr_free(dynstr); } diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh index a698de6b6bb..ba7b976c28c 100644 --- a/source/blender/gpu/intern/gpu_shader_private.hh +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -25,6 +25,9 @@ namespace gpu { class GPULogParser; +/* Set to 1 to log the full source of shaders that fail to compile. */ +#define DEBUG_LOG_SHADER_SRC_ON_ERROR 0 + /** * Compilation is done on a list of GLSL sources. This list contains placeholders that should be * provided by the backend shader. These defines contains the locations where the backend can patch diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 9180056fb3c..83d9c519c30 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -1173,6 +1173,30 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage, sources[SOURCES_INDEX_VERSION] = glsl_patch_get(gl_stage); sources[SOURCES_INDEX_SPECIALIZATION_CONSTANTS] = constants_source.c_str(); + if (DEBUG_LOG_SHADER_SRC_ON_ERROR) { + /* Store the generated source for printing in case the link fails. */ + StringRefNull source_type; + switch (gl_stage) { + case GL_VERTEX_SHADER: + source_type = "VertShader"; + break; + case GL_GEOMETRY_SHADER: + source_type = "GeomShader"; + break; + case GL_FRAGMENT_SHADER: + source_type = "FragShader"; + break; + case GL_COMPUTE_SHADER: + source_type = "ComputeShader"; + break; + } + + debug_source += "\n\n----------" + source_type + "----------\n\n"; + for (const char *source : sources) { + debug_source.append(source); + } + } + glShaderSource(shader, sources.size(), sources.data(), nullptr); glCompileShader(shader); @@ -1510,7 +1534,7 @@ bool GLShader::program_link() if (!status) { char log[5000]; glGetProgramInfoLog(program_id, sizeof(log), nullptr, log); - Span sources; + Span sources = {debug_source.c_str()}; GLLogParser parser; print_log(sources, log, "Linking", true, &parser); } diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh index d0cd351fa07..fb063cb0acb 100644 --- a/source/blender/gpu/opengl/gl_shader.hh +++ b/source/blender/gpu/opengl/gl_shader.hh @@ -139,6 +139,8 @@ class GLShader : public Shader { eGPUShaderTFBType transform_feedback_type_ = GPU_SHADER_TFB_NONE; + std::string debug_source; + public: GLShader(const char *name); ~GLShader();