summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJFonS <joan.fonssanchez@gmail.com>2018-08-31 13:11:13 +0200
committerJFonS <joan.fonssanchez@gmail.com>2018-08-31 19:24:48 +0200
commitf495cede0b7e07e67c5342aa1a28a9cadfb28dc6 (patch)
tree08d8bac742faafa70b0e343978864930e088763a
parentcb63cc86e5ff8d70dc074381eb5f7d32298cd2ef (diff)
Fix handling of shader constants that caused crash, closes #15166
-rw-r--r--servers/visual/shader_language.cpp47
1 files changed, 31 insertions, 16 deletions
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index ffb130048f..9500f35732 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -2368,9 +2368,9 @@ int ShaderLanguage::get_cardinality(DataType p_type) {
2,
3,
4,
- 2,
- 3,
4,
+ 9,
+ 16,
1,
1,
1,
@@ -3307,7 +3307,9 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
ERR_FAIL_COND_V(op->arguments[0]->type != Node::TYPE_VARIABLE, p_node);
- DataType base = get_scalar_type(op->get_datatype());
+ DataType type = op->get_datatype();
+ DataType base = get_scalar_type(type);
+ int cardinality = get_cardinality(type);
Vector<ConstantNode::Value> values;
@@ -3318,19 +3320,9 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i]);
if (get_scalar_type(cn->datatype) == base) {
-
- 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
+ for (int j = 0; j < cn->values.size(); j++) {
+ values.push_back(cn->values[j]);
+ }
} else if (get_scalar_type(cn->datatype) == cn->datatype) {
ConstantNode::Value v;
@@ -3347,6 +3339,29 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
}
}
+ if (values.size() == 1) {
+ if (type >= TYPE_MAT2 && type <= TYPE_MAT4) {
+ ConstantNode::Value value = values[0];
+ ConstantNode::Value zero;
+ zero.real = 0.0f;
+ int size = 2 + (type - TYPE_MAT2);
+
+ values.clear();
+ for (int i = 0; i < size; i++) {
+ for (int j = 0; j < size; j++) {
+ values.push_back(i == j ? value : zero);
+ }
+ }
+ } else {
+ for (int i = 1; i < cardinality; i++) {
+ values.push_back(values[0]);
+ }
+ }
+ } else if (values.size() != cardinality) {
+ ERR_PRINT("Failed to reduce expression, values and cardinality mismatch.");
+ return p_node;
+ }
+
ConstantNode *cn = alloc_node<ConstantNode>();
cn->datatype = op->get_datatype();
cn->values = values;