From 8a1c9864555b2a9ab6ddfe62ab7fe4cbb42758db Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Fri, 13 Aug 2021 09:30:35 +0300 Subject: [PATCH] [3.x] Fix shader crash when using local var with the same name as varying --- drivers/gles2/shader_compiler_gles2.cpp | 4 ++-- drivers/gles3/shader_compiler_gles3.cpp | 4 ++-- servers/visual/shader_language.cpp | 5 +++++ servers/visual/shader_language.h | 8 ++++++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 6c4a77eb28..7c75e852f9 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -549,7 +549,7 @@ String ShaderCompilerGLES2::_dump_node_code(const SL::Node *p_node, int p_level, SL::VariableNode *var_node = (SL::VariableNode *)p_node; bool use_fragment_varying = false; - if (current_func_name != vertex_name) { + if (!var_node->is_local && current_func_name != vertex_name) { if (p_assigning) { if (shader->varyings.has(var_node->name)) { use_fragment_varying = true; @@ -650,7 +650,7 @@ String ShaderCompilerGLES2::_dump_node_code(const SL::Node *p_node, int p_level, SL::ArrayNode *arr_node = (SL::ArrayNode *)p_node; bool use_fragment_varying = false; - if (current_func_name != vertex_name) { + if (!arr_node->is_local && current_func_name != vertex_name) { if (arr_node->assign_expression != nullptr) { use_fragment_varying = true; } else { diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 23defa2379..7966fe0085 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -683,7 +683,7 @@ String ShaderCompilerGLES3::_dump_node_code(const SL::Node *p_node, int p_level, SL::VariableNode *vnode = (SL::VariableNode *)p_node; bool use_fragment_varying = false; - if (current_func_name != vertex_name) { + if (!vnode->is_local && current_func_name != vertex_name) { if (p_assigning) { if (shader->varyings.has(vnode->name)) { use_fragment_varying = true; @@ -802,7 +802,7 @@ String ShaderCompilerGLES3::_dump_node_code(const SL::Node *p_node, int p_level, SL::ArrayNode *anode = (SL::ArrayNode *)p_node; bool use_fragment_varying = false; - if (current_func_name != vertex_name) { + if (!anode->is_local && current_func_name != vertex_name) { if (anode->assign_expression != nullptr) { use_fragment_varying = true; } else { diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 48f4086355..e870a1e5fe 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -3495,6 +3495,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons bool is_const = false; int array_size = 0; StringName struct_name; + bool is_local = false; if (p_block && p_block->block_tag != SubClassTag::TAG_GLOBAL) { int idx = 0; @@ -3547,6 +3548,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("Can't use function as identifier: " + String(identifier)); return nullptr; } + + is_local = ident_type == IDENTIFIER_LOCAL_VAR || ident_type == IDENTIFIER_FUNCTION_ARGUMENT; } Node *index_expression = nullptr; @@ -3623,6 +3626,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons arrname->call_expression = call_expression; arrname->assign_expression = assign_expression; arrname->is_const = is_const; + arrname->is_local = is_local; expr = arrname; } else { @@ -3631,6 +3635,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons varname->datatype_cache = data_type; varname->is_const = is_const; varname->struct_name = struct_name; + varname->is_local = is_local; expr = varname; } } diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 20139796cc..b665c705b6 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -357,11 +357,13 @@ public: virtual DataType get_datatype() const { return datatype_cache; } virtual String get_datatype_name() const { return String(struct_name); } bool is_const; + bool is_local; VariableNode() : Node(TYPE_VARIABLE), datatype_cache(TYPE_VOID), - is_const(false) {} + is_const(false), + is_local(false) {} }; struct VariableDeclarationNode : public Node { @@ -393,6 +395,7 @@ public: Node *call_expression; Node *assign_expression; bool is_const; + bool is_local; virtual DataType get_datatype() const { return datatype_cache; } virtual String get_datatype_name() const { return String(struct_name); } @@ -403,7 +406,8 @@ public: index_expression(nullptr), call_expression(nullptr), assign_expression(nullptr), - is_const(false) {} + is_const(false), + is_local(false) {} }; struct ArrayConstructNode : public Node {