Browse Source

Allow shader arrays to be passed as parameters and return value

Yuri Roubinsky 4 years ago
parent
commit
5874b7a29c

+ 40 - 19
servers/rendering/renderer_rd/shader_compiler_rd.cpp

@@ -391,10 +391,21 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S
 
 
 		String header;
 		String header;
 		if (fnode->return_type == SL::TYPE_STRUCT) {
 		if (fnode->return_type == SL::TYPE_STRUCT) {
-			header = _mkid(fnode->return_struct_name) + " " + _mkid(fnode->name) + "(";
+			header = _mkid(fnode->return_struct_name);
 		} else {
 		} else {
-			header = _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "(";
+			header = _typestr(fnode->return_type);
 		}
 		}
+
+		if (fnode->return_array_size > 0) {
+			header += "[";
+			header += itos(fnode->return_array_size);
+			header += "]";
+		}
+
+		header += " ";
+		header += _mkid(fnode->name);
+		header += "(";
+
 		for (int i = 0; i < fnode->arguments.size(); i++) {
 		for (int i = 0; i < fnode->arguments.size(); i++) {
 			if (i > 0) {
 			if (i > 0) {
 				header += ", ";
 				header += ", ";
@@ -407,6 +418,11 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S
 			} else {
 			} else {
 				header += _qualstr(fnode->arguments[i].qualifier) + _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + _mkid(fnode->arguments[i].name);
 				header += _qualstr(fnode->arguments[i].qualifier) + _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + _mkid(fnode->arguments[i].name);
 			}
 			}
+			if (fnode->arguments[i].array_size > 0) {
+				header += "[";
+				header += itos(fnode->arguments[i].array_size);
+				header += "]";
+			}
 		}
 		}
 
 
 		header += ")\n";
 		header += ")\n";
@@ -959,25 +975,30 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
 					declaration += itos(adnode->declarations[i].size);
 					declaration += itos(adnode->declarations[i].size);
 				}
 				}
 				declaration += "]";
 				declaration += "]";
-				int sz = adnode->declarations[i].initializer.size();
-				if (sz > 0) {
+				if (adnode->declarations[i].single_expression) {
 					declaration += "=";
 					declaration += "=";
-					if (adnode->datatype == SL::TYPE_STRUCT) {
-						declaration += _mkid(adnode->struct_name);
-					} else {
-						declaration += _typestr(adnode->datatype);
-					}
-					declaration += "[";
-					declaration += itos(sz);
-					declaration += "]";
-					declaration += "(";
-					for (int j = 0; j < sz; j++) {
-						declaration += _dump_node_code(adnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
-						if (j != sz - 1) {
-							declaration += ", ";
+					declaration += _dump_node_code(adnode->declarations[i].initializer[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+				} else {
+					int sz = adnode->declarations[i].initializer.size();
+					if (sz > 0) {
+						declaration += "=";
+						if (adnode->datatype == SL::TYPE_STRUCT) {
+							declaration += _mkid(adnode->struct_name);
+						} else {
+							declaration += _typestr(adnode->datatype);
+						}
+						declaration += "[";
+						declaration += itos(sz);
+						declaration += "]";
+						declaration += "(";
+						for (int j = 0; j < sz; j++) {
+							declaration += _dump_node_code(adnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+							if (j != sz - 1) {
+								declaration += ", ";
+							}
 						}
 						}
+						declaration += ")";
 					}
 					}
-					declaration += ")";
 				}
 				}
 			}
 			}
 
 
@@ -988,7 +1009,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
 			bool use_fragment_varying = false;
 			bool use_fragment_varying = false;
 
 
 			if (!(p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_VERTEX)) {
 			if (!(p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_VERTEX)) {
-				if (anode->assign_expression != nullptr) {
+				if (anode->assign_expression != nullptr && shader->varyings.has(anode->name)) {
 					use_fragment_varying = true;
 					use_fragment_varying = true;
 				} else {
 				} else {
 					if (p_assigning) {
 					if (p_assigning) {

File diff suppressed because it is too large
+ 535 - 208
servers/rendering/shader_language.cpp


+ 45 - 16
servers/rendering/shader_language.h

@@ -369,6 +369,8 @@ public:
 
 
 		virtual DataType get_datatype() const { return TYPE_VOID; }
 		virtual DataType get_datatype() const { return TYPE_VOID; }
 		virtual String get_datatype_name() const { return ""; }
 		virtual String get_datatype_name() const { return ""; }
+		virtual int get_array_size() const { return 0; }
+		virtual bool is_indexed() const { return false; }
 
 
 		Node(Type t) :
 		Node(Type t) :
 				type(t) {}
 				type(t) {}
@@ -388,11 +390,15 @@ public:
 	struct OperatorNode : public Node {
 	struct OperatorNode : public Node {
 		DataType return_cache = TYPE_VOID;
 		DataType return_cache = TYPE_VOID;
 		DataPrecision return_precision_cache = PRECISION_DEFAULT;
 		DataPrecision return_precision_cache = PRECISION_DEFAULT;
+		int return_array_size = 0;
 		Operator op = OP_EQUAL;
 		Operator op = OP_EQUAL;
 		StringName struct_name;
 		StringName struct_name;
 		Vector<Node *> arguments;
 		Vector<Node *> arguments;
-		virtual DataType get_datatype() const { return return_cache; }
-		virtual String get_datatype_name() const { return String(struct_name); }
+
+		virtual DataType get_datatype() const override { return return_cache; }
+		virtual String get_datatype_name() const override { return String(struct_name); }
+		virtual int get_array_size() const override { return return_array_size; }
+		virtual bool is_indexed() const override { return op == OP_INDEX; }
 
 
 		OperatorNode() :
 		OperatorNode() :
 				Node(TYPE_OPERATOR) {}
 				Node(TYPE_OPERATOR) {}
@@ -402,10 +408,11 @@ public:
 		DataType datatype_cache = TYPE_VOID;
 		DataType datatype_cache = TYPE_VOID;
 		StringName name;
 		StringName name;
 		StringName struct_name;
 		StringName struct_name;
-		virtual DataType get_datatype() const { return datatype_cache; }
-		virtual String get_datatype_name() const { return String(struct_name); }
 		bool is_const = false;
 		bool is_const = false;
 
 
+		virtual DataType get_datatype() const override { return datatype_cache; }
+		virtual String get_datatype_name() const override { return String(struct_name); }
+
 		VariableNode() :
 		VariableNode() :
 				Node(TYPE_VARIABLE) {}
 				Node(TYPE_VARIABLE) {}
 	};
 	};
@@ -420,9 +427,9 @@ public:
 			StringName name;
 			StringName name;
 			Node *initializer;
 			Node *initializer;
 		};
 		};
-
 		Vector<Declaration> declarations;
 		Vector<Declaration> declarations;
-		virtual DataType get_datatype() const { return datatype; }
+
+		virtual DataType get_datatype() const override { return datatype; }
 
 
 		VariableDeclarationNode() :
 		VariableDeclarationNode() :
 				Node(TYPE_VARIABLE_DECLARATION) {}
 				Node(TYPE_VARIABLE_DECLARATION) {}
@@ -436,9 +443,12 @@ public:
 		Node *call_expression = nullptr;
 		Node *call_expression = nullptr;
 		Node *assign_expression = nullptr;
 		Node *assign_expression = nullptr;
 		bool is_const = false;
 		bool is_const = false;
+		int array_size = 0;
 
 
-		virtual DataType get_datatype() const { return datatype_cache; }
-		virtual String get_datatype_name() const { return String(struct_name); }
+		virtual DataType get_datatype() const override { return datatype_cache; }
+		virtual String get_datatype_name() const override { return String(struct_name); }
+		virtual int get_array_size() const override { return array_size; }
+		virtual bool is_indexed() const override { return index_expression != nullptr; }
 
 
 		ArrayNode() :
 		ArrayNode() :
 				Node(TYPE_ARRAY) {}
 				Node(TYPE_ARRAY) {}
@@ -449,6 +459,10 @@ public:
 		String struct_name;
 		String struct_name;
 		Vector<Node *> initializer;
 		Vector<Node *> initializer;
 
 
+		virtual DataType get_datatype() const override { return datatype; }
+		virtual String get_datatype_name() const override { return struct_name; }
+		virtual int get_array_size() const override { return initializer.size(); }
+
 		ArrayConstructNode() :
 		ArrayConstructNode() :
 				Node(TYPE_ARRAY_CONSTRUCT) {}
 				Node(TYPE_ARRAY_CONSTRUCT) {}
 	};
 	};
@@ -464,10 +478,11 @@ public:
 			StringName name;
 			StringName name;
 			uint32_t size;
 			uint32_t size;
 			Vector<Node *> initializer;
 			Vector<Node *> initializer;
+			bool single_expression;
 		};
 		};
-
 		Vector<Declaration> declarations;
 		Vector<Declaration> declarations;
-		virtual DataType get_datatype() const { return datatype; }
+
+		virtual DataType get_datatype() const override { return datatype; }
 
 
 		ArrayDeclarationNode() :
 		ArrayDeclarationNode() :
 				Node(TYPE_ARRAY_DECLARATION) {}
 				Node(TYPE_ARRAY_DECLARATION) {}
@@ -487,8 +502,10 @@ public:
 
 
 		Vector<Value> values;
 		Vector<Value> values;
 		Vector<ArrayDeclarationNode::Declaration> array_declarations;
 		Vector<ArrayDeclarationNode::Declaration> array_declarations;
-		virtual DataType get_datatype() const { return datatype; }
-		virtual String get_datatype_name() const { return struct_name; }
+
+		virtual DataType get_datatype() const override { return datatype; }
+		virtual String get_datatype_name() const override { return struct_name; }
+		virtual int get_array_size() const override { return array_size; }
 
 
 		ConstantNode() :
 		ConstantNode() :
 				Node(TYPE_CONSTANT) {}
 				Node(TYPE_CONSTANT) {}
@@ -553,8 +570,10 @@ public:
 		Node *call_expression = nullptr;
 		Node *call_expression = nullptr;
 		bool has_swizzling_duplicates = false;
 		bool has_swizzling_duplicates = false;
 
 
-		virtual DataType get_datatype() const { return datatype; }
-		virtual String get_datatype_name() const { return String(struct_name); }
+		virtual DataType get_datatype() const override { return datatype; }
+		virtual String get_datatype_name() const override { return String(struct_name); }
+		virtual int get_array_size() const override { return array_size; }
+		virtual bool is_indexed() const override { return index_expression != nullptr || call_expression != nullptr; }
 
 
 		MemberNode() :
 		MemberNode() :
 				Node(TYPE_MEMBER) {}
 				Node(TYPE_MEMBER) {}
@@ -580,6 +599,7 @@ public:
 			bool tex_builtin_check;
 			bool tex_builtin_check;
 			StringName tex_builtin;
 			StringName tex_builtin;
 			bool is_const;
 			bool is_const;
+			int array_size;
 
 
 			Map<StringName, Set<int>> tex_argument_connect;
 			Map<StringName, Set<int>> tex_argument_connect;
 		};
 		};
@@ -588,10 +608,15 @@ public:
 		DataType return_type = TYPE_VOID;
 		DataType return_type = TYPE_VOID;
 		StringName return_struct_name;
 		StringName return_struct_name;
 		DataPrecision return_precision = PRECISION_DEFAULT;
 		DataPrecision return_precision = PRECISION_DEFAULT;
+		int return_array_size = 0;
 		Vector<Argument> arguments;
 		Vector<Argument> arguments;
 		BlockNode *body = nullptr;
 		BlockNode *body = nullptr;
 		bool can_discard = false;
 		bool can_discard = false;
 
 
+		virtual DataType get_datatype() const override { return return_type; }
+		virtual String get_datatype_name() const override { return String(return_struct_name); }
+		virtual int get_array_size() const override { return return_array_size; }
+
 		FunctionNode() :
 		FunctionNode() :
 				Node(TYPE_FUNCTION) {}
 				Node(TYPE_FUNCTION) {}
 	};
 	};
@@ -842,6 +867,8 @@ private:
 	int tk_line;
 	int tk_line;
 
 
 	StringName current_function;
 	StringName current_function;
+	bool last_const = false;
+	bool pass_array = false;
 	StringName last_name;
 	StringName last_name;
 
 
 	VaryingFunctionNames varying_function_names;
 	VaryingFunctionNames varying_function_names;
@@ -894,7 +921,7 @@ private:
 #endif // DEBUG_ENABLED
 #endif // DEBUG_ENABLED
 	bool _is_operator_assign(Operator p_op) const;
 	bool _is_operator_assign(Operator p_op) const;
 	bool _validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message = nullptr);
 	bool _validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message = nullptr);
-	bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr);
+	bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr, int *r_ret_size = nullptr);
 
 
 	struct BuiltinFuncDef {
 	struct BuiltinFuncDef {
 		enum { MAX_ARGS = 5 };
 		enum { MAX_ARGS = 5 };
@@ -925,7 +952,8 @@ private:
 	static const BuiltinFuncOutArgs builtin_func_out_args[];
 	static const BuiltinFuncOutArgs builtin_func_out_args[];
 
 
 	Error _validate_datatype(DataType p_type);
 	Error _validate_datatype(DataType p_type);
-	bool _compare_datatypes_in_nodes(Node *a, Node *b) const;
+	bool _compare_datatypes(DataType p_datatype_a, String p_datatype_name_a, int p_array_size_a, DataType p_datatype_b, String p_datatype_name_b, int p_array_size_b);
+	bool _compare_datatypes_in_nodes(Node *a, Node *b);
 
 
 	bool _validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str);
 	bool _validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str);
 	bool _parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg = nullptr);
 	bool _parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg = nullptr);
@@ -936,6 +964,7 @@ private:
 	bool _check_node_constness(const Node *p_node) const;
 	bool _check_node_constness(const Node *p_node) const;
 
 
 	Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
 	Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
+	Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info);
 	Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size);
 	Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size);
 	ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
 	ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
 
 

Some files were not shown because too many files changed in this diff