summaryrefslogtreecommitdiffstats
path: root/servers/rendering/shader_language.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/shader_language.cpp')
-rw-r--r--servers/rendering/shader_language.cpp46
1 files changed, 37 insertions, 9 deletions
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 568aec2ff6..66fcefe228 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -898,6 +898,13 @@ bool ShaderLanguage::_lookup_next(Token &r_tk) {
return false;
}
+ShaderLanguage::Token ShaderLanguage::_peek() {
+ TkPos pre_pos = _get_tkpos();
+ Token tk = _get_token();
+ _set_tkpos(pre_pos);
+ return tk;
+}
+
String ShaderLanguage::token_debug(const String &p_code) {
clear();
@@ -4761,7 +4768,16 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi
return false;
}
-bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(const StringName &p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat) {
+ShaderLanguage::ShaderNode::Uniform::Hint ShaderLanguage::_sanitize_hint(ShaderNode::Uniform::Hint p_hint) {
+ if (p_hint == ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
+ p_hint == ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
+ p_hint == ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
+ return p_hint;
+ }
+ return ShaderNode::Uniform::HINT_NONE;
+}
+
+bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(const StringName &p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat, ShaderNode::Uniform::Hint p_hint) {
for (int i = 0; i < shader->vfunctions.size(); i++) {
if (shader->vfunctions[i].name == p_name) {
ERR_FAIL_INDEX_V(p_argument, shader->vfunctions[i].function->arguments.size(), false);
@@ -4770,20 +4786,21 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(const Str
_set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using both built-ins and uniform textures, this is not supported (use either one or the other)."), p_argument, String(p_name)));
return false;
} else if (arg->tex_argument_check) {
- //was checked, verify that filter and repeat are the same
- if (arg->tex_argument_filter == p_filter && arg->tex_argument_repeat == p_repeat) {
+ // Was checked, verify that filter, repeat, and hint are the same.
+ if (arg->tex_argument_filter == p_filter && arg->tex_argument_repeat == p_repeat && arg->tex_hint == _sanitize_hint(p_hint)) {
return true;
} else {
- _set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using textures that differ in either filter or repeat setting."), p_argument, String(p_name)));
+ _set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using textures that differ in either filter, repeat, or texture hint setting."), p_argument, String(p_name)));
return false;
}
} else {
arg->tex_argument_check = true;
arg->tex_argument_filter = p_filter;
arg->tex_argument_repeat = p_repeat;
+ arg->tex_hint = _sanitize_hint(p_hint);
for (KeyValue<StringName, HashSet<int>> &E : arg->tex_argument_connect) {
for (const int &F : E.value) {
- if (!_propagate_function_call_sampler_uniform_settings(E.key, F, p_filter, p_repeat)) {
+ if (!_propagate_function_call_sampler_uniform_settings(E.key, F, p_filter, p_repeat, p_hint)) {
return false;
}
}
@@ -5583,7 +5600,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
//propagate
- if (!_propagate_function_call_sampler_uniform_settings(name, i, u->filter, u->repeat)) {
+ if (!_propagate_function_call_sampler_uniform_settings(name, i, u->filter, u->repeat, u->hint)) {
return nullptr;
}
} else if (p_function_info.built_ins.has(varname)) {
@@ -8051,7 +8068,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (!expr) {
return ERR_PARSE_ERROR;
}
- is_condition = expr->type == Node::NODE_TYPE_OPERATOR && expr->get_datatype() == TYPE_BOOL;
+ is_condition = expr->get_datatype() == TYPE_BOOL;
if (expr->type == Node::NODE_TYPE_OPERATOR) {
OperatorNode *op = static_cast<OperatorNode *>(expr);
@@ -8067,7 +8084,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_CONDITION) {
if (tk.type == TK_COMMA) {
if (!is_condition) {
- _set_error(RTR("The middle expression is expected to be a boolean operator."));
+ _set_error(RTR("The middle expression is expected to have a boolean data type."));
+ return ERR_PARSE_ERROR;
+ }
+ tk = _peek();
+ if (tk.type == TK_SEMICOLON) {
+ _set_error(vformat(RTR("Expected expression, found: '%s'."), get_token_text(tk)));
return ERR_PARSE_ERROR;
}
continue;
@@ -8078,6 +8100,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
} else if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_EXPRESSION) {
if (tk.type == TK_COMMA) {
+ tk = _peek();
+ if (tk.type == TK_PARENTHESIS_CLOSE) {
+ _set_error(vformat(RTR("Expected expression, found: '%s'."), get_token_text(tk)));
+ return ERR_PARSE_ERROR;
+ }
continue;
}
if (tk.type != TK_PARENTHESIS_CLOSE) {
@@ -8096,7 +8123,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_PARSE_ERROR;
}
if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_CONDITION && !is_condition) {
- _set_error(RTR("The middle expression is expected to be a boolean operator."));
+ _set_error(RTR("The middle expression is expected to have a boolean data type."));
return ERR_PARSE_ERROR;
}
}
@@ -9207,6 +9234,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
tk = _get_token();
if (tk.type == TK_IDENTIFIER) {
current_uniform_group_name = tk.text;
+ current_uniform_subgroup_name = "";
tk = _get_token();
if (tk.type == TK_PERIOD) {
tk = _get_token();