Browse Source

Merge pull request #30500 from Chaosus/shader_arrays

Implemented local shader arrays
Rémi Verschelde 6 years ago
parent
commit
e6230a36f8

+ 74 - 0
drivers/gles2/shader_compiler_gles2.cpp

@@ -510,7 +510,81 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
 				}
 			}
 		} break;
+		case SL::Node::TYPE_ARRAY_DECLARATION: {
 
+			SL::ArrayDeclarationNode *var_dec_node = (SL::ArrayDeclarationNode *)p_node;
+
+			StringBuffer<> declaration;
+
+			declaration += _prestr(var_dec_node->precision);
+			declaration += _typestr(var_dec_node->datatype);
+
+			for (int i = 0; i < var_dec_node->declarations.size(); i++) {
+
+				if (i > 0) {
+					declaration += ",";
+				}
+
+				declaration += " ";
+
+				declaration += _mkid(var_dec_node->declarations[i].name);
+				declaration += "[";
+				declaration += itos(var_dec_node->declarations[i].size);
+				declaration += "]";
+			}
+
+			code += declaration.as_string();
+		} break;
+		case SL::Node::TYPE_ARRAY: {
+			SL::ArrayNode *var_node = (SL::ArrayNode *)p_node;
+
+			if (p_assigning && p_actions.write_flag_pointers.has(var_node->name)) {
+				*p_actions.write_flag_pointers[var_node->name] = true;
+			}
+
+			if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) {
+				String define = p_default_actions.usage_defines[var_node->name];
+
+				if (define.begins_with("@")) {
+					define = p_default_actions.usage_defines[define.substr(1, define.length())];
+				}
+
+				r_gen_code.custom_defines.push_back(define.utf8());
+				used_name_defines.insert(var_node->name);
+			}
+
+			if (p_actions.usage_flag_pointers.has(var_node->name) && !used_flag_pointers.has(var_node->name)) {
+				*p_actions.usage_flag_pointers[var_node->name] = true;
+				used_flag_pointers.insert(var_node->name);
+			}
+
+			if (p_default_actions.renames.has(var_node->name)) {
+				code += p_default_actions.renames[var_node->name];
+			} else {
+				code += _mkid(var_node->name);
+			}
+
+			if (var_node->call_expression != NULL) {
+				code += ".";
+				code += _dump_node_code(var_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+			}
+
+			if (var_node->index_expression != NULL) {
+				code += "[";
+				code += _dump_node_code(var_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+				code += "]";
+			}
+
+			if (var_node->name == time_name) {
+				if (current_func_name == vertex_name) {
+					r_gen_code.uses_vertex_time = true;
+				}
+				if (current_func_name == fragment_name || current_func_name == light_name) {
+					r_gen_code.uses_fragment_time = true;
+				}
+			}
+
+		} break;
 		case SL::Node::TYPE_CONSTANT: {
 			SL::ConstantNode *const_node = (SL::ConstantNode *)p_node;
 

+ 66 - 0
drivers/gles3/shader_compiler_gles3.cpp

@@ -606,6 +606,72 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
 				}
 			}
 
+		} break;
+		case SL::Node::TYPE_ARRAY_DECLARATION: {
+
+			SL::ArrayDeclarationNode *vdnode = (SL::ArrayDeclarationNode *)p_node;
+
+			String declaration = _prestr(vdnode->precision) + _typestr(vdnode->datatype);
+			for (int i = 0; i < vdnode->declarations.size(); i++) {
+				if (i > 0) {
+					declaration += ",";
+				} else {
+					declaration += " ";
+				}
+				declaration += _mkid(vdnode->declarations[i].name);
+				declaration += "[";
+				declaration += itos(vdnode->declarations[i].size);
+				declaration += "]";
+			}
+
+			code += declaration;
+		} break;
+		case SL::Node::TYPE_ARRAY: {
+			SL::ArrayNode *vnode = (SL::ArrayNode *)p_node;
+
+			if (p_assigning && p_actions.write_flag_pointers.has(vnode->name)) {
+				*p_actions.write_flag_pointers[vnode->name] = true;
+			}
+
+			if (p_default_actions.usage_defines.has(vnode->name) && !used_name_defines.has(vnode->name)) {
+				String define = p_default_actions.usage_defines[vnode->name];
+				if (define.begins_with("@")) {
+					define = p_default_actions.usage_defines[define.substr(1, define.length())];
+				}
+				r_gen_code.defines.push_back(define.utf8());
+				used_name_defines.insert(vnode->name);
+			}
+
+			if (p_actions.usage_flag_pointers.has(vnode->name) && !used_flag_pointers.has(vnode->name)) {
+				*p_actions.usage_flag_pointers[vnode->name] = true;
+				used_flag_pointers.insert(vnode->name);
+			}
+
+			if (p_default_actions.renames.has(vnode->name))
+				code = p_default_actions.renames[vnode->name];
+			else
+				code = _mkid(vnode->name);
+
+			if (vnode->call_expression != NULL) {
+				code += ".";
+				code += _dump_node_code(vnode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+			}
+
+			if (vnode->index_expression != NULL) {
+				code += "[";
+				code += _dump_node_code(vnode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+				code += "]";
+			}
+
+			if (vnode->name == time_name) {
+				if (current_func_name == vertex_name) {
+					r_gen_code.uses_vertex_time = true;
+				}
+				if (current_func_name == fragment_name || current_func_name == light_name) {
+					r_gen_code.uses_fragment_time = true;
+				}
+			}
+
 		} break;
 		case SL::Node::TYPE_CONSTANT: {
 			SL::ConstantNode *cnode = (SL::ConstantNode *)p_node;

+ 7 - 0
main/tests/test_shader_lang.cpp

@@ -197,6 +197,13 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
 		case SL::Node::TYPE_VARIABLE_DECLARATION: {
 			// FIXME: Implement
 		} break;
+		case SL::Node::TYPE_ARRAY: {
+			SL::ArrayNode *vnode = (SL::ArrayNode *)p_node;
+			code = vnode->name;
+		} break;
+		case SL::Node::TYPE_ARRAY_DECLARATION: {
+			// FIXME: Implement
+		} break;
 		case SL::Node::TYPE_CONSTANT: {
 			SL::ConstantNode *cnode = (SL::ConstantNode *)p_node;
 			return get_constant_text(cnode->datatype, cnode->values);

File diff suppressed because it is too large
+ 699 - 691
servers/visual/shader_language.cpp


+ 45 - 2
servers/visual/shader_language.h

@@ -288,7 +288,9 @@ public:
 			TYPE_CONSTANT,
 			TYPE_OPERATOR,
 			TYPE_CONTROL_FLOW,
-			TYPE_MEMBER
+			TYPE_MEMBER,
+			TYPE_ARRAY,
+			TYPE_ARRAY_DECLARATION,
 		};
 
 		Type type;
@@ -352,6 +354,39 @@ public:
 				datatype(TYPE_VOID) {}
 	};
 
+	struct ArrayNode : public Node {
+		DataType datatype_cache;
+		StringName name;
+		Node *index_expression;
+		Node *call_expression;
+
+		virtual DataType get_datatype() const { return datatype_cache; }
+
+		ArrayNode() :
+				Node(TYPE_ARRAY),
+				datatype_cache(TYPE_VOID),
+				index_expression(NULL),
+				call_expression(NULL) {}
+	};
+
+	struct ArrayDeclarationNode : public Node {
+		DataPrecision precision;
+		DataType datatype;
+
+		struct Declaration {
+			StringName name;
+			uint32_t size;
+		};
+
+		Vector<Declaration> declarations;
+		virtual DataType get_datatype() const { return datatype; }
+
+		ArrayDeclarationNode() :
+				Node(TYPE_ARRAY_DECLARATION),
+				precision(PRECISION_DEFAULT),
+				datatype(TYPE_VOID) {}
+	};
+
 	struct ConstantNode : public Node {
 		DataType datatype;
 
@@ -380,6 +415,7 @@ public:
 			DataType type;
 			DataPrecision precision;
 			int line; //for completion
+			int array_size;
 		};
 
 		Map<StringName, Variable> variables;
@@ -645,16 +681,22 @@ private:
 		IDENTIFIER_CONSTANT,
 	};
 
-	bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL);
+	bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL, int *r_array_size = NULL);
 	bool _is_operator_assign(Operator p_op) const;
 	bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = NULL);
 	bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL);
 
+	enum SubClassTag {
+		TAG_GLOBAL,
+		TAG_ARRAY
+	};
+
 	struct BuiltinFuncDef {
 		enum { MAX_ARGS = 5 };
 		const char *name;
 		DataType rettype;
 		const DataType args[MAX_ARGS];
+		SubClassTag tag;
 	};
 
 	struct BuiltinFuncOutArgs { //arguments used as out in built in functions
@@ -666,6 +708,7 @@ private:
 	int completion_line;
 	BlockNode *completion_block;
 	DataType completion_base;
+	SubClassTag completion_class;
 	StringName completion_function;
 	int completion_argument;
 

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