diff options
Diffstat (limited to 'servers/rendering/shader_language.cpp')
-rw-r--r-- | servers/rendering/shader_language.cpp | 46 |
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(); |