Browse Source

Merge pull request #18533 from JFonS/fix_shader_compile

Fix vector reduction in shader language
Juan Linietsky 7 years ago
parent
commit
0db4c576f1
2 changed files with 44 additions and 3 deletions
  1. 43 3
      servers/visual/shader_language.cpp
  2. 1 0
      servers/visual/shader_language.h

+ 43 - 3
servers/visual/shader_language.cpp

@@ -2207,6 +2207,37 @@ ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) {
 	return scalar_types[p_type];
 }
 
+int ShaderLanguage::get_cardinality(DataType p_type) {
+	static const int cardinality_table[] = {
+		0,
+		1,
+		2,
+		3,
+		4,
+		1,
+		2,
+		3,
+		4,
+		1,
+		2,
+		3,
+		4,
+		1,
+		2,
+		3,
+		4,
+		2,
+		3,
+		4,
+		1,
+		1,
+		1,
+		1,
+	};
+
+	return cardinality_table[p_type];
+}
+
 bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier) {
 
 	identifier = StringName();
@@ -3111,9 +3142,18 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
 
 				if (get_scalar_type(cn->datatype) == base) {
 
-					for (int j = 0; j < cn->values.size(); j++) {
-						values.push_back(cn->values[j]);
-					}
+					int cardinality = get_cardinality(op->arguments[i]->get_datatype());
+					if (cn->values.size() == cardinality) {
+
+						for (int j = 0; j < cn->values.size(); j++) {
+							values.push_back(cn->values[j]);
+						}
+					} else if (cn->values.size() == 1) {
+
+						for (int j = 0; j < cardinality; j++) {
+							values.push_back(cn->values[0]);
+						}
+					} // else: should be filtered by the parser as it's an invalid constructor
 				} else if (get_scalar_type(cn->datatype) == cn->datatype) {
 
 					ConstantNode::Value v;

+ 1 - 0
servers/visual/shader_language.h

@@ -533,6 +533,7 @@ public:
 
 	static bool convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value = NULL);
 	static DataType get_scalar_type(DataType p_type);
+	static int get_cardinality(DataType p_type);
 	static bool is_scalar_type(DataType p_type);
 	static bool is_sampler_type(DataType p_type);