浏览代码

Merge pull request #51610 from Chaosus/shader_fix_varying_error_3.x

[3.x] Fix shader crash when using local var with the same name as varying
Yuri Roubinsky 4 年之前
父节点
当前提交
17bbdba80e

+ 2 - 2
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 {

+ 2 - 2
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 {

+ 5 - 0
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;
 				}
 			}

+ 6 - 2
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 {