diff options
author | Jeroen Bakker <jeroen@blender.org> | 2021-06-28 13:20:59 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2021-06-28 13:23:10 +0300 |
commit | 1b942ef90c9b4b7fe98af50357aa76b74754f7ff (patch) | |
tree | 498267617e896181ce67d6c68b219289b76eec6f /source/blender/gpu/opengl | |
parent | dbd4ff4163617baa3d93dca257be3b2610c28782 (diff) |
GPU: Refactored +cleanup compilation log parsing.
Old implementation has a single parser of many different
formats. With the introduction of Vulkan this would lead
to another parser in the same function. This patch
separates the log parsing using a visitor pattern so the
log parsing can be configured per GPU backend or even
per driver.
With Vulkan we manage the compiler our self so the parsing
will become more straight forward. The OpenGL part depends
on many factors (OS, Driver) and perhaps even GPU.
Diffstat (limited to 'source/blender/gpu/opengl')
-rw-r--r-- | source/blender/gpu/opengl/gl_shader.cc | 12 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_shader.hh | 11 | ||||
-rw-r--r-- | source/blender/gpu/opengl/gl_shader_log.cc | 87 |
3 files changed, 105 insertions, 5 deletions
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index e77347d99eb..66a1bd5ceb7 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -158,18 +158,19 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *> char log[5000] = ""; glGetShaderInfoLog(shader, sizeof(log), nullptr, log); if (log[0] != '\0') { + GLLogParser parser; switch (gl_stage) { case GL_VERTEX_SHADER: - this->print_log(sources, log, "VertShader", !status); + this->print_log(sources, log, "VertShader", !status, &parser); break; case GL_GEOMETRY_SHADER: - this->print_log(sources, log, "GeomShader", !status); + this->print_log(sources, log, "GeomShader", !status, &parser); break; case GL_FRAGMENT_SHADER: - this->print_log(sources, log, "FragShader", !status); + this->print_log(sources, log, "FragShader", !status, &parser); break; case GL_COMPUTE_SHADER: - this->print_log(sources, log, "ComputeShader", !status); + this->print_log(sources, log, "ComputeShader", !status, &parser); break; } } @@ -220,7 +221,8 @@ bool GLShader::finalize() char log[5000]; glGetProgramInfoLog(shader_program_, sizeof(log), nullptr, log); Span<const char *> sources; - this->print_log(sources, log, "Linking", true); + GLLogParser parser; + this->print_log(sources, log, "Linking", true, &parser); return false; } diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh index 48aaaf2283d..770bc29747e 100644 --- a/source/blender/gpu/opengl/gl_shader.hh +++ b/source/blender/gpu/opengl/gl_shader.hh @@ -84,5 +84,16 @@ class GLShader : public Shader { MEM_CXX_CLASS_ALLOC_FUNCS("GLShader"); }; +class GLLogParser : public GPULogParser { + public: + char *parse_line(char *log_line, GPULogItem &log_item) override; + + protected: + char *skip_severity_prefix(char *log_line, GPULogItem &log_item); + char *skip_severity_keyword(char *log_line, GPULogItem &log_item); + + MEM_CXX_CLASS_ALLOC_FUNCS("GLLogParser"); +}; + } // namespace gpu } // namespace blender diff --git a/source/blender/gpu/opengl/gl_shader_log.cc b/source/blender/gpu/opengl/gl_shader_log.cc new file mode 100644 index 00000000000..393f852b463 --- /dev/null +++ b/source/blender/gpu/opengl/gl_shader_log.cc @@ -0,0 +1,87 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2021 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup gpu + */ + +#include "gl_shader.hh" + +#include "GPU_platform.h" + +namespace blender::gpu { + +char *GLLogParser::parse_line(char *log_line, GPULogItem &log_item) +{ + /* Skip ERROR: or WARNING:. */ + log_line = skip_severity_prefix(log_line, log_item); + log_line = skip_separators(log_line, ':', '(', ' '); + + /* Parse error line & char numbers. */ + if (log_line[0] >= '0' && log_line[0] <= '9') { + char *error_line_number_end; + log_item.cursor.row = (int)strtol(log_line, &error_line_number_end, 10); + /* Try to fetch the error character (not always available). */ + if (ELEM(error_line_number_end[0], '(', ':') && error_line_number_end[1] != ' ') { + log_item.cursor.column = (int)strtol(error_line_number_end + 1, &log_line, 10); + } + else { + log_line = error_line_number_end; + } + /* There can be a 3rd number (case of mesa driver). */ + if (ELEM(log_line[0], '(', ':') && log_line[1] >= '0' && log_line[1] <= '9') { + log_item.cursor.source = log_item.cursor.row; + log_item.cursor.row = log_item.cursor.column; + log_item.cursor.column = (int)strtol(log_line + 1, &error_line_number_end, 10); + log_line = error_line_number_end; + } + } + + if ((log_item.cursor.row != -1) && (log_item.cursor.column != -1)) { + if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_OFFICIAL) || + GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) { + /* 0:line */ + log_item.cursor.row = log_item.cursor.column; + log_item.cursor.column = -1; + } + else { + /* line:char */ + } + } + + log_line = skip_separators(log_line, ':', ')', ' '); + + /* Skip to message. Avoid redundant info. */ + log_line = skip_severity_keyword(log_line, log_item); + log_line = skip_separators(log_line, ':', ')', ' '); + + return log_line; +} + +char *GLLogParser::skip_severity_prefix(char *log_line, GPULogItem &log_item) +{ + return skip_severity(log_line, log_item, "ERROR", "WARNING"); +} + +char *GLLogParser::skip_severity_keyword(char *log_line, GPULogItem &log_item) +{ + return skip_severity(log_line, log_item, "error", "warning"); +} + +} // namespace blender::gpu |