summaryrefslogtreecommitdiff
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.cpp87
1 files changed, 64 insertions, 23 deletions
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index d6acad83f7..e9b1cb366d 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -33,15 +33,15 @@
#include "core/print_string.h"
#include "servers/rendering_server.h"
-static bool _is_text_char(CharType c) {
+static bool _is_text_char(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
-static bool _is_number(CharType c) {
+static bool _is_number(char32_t c) {
return (c >= '0' && c <= '9');
}
-static bool _is_hex(CharType c) {
+static bool _is_hex(char32_t c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
@@ -334,7 +334,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
};
ShaderLanguage::Token ShaderLanguage::_get_token() {
-#define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : CharType(0))
+#define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : char32_t(0))
while (true) {
char_idx++;
@@ -582,11 +582,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
break;
}
- str += CharType(GETCHAR(i));
+ str += char32_t(GETCHAR(i));
i++;
}
- CharType last_char = str[str.length() - 1];
+ char32_t last_char = str[str.length() - 1];
if (hexa_found) {
//integer(hex)
@@ -663,7 +663,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
String str;
while (_is_text_char(GETCHAR(0))) {
- str += CharType(GETCHAR(0));
+ str += char32_t(GETCHAR(0));
char_idx++;
}
@@ -2353,10 +2353,13 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
err += ",";
}
- if (p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && p_func->arguments[i + 1]->get_datatype() == TYPE_INT && static_cast<ConstantNode *>(p_func->arguments[i + 1])->values[0].sint < 0) {
- err += "-";
+ String arg_name;
+ if (args[i] == TYPE_STRUCT) {
+ arg_name = args2[i];
+ } else {
+ arg_name = get_datatype_name(args[i]);
}
- err += get_datatype_name(args[i]);
+ err += arg_name;
}
err += ")";
_set_error(err);
@@ -2380,6 +2383,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
return false;
}
+ int last_arg_count = 0;
+ String arg_list = "";
+
for (int i = 0; i < shader->functions.size(); i++) {
if (name != shader->functions[i].name) {
continue;
@@ -2391,21 +2397,45 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
FunctionNode *pfunc = shader->functions[i].function;
+ if (arg_list == "") {
+ for (int j = 0; j < pfunc->arguments.size(); j++) {
+ if (j > 0) {
+ arg_list += ", ";
+ }
+ String func_arg_name;
+ if (pfunc->arguments[j].type == TYPE_STRUCT) {
+ func_arg_name = pfunc->arguments[j].type_str;
+ } else {
+ func_arg_name = get_datatype_name(pfunc->arguments[j].type);
+ }
+ arg_list += func_arg_name;
+ }
+ }
if (pfunc->arguments.size() != args.size()) {
+ last_arg_count = pfunc->arguments.size();
continue;
}
bool fail = false;
for (int j = 0; j < args.size(); j++) {
- if (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str) {
- fail = true;
- break;
- }
if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) {
//all good, but it needs implicit conversion later
- } else if (args[j] != pfunc->arguments[j].type) {
+ } else if (args[j] != pfunc->arguments[j].type || (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str)) {
+ String func_arg_name;
+ if (pfunc->arguments[j].type == TYPE_STRUCT) {
+ func_arg_name = pfunc->arguments[j].type_str;
+ } else {
+ func_arg_name = get_datatype_name(pfunc->arguments[j].type);
+ }
+ String arg_name;
+ if (args[j] == TYPE_STRUCT) {
+ arg_name = args2[j];
+ } else {
+ arg_name = get_datatype_name(args[j]);
+ }
+ _set_error(vformat("Invalid argument for \"%s(%s)\" function: argument %s should be %s but is %s.", String(name), arg_list, j + 1, func_arg_name, arg_name));
fail = true;
break;
}
@@ -2441,6 +2471,12 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
}
+ if (last_arg_count > args.size()) {
+ _set_error(vformat("Too few arguments for \"%s(%s)\" call. Expected at least %s but received %s.", String(name), arg_list, last_arg_count, args.size()));
+ } else if (last_arg_count < args.size()) {
+ _set_error(vformat("Too many arguments for \"%s(%s)\" call. Expected at most %s but received %s.", String(name), arg_list, last_arg_count, args.size()));
+ }
+
return false;
}
@@ -3869,7 +3905,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break;
}
- const CharType *c = ident.ptr();
+ const char32_t *c = ident.ptr();
for (int i = 0; i < l; i++) {
switch (c[i]) {
case 'r':
@@ -3933,7 +3969,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break;
}
- const CharType *c = ident.ptr();
+ const char32_t *c = ident.ptr();
for (int i = 0; i < l; i++) {
switch (c[i]) {
case 'r':
@@ -4000,7 +4036,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break;
}
- const CharType *c = ident.ptr();
+ const char32_t *c = ident.ptr();
for (int i = 0; i < l; i++) {
switch (c[i]) {
case 'r':
@@ -6979,6 +7015,11 @@ bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionI
return true;
}
}
+ if (p_functions.has("compute")) {
+ if (p_functions["compute"].built_ins.has(p_name)) {
+ return true;
+ }
+ }
return false;
}
@@ -7034,7 +7075,7 @@ Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperat
static int _get_first_ident_pos(const String &p_code) {
int idx = 0;
-#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : CharType(0))
+#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : char32_t(0))
while (true) {
if (GETCHAR(0) == '/' && GETCHAR(1) == '/') {
@@ -7295,7 +7336,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
if (j == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
if (shader->functions[i].function->arguments[j].is_const) {
@@ -7315,7 +7356,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
calltip += shader->functions[i].function->arguments[j].name;
if (j == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
}
@@ -7378,7 +7419,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
if (i == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
if (out_arg >= 0 && i == out_arg) {
@@ -7388,7 +7429,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
calltip += get_datatype_name(builtin_func_defs[idx].args[i]);
if (i == completion_argument) {
- calltip += CharType(0xFFFF);
+ calltip += char32_t(0xFFFF);
}
found_arg = true;