summaryrefslogtreecommitdiffstats
path: root/servers
diff options
context:
space:
mode:
authorYuri Rubinsky <chaosus89@gmail.com>2024-10-24 09:38:10 +0300
committerGitHub <noreply@github.com>2024-10-24 09:38:10 +0300
commitff9fb0abea2027c35f0a024297c780648cc806bc (patch)
tree6e83b5f24476e40fccc9f7cd5173117de6389584 /servers
parent03641a425f1fb161fcd0bd65460f2e9b3c242e83 (diff)
parentad7e7a51b21a0c1b5b7142fcace66a7c00407c6a (diff)
downloadredot-engine-ff9fb0abea2027c35f0a024297c780648cc806bc.tar.gz
Merge pull request #93590 from Chaosus/shader_custom_func_discard
Allow usage of `discard` inside custom shader functions
Diffstat (limited to 'servers')
-rw-r--r--servers/rendering/shader_language.cpp23
-rw-r--r--servers/rendering/shader_language.h3
2 files changed, 18 insertions, 8 deletions
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 26df210e65..7c4128b0e3 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -356,7 +356,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_CF_BREAK, "break", CF_BLOCK, {}, {} },
{ TK_CF_CONTINUE, "continue", CF_BLOCK, {}, {} },
{ TK_CF_RETURN, "return", CF_BLOCK, {}, {} },
- { TK_CF_DISCARD, "discard", CF_BLOCK, { "particles", "sky", "fog" }, { "fragment" } },
+ { TK_CF_DISCARD, "discard", CF_BLOCK, { "particles", "sky", "fog" }, { "vertex" } },
// function specifier keywords
@@ -8599,6 +8599,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
block = block->parent_block;
}
} else if (tk.type == TK_CF_DISCARD) {
+ if (!is_discard_supported) {
+ _set_error(vformat(RTR("Use of '%s' is not supported for the '%s' shader type."), "discard", shader_type_identifier));
+ return ERR_PARSE_ERROR;
+ }
+
//check return type
BlockNode *b = p_block;
while (b && !b->parent_function) {
@@ -8610,7 +8615,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (!b->parent_function->can_discard) {
- _set_error(vformat(RTR("Use of '%s' is not allowed here."), "discard"));
+ _set_error(vformat(RTR("'%s' cannot be used within the '%s' processor function."), "discard", b->parent_function->name));
return ERR_PARSE_ERROR;
}
@@ -8619,6 +8624,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
pos = _get_tkpos();
tk = _get_token();
+
+ calls_info[b->parent_function->name].uses_restricted_items.push_back(Pair<StringName, CallInfo::Item>("discard", CallInfo::Item(CallInfo::Item::ITEM_TYPE_BUILTIN, pos)));
+
if (tk.type != TK_SEMICOLON) {
_set_expected_after_error(";", "discard");
return ERR_PARSE_ERROR;
@@ -8856,7 +8864,9 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
stages = &p_functions;
- is_supported_frag_only_funcs = shader_type_identifier == "canvas_item" || shader_type_identifier == "spatial" || shader_type_identifier == "sky";
+
+ is_discard_supported = shader_type_identifier == "canvas_item" || shader_type_identifier == "spatial";
+ is_supported_frag_only_funcs = is_discard_supported || shader_type_identifier == "sky";
const FunctionInfo &constants = p_functions.has("constants") ? p_functions["constants"] : FunctionInfo();
@@ -10350,6 +10360,8 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
if (p_functions.has(name)) {
func_node->can_discard = p_functions[name].can_discard;
+ } else {
+ func_node->can_discard = is_discard_supported; // Allow use it for custom functions (in supported shader types).
}
if (!function_overload_count.has(name)) {
@@ -10940,10 +10952,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
break; // Ignore hint keywords (parsed below).
}
if (keyword_list[i].flags & keyword_completion_context) {
- if (keyword_list[i].excluded_shader_types.has(shader_type_identifier)) {
- continue;
- }
- if (!keyword_list[i].functions.is_empty() && !keyword_list[i].functions.has(current_function)) {
+ if (keyword_list[i].excluded_shader_types.has(shader_type_identifier) || keyword_list[i].excluded_functions.has(current_function)) {
continue;
}
ScriptLanguage::CodeCompletionOption option(keyword_list[i].text, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index 3bbddf7be5..ddd4c41059 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -935,7 +935,7 @@ private:
const char *text;
uint32_t flags;
const Vector<String> excluded_shader_types;
- const Vector<String> functions;
+ const Vector<String> excluded_functions;
};
static const KeyWord keyword_list[];
@@ -1151,6 +1151,7 @@ private:
const HashMap<StringName, FunctionInfo> *stages = nullptr;
bool is_supported_frag_only_funcs = false;
+ bool is_discard_supported = false;
bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier);
static const BuiltinFuncDef builtin_func_defs[];