Browse Source

Re-allows constants in global space to be initialized with function call

Yuri Roubinski 1 year ago
parent
commit
d3d20f15bf

+ 13 - 13
servers/rendering/shader_compiler.cpp

@@ -303,8 +303,8 @@ String ShaderCompiler::_get_sampler_name(ShaderLanguage::TextureFilter p_filter,
 void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, HashSet<StringName> &added) {
 void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, HashSet<StringName> &added) {
 	int fidx = -1;
 	int fidx = -1;
 
 
-	for (int i = 0; i < p_node->functions.size(); i++) {
-		if (p_node->functions[i].name == p_for_func) {
+	for (int i = 0; i < p_node->vfunctions.size(); i++) {
+		if (p_node->vfunctions[i].name == p_for_func) {
 			fidx = i;
 			fidx = i;
 			break;
 			break;
 		}
 		}
@@ -314,7 +314,7 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str
 
 
 	Vector<StringName> uses_functions;
 	Vector<StringName> uses_functions;
 
 
-	for (const StringName &E : p_node->functions[fidx].uses_function) {
+	for (const StringName &E : p_node->vfunctions[fidx].uses_function) {
 		uses_functions.push_back(E);
 		uses_functions.push_back(E);
 	}
 	}
 	uses_functions.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced
 	uses_functions.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced
@@ -328,9 +328,9 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str
 
 
 		SL::FunctionNode *fnode = nullptr;
 		SL::FunctionNode *fnode = nullptr;
 
 
-		for (int i = 0; i < p_node->functions.size(); i++) {
-			if (p_node->functions[i].name == uses_functions[k]) {
-				fnode = p_node->functions[i].function;
+		for (int i = 0; i < p_node->vfunctions.size(); i++) {
+			if (p_node->vfunctions[i].name == uses_functions[k]) {
+				fnode = p_node->vfunctions[i].function;
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -765,8 +765,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
 			HashMap<StringName, String> function_code;
 			HashMap<StringName, String> function_code;
 
 
 			//code for functions
 			//code for functions
-			for (int i = 0; i < pnode->functions.size(); i++) {
-				SL::FunctionNode *fnode = pnode->functions[i].function;
+			for (int i = 0; i < pnode->vfunctions.size(); i++) {
+				SL::FunctionNode *fnode = pnode->vfunctions[i].function;
 				function = fnode;
 				function = fnode;
 				current_func_name = fnode->name;
 				current_func_name = fnode->name;
 				function_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
 				function_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
@@ -777,8 +777,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
 
 
 			HashSet<StringName> added_funcs_per_stage[STAGE_MAX];
 			HashSet<StringName> added_funcs_per_stage[STAGE_MAX];
 
 
-			for (int i = 0; i < pnode->functions.size(); i++) {
-				SL::FunctionNode *fnode = pnode->functions[i].function;
+			for (int i = 0; i < pnode->vfunctions.size(); i++) {
+				SL::FunctionNode *fnode = pnode->vfunctions[i].function;
 
 
 				function = fnode;
 				function = fnode;
 
 
@@ -1150,9 +1150,9 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
 					const bool is_internal_func = internal_functions.has(vnode->name);
 					const bool is_internal_func = internal_functions.has(vnode->name);
 
 
 					if (!is_internal_func) {
 					if (!is_internal_func) {
-						for (int i = 0; i < shader->functions.size(); i++) {
-							if (shader->functions[i].name == vnode->name) {
-								func = shader->functions[i].function;
+						for (int i = 0; i < shader->vfunctions.size(); i++) {
+							if (shader->vfunctions[i].name == vnode->name) {
+								func = shader->vfunctions[i].function;
 								break;
 								break;
 							}
 							}
 						}
 						}

+ 53 - 50
servers/rendering/shader_language.cpp

@@ -1433,17 +1433,17 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
 		return true;
 		return true;
 	}
 	}
 
 
-	for (int i = 0; i < shader->functions.size(); i++) {
-		if (!shader->functions[i].callable) {
+	for (int i = 0; i < shader->vfunctions.size(); i++) {
+		if (!shader->vfunctions[i].callable) {
 			continue;
 			continue;
 		}
 		}
 
 
-		if (shader->functions[i].name == p_identifier) {
+		if (shader->vfunctions[i].name == p_identifier) {
 			if (r_data_type) {
 			if (r_data_type) {
-				*r_data_type = shader->functions[i].function->return_type;
+				*r_data_type = shader->vfunctions[i].function->return_type;
 			}
 			}
 			if (r_array_size) {
 			if (r_array_size) {
-				*r_array_size = shader->functions[i].function->return_array_size;
+				*r_array_size = shader->vfunctions[i].function->return_array_size;
 			}
 			}
 			if (r_type) {
 			if (r_type) {
 				*r_type = IDENTIFIER_FUNCTION;
 				*r_type = IDENTIFIER_FUNCTION;
@@ -3391,18 +3391,18 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
 	bool exists = false;
 	bool exists = false;
 	String arg_list = "";
 	String arg_list = "";
 
 
-	for (int i = 0; i < shader->functions.size(); i++) {
-		if (name != shader->functions[i].name) {
+	for (int i = 0; i < shader->vfunctions.size(); i++) {
+		if (name != shader->vfunctions[i].name) {
 			continue;
 			continue;
 		}
 		}
 		exists = true;
 		exists = true;
 
 
-		if (!shader->functions[i].callable) {
+		if (!shader->vfunctions[i].callable) {
 			_set_error(vformat(RTR("Function '%s' can't be called from source code."), String(name)));
 			_set_error(vformat(RTR("Function '%s' can't be called from source code."), String(name)));
 			return false;
 			return false;
 		}
 		}
 
 
-		FunctionNode *pfunc = shader->functions[i].function;
+		FunctionNode *pfunc = shader->vfunctions[i].function;
 		if (arg_list.is_empty()) {
 		if (arg_list.is_empty()) {
 			for (int j = 0; j < pfunc->arguments.size(); j++) {
 			for (int j = 0; j < pfunc->arguments.size(); j++) {
 				if (j > 0) {
 				if (j > 0) {
@@ -4640,10 +4640,10 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi
 }
 }
 
 
 bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat) {
 bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat) {
-	for (int i = 0; i < shader->functions.size(); i++) {
-		if (shader->functions[i].name == p_name) {
-			ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
-			FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
+	for (int i = 0; i < shader->vfunctions.size(); i++) {
+		if (shader->vfunctions[i].name == p_name) {
+			ERR_FAIL_INDEX_V(p_argument, shader->vfunctions[i].function->arguments.size(), false);
+			FunctionNode::Argument *arg = &shader->vfunctions[i].function->arguments.write[p_argument];
 			if (arg->tex_builtin_check) {
 			if (arg->tex_builtin_check) {
 				_set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using both built-ins and uniform textures, this is not supported (use either one or the other)."), p_argument, String(p_name)));
 				_set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using both built-ins and uniform textures, this is not supported (use either one or the other)."), p_argument, String(p_name)));
 				return false;
 				return false;
@@ -4674,10 +4674,10 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam
 }
 }
 
 
 bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin) {
 bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin) {
-	for (int i = 0; i < shader->functions.size(); i++) {
-		if (shader->functions[i].name == p_name) {
-			ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
-			FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
+	for (int i = 0; i < shader->vfunctions.size(); i++) {
+		if (shader->vfunctions[i].name == p_name) {
+			ERR_FAIL_INDEX_V(p_argument, shader->vfunctions[i].function->arguments.size(), false);
+			FunctionNode::Argument *arg = &shader->vfunctions[i].function->arguments.write[p_argument];
 			if (arg->tex_argument_check) {
 			if (arg->tex_argument_check) {
 				_set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using both built-ins and uniform textures, this is not supported (use either one or the other)."), p_argument, String(p_name)));
 				_set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using both built-ins and uniform textures, this is not supported (use either one or the other)."), p_argument, String(p_name)));
 				return false;
 				return false;
@@ -5207,11 +5207,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
 					expr = func;
 					expr = func;
 
 
 				} else { //a function call
 				} else { //a function call
-					if (p_block == nullptr) { // Non-constructor function call in global space is forbidden.
-						if (is_const_decl) {
+
+					// Non-builtin function call is forbidden for constant declaration.
+					if (is_const_decl) {
+						if (shader->functions.has(identifier)) {
 							_set_error(RTR("Expected constant expression."));
 							_set_error(RTR("Expected constant expression."));
+							return nullptr;
 						}
 						}
-						return nullptr;
 					}
 					}
 
 
 					const StringName &name = identifier;
 					const StringName &name = identifier;
@@ -5238,12 +5240,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
 
 
 					//test if function was parsed first
 					//test if function was parsed first
 					int function_index = -1;
 					int function_index = -1;
-					for (int i = 0; i < shader->functions.size(); i++) {
-						if (shader->functions[i].name == name) {
+					for (int i = 0; i < shader->vfunctions.size(); i++) {
+						if (shader->vfunctions[i].name == name) {
 							//add to current function as dependency
 							//add to current function as dependency
-							for (int j = 0; j < shader->functions.size(); j++) {
-								if (shader->functions[j].name == current_function) {
-									shader->functions.write[j].uses_function.insert(name);
+							for (int j = 0; j < shader->vfunctions.size(); j++) {
+								if (shader->vfunctions[j].name == current_function) {
+									shader->vfunctions.write[j].uses_function.insert(name);
 									break;
 									break;
 								}
 								}
 							}
 							}
@@ -5276,7 +5278,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
 						//connect texture arguments, so we can cache in the
 						//connect texture arguments, so we can cache in the
 						//argument what type of filter and repeat to use
 						//argument what type of filter and repeat to use
 
 
-						FunctionNode *call_function = shader->functions[function_index].function;
+						FunctionNode *call_function = shader->vfunctions[function_index].function;
 						if (call_function) {
 						if (call_function) {
 							func->return_cache = call_function->get_datatype();
 							func->return_cache = call_function->get_datatype();
 							func->struct_name = call_function->get_datatype_name();
 							func->struct_name = call_function->get_datatype_name();
@@ -9454,8 +9456,8 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
 					}
 					}
 				}
 				}
 
 
-				for (int i = 0; i < shader->functions.size(); i++) {
-					if (!shader->functions[i].callable && shader->functions[i].name == name) {
+				for (int i = 0; i < shader->vfunctions.size(); i++) {
+					if (!shader->vfunctions[i].callable && shader->vfunctions[i].name == name) {
 						_set_redefinition_error(String(name));
 						_set_redefinition_error(String(name));
 						return ERR_PARSE_ERROR;
 						return ERR_PARSE_ERROR;
 					}
 					}
@@ -9470,7 +9472,8 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
 
 
 				function.function = func_node;
 				function.function = func_node;
 
 
-				shader->functions.push_back(function);
+				shader->functions.insert(name, function);
+				shader->vfunctions.push_back(function);
 
 
 				func_node->name = name;
 				func_node->name = name;
 				func_node->return_type = type;
 				func_node->return_type = type;
@@ -10114,8 +10117,8 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
 					continue;
 					continue;
 				}
 				}
 				bool found = false;
 				bool found = false;
-				for (int i = 0; i < shader->functions.size(); i++) {
-					if (shader->functions[i].name == E.key) {
+				for (int i = 0; i < shader->vfunctions.size(); i++) {
+					if (shader->vfunctions[i].name == E.key) {
 						found = true;
 						found = true;
 						break;
 						break;
 					}
 					}
@@ -10235,11 +10238,11 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
 					}
 					}
 				}
 				}
 
 
-				for (int i = 0; i < shader->functions.size(); i++) {
-					if (!shader->functions[i].callable || shader->functions[i].name == skip_function) {
+				for (int i = 0; i < shader->vfunctions.size(); i++) {
+					if (!shader->vfunctions[i].callable || shader->vfunctions[i].name == skip_function) {
 						continue;
 						continue;
 					}
 					}
-					matches.insert(String(shader->functions[i].name), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
+					matches.insert(String(shader->vfunctions[i].name), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
 				}
 				}
 
 
 				int idx = 0;
 				int idx = 0;
@@ -10297,26 +10300,26 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
 				block = block->parent_block;
 				block = block->parent_block;
 			}
 			}
 
 
-			for (int i = 0; i < shader->functions.size(); i++) {
-				if (!shader->functions[i].callable) {
+			for (int i = 0; i < shader->vfunctions.size(); i++) {
+				if (!shader->vfunctions[i].callable) {
 					continue;
 					continue;
 				}
 				}
-				if (shader->functions[i].name == completion_function) {
+				if (shader->vfunctions[i].name == completion_function) {
 					String calltip;
 					String calltip;
 
 
-					calltip += get_datatype_name(shader->functions[i].function->return_type);
+					calltip += get_datatype_name(shader->vfunctions[i].function->return_type);
 
 
-					if (shader->functions[i].function->return_array_size > 0) {
+					if (shader->vfunctions[i].function->return_array_size > 0) {
 						calltip += "[";
 						calltip += "[";
-						calltip += itos(shader->functions[i].function->return_array_size);
+						calltip += itos(shader->vfunctions[i].function->return_array_size);
 						calltip += "]";
 						calltip += "]";
 					}
 					}
 
 
 					calltip += " ";
 					calltip += " ";
-					calltip += shader->functions[i].name;
+					calltip += shader->vfunctions[i].name;
 					calltip += "(";
 					calltip += "(";
 
 
-					for (int j = 0; j < shader->functions[i].function->arguments.size(); j++) {
+					for (int j = 0; j < shader->vfunctions[i].function->arguments.size(); j++) {
 						if (j > 0) {
 						if (j > 0) {
 							calltip += ", ";
 							calltip += ", ";
 						} else {
 						} else {
@@ -10327,25 +10330,25 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
 							calltip += char32_t(0xFFFF);
 							calltip += char32_t(0xFFFF);
 						}
 						}
 
 
-						if (shader->functions[i].function->arguments[j].is_const) {
+						if (shader->vfunctions[i].function->arguments[j].is_const) {
 							calltip += "const ";
 							calltip += "const ";
 						}
 						}
 
 
-						if (shader->functions[i].function->arguments[j].qualifier != ArgumentQualifier::ARGUMENT_QUALIFIER_IN) {
-							if (shader->functions[i].function->arguments[j].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT) {
+						if (shader->vfunctions[i].function->arguments[j].qualifier != ArgumentQualifier::ARGUMENT_QUALIFIER_IN) {
+							if (shader->vfunctions[i].function->arguments[j].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT) {
 								calltip += "out ";
 								calltip += "out ";
 							} else { // ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT
 							} else { // ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT
 								calltip += "inout ";
 								calltip += "inout ";
 							}
 							}
 						}
 						}
 
 
-						calltip += get_datatype_name(shader->functions[i].function->arguments[j].type);
+						calltip += get_datatype_name(shader->vfunctions[i].function->arguments[j].type);
 						calltip += " ";
 						calltip += " ";
-						calltip += shader->functions[i].function->arguments[j].name;
+						calltip += shader->vfunctions[i].function->arguments[j].name;
 
 
-						if (shader->functions[i].function->arguments[j].array_size > 0) {
+						if (shader->vfunctions[i].function->arguments[j].array_size > 0) {
 							calltip += "[";
 							calltip += "[";
-							calltip += itos(shader->functions[i].function->arguments[j].array_size);
+							calltip += itos(shader->vfunctions[i].function->arguments[j].array_size);
 							calltip += "]";
 							calltip += "]";
 						}
 						}
 
 
@@ -10354,7 +10357,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
 						}
 						}
 					}
 					}
 
 
-					if (shader->functions[i].function->arguments.size()) {
+					if (shader->vfunctions[i].function->arguments.size()) {
 						calltip += " ";
 						calltip += " ";
 					}
 					}
 					calltip += ")";
 					calltip += ")";

+ 2 - 1
servers/rendering/shader_language.h

@@ -711,9 +711,10 @@ public:
 		HashMap<StringName, Varying> varyings;
 		HashMap<StringName, Varying> varyings;
 		HashMap<StringName, Uniform> uniforms;
 		HashMap<StringName, Uniform> uniforms;
 		HashMap<StringName, Struct> structs;
 		HashMap<StringName, Struct> structs;
+		HashMap<StringName, Function> functions;
 		Vector<StringName> render_modes;
 		Vector<StringName> render_modes;
 
 
-		Vector<Function> functions;
+		Vector<Function> vfunctions;
 		Vector<Constant> vconstants;
 		Vector<Constant> vconstants;
 		Vector<Struct> vstructs;
 		Vector<Struct> vstructs;