From a4c2060b91467987c930e4dd77a6673acd072ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 10 May 2022 00:47:44 +0200 Subject: Fix T97545 GPU: Crash caused by uncommented quote char in source string Some drivers completely forbid quote characters even in unused preprocessor directives. This patch adds a debug build check for all `.glsl` files that need to be manually handled. For shared headers with `#include` directives, we need to do runtime patching of the source to remove the quote. Also fix an instance of the quotes check failing in `eevee_next`. --- .../eevee_next/shaders/eevee_attributes_lib.glsl | 2 +- source/blender/gpu/intern/gpu_shader_dependency.cc | 44 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl index abecb373995..3c5acf62e30 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl @@ -164,7 +164,7 @@ float attr_load_float(samplerBuffer cd_buf) * \{ */ # ifndef OBINFO_LIB -# error "draw_object_infos is mandatory for volume objects" +# error draw_object_infos is mandatory for volume objects # endif vec3 g_orco; diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc index 460b6d32967..f69c56b5f3f 100644 --- a/source/blender/gpu/intern/gpu_shader_dependency.cc +++ b/source/blender/gpu/intern/gpu_shader_dependency.cc @@ -8,6 +8,7 @@ * shader files. */ +#include #include #include #include @@ -98,6 +99,10 @@ struct GPUSource { /* Limit to shared header files to avoid the temptation to use C++ syntax in .glsl files. */ if (filename.endswith(".h") || filename.endswith(".hh")) { enum_preprocess(); + quote_preprocess(); + } + else { + check_no_quotes(); } if (is_from_material_library()) { @@ -173,6 +178,44 @@ struct GPUSource { continue; \ } + /** + * Some drivers completely forbid quote characters even in unused preprocessor directives. + * We fix the cases where we can't manually patch in `enum_preprocess()`. + * This check ensure none are present in non-patched sources. (see T97545) + */ + void check_no_quotes() + { +#ifdef DEBUG + int64_t pos = -1; + do { + pos = source.find('"', pos + 1); + if (pos == -1) { + break; + } + if (!is_in_comment(source, pos)) { + print_error(source, pos, "Quote characters are forbidden in GLSL files"); + } + } while (true); +#endif + } + + /** + * Some drivers completely forbid string characters even in unused preprocessor directives. + * This fixes the cases we cannot manually patch: Shared headers #includes. (see T97545) + * TODO(fclem): This could be done during the datatoc step. + */ + void quote_preprocess() + { + if (source.find_first_of('"') == -1) { + return; + } + + processed_source = source; + std::replace(processed_source.begin(), processed_source.end(), '"', ' '); + + source = processed_source.c_str(); + } + /** * Transform C,C++ enum declaration into GLSL compatible defines and constants: * @@ -282,6 +325,7 @@ struct GPUSource { if (last_pos != 0) { output += input.substr(last_pos); } + processed_source = output; source = processed_source.c_str(); }; -- cgit v1.2.3