Browse Source

Unify variable and array declarations in shaders

Yuri Roubinsky 3 years ago
parent
commit
36a82c8c69

+ 38 - 57
servers/rendering/shader_compiler.cpp

@@ -832,16 +832,49 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
 			} else {
 				declaration += _prestr(vdnode->precision) + _typestr(vdnode->datatype);
 			}
+			declaration += " ";
 			for (int i = 0; i < vdnode->declarations.size(); i++) {
+				bool is_array = vdnode->declarations[i].size > 0;
 				if (i > 0) {
 					declaration += ",";
-				} else {
-					declaration += " ";
 				}
 				declaration += _mkid(vdnode->declarations[i].name);
-				if (vdnode->declarations[i].initializer) {
-					declaration += "=";
-					declaration += _dump_node_code(vdnode->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+				if (is_array) {
+					declaration += "[";
+					if (vdnode->declarations[i].size_expression != nullptr) {
+						declaration += _dump_node_code(vdnode->declarations[i].size_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+					} else {
+						declaration += itos(vdnode->declarations[i].size);
+					}
+					declaration += "]";
+				}
+
+				if (!is_array || vdnode->declarations[i].single_expression) {
+					if (!vdnode->declarations[i].initializer.is_empty()) {
+						declaration += "=";
+						declaration += _dump_node_code(vdnode->declarations[i].initializer[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+					}
+				} else {
+					int size = vdnode->declarations[i].initializer.size();
+					if (size > 0) {
+						declaration += "=";
+						if (vdnode->datatype == SL::TYPE_STRUCT) {
+							declaration += _mkid(vdnode->struct_name);
+						} else {
+							declaration += _typestr(vdnode->datatype);
+						}
+						declaration += "[";
+						declaration += itos(size);
+						declaration += "]";
+						declaration += "(";
+						for (int j = 0; j < size; j++) {
+							if (j > 0) {
+								declaration += ",";
+							}
+							declaration += _dump_node_code(vdnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+						}
+						declaration += ")";
+					}
 				}
 			}
 
@@ -943,58 +976,6 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
 			}
 			code += ")";
 		} break;
-		case SL::Node::TYPE_ARRAY_DECLARATION: {
-			SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node;
-			String declaration;
-			declaration += _constr(adnode->is_const);
-			if (adnode->datatype == SL::TYPE_STRUCT) {
-				declaration += _mkid(adnode->struct_name);
-			} else {
-				declaration += _prestr(adnode->precision) + _typestr(adnode->datatype);
-			}
-			for (int i = 0; i < adnode->declarations.size(); i++) {
-				if (i > 0) {
-					declaration += ",";
-				} else {
-					declaration += " ";
-				}
-				declaration += _mkid(adnode->declarations[i].name);
-				declaration += "[";
-				if (adnode->size_expression != nullptr) {
-					declaration += _dump_node_code(adnode->size_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
-				} else {
-					declaration += itos(adnode->declarations[i].size);
-				}
-				declaration += "]";
-				if (adnode->declarations[i].single_expression) {
-					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 += ")";
-					}
-				}
-			}
-
-			code += declaration;
-		} break;
 		case SL::Node::TYPE_ARRAY: {
 			SL::ArrayNode *anode = (SL::ArrayNode *)p_node;
 			bool use_fragment_varying = false;

+ 35 - 81
servers/rendering/shader_language.cpp

@@ -6428,17 +6428,23 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 				return ERR_PARSE_ERROR;
 			}
 
-			Node *vardecl = nullptr;
 			int array_size = 0;
 			bool fixed_array_size = false;
 			bool first = true;
 
+			VariableDeclarationNode *vdnode = alloc_node<VariableDeclarationNode>();
+			vdnode->precision = precision;
+			if (is_struct) {
+				vdnode->struct_name = struct_name;
+				vdnode->datatype = TYPE_STRUCT;
+			} else {
+				vdnode->datatype = type;
+			};
+			vdnode->is_const = is_const;
+
 			do {
 				bool unknown_size = false;
-				Node *size_expr = nullptr;
-
-				ArrayDeclarationNode *anode = nullptr;
-				ArrayDeclarationNode::Declaration adecl;
+				VariableDeclarationNode::Declaration decl;
 
 				tk = _get_token();
 
@@ -6451,12 +6457,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 					}
 
 					if (tk.type == TK_BRACKET_OPEN) {
-						Error error = _parse_array_size(p_block, p_function_info, false, &size_expr, &array_size, &unknown_size);
+						Error error = _parse_array_size(p_block, p_function_info, false, &decl.size_expression, &array_size, &unknown_size);
 						if (error != OK) {
 							return error;
 						}
-						adecl.single_expression = false;
-						adecl.size = array_size;
+						decl.size = array_size;
 
 						fixed_array_size = true;
 						tk = _get_token();
@@ -6476,8 +6481,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 						return ERR_PARSE_ERROR;
 					}
 				}
-
-				adecl.name = name;
+				decl.name = name;
 
 #ifdef DEBUG_ENABLED
 				if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG)) {
@@ -6503,45 +6507,24 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 
 				tk = _get_token();
 
-				bool is_array_decl = var.array_size > 0 || unknown_size;
-
 				if (tk.type == TK_BRACKET_OPEN) {
 					if (RenderingServer::get_singleton()->is_low_end() && is_const) {
 						_set_error("Local const arrays are supported only on high-end platform!");
 						return ERR_PARSE_ERROR;
 					}
 
-					Error error = _parse_array_size(p_block, p_function_info, false, &size_expr, &var.array_size, &unknown_size);
+					Error error = _parse_array_size(p_block, p_function_info, false, &decl.size_expression, &var.array_size, &unknown_size);
 					if (error != OK) {
 						return error;
 					}
 
-					adecl.single_expression = false;
-					adecl.size = var.array_size;
+					decl.size = var.array_size;
 					array_size = var.array_size;
 
-					is_array_decl = true;
 					tk = _get_token();
 				}
 
-				if (is_array_decl) {
-					{
-						anode = alloc_node<ArrayDeclarationNode>();
-
-						if (is_struct) {
-							anode->struct_name = struct_name;
-							anode->datatype = TYPE_STRUCT;
-						} else {
-							anode->datatype = type;
-						}
-
-						anode->precision = precision;
-						anode->is_const = is_const;
-						anode->size_expression = size_expr;
-
-						vardecl = (Node *)anode;
-					}
-
+				if (var.array_size > 0 || unknown_size) {
 					bool full_def = false;
 
 					if (tk.type == TK_OP_ASSIGN) {
@@ -6562,7 +6545,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 								return ERR_PARSE_ERROR;
 							} else {
 								if (unknown_size) {
-									adecl.size = n->get_array_size();
+									decl.size = n->get_array_size();
 									var.array_size = n->get_array_size();
 								}
 
@@ -6570,8 +6553,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 									return ERR_PARSE_ERROR;
 								}
 
-								adecl.single_expression = true;
-								adecl.initializer.push_back(n);
+								decl.single_expression = true;
+								decl.initializer.push_back(n);
 							}
 
 							tk = _get_token();
@@ -6685,7 +6668,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 										return ERR_PARSE_ERROR;
 									}
 
-									if (anode->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) {
+									if (is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) {
 										_set_error("Expected constant expression");
 										return ERR_PARSE_ERROR;
 									}
@@ -6696,13 +6679,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 
 									tk = _get_token();
 									if (tk.type == TK_COMMA) {
-										adecl.initializer.push_back(n);
+										decl.initializer.push_back(n);
 										continue;
 									} else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) {
-										adecl.initializer.push_back(n);
+										decl.initializer.push_back(n);
 										break;
 									} else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) {
-										adecl.initializer.push_back(n);
+										decl.initializer.push_back(n);
 										break;
 									} else {
 										if (curly) {
@@ -6714,9 +6697,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 									}
 								}
 								if (unknown_size) {
-									adecl.size = adecl.initializer.size();
-									var.array_size = adecl.initializer.size();
-								} else if (adecl.initializer.size() != var.array_size) {
+									decl.size = decl.initializer.size();
+									var.array_size = decl.initializer.size();
+								} else if (decl.initializer.size() != var.array_size) {
 									_set_error("Array size mismatch");
 									return ERR_PARSE_ERROR;
 								}
@@ -6728,36 +6711,20 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 							_set_error("Expected array initialization");
 							return ERR_PARSE_ERROR;
 						}
-						if (anode->is_const) {
+						if (is_const) {
 							_set_error("Expected initialization of constant");
 							return ERR_PARSE_ERROR;
 						}
 					}
 
 					array_size = var.array_size;
-					anode->declarations.push_back(adecl);
 				} else if (tk.type == TK_OP_ASSIGN) {
-					VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>();
-					if (is_struct) {
-						node->struct_name = struct_name;
-						node->datatype = TYPE_STRUCT;
-					} else {
-						node->datatype = type;
-					}
-					node->precision = precision;
-					node->is_const = is_const;
-					vardecl = (Node *)node;
-
-					VariableDeclarationNode::Declaration decl;
-					decl.name = name;
-					decl.initializer = nullptr;
-
 					//variable created with assignment! must parse an expression
 					Node *n = _parse_and_reduce_expression(p_block, p_function_info);
 					if (!n) {
 						return ERR_PARSE_ERROR;
 					}
-					if (node->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) {
+					if (is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) {
 						OperatorNode *op = ((OperatorNode *)n);
 						for (int i = 1; i < op->arguments.size(); i++) {
 							if (!_check_node_constness(op->arguments[i])) {
@@ -6766,7 +6733,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 							}
 						}
 					}
-					decl.initializer = n;
 
 					if (n->type == Node::TYPE_CONSTANT) {
 						ConstantNode *const_node = static_cast<ConstantNode *>(n);
@@ -6778,31 +6744,17 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 					if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) {
 						return ERR_PARSE_ERROR;
 					}
+
+					decl.initializer.push_back(n);
 					tk = _get_token();
-					node->declarations.push_back(decl);
 				} else {
 					if (is_const) {
 						_set_error("Expected initialization of constant");
 						return ERR_PARSE_ERROR;
 					}
-
-					VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>();
-					if (is_struct) {
-						node->struct_name = struct_name;
-						node->datatype = TYPE_STRUCT;
-					} else {
-						node->datatype = type;
-					}
-					node->precision = precision;
-					vardecl = (Node *)node;
-
-					VariableDeclarationNode::Declaration decl;
-					decl.name = name;
-					decl.initializer = nullptr;
-					node->declarations.push_back(decl);
 				}
 
-				p_block->statements.push_back(vardecl);
+				vdnode->declarations.push_back(decl);
 				p_block->variables[name] = var;
 
 				if (!fixed_array_size) {
@@ -6821,6 +6773,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
 					return ERR_PARSE_ERROR;
 				}
 			} while (tk.type == TK_COMMA); //another variable
+
+			p_block->statements.push_back((Node *)vdnode);
 		} else if (tk.type == TK_CURLY_BRACKET_OPEN) {
 			//a sub block, just because..
 			BlockNode *block = alloc_node<BlockNode>();
@@ -8337,7 +8291,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
 							if (constant.array_size > 0 || unknown_size) {
 								bool full_def = false;
 
-								ArrayDeclarationNode::Declaration decl;
+								VariableDeclarationNode::Declaration decl;
 								decl.name = name;
 								decl.size = constant.array_size;
 

+ 5 - 24
servers/rendering/shader_language.h

@@ -362,7 +362,6 @@ public:
 			TYPE_CONTROL_FLOW,
 			TYPE_MEMBER,
 			TYPE_ARRAY,
-			TYPE_ARRAY_DECLARATION,
 			TYPE_ARRAY_CONSTRUCT,
 			TYPE_STRUCT,
 		};
@@ -428,7 +427,10 @@ public:
 
 		struct Declaration {
 			StringName name;
-			Node *initializer;
+			uint32_t size = 0U;
+			Node *size_expression = nullptr;
+			Vector<Node *> initializer;
+			bool single_expression = false;
 		};
 		Vector<Declaration> declarations;
 
@@ -471,27 +473,6 @@ public:
 				Node(TYPE_ARRAY_CONSTRUCT) {}
 	};
 
-	struct ArrayDeclarationNode : public Node {
-		DataPrecision precision = PRECISION_DEFAULT;
-		DataType datatype = TYPE_VOID;
-		String struct_name;
-		bool is_const = false;
-		Node *size_expression = nullptr;
-
-		struct Declaration {
-			StringName name;
-			uint32_t size;
-			Vector<Node *> initializer;
-			bool single_expression;
-		};
-		Vector<Declaration> declarations;
-
-		virtual DataType get_datatype() const override { return datatype; }
-
-		ArrayDeclarationNode() :
-				Node(TYPE_ARRAY_DECLARATION) {}
-	};
-
 	struct ConstantNode : public Node {
 		DataType datatype = TYPE_VOID;
 		String struct_name = "";
@@ -505,7 +486,7 @@ public:
 		};
 
 		Vector<Value> values;
-		Vector<ArrayDeclarationNode::Declaration> array_declarations;
+		Vector<VariableDeclarationNode::Declaration> array_declarations;
 
 		virtual DataType get_datatype() const override { return datatype; }
 		virtual String get_datatype_name() const override { return struct_name; }

+ 0 - 3
tests/servers/test_shader_lang.cpp

@@ -211,9 +211,6 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
 			SL::ArrayNode *vnode = (SL::ArrayNode *)p_node;
 			code = vnode->name;
 		} break;
-		case SL::Node::TYPE_ARRAY_DECLARATION: {
-			// FIXME: Implement
-		} break;
 		case SL::Node::TYPE_ARRAY_CONSTRUCT: {
 			// FIXME: Implement
 		} break;