summaryrefslogtreecommitdiffstats
path: root/servers/rendering/shader_language.cpp
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-10-03 17:20:23 +0200
committerRémi Verschelde <rverschelde@gmail.com>2023-10-03 17:20:23 +0200
commit24c166dfe205f8a5d07c8786b78568f5a5684174 (patch)
tree6ae4baf800c584a3b8125a81f9cdf090e78f4353 /servers/rendering/shader_language.cpp
parenta3d6d60fe17835abcd6da59762c1eedc819eed2b (diff)
parentd3d20f15bf16e6b10f35429b608b6fa27e55aee8 (diff)
downloadredot-engine-24c166dfe205f8a5d07c8786b78568f5a5684174.tar.gz
Merge pull request #81619 from Chaosus/fix_shader_const
Re-allows constants in global space to be initialized with function call
Diffstat (limited to 'servers/rendering/shader_language.cpp')
-rw-r--r--servers/rendering/shader_language.cpp103
1 files changed, 53 insertions, 50 deletions
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 6f3280e6a1..34ffc1e90f 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -1455,17 +1455,17 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
return true;
}
- for (int i = 0; i < shader->functions.size(); i++) {
- if (!shader->functions[i].callable) {
+ for (int i = 0; i < shader->vfunctions.size(); i++) {
+ if (!shader->vfunctions[i].callable) {
continue;
}
- if (shader->functions[i].name == p_identifier) {
+ if (shader->vfunctions[i].name == p_identifier) {
if (r_data_type) {
- *r_data_type = shader->functions[i].function->return_type;
+ *r_data_type = shader->vfunctions[i].function->return_type;
}
if (r_array_size) {
- *r_array_size = shader->functions[i].function->return_array_size;
+ *r_array_size = shader->vfunctions[i].function->return_array_size;
}
if (r_type) {
*r_type = IDENTIFIER_FUNCTION;
@@ -3413,18 +3413,18 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
bool exists = false;
String arg_list = "";
- for (int i = 0; i < shader->functions.size(); i++) {
- if (name != shader->functions[i].name) {
+ for (int i = 0; i < shader->vfunctions.size(); i++) {
+ if (name != shader->vfunctions[i].name) {
continue;
}
exists = true;
- if (!shader->functions[i].callable) {
+ if (!shader->vfunctions[i].callable) {
_set_error(vformat(RTR("Function '%s' can't be called from source code."), String(name)));
return false;
}
- FunctionNode *pfunc = shader->functions[i].function;
+ FunctionNode *pfunc = shader->vfunctions[i].function;
if (arg_list.is_empty()) {
for (int j = 0; j < pfunc->arguments.size(); j++) {
if (j > 0) {
@@ -4662,10 +4662,10 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_functi
}
bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat) {
- for (int i = 0; i < shader->functions.size(); i++) {
- if (shader->functions[i].name == p_name) {
- ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
- FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
+ 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);
+ FunctionNode::Argument *arg = &shader->vfunctions[i].function->arguments.write[p_argument];
if (arg->tex_builtin_check) {
_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;
@@ -4696,10 +4696,10 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam
}
bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin) {
- for (int i = 0; i < shader->functions.size(); i++) {
- if (shader->functions[i].name == p_name) {
- ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
- FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
+ 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);
+ FunctionNode::Argument *arg = &shader->vfunctions[i].function->arguments.write[p_argument];
if (arg->tex_argument_check) {
_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;
@@ -5229,11 +5229,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = func;
} else { //a function call
- if (p_block == nullptr) { // Non-constructor function call in global space is forbidden.
- if (is_const_decl) {
+
+ // Non-builtin function call is forbidden for constant declaration.
+ if (is_const_decl) {
+ if (shader->functions.has(identifier)) {
_set_error(RTR("Expected constant expression."));
+ return nullptr;
}
- return nullptr;
}
const StringName &name = identifier;
@@ -5260,12 +5262,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
//test if function was parsed first
int function_index = -1;
- for (int i = 0; i < shader->functions.size(); i++) {
- if (shader->functions[i].name == name) {
+ for (int i = 0; i < shader->vfunctions.size(); i++) {
+ if (shader->vfunctions[i].name == name) {
//add to current function as dependency
- for (int j = 0; j < shader->functions.size(); j++) {
- if (shader->functions[j].name == current_function) {
- shader->functions.write[j].uses_function.insert(name);
+ for (int j = 0; j < shader->vfunctions.size(); j++) {
+ if (shader->vfunctions[j].name == current_function) {
+ shader->vfunctions.write[j].uses_function.insert(name);
break;
}
}
@@ -5298,7 +5300,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
//connect texture arguments, so we can cache in the
//argument what type of filter and repeat to use
- FunctionNode *call_function = shader->functions[function_index].function;
+ FunctionNode *call_function = shader->vfunctions[function_index].function;
if (call_function) {
func->return_cache = call_function->get_datatype();
func->struct_name = call_function->get_datatype_name();
@@ -9476,8 +9478,8 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
}
}
- for (int i = 0; i < shader->functions.size(); i++) {
- if (!shader->functions[i].callable && shader->functions[i].name == name) {
+ for (int i = 0; i < shader->vfunctions.size(); i++) {
+ if (!shader->vfunctions[i].callable && shader->vfunctions[i].name == name) {
_set_redefinition_error(String(name));
return ERR_PARSE_ERROR;
}
@@ -9492,7 +9494,8 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
function.function = func_node;
- shader->functions.push_back(function);
+ shader->functions.insert(name, function);
+ shader->vfunctions.push_back(function);
func_node->name = name;
func_node->return_type = type;
@@ -10136,8 +10139,8 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
continue;
}
bool found = false;
- for (int i = 0; i < shader->functions.size(); i++) {
- if (shader->functions[i].name == E.key) {
+ for (int i = 0; i < shader->vfunctions.size(); i++) {
+ if (shader->vfunctions[i].name == E.key) {
found = true;
break;
}
@@ -10257,11 +10260,11 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
}
}
- for (int i = 0; i < shader->functions.size(); i++) {
- if (!shader->functions[i].callable || shader->functions[i].name == skip_function) {
+ for (int i = 0; i < shader->vfunctions.size(); i++) {
+ if (!shader->vfunctions[i].callable || shader->vfunctions[i].name == skip_function) {
continue;
}
- matches.insert(String(shader->functions[i].name), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
+ matches.insert(String(shader->vfunctions[i].name), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
}
int idx = 0;
@@ -10319,26 +10322,26 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
block = block->parent_block;
}
- for (int i = 0; i < shader->functions.size(); i++) {
- if (!shader->functions[i].callable) {
+ for (int i = 0; i < shader->vfunctions.size(); i++) {
+ if (!shader->vfunctions[i].callable) {
continue;
}
- if (shader->functions[i].name == completion_function) {
+ if (shader->vfunctions[i].name == completion_function) {
String calltip;
- calltip += get_datatype_name(shader->functions[i].function->return_type);
+ calltip += get_datatype_name(shader->vfunctions[i].function->return_type);
- if (shader->functions[i].function->return_array_size > 0) {
+ if (shader->vfunctions[i].function->return_array_size > 0) {
calltip += "[";
- calltip += itos(shader->functions[i].function->return_array_size);
+ calltip += itos(shader->vfunctions[i].function->return_array_size);
calltip += "]";
}
calltip += " ";
- calltip += shader->functions[i].name;
+ calltip += shader->vfunctions[i].name;
calltip += "(";
- for (int j = 0; j < shader->functions[i].function->arguments.size(); j++) {
+ for (int j = 0; j < shader->vfunctions[i].function->arguments.size(); j++) {
if (j > 0) {
calltip += ", ";
} else {
@@ -10349,25 +10352,25 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
calltip += char32_t(0xFFFF);
}
- if (shader->functions[i].function->arguments[j].is_const) {
+ if (shader->vfunctions[i].function->arguments[j].is_const) {
calltip += "const ";
}
- if (shader->functions[i].function->arguments[j].qualifier != ArgumentQualifier::ARGUMENT_QUALIFIER_IN) {
- if (shader->functions[i].function->arguments[j].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT) {
+ if (shader->vfunctions[i].function->arguments[j].qualifier != ArgumentQualifier::ARGUMENT_QUALIFIER_IN) {
+ if (shader->vfunctions[i].function->arguments[j].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT) {
calltip += "out ";
} else { // ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT
calltip += "inout ";
}
}
- calltip += get_datatype_name(shader->functions[i].function->arguments[j].type);
+ calltip += get_datatype_name(shader->vfunctions[i].function->arguments[j].type);
calltip += " ";
- calltip += shader->functions[i].function->arguments[j].name;
+ calltip += shader->vfunctions[i].function->arguments[j].name;
- if (shader->functions[i].function->arguments[j].array_size > 0) {
+ if (shader->vfunctions[i].function->arguments[j].array_size > 0) {
calltip += "[";
- calltip += itos(shader->functions[i].function->arguments[j].array_size);
+ calltip += itos(shader->vfunctions[i].function->arguments[j].array_size);
calltip += "]";
}
@@ -10376,7 +10379,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
}
}
- if (shader->functions[i].function->arguments.size()) {
+ if (shader->vfunctions[i].function->arguments.size()) {
calltip += " ";
}
calltip += ")";