From 5b86f366c7a5cc64336a491bee41e05fb52d6174 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Thu, 26 Nov 2020 14:01:04 +0200 Subject: [PATCH] gl-renderer: dump failed shader source To help debugging shader compilation errors, print the shader source the way it was given to the GLSL compiler and with line numbers that match the compiler error messages. This is necessary because some snippets are added at runtime to the beginning, the source is not only what is in the respective .glsl file. I did look into using #line directives, but you cannot put source file names to it, only "source string numbers" which must be an integer expression. If we used #line, the reader would need to know that string number 0 is the version, string 1 is the config and string number 2 is fragment.glsl. I think that would have been too cumbersome. Signed-off-by: Pekka Paalanen --- libweston/renderer-gl/gl-shaders.c | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/libweston/renderer-gl/gl-shaders.c b/libweston/renderer-gl/gl-shaders.c index 84275fec..a55005a3 100644 --- a/libweston/renderer-gl/gl-shaders.c +++ b/libweston/renderer-gl/gl-shaders.c @@ -29,6 +29,8 @@ #include +#include + #include "gl-renderer.h" #include "gl-renderer-internal.h" @@ -38,6 +40,43 @@ /* static const char fragment_shader[]; fragment.glsl */ #include "fragment-shader.h" +static void +dump_program_with_line_numbers(int count, const char **sources) +{ + FILE *fp; + char *dumpstr; + size_t dumpstrsz; + const char *cur; + const char *delim; + int line = 1; + int i; + bool new_line = true; + + fp = open_memstream(&dumpstr, &dumpstrsz); + if (!fp) + return; + + for (i = 0; i < count; i++) { + cur = sources[i]; + while ((delim = strchr(cur, '\n'))) { + if (new_line) + fprintf(fp, "%6d: ", line++); + fprintf(fp, "%.*s\n", (int)(delim - cur), cur); + new_line = true; + cur = delim + 1; + } + if (new_line) + fprintf(fp, "%6d: ", line++); + new_line = false; + fprintf(fp, "%s", cur); + } + + if (fclose(fp) == 0) + weston_log_continue("%s\n", dumpstr); + + free(dumpstr); +} + static int compile_shader(GLenum type, int count, const char **sources) { @@ -52,6 +91,8 @@ compile_shader(GLenum type, int count, const char **sources) if (!status) { glGetShaderInfoLog(s, sizeof msg, NULL, msg); weston_log("shader info: %s\n", msg); + weston_log("shader source:\n"); + dump_program_with_line_numbers(count, sources); return GL_NONE; }