mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Re-allows constants in global space to be initialized with function call
This commit is contained in:
parent
3ed4497113
commit
d3d20f15bf
3 changed files with 68 additions and 64 deletions
|
@ -303,8 +303,8 @@ String ShaderCompiler::_get_sampler_name(ShaderLanguage::TextureFilter p_filter,
|
||||||
void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, HashSet<StringName> &added) {
|
void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, HashSet<StringName> &added) {
|
||||||
int fidx = -1;
|
int fidx = -1;
|
||||||
|
|
||||||
for (int i = 0; i < p_node->functions.size(); i++) {
|
for (int i = 0; i < p_node->vfunctions.size(); i++) {
|
||||||
if (p_node->functions[i].name == p_for_func) {
|
if (p_node->vfunctions[i].name == p_for_func) {
|
||||||
fidx = i;
|
fidx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str
|
||||||
|
|
||||||
Vector<StringName> uses_functions;
|
Vector<StringName> uses_functions;
|
||||||
|
|
||||||
for (const StringName &E : p_node->functions[fidx].uses_function) {
|
for (const StringName &E : p_node->vfunctions[fidx].uses_function) {
|
||||||
uses_functions.push_back(E);
|
uses_functions.push_back(E);
|
||||||
}
|
}
|
||||||
uses_functions.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced
|
uses_functions.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced
|
||||||
|
@ -328,9 +328,9 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str
|
||||||
|
|
||||||
SL::FunctionNode *fnode = nullptr;
|
SL::FunctionNode *fnode = nullptr;
|
||||||
|
|
||||||
for (int i = 0; i < p_node->functions.size(); i++) {
|
for (int i = 0; i < p_node->vfunctions.size(); i++) {
|
||||||
if (p_node->functions[i].name == uses_functions[k]) {
|
if (p_node->vfunctions[i].name == uses_functions[k]) {
|
||||||
fnode = p_node->functions[i].function;
|
fnode = p_node->vfunctions[i].function;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -765,8 +765,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
|
||||||
HashMap<StringName, String> function_code;
|
HashMap<StringName, String> function_code;
|
||||||
|
|
||||||
//code for functions
|
//code for functions
|
||||||
for (int i = 0; i < pnode->functions.size(); i++) {
|
for (int i = 0; i < pnode->vfunctions.size(); i++) {
|
||||||
SL::FunctionNode *fnode = pnode->functions[i].function;
|
SL::FunctionNode *fnode = pnode->vfunctions[i].function;
|
||||||
function = fnode;
|
function = fnode;
|
||||||
current_func_name = fnode->name;
|
current_func_name = fnode->name;
|
||||||
function_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
function_code[fnode->name] = _dump_node_code(fnode->body, p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
|
@ -777,8 +777,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
|
||||||
|
|
||||||
HashSet<StringName> added_funcs_per_stage[STAGE_MAX];
|
HashSet<StringName> added_funcs_per_stage[STAGE_MAX];
|
||||||
|
|
||||||
for (int i = 0; i < pnode->functions.size(); i++) {
|
for (int i = 0; i < pnode->vfunctions.size(); i++) {
|
||||||
SL::FunctionNode *fnode = pnode->functions[i].function;
|
SL::FunctionNode *fnode = pnode->vfunctions[i].function;
|
||||||
|
|
||||||
function = fnode;
|
function = fnode;
|
||||||
|
|
||||||
|
@ -1150,9 +1150,9 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
|
||||||
const bool is_internal_func = internal_functions.has(vnode->name);
|
const bool is_internal_func = internal_functions.has(vnode->name);
|
||||||
|
|
||||||
if (!is_internal_func) {
|
if (!is_internal_func) {
|
||||||
for (int i = 0; i < shader->functions.size(); i++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (shader->functions[i].name == vnode->name) {
|
if (shader->vfunctions[i].name == vnode->name) {
|
||||||
func = shader->functions[i].function;
|
func = shader->vfunctions[i].function;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1433,17 +1433,17 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < shader->functions.size(); i++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (!shader->functions[i].callable) {
|
if (!shader->vfunctions[i].callable) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader->functions[i].name == p_identifier) {
|
if (shader->vfunctions[i].name == p_identifier) {
|
||||||
if (r_data_type) {
|
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) {
|
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) {
|
if (r_type) {
|
||||||
*r_type = IDENTIFIER_FUNCTION;
|
*r_type = IDENTIFIER_FUNCTION;
|
||||||
|
@ -3391,18 +3391,18 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
String arg_list = "";
|
String arg_list = "";
|
||||||
|
|
||||||
for (int i = 0; i < shader->functions.size(); i++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (name != shader->functions[i].name) {
|
if (name != shader->vfunctions[i].name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
exists = true;
|
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)));
|
_set_error(vformat(RTR("Function '%s' can't be called from source code."), String(name)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionNode *pfunc = shader->functions[i].function;
|
FunctionNode *pfunc = shader->vfunctions[i].function;
|
||||||
if (arg_list.is_empty()) {
|
if (arg_list.is_empty()) {
|
||||||
for (int j = 0; j < pfunc->arguments.size(); j++) {
|
for (int j = 0; j < pfunc->arguments.size(); j++) {
|
||||||
if (j > 0) {
|
if (j > 0) {
|
||||||
|
@ -4640,10 +4640,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) {
|
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++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (shader->functions[i].name == p_name) {
|
if (shader->vfunctions[i].name == p_name) {
|
||||||
ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
|
ERR_FAIL_INDEX_V(p_argument, shader->vfunctions[i].function->arguments.size(), false);
|
||||||
FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
|
FunctionNode::Argument *arg = &shader->vfunctions[i].function->arguments.write[p_argument];
|
||||||
if (arg->tex_builtin_check) {
|
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)));
|
_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;
|
return false;
|
||||||
|
@ -4674,10 +4674,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) {
|
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++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (shader->functions[i].name == p_name) {
|
if (shader->vfunctions[i].name == p_name) {
|
||||||
ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
|
ERR_FAIL_INDEX_V(p_argument, shader->vfunctions[i].function->arguments.size(), false);
|
||||||
FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
|
FunctionNode::Argument *arg = &shader->vfunctions[i].function->arguments.write[p_argument];
|
||||||
if (arg->tex_argument_check) {
|
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)));
|
_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;
|
return false;
|
||||||
|
@ -5207,11 +5207,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
||||||
expr = func;
|
expr = func;
|
||||||
|
|
||||||
} else { //a function call
|
} 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."));
|
_set_error(RTR("Expected constant expression."));
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const StringName &name = identifier;
|
const StringName &name = identifier;
|
||||||
|
@ -5238,12 +5240,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
||||||
|
|
||||||
//test if function was parsed first
|
//test if function was parsed first
|
||||||
int function_index = -1;
|
int function_index = -1;
|
||||||
for (int i = 0; i < shader->functions.size(); i++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (shader->functions[i].name == name) {
|
if (shader->vfunctions[i].name == name) {
|
||||||
//add to current function as dependency
|
//add to current function as dependency
|
||||||
for (int j = 0; j < shader->functions.size(); j++) {
|
for (int j = 0; j < shader->vfunctions.size(); j++) {
|
||||||
if (shader->functions[j].name == current_function) {
|
if (shader->vfunctions[j].name == current_function) {
|
||||||
shader->functions.write[j].uses_function.insert(name);
|
shader->vfunctions.write[j].uses_function.insert(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5276,7 +5278,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
||||||
//connect texture arguments, so we can cache in the
|
//connect texture arguments, so we can cache in the
|
||||||
//argument what type of filter and repeat to use
|
//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) {
|
if (call_function) {
|
||||||
func->return_cache = call_function->get_datatype();
|
func->return_cache = call_function->get_datatype();
|
||||||
func->struct_name = call_function->get_datatype_name();
|
func->struct_name = call_function->get_datatype_name();
|
||||||
|
@ -9454,8 +9456,8 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < shader->functions.size(); i++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (!shader->functions[i].callable && shader->functions[i].name == name) {
|
if (!shader->vfunctions[i].callable && shader->vfunctions[i].name == name) {
|
||||||
_set_redefinition_error(String(name));
|
_set_redefinition_error(String(name));
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -9470,7 +9472,8 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
|
||||||
|
|
||||||
function.function = func_node;
|
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->name = name;
|
||||||
func_node->return_type = type;
|
func_node->return_type = type;
|
||||||
|
@ -10114,8 +10117,8 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int i = 0; i < shader->functions.size(); i++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (shader->functions[i].name == E.key) {
|
if (shader->vfunctions[i].name == E.key) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10235,11 +10238,11 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < shader->functions.size(); i++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (!shader->functions[i].callable || shader->functions[i].name == skip_function) {
|
if (!shader->vfunctions[i].callable || shader->vfunctions[i].name == skip_function) {
|
||||||
continue;
|
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;
|
int idx = 0;
|
||||||
|
@ -10297,26 +10300,26 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
|
||||||
block = block->parent_block;
|
block = block->parent_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < shader->functions.size(); i++) {
|
for (int i = 0; i < shader->vfunctions.size(); i++) {
|
||||||
if (!shader->functions[i].callable) {
|
if (!shader->vfunctions[i].callable) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (shader->functions[i].name == completion_function) {
|
if (shader->vfunctions[i].name == completion_function) {
|
||||||
String calltip;
|
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 += "[";
|
||||||
calltip += itos(shader->functions[i].function->return_array_size);
|
calltip += itos(shader->vfunctions[i].function->return_array_size);
|
||||||
calltip += "]";
|
calltip += "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
calltip += " ";
|
calltip += " ";
|
||||||
calltip += shader->functions[i].name;
|
calltip += shader->vfunctions[i].name;
|
||||||
calltip += "(";
|
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) {
|
if (j > 0) {
|
||||||
calltip += ", ";
|
calltip += ", ";
|
||||||
} else {
|
} else {
|
||||||
|
@ -10327,25 +10330,25 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
|
||||||
calltip += char32_t(0xFFFF);
|
calltip += char32_t(0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader->functions[i].function->arguments[j].is_const) {
|
if (shader->vfunctions[i].function->arguments[j].is_const) {
|
||||||
calltip += "const ";
|
calltip += "const ";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader->functions[i].function->arguments[j].qualifier != ArgumentQualifier::ARGUMENT_QUALIFIER_IN) {
|
if (shader->vfunctions[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_OUT) {
|
||||||
calltip += "out ";
|
calltip += "out ";
|
||||||
} else { // ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT
|
} else { // ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT
|
||||||
calltip += "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 += " ";
|
||||||
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 += "[";
|
||||||
calltip += itos(shader->functions[i].function->arguments[j].array_size);
|
calltip += itos(shader->vfunctions[i].function->arguments[j].array_size);
|
||||||
calltip += "]";
|
calltip += "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10354,7 +10357,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 += " ";
|
||||||
}
|
}
|
||||||
calltip += ")";
|
calltip += ")";
|
||||||
|
|
|
@ -711,9 +711,10 @@ public:
|
||||||
HashMap<StringName, Varying> varyings;
|
HashMap<StringName, Varying> varyings;
|
||||||
HashMap<StringName, Uniform> uniforms;
|
HashMap<StringName, Uniform> uniforms;
|
||||||
HashMap<StringName, Struct> structs;
|
HashMap<StringName, Struct> structs;
|
||||||
|
HashMap<StringName, Function> functions;
|
||||||
Vector<StringName> render_modes;
|
Vector<StringName> render_modes;
|
||||||
|
|
||||||
Vector<Function> functions;
|
Vector<Function> vfunctions;
|
||||||
Vector<Constant> vconstants;
|
Vector<Constant> vconstants;
|
||||||
Vector<Struct> vstructs;
|
Vector<Struct> vstructs;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue