1/**************************************************************************/
2/* shader_language.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#include "shader_language.h"
32
33#include "core/os/os.h"
34#include "core/string/print_string.h"
35#include "core/templates/local_vector.h"
36#include "servers/rendering/renderer_compositor.h"
37#include "servers/rendering_server.h"
38#include "shader_types.h"
39
40#define HAS_WARNING(flag) (warning_flags & flag)
41
42String ShaderLanguage::get_operator_text(Operator p_op) {
43 static const char *op_names[OP_MAX] = { "==",
44 "!=",
45 "<",
46 "<=",
47 ">",
48 ">=",
49 "&&",
50 "||",
51 "!",
52 "-",
53 "+",
54 "-",
55 "*",
56 "/",
57 "%",
58 "<<",
59 ">>",
60 "=",
61 "+=",
62 "-=",
63 "*=",
64 "/=",
65 "%=",
66 "<<=",
67 ">>=",
68 "&=",
69 "|=",
70 "^=",
71 "&",
72 "|",
73 "^",
74 "~",
75 "++",
76 "--",
77 "?",
78 ":",
79 "++",
80 "--",
81 "()",
82 "construct",
83 "index",
84 "empty" };
85
86 return op_names[p_op];
87}
88
89const char *ShaderLanguage::token_names[TK_MAX] = {
90 "EMPTY",
91 "IDENTIFIER",
92 "TRUE",
93 "FALSE",
94 "FLOAT_CONSTANT",
95 "INT_CONSTANT",
96 "UINT_CONSTANT",
97 "TYPE_VOID",
98 "TYPE_BOOL",
99 "TYPE_BVEC2",
100 "TYPE_BVEC3",
101 "TYPE_BVEC4",
102 "TYPE_INT",
103 "TYPE_IVEC2",
104 "TYPE_IVEC3",
105 "TYPE_IVEC4",
106 "TYPE_UINT",
107 "TYPE_UVEC2",
108 "TYPE_UVEC3",
109 "TYPE_UVEC4",
110 "TYPE_FLOAT",
111 "TYPE_VEC2",
112 "TYPE_VEC3",
113 "TYPE_VEC4",
114 "TYPE_MAT2",
115 "TYPE_MAT3",
116 "TYPE_MAT4",
117 "TYPE_SAMPLER2D",
118 "TYPE_ISAMPLER2D",
119 "TYPE_USAMPLER2D",
120 "TYPE_SAMPLER2DARRAY",
121 "TYPE_ISAMPLER2DARRAY",
122 "TYPE_USAMPLER2DARRAY",
123 "TYPE_SAMPLER3D",
124 "TYPE_ISAMPLER3D",
125 "TYPE_USAMPLER3D",
126 "TYPE_SAMPLERCUBE",
127 "TYPE_SAMPLERCUBEARRAY",
128 "INTERPOLATION_FLAT",
129 "INTERPOLATION_SMOOTH",
130 "CONST",
131 "STRUCT",
132 "PRECISION_LOW",
133 "PRECISION_MID",
134 "PRECISION_HIGH",
135 "OP_EQUAL",
136 "OP_NOT_EQUAL",
137 "OP_LESS",
138 "OP_LESS_EQUAL",
139 "OP_GREATER",
140 "OP_GREATER_EQUAL",
141 "OP_AND",
142 "OP_OR",
143 "OP_NOT",
144 "OP_ADD",
145 "OP_SUB",
146 "OP_MUL",
147 "OP_DIV",
148 "OP_MOD",
149 "OP_SHIFT_LEFT",
150 "OP_SHIFT_RIGHT",
151 "OP_ASSIGN",
152 "OP_ASSIGN_ADD",
153 "OP_ASSIGN_SUB",
154 "OP_ASSIGN_MUL",
155 "OP_ASSIGN_DIV",
156 "OP_ASSIGN_MOD",
157 "OP_ASSIGN_SHIFT_LEFT",
158 "OP_ASSIGN_SHIFT_RIGHT",
159 "OP_ASSIGN_BIT_AND",
160 "OP_ASSIGN_BIT_OR",
161 "OP_ASSIGN_BIT_XOR",
162 "OP_BIT_AND",
163 "OP_BIT_OR",
164 "OP_BIT_XOR",
165 "OP_BIT_INVERT",
166 "OP_INCREMENT",
167 "OP_DECREMENT",
168 "CF_IF",
169 "CF_ELSE",
170 "CF_FOR",
171 "CF_WHILE",
172 "CF_DO",
173 "CF_SWITCH",
174 "CF_CASE",
175 "CF_DEFAULT",
176 "CF_BREAK",
177 "CF_CONTINUE",
178 "CF_RETURN",
179 "CF_DISCARD",
180 "BRACKET_OPEN",
181 "BRACKET_CLOSE",
182 "CURLY_BRACKET_OPEN",
183 "CURLY_BRACKET_CLOSE",
184 "PARENTHESIS_OPEN",
185 "PARENTHESIS_CLOSE",
186 "QUESTION",
187 "COMMA",
188 "COLON",
189 "SEMICOLON",
190 "PERIOD",
191 "UNIFORM",
192 "UNIFORM_GROUP",
193 "INSTANCE",
194 "GLOBAL",
195 "VARYING",
196 "ARG_IN",
197 "ARG_OUT",
198 "ARG_INOUT",
199 "RENDER_MODE",
200 "HINT_DEFAULT_WHITE_TEXTURE",
201 "HINT_DEFAULT_BLACK_TEXTURE",
202 "HINT_DEFAULT_TRANSPARENT_TEXTURE",
203 "HINT_NORMAL_TEXTURE",
204 "HINT_ROUGHNESS_NORMAL_TEXTURE",
205 "HINT_ROUGHNESS_R",
206 "HINT_ROUGHNESS_G",
207 "HINT_ROUGHNESS_B",
208 "HINT_ROUGHNESS_A",
209 "HINT_ROUGHNESS_GRAY",
210 "HINT_ANISOTROPY_TEXTURE",
211 "HINT_SOURCE_COLOR",
212 "HINT_RANGE",
213 "HINT_INSTANCE_INDEX",
214 "HINT_SCREEN_TEXTURE",
215 "HINT_NORMAL_ROUGHNESS_TEXTURE",
216 "HINT_DEPTH_TEXTURE",
217 "FILTER_NEAREST",
218 "FILTER_LINEAR",
219 "FILTER_NEAREST_MIPMAP",
220 "FILTER_LINEAR_MIPMAP",
221 "FILTER_NEAREST_MIPMAP_ANISOTROPIC",
222 "FILTER_LINEAR_MIPMAP_ANISOTROPIC",
223 "REPEAT_ENABLE",
224 "REPEAT_DISABLE",
225 "SHADER_TYPE",
226 "CURSOR",
227 "ERROR",
228 "EOF",
229};
230
231String ShaderLanguage::get_token_text(Token p_token) {
232 String name = token_names[p_token.type];
233 if (p_token.is_integer_constant() || p_token.type == TK_FLOAT_CONSTANT) {
234 name += "(" + rtos(p_token.constant) + ")";
235 } else if (p_token.type == TK_IDENTIFIER) {
236 name += "(" + String(p_token.text) + ")";
237 } else if (p_token.type == TK_ERROR) {
238 name += "(" + String(p_token.text) + ")";
239 }
240
241 return name;
242}
243
244ShaderLanguage::Token ShaderLanguage::_make_token(TokenType p_type, const StringName &p_text) {
245 Token tk;
246 tk.type = p_type;
247 tk.text = p_text;
248 tk.line = tk_line;
249 if (tk.type == TK_ERROR) {
250 _set_error(p_text);
251 }
252 return tk;
253}
254
255enum ContextFlag : uint32_t {
256 CF_UNSPECIFIED = 0U,
257 CF_BLOCK = 1U, // "void test() { <x> }"
258 CF_FUNC_DECL_PARAM_SPEC = 2U, // "void test(<x> int param) {}"
259 CF_FUNC_DECL_PARAM_TYPE = 4U, // "void test(<x> param) {}"
260 CF_IF_DECL = 8U, // "if(<x>) {}"
261 CF_BOOLEAN = 16U, // "bool t = <x>;"
262 CF_GLOBAL_SPACE = 32U, // "struct", "const", "void" etc.
263 CF_DATATYPE = 64U, // "<x> value;"
264 CF_UNIFORM_TYPE = 128U, // "uniform <x> myUniform;"
265 CF_VARYING_TYPE = 256U, // "varying <x> myVarying;"
266 CF_PRECISION_MODIFIER = 512U, // "<x> vec4 a = vec4(0.0, 1.0, 2.0, 3.0);"
267 CF_INTERPOLATION_QUALIFIER = 1024U, // "varying <x> vec3 myColor;"
268 CF_UNIFORM_KEYWORD = 2048U, // "uniform"
269 CF_CONST_KEYWORD = 4096U, // "const"
270 CF_UNIFORM_QUALIFIER = 8192U, // "<x> uniform float t;"
271 CF_SHADER_TYPE = 16384U, // "shader_type"
272};
273
274const uint32_t KCF_DATATYPE = CF_BLOCK | CF_GLOBAL_SPACE | CF_DATATYPE | CF_FUNC_DECL_PARAM_TYPE | CF_UNIFORM_TYPE;
275const uint32_t KCF_SAMPLER_DATATYPE = CF_FUNC_DECL_PARAM_TYPE | CF_UNIFORM_TYPE;
276
277const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
278 { TK_TRUE, "true", CF_BLOCK | CF_IF_DECL | CF_BOOLEAN, {}, {} },
279 { TK_FALSE, "false", CF_BLOCK | CF_IF_DECL | CF_BOOLEAN, {}, {} },
280
281 // data types
282
283 { TK_TYPE_VOID, "void", CF_GLOBAL_SPACE, {}, {} },
284 { TK_TYPE_BOOL, "bool", KCF_DATATYPE, {}, {} },
285 { TK_TYPE_BVEC2, "bvec2", KCF_DATATYPE, {}, {} },
286 { TK_TYPE_BVEC3, "bvec3", KCF_DATATYPE, {}, {} },
287 { TK_TYPE_BVEC4, "bvec4", KCF_DATATYPE, {}, {} },
288 { TK_TYPE_INT, "int", KCF_DATATYPE, {}, {} },
289 { TK_TYPE_IVEC2, "ivec2", KCF_DATATYPE, {}, {} },
290 { TK_TYPE_IVEC3, "ivec3", KCF_DATATYPE, {}, {} },
291 { TK_TYPE_IVEC4, "ivec4", KCF_DATATYPE, {}, {} },
292 { TK_TYPE_UINT, "uint", KCF_DATATYPE, {}, {} },
293 { TK_TYPE_UVEC2, "uvec2", KCF_DATATYPE, {}, {} },
294 { TK_TYPE_UVEC3, "uvec3", KCF_DATATYPE, {}, {} },
295 { TK_TYPE_UVEC4, "uvec4", KCF_DATATYPE, {}, {} },
296 { TK_TYPE_FLOAT, "float", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
297 { TK_TYPE_VEC2, "vec2", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
298 { TK_TYPE_VEC3, "vec3", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
299 { TK_TYPE_VEC4, "vec4", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
300 { TK_TYPE_MAT2, "mat2", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
301 { TK_TYPE_MAT3, "mat3", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
302 { TK_TYPE_MAT4, "mat4", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
303 { TK_TYPE_SAMPLER2D, "sampler2D", KCF_SAMPLER_DATATYPE, {}, {} },
304 { TK_TYPE_ISAMPLER2D, "isampler2D", KCF_SAMPLER_DATATYPE, {}, {} },
305 { TK_TYPE_USAMPLER2D, "usampler2D", KCF_SAMPLER_DATATYPE, {}, {} },
306 { TK_TYPE_SAMPLER2DARRAY, "sampler2DArray", KCF_SAMPLER_DATATYPE, {}, {} },
307 { TK_TYPE_ISAMPLER2DARRAY, "isampler2DArray", KCF_SAMPLER_DATATYPE, {}, {} },
308 { TK_TYPE_USAMPLER2DARRAY, "usampler2DArray", KCF_SAMPLER_DATATYPE, {}, {} },
309 { TK_TYPE_SAMPLER3D, "sampler3D", KCF_SAMPLER_DATATYPE, {}, {} },
310 { TK_TYPE_ISAMPLER3D, "isampler3D", KCF_SAMPLER_DATATYPE, {}, {} },
311 { TK_TYPE_USAMPLER3D, "usampler3D", KCF_SAMPLER_DATATYPE, {}, {} },
312 { TK_TYPE_SAMPLERCUBE, "samplerCube", KCF_SAMPLER_DATATYPE, {}, {} },
313 { TK_TYPE_SAMPLERCUBEARRAY, "samplerCubeArray", KCF_SAMPLER_DATATYPE, {}, {} },
314
315 // interpolation qualifiers
316
317 { TK_INTERPOLATION_FLAT, "flat", CF_INTERPOLATION_QUALIFIER, {}, {} },
318 { TK_INTERPOLATION_SMOOTH, "smooth", CF_INTERPOLATION_QUALIFIER, {}, {} },
319
320 // precision modifiers
321
322 { TK_PRECISION_LOW, "lowp", CF_BLOCK | CF_PRECISION_MODIFIER, {}, {} },
323 { TK_PRECISION_MID, "mediump", CF_BLOCK | CF_PRECISION_MODIFIER, {}, {} },
324 { TK_PRECISION_HIGH, "highp", CF_BLOCK | CF_PRECISION_MODIFIER, {}, {} },
325
326 // global space keywords
327
328 { TK_UNIFORM, "uniform", CF_GLOBAL_SPACE | CF_UNIFORM_KEYWORD, {}, {} },
329 { TK_UNIFORM_GROUP, "group_uniforms", CF_GLOBAL_SPACE, {}, {} },
330 { TK_VARYING, "varying", CF_GLOBAL_SPACE, { "particles", "sky", "fog" }, {} },
331 { TK_CONST, "const", CF_BLOCK | CF_GLOBAL_SPACE | CF_CONST_KEYWORD, {}, {} },
332 { TK_STRUCT, "struct", CF_GLOBAL_SPACE, {}, {} },
333 { TK_SHADER_TYPE, "shader_type", CF_SHADER_TYPE, {}, {} },
334 { TK_RENDER_MODE, "render_mode", CF_GLOBAL_SPACE, {}, {} },
335
336 // uniform qualifiers
337
338 { TK_INSTANCE, "instance", CF_GLOBAL_SPACE | CF_UNIFORM_QUALIFIER, {}, {} },
339 { TK_GLOBAL, "global", CF_GLOBAL_SPACE | CF_UNIFORM_QUALIFIER, {}, {} },
340
341 // block keywords
342
343 { TK_CF_IF, "if", CF_BLOCK, {}, {} },
344 { TK_CF_ELSE, "else", CF_BLOCK, {}, {} },
345 { TK_CF_FOR, "for", CF_BLOCK, {}, {} },
346 { TK_CF_WHILE, "while", CF_BLOCK, {}, {} },
347 { TK_CF_DO, "do", CF_BLOCK, {}, {} },
348 { TK_CF_SWITCH, "switch", CF_BLOCK, {}, {} },
349 { TK_CF_CASE, "case", CF_BLOCK, {}, {} },
350 { TK_CF_DEFAULT, "default", CF_BLOCK, {}, {} },
351 { TK_CF_BREAK, "break", CF_BLOCK, {}, {} },
352 { TK_CF_CONTINUE, "continue", CF_BLOCK, {}, {} },
353 { TK_CF_RETURN, "return", CF_BLOCK, {}, {} },
354 { TK_CF_DISCARD, "discard", CF_BLOCK, { "particles", "sky", "fog" }, { "fragment" } },
355
356 // function specifier keywords
357
358 { TK_ARG_IN, "in", CF_FUNC_DECL_PARAM_SPEC, {}, {} },
359 { TK_ARG_OUT, "out", CF_FUNC_DECL_PARAM_SPEC, {}, {} },
360 { TK_ARG_INOUT, "inout", CF_FUNC_DECL_PARAM_SPEC, {}, {} },
361
362 // hints
363
364 { TK_HINT_SOURCE_COLOR, "source_color", CF_UNSPECIFIED, {}, {} },
365 { TK_HINT_RANGE, "hint_range", CF_UNSPECIFIED, {}, {} },
366 { TK_HINT_INSTANCE_INDEX, "instance_index", CF_UNSPECIFIED, {}, {} },
367
368 // sampler hints
369
370 { TK_HINT_NORMAL_TEXTURE, "hint_normal", CF_UNSPECIFIED, {}, {} },
371 { TK_HINT_DEFAULT_WHITE_TEXTURE, "hint_default_white", CF_UNSPECIFIED, {}, {} },
372 { TK_HINT_DEFAULT_BLACK_TEXTURE, "hint_default_black", CF_UNSPECIFIED, {}, {} },
373 { TK_HINT_DEFAULT_TRANSPARENT_TEXTURE, "hint_default_transparent", CF_UNSPECIFIED, {}, {} },
374 { TK_HINT_ANISOTROPY_TEXTURE, "hint_anisotropy", CF_UNSPECIFIED, {}, {} },
375 { TK_HINT_ROUGHNESS_R, "hint_roughness_r", CF_UNSPECIFIED, {}, {} },
376 { TK_HINT_ROUGHNESS_G, "hint_roughness_g", CF_UNSPECIFIED, {}, {} },
377 { TK_HINT_ROUGHNESS_B, "hint_roughness_b", CF_UNSPECIFIED, {}, {} },
378 { TK_HINT_ROUGHNESS_A, "hint_roughness_a", CF_UNSPECIFIED, {}, {} },
379 { TK_HINT_ROUGHNESS_NORMAL_TEXTURE, "hint_roughness_normal", CF_UNSPECIFIED, {}, {} },
380 { TK_HINT_ROUGHNESS_GRAY, "hint_roughness_gray", CF_UNSPECIFIED, {}, {} },
381 { TK_HINT_SCREEN_TEXTURE, "hint_screen_texture", CF_UNSPECIFIED, {}, {} },
382 { TK_HINT_NORMAL_ROUGHNESS_TEXTURE, "hint_normal_roughness_texture", CF_UNSPECIFIED, {}, {} },
383 { TK_HINT_DEPTH_TEXTURE, "hint_depth_texture", CF_UNSPECIFIED, {}, {} },
384
385 { TK_FILTER_NEAREST, "filter_nearest", CF_UNSPECIFIED, {}, {} },
386 { TK_FILTER_LINEAR, "filter_linear", CF_UNSPECIFIED, {}, {} },
387 { TK_FILTER_NEAREST_MIPMAP, "filter_nearest_mipmap", CF_UNSPECIFIED, {}, {} },
388 { TK_FILTER_LINEAR_MIPMAP, "filter_linear_mipmap", CF_UNSPECIFIED, {}, {} },
389 { TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC, "filter_nearest_mipmap_anisotropic", CF_UNSPECIFIED, {}, {} },
390 { TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC, "filter_linear_mipmap_anisotropic", CF_UNSPECIFIED, {}, {} },
391 { TK_REPEAT_ENABLE, "repeat_enable", CF_UNSPECIFIED, {}, {} },
392 { TK_REPEAT_DISABLE, "repeat_disable", CF_UNSPECIFIED, {}, {} },
393
394 { TK_ERROR, nullptr, CF_UNSPECIFIED, {}, {} }
395};
396
397ShaderLanguage::Token ShaderLanguage::_get_token() {
398#define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : char32_t(0))
399
400 while (true) {
401 char_idx++;
402 switch (GETCHAR(-1)) {
403 case 0:
404 return _make_token(TK_EOF);
405 case 0xFFFF:
406 return _make_token(TK_CURSOR); //for completion
407 case '\t':
408 case '\r':
409 case ' ':
410 continue;
411 case '\n':
412 tk_line++;
413 continue;
414 case '/': {
415 switch (GETCHAR(0)) {
416 case '*': { // block comment
417
418 char_idx++;
419 while (true) {
420 if (GETCHAR(0) == 0) {
421 return _make_token(TK_EOF);
422 }
423 if (GETCHAR(0) == '*' && GETCHAR(1) == '/') {
424 char_idx += 2;
425 break;
426 } else if (GETCHAR(0) == '\n') {
427 tk_line++;
428 }
429
430 char_idx++;
431 }
432
433 } break;
434 case '/': { // line comment skip
435
436 while (true) {
437 if (GETCHAR(0) == '\n') {
438 tk_line++;
439 char_idx++;
440 break;
441 }
442 if (GETCHAR(0) == 0) {
443 return _make_token(TK_EOF);
444 }
445 char_idx++;
446 }
447
448 } break;
449 case '=': { // diveq
450
451 char_idx++;
452 return _make_token(TK_OP_ASSIGN_DIV);
453
454 } break;
455 default:
456 return _make_token(TK_OP_DIV);
457 }
458
459 continue; //a comment, continue to next token
460 } break;
461 case '=': {
462 if (GETCHAR(0) == '=') {
463 char_idx++;
464 return _make_token(TK_OP_EQUAL);
465 }
466
467 return _make_token(TK_OP_ASSIGN);
468
469 } break;
470 case '<': {
471 if (GETCHAR(0) == '=') {
472 char_idx++;
473 return _make_token(TK_OP_LESS_EQUAL);
474 } else if (GETCHAR(0) == '<') {
475 char_idx++;
476 if (GETCHAR(0) == '=') {
477 char_idx++;
478 return _make_token(TK_OP_ASSIGN_SHIFT_LEFT);
479 }
480
481 return _make_token(TK_OP_SHIFT_LEFT);
482 }
483
484 return _make_token(TK_OP_LESS);
485
486 } break;
487 case '>': {
488 if (GETCHAR(0) == '=') {
489 char_idx++;
490 return _make_token(TK_OP_GREATER_EQUAL);
491 } else if (GETCHAR(0) == '>') {
492 char_idx++;
493 if (GETCHAR(0) == '=') {
494 char_idx++;
495 return _make_token(TK_OP_ASSIGN_SHIFT_RIGHT);
496 }
497
498 return _make_token(TK_OP_SHIFT_RIGHT);
499 }
500
501 return _make_token(TK_OP_GREATER);
502
503 } break;
504 case '!': {
505 if (GETCHAR(0) == '=') {
506 char_idx++;
507 return _make_token(TK_OP_NOT_EQUAL);
508 }
509
510 return _make_token(TK_OP_NOT);
511
512 } break;
513 //case '"' //string - no strings in shader
514 //case '\'' //string - no strings in shader
515 case '{':
516 return _make_token(TK_CURLY_BRACKET_OPEN);
517 case '}':
518 return _make_token(TK_CURLY_BRACKET_CLOSE);
519 case '[':
520 return _make_token(TK_BRACKET_OPEN);
521 case ']':
522 return _make_token(TK_BRACKET_CLOSE);
523 case '(':
524 return _make_token(TK_PARENTHESIS_OPEN);
525 case ')':
526 return _make_token(TK_PARENTHESIS_CLOSE);
527 case ',':
528 return _make_token(TK_COMMA);
529 case ';':
530 return _make_token(TK_SEMICOLON);
531 case '?':
532 return _make_token(TK_QUESTION);
533 case ':':
534 return _make_token(TK_COLON);
535 case '^':
536 if (GETCHAR(0) == '=') {
537 char_idx++;
538 return _make_token(TK_OP_ASSIGN_BIT_XOR);
539 }
540 return _make_token(TK_OP_BIT_XOR);
541 case '~':
542 return _make_token(TK_OP_BIT_INVERT);
543 case '&': {
544 if (GETCHAR(0) == '=') {
545 char_idx++;
546 return _make_token(TK_OP_ASSIGN_BIT_AND);
547 } else if (GETCHAR(0) == '&') {
548 char_idx++;
549 return _make_token(TK_OP_AND);
550 }
551 return _make_token(TK_OP_BIT_AND);
552 } break;
553 case '|': {
554 if (GETCHAR(0) == '=') {
555 char_idx++;
556 return _make_token(TK_OP_ASSIGN_BIT_OR);
557 } else if (GETCHAR(0) == '|') {
558 char_idx++;
559 return _make_token(TK_OP_OR);
560 }
561 return _make_token(TK_OP_BIT_OR);
562
563 } break;
564 case '*': {
565 if (GETCHAR(0) == '=') {
566 char_idx++;
567 return _make_token(TK_OP_ASSIGN_MUL);
568 }
569 return _make_token(TK_OP_MUL);
570 } break;
571 case '+': {
572 if (GETCHAR(0) == '=') {
573 char_idx++;
574 return _make_token(TK_OP_ASSIGN_ADD);
575 } else if (GETCHAR(0) == '+') {
576 char_idx++;
577 return _make_token(TK_OP_INCREMENT);
578 }
579
580 return _make_token(TK_OP_ADD);
581 } break;
582 case '-': {
583 if (GETCHAR(0) == '=') {
584 char_idx++;
585 return _make_token(TK_OP_ASSIGN_SUB);
586 } else if (GETCHAR(0) == '-') {
587 char_idx++;
588 return _make_token(TK_OP_DECREMENT);
589 }
590
591 return _make_token(TK_OP_SUB);
592 } break;
593 case '%': {
594 if (GETCHAR(0) == '=') {
595 char_idx++;
596 return _make_token(TK_OP_ASSIGN_MOD);
597 }
598
599 return _make_token(TK_OP_MOD);
600 } break;
601 case '@': {
602 if (GETCHAR(0) == '@' && GETCHAR(1) == '>') {
603 char_idx += 2;
604
605 LocalVector<char32_t> incp;
606 while (GETCHAR(0) != '\n') {
607 incp.push_back(GETCHAR(0));
608 char_idx++;
609 }
610 incp.push_back(0); // Zero end it.
611 String include_path(incp.ptr());
612 include_positions.write[include_positions.size() - 1].line = tk_line;
613 FilePosition fp;
614 fp.file = include_path;
615 fp.line = 0;
616 tk_line = 0;
617 include_positions.push_back(fp);
618
619 } else if (GETCHAR(0) == '@' && GETCHAR(1) == '<') {
620 if (include_positions.size() == 1) {
621 return _make_token(TK_ERROR, "Invalid include exit hint @@< without matching enter hint.");
622 }
623 char_idx += 2;
624
625 include_positions.resize(include_positions.size() - 1); // Pop back.
626 tk_line = include_positions[include_positions.size() - 1].line - 1; // Restore line.
627
628 } else {
629 return _make_token(TK_ERROR, "Invalid include enter/exit hint token (@@> and @@<)");
630 }
631 } break;
632 default: {
633 char_idx--; //go back one, since we have no idea what this is
634
635 if (is_digit(GETCHAR(0)) || (GETCHAR(0) == '.' && is_digit(GETCHAR(1)))) {
636 // parse number
637 bool hexa_found = false;
638 bool period_found = false;
639 bool exponent_found = false;
640 bool float_suffix_found = false;
641 bool uint_suffix_found = false;
642 bool end_suffix_found = false;
643
644 enum {
645 CASE_ALL,
646 CASE_HEXA_PERIOD,
647 CASE_EXPONENT,
648 CASE_SIGN_AFTER_EXPONENT,
649 CASE_NONE,
650 CASE_MAX,
651 } lut_case = CASE_ALL;
652
653 static bool suffix_lut[CASE_MAX][127];
654
655 if (!is_const_suffix_lut_initialized) {
656 is_const_suffix_lut_initialized = true;
657
658 for (int i = 0; i < 127; i++) {
659 char t = char(i);
660
661 suffix_lut[CASE_ALL][i] = t == '.' || t == 'x' || t == 'e' || t == 'f' || t == 'u' || t == '-' || t == '+';
662 suffix_lut[CASE_HEXA_PERIOD][i] = t == 'e' || t == 'f' || t == 'u';
663 suffix_lut[CASE_EXPONENT][i] = t == 'f' || t == '-' || t == '+';
664 suffix_lut[CASE_SIGN_AFTER_EXPONENT][i] = t == 'f';
665 suffix_lut[CASE_NONE][i] = false;
666 }
667 }
668
669 String str;
670 int i = 0;
671 bool digit_after_exp = false;
672
673 while (true) {
674 const char32_t symbol = String::char_lowercase(GETCHAR(i));
675 bool error = false;
676
677 if (is_digit(symbol)) {
678 if (exponent_found) {
679 digit_after_exp = true;
680 }
681 if (end_suffix_found) {
682 error = true;
683 }
684 } else {
685 if (symbol < 0x7F && suffix_lut[lut_case][symbol]) {
686 if (symbol == 'x') {
687 hexa_found = true;
688 lut_case = CASE_HEXA_PERIOD;
689 } else if (symbol == '.') {
690 period_found = true;
691 lut_case = CASE_HEXA_PERIOD;
692 } else if (symbol == 'e' && !hexa_found) {
693 exponent_found = true;
694 lut_case = CASE_EXPONENT;
695 } else if (symbol == 'f' && !hexa_found) {
696 if (!period_found && !exponent_found) {
697 error = true;
698 }
699 float_suffix_found = true;
700 end_suffix_found = true;
701 lut_case = CASE_NONE;
702 } else if (symbol == 'u') {
703 uint_suffix_found = true;
704 end_suffix_found = true;
705 lut_case = CASE_NONE;
706 } else if (symbol == '-' || symbol == '+') {
707 if (exponent_found) {
708 lut_case = CASE_SIGN_AFTER_EXPONENT;
709 } else {
710 break;
711 }
712 }
713 } else if (!hexa_found || !is_hex_digit(symbol)) {
714 if (is_ascii_identifier_char(symbol)) {
715 error = true;
716 } else {
717 break;
718 }
719 }
720 }
721
722 if (error) {
723 if (hexa_found) {
724 return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant");
725 }
726 if (period_found || exponent_found || float_suffix_found) {
727 return _make_token(TK_ERROR, "Invalid (float) numeric constant");
728 }
729 if (uint_suffix_found) {
730 return _make_token(TK_ERROR, "Invalid (unsigned integer) numeric constant");
731 }
732 return _make_token(TK_ERROR, "Invalid (integer) numeric constant");
733 }
734 str += symbol;
735 i++;
736 }
737
738 char32_t last_char = str[str.length() - 1];
739
740 if (hexa_found) { // Integer (hex).
741 if (uint_suffix_found) {
742 // Strip the suffix.
743 str = str.left(str.length() - 1);
744
745 // Compensate reading cursor position.
746 char_idx += 1;
747 }
748 if (str.size() > 11 || !str.is_valid_hex_number(true)) { // > 0xFFFFFFFF
749 return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant");
750 }
751 } else if (period_found || exponent_found || float_suffix_found) { // Float
752 if (exponent_found && (!digit_after_exp || (!is_digit(last_char) && last_char != 'f'))) { // Checks for eg: "2E", "2E-", "2E+" and 0ef, 0e+f, 0.0ef, 0.0e-f (exponent without digit after it).
753 return _make_token(TK_ERROR, "Invalid (float) numeric constant");
754 }
755 if (period_found) {
756 if (float_suffix_found) {
757 //checks for eg "1.f" or "1.99f" notations
758 if (last_char != 'f') {
759 return _make_token(TK_ERROR, "Invalid (float) numeric constant");
760 }
761 } else {
762 //checks for eg. "1." or "1.99" notations
763 if (last_char != '.' && !is_digit(last_char)) {
764 return _make_token(TK_ERROR, "Invalid (float) numeric constant");
765 }
766 }
767 } else if (float_suffix_found) {
768 // if no period found the float suffix must be the last character, like in "2f" for "2.0"
769 if (last_char != 'f') {
770 return _make_token(TK_ERROR, "Invalid (float) numeric constant");
771 }
772 }
773
774 if (float_suffix_found) {
775 // Strip the suffix.
776 str = str.left(str.length() - 1);
777 // Compensate reading cursor position.
778 char_idx += 1;
779 }
780
781 if (!str.is_valid_float()) {
782 return _make_token(TK_ERROR, "Invalid (float) numeric constant");
783 }
784 } else { // Integer
785 if (uint_suffix_found) {
786 // Strip the suffix.
787 str = str.left(str.length() - 1);
788 // Compensate reading cursor position.
789 char_idx += 1;
790 }
791 if (!str.is_valid_int()) {
792 if (uint_suffix_found) {
793 return _make_token(TK_ERROR, "Invalid (unsigned integer) numeric constant");
794 } else {
795 return _make_token(TK_ERROR, "Invalid (integer) numeric constant");
796 }
797 }
798 }
799
800 char_idx += str.length();
801 Token tk;
802 if (period_found || exponent_found || float_suffix_found) {
803 tk.type = TK_FLOAT_CONSTANT;
804 } else if (uint_suffix_found) {
805 tk.type = TK_UINT_CONSTANT;
806 } else {
807 tk.type = TK_INT_CONSTANT;
808 }
809
810 if (hexa_found) {
811 tk.constant = (double)str.hex_to_int();
812 } else {
813 tk.constant = str.to_float();
814 }
815 tk.line = tk_line;
816
817 return tk;
818 }
819
820 if (GETCHAR(0) == '.') {
821 //parse period
822 char_idx++;
823 return _make_token(TK_PERIOD);
824 }
825
826 if (is_ascii_identifier_char(GETCHAR(0))) {
827 // parse identifier
828 String str;
829
830 while (is_ascii_identifier_char(GETCHAR(0))) {
831 str += char32_t(GETCHAR(0));
832 char_idx++;
833 }
834
835 //see if keyword
836 //should be converted to a static map
837 int idx = 0;
838
839 while (keyword_list[idx].text) {
840 if (str == keyword_list[idx].text) {
841 return _make_token(keyword_list[idx].token);
842 }
843 idx++;
844 }
845
846 str = str.replace("dus_", "_");
847
848 return _make_token(TK_IDENTIFIER, str);
849 }
850
851 if (GETCHAR(0) > 32) {
852 return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)) + ": '" + String::chr(GETCHAR(0)) + "'");
853 } else {
854 return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)));
855 }
856
857 } break;
858 }
859 }
860 ERR_PRINT("BUG");
861 return Token();
862
863#undef GETCHAR
864}
865
866bool ShaderLanguage::_lookup_next(Token &r_tk) {
867 TkPos pre_pos = _get_tkpos();
868 int line = pre_pos.tk_line;
869 _get_token();
870 Token tk = _get_token();
871 _set_tkpos(pre_pos);
872 if (tk.line == line) {
873 r_tk = tk;
874 return true;
875 }
876 return false;
877}
878
879String ShaderLanguage::token_debug(const String &p_code) {
880 clear();
881
882 code = p_code;
883
884 String output;
885
886 Token tk = _get_token();
887 while (tk.type != TK_EOF && tk.type != TK_ERROR) {
888 output += itos(tk_line) + ": " + get_token_text(tk) + "\n";
889 tk = _get_token();
890 }
891
892 return output;
893}
894
895bool ShaderLanguage::is_token_variable_datatype(TokenType p_type) {
896 return (
897 p_type == TK_TYPE_VOID ||
898 p_type == TK_TYPE_BOOL ||
899 p_type == TK_TYPE_BVEC2 ||
900 p_type == TK_TYPE_BVEC3 ||
901 p_type == TK_TYPE_BVEC4 ||
902 p_type == TK_TYPE_INT ||
903 p_type == TK_TYPE_IVEC2 ||
904 p_type == TK_TYPE_IVEC3 ||
905 p_type == TK_TYPE_IVEC4 ||
906 p_type == TK_TYPE_UINT ||
907 p_type == TK_TYPE_UVEC2 ||
908 p_type == TK_TYPE_UVEC3 ||
909 p_type == TK_TYPE_UVEC4 ||
910 p_type == TK_TYPE_FLOAT ||
911 p_type == TK_TYPE_VEC2 ||
912 p_type == TK_TYPE_VEC3 ||
913 p_type == TK_TYPE_VEC4 ||
914 p_type == TK_TYPE_MAT2 ||
915 p_type == TK_TYPE_MAT3 ||
916 p_type == TK_TYPE_MAT4);
917}
918
919bool ShaderLanguage::is_token_datatype(TokenType p_type) {
920 return (
921 p_type == TK_TYPE_VOID ||
922 p_type == TK_TYPE_BOOL ||
923 p_type == TK_TYPE_BVEC2 ||
924 p_type == TK_TYPE_BVEC3 ||
925 p_type == TK_TYPE_BVEC4 ||
926 p_type == TK_TYPE_INT ||
927 p_type == TK_TYPE_IVEC2 ||
928 p_type == TK_TYPE_IVEC3 ||
929 p_type == TK_TYPE_IVEC4 ||
930 p_type == TK_TYPE_UINT ||
931 p_type == TK_TYPE_UVEC2 ||
932 p_type == TK_TYPE_UVEC3 ||
933 p_type == TK_TYPE_UVEC4 ||
934 p_type == TK_TYPE_FLOAT ||
935 p_type == TK_TYPE_VEC2 ||
936 p_type == TK_TYPE_VEC3 ||
937 p_type == TK_TYPE_VEC4 ||
938 p_type == TK_TYPE_MAT2 ||
939 p_type == TK_TYPE_MAT3 ||
940 p_type == TK_TYPE_MAT4 ||
941 p_type == TK_TYPE_SAMPLER2D ||
942 p_type == TK_TYPE_ISAMPLER2D ||
943 p_type == TK_TYPE_USAMPLER2D ||
944 p_type == TK_TYPE_SAMPLER2DARRAY ||
945 p_type == TK_TYPE_ISAMPLER2DARRAY ||
946 p_type == TK_TYPE_USAMPLER2DARRAY ||
947 p_type == TK_TYPE_SAMPLER3D ||
948 p_type == TK_TYPE_ISAMPLER3D ||
949 p_type == TK_TYPE_USAMPLER3D ||
950 p_type == TK_TYPE_SAMPLERCUBE ||
951 p_type == TK_TYPE_SAMPLERCUBEARRAY);
952}
953
954ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) {
955 return DataType(p_type - TK_TYPE_VOID);
956}
957
958bool ShaderLanguage::is_token_interpolation(TokenType p_type) {
959 return (
960 p_type == TK_INTERPOLATION_FLAT ||
961 p_type == TK_INTERPOLATION_SMOOTH);
962}
963
964ShaderLanguage::DataInterpolation ShaderLanguage::get_token_interpolation(TokenType p_type) {
965 if (p_type == TK_INTERPOLATION_FLAT) {
966 return INTERPOLATION_FLAT;
967 } else {
968 return INTERPOLATION_SMOOTH;
969 }
970}
971
972bool ShaderLanguage::is_token_precision(TokenType p_type) {
973 return (
974 p_type == TK_PRECISION_LOW ||
975 p_type == TK_PRECISION_MID ||
976 p_type == TK_PRECISION_HIGH);
977}
978
979bool ShaderLanguage::is_token_arg_qual(TokenType p_type) {
980 return (
981 p_type == TK_ARG_IN ||
982 p_type == TK_ARG_OUT ||
983 p_type == TK_ARG_INOUT);
984}
985
986ShaderLanguage::DataPrecision ShaderLanguage::get_token_precision(TokenType p_type) {
987 if (p_type == TK_PRECISION_LOW) {
988 return PRECISION_LOWP;
989 } else if (p_type == TK_PRECISION_HIGH) {
990 return PRECISION_HIGHP;
991 } else {
992 return PRECISION_MEDIUMP;
993 }
994}
995
996String ShaderLanguage::get_precision_name(DataPrecision p_type) {
997 switch (p_type) {
998 case PRECISION_LOWP:
999 return "lowp";
1000 case PRECISION_MEDIUMP:
1001 return "mediump";
1002 case PRECISION_HIGHP:
1003 return "highp";
1004 default:
1005 break;
1006 }
1007 return "";
1008}
1009
1010String ShaderLanguage::get_interpolation_name(DataInterpolation p_interpolation) {
1011 switch (p_interpolation) {
1012 case INTERPOLATION_FLAT:
1013 return "flat";
1014 case INTERPOLATION_SMOOTH:
1015 return "smooth";
1016 default:
1017 break;
1018 }
1019 return "";
1020}
1021
1022String ShaderLanguage::get_datatype_name(DataType p_type) {
1023 switch (p_type) {
1024 case TYPE_VOID:
1025 return "void";
1026 case TYPE_BOOL:
1027 return "bool";
1028 case TYPE_BVEC2:
1029 return "bvec2";
1030 case TYPE_BVEC3:
1031 return "bvec3";
1032 case TYPE_BVEC4:
1033 return "bvec4";
1034 case TYPE_INT:
1035 return "int";
1036 case TYPE_IVEC2:
1037 return "ivec2";
1038 case TYPE_IVEC3:
1039 return "ivec3";
1040 case TYPE_IVEC4:
1041 return "ivec4";
1042 case TYPE_UINT:
1043 return "uint";
1044 case TYPE_UVEC2:
1045 return "uvec2";
1046 case TYPE_UVEC3:
1047 return "uvec3";
1048 case TYPE_UVEC4:
1049 return "uvec4";
1050 case TYPE_FLOAT:
1051 return "float";
1052 case TYPE_VEC2:
1053 return "vec2";
1054 case TYPE_VEC3:
1055 return "vec3";
1056 case TYPE_VEC4:
1057 return "vec4";
1058 case TYPE_MAT2:
1059 return "mat2";
1060 case TYPE_MAT3:
1061 return "mat3";
1062 case TYPE_MAT4:
1063 return "mat4";
1064 case TYPE_SAMPLER2D:
1065 return "sampler2D";
1066 case TYPE_ISAMPLER2D:
1067 return "isampler2D";
1068 case TYPE_USAMPLER2D:
1069 return "usampler2D";
1070 case TYPE_SAMPLER2DARRAY:
1071 return "sampler2DArray";
1072 case TYPE_ISAMPLER2DARRAY:
1073 return "isampler2DArray";
1074 case TYPE_USAMPLER2DARRAY:
1075 return "usampler2DArray";
1076 case TYPE_SAMPLER3D:
1077 return "sampler3D";
1078 case TYPE_ISAMPLER3D:
1079 return "isampler3D";
1080 case TYPE_USAMPLER3D:
1081 return "usampler3D";
1082 case TYPE_SAMPLERCUBE:
1083 return "samplerCube";
1084 case TYPE_SAMPLERCUBEARRAY:
1085 return "samplerCubeArray";
1086 case TYPE_STRUCT:
1087 return "struct";
1088 case TYPE_MAX:
1089 return "invalid";
1090 }
1091
1092 return "";
1093}
1094
1095String ShaderLanguage::get_uniform_hint_name(ShaderNode::Uniform::Hint p_hint) {
1096 String result;
1097 switch (p_hint) {
1098 case ShaderNode::Uniform::HINT_RANGE: {
1099 result = "hint_range";
1100 } break;
1101 case ShaderNode::Uniform::HINT_SOURCE_COLOR: {
1102 result = "source_color";
1103 } break;
1104 case ShaderNode::Uniform::HINT_NORMAL: {
1105 result = "hint_normal";
1106 } break;
1107 case ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL: {
1108 result = "hint_roughness_normal";
1109 } break;
1110 case ShaderNode::Uniform::HINT_ROUGHNESS_R: {
1111 result = "hint_roughness_r";
1112 } break;
1113 case ShaderNode::Uniform::HINT_ROUGHNESS_G: {
1114 result = "hint_roughness_g";
1115 } break;
1116 case ShaderNode::Uniform::HINT_ROUGHNESS_B: {
1117 result = "hint_roughness_b";
1118 } break;
1119 case ShaderNode::Uniform::HINT_ROUGHNESS_A: {
1120 result = "hint_roughness_a";
1121 } break;
1122 case ShaderNode::Uniform::HINT_ROUGHNESS_GRAY: {
1123 result = "hint_roughness_gray";
1124 } break;
1125 case ShaderNode::Uniform::HINT_DEFAULT_BLACK: {
1126 result = "hint_default_black";
1127 } break;
1128 case ShaderNode::Uniform::HINT_DEFAULT_WHITE: {
1129 result = "hint_default_white";
1130 } break;
1131 case ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT: {
1132 result = "hint_default_transparent";
1133 } break;
1134 case ShaderNode::Uniform::HINT_ANISOTROPY: {
1135 result = "hint_anisotropy";
1136 } break;
1137 case ShaderNode::Uniform::HINT_SCREEN_TEXTURE: {
1138 result = "hint_screen_texture";
1139 } break;
1140 case ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE: {
1141 result = "hint_normal_roughness_texture";
1142 } break;
1143 case ShaderNode::Uniform::HINT_DEPTH_TEXTURE: {
1144 result = "hint_depth_texture";
1145 } break;
1146 default:
1147 break;
1148 }
1149 return result;
1150}
1151
1152String ShaderLanguage::get_texture_filter_name(TextureFilter p_filter) {
1153 String result;
1154 switch (p_filter) {
1155 case FILTER_NEAREST: {
1156 result = "filter_nearest";
1157 } break;
1158 case FILTER_LINEAR: {
1159 result = "filter_linear";
1160 } break;
1161 case FILTER_NEAREST_MIPMAP: {
1162 result = "filter_nearest_mipmap";
1163 } break;
1164 case FILTER_LINEAR_MIPMAP: {
1165 result = "filter_linear_mipmap";
1166 } break;
1167 case FILTER_NEAREST_MIPMAP_ANISOTROPIC: {
1168 result = "filter_nearest_mipmap_anisotropic";
1169 } break;
1170 case FILTER_LINEAR_MIPMAP_ANISOTROPIC: {
1171 result = "filter_linear_mipmap_anisotropic";
1172 } break;
1173 default: {
1174 } break;
1175 }
1176 return result;
1177}
1178
1179String ShaderLanguage::get_texture_repeat_name(TextureRepeat p_repeat) {
1180 String result;
1181 switch (p_repeat) {
1182 case REPEAT_DISABLE: {
1183 result = "repeat_disable";
1184 } break;
1185 case REPEAT_ENABLE: {
1186 result = "repeat_enable";
1187 } break;
1188 default: {
1189 } break;
1190 }
1191 return result;
1192}
1193
1194bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) {
1195 return is_token_datatype(p_type) && p_type != TK_TYPE_VOID;
1196}
1197
1198void ShaderLanguage::clear() {
1199 current_function = StringName();
1200 last_name = StringName();
1201 last_type = IDENTIFIER_MAX;
1202 current_uniform_group_name = "";
1203 current_uniform_subgroup_name = "";
1204 current_uniform_hint = ShaderNode::Uniform::HINT_NONE;
1205 current_uniform_filter = FILTER_DEFAULT;
1206 current_uniform_repeat = REPEAT_DEFAULT;
1207 current_uniform_instance_index_defined = false;
1208
1209 completion_type = COMPLETION_NONE;
1210 completion_block = nullptr;
1211 completion_function = StringName();
1212 completion_class = TAG_GLOBAL;
1213 completion_struct = StringName();
1214 completion_base = TYPE_VOID;
1215 completion_base_array = false;
1216
1217 include_positions.clear();
1218 include_positions.push_back(FilePosition());
1219
1220#ifdef DEBUG_ENABLED
1221 keyword_completion_context = CF_UNSPECIFIED;
1222 used_constants.clear();
1223 used_varyings.clear();
1224 used_uniforms.clear();
1225 used_functions.clear();
1226 used_structs.clear();
1227 used_local_vars.clear();
1228 warnings.clear();
1229#endif // DEBUG_ENABLED
1230
1231 error_line = 0;
1232 tk_line = 1;
1233 char_idx = 0;
1234 error_set = false;
1235 error_str = "";
1236 is_const_decl = false;
1237 while (nodes) {
1238 Node *n = nodes;
1239 nodes = nodes->next;
1240 memdelete(n);
1241 }
1242}
1243
1244#ifdef DEBUG_ENABLED
1245void ShaderLanguage::_parse_used_identifier(const StringName &p_identifier, IdentifierType p_type, const StringName &p_function) {
1246 switch (p_type) {
1247 case IdentifierType::IDENTIFIER_CONSTANT:
1248 if (HAS_WARNING(ShaderWarning::UNUSED_CONSTANT_FLAG) && used_constants.has(p_identifier)) {
1249 used_constants[p_identifier].used = true;
1250 }
1251 break;
1252 case IdentifierType::IDENTIFIER_VARYING:
1253 if (HAS_WARNING(ShaderWarning::UNUSED_VARYING_FLAG) && used_varyings.has(p_identifier)) {
1254 if (shader->varyings[p_identifier].stage != ShaderNode::Varying::STAGE_VERTEX && shader->varyings[p_identifier].stage != ShaderNode::Varying::STAGE_FRAGMENT) {
1255 used_varyings[p_identifier].used = true;
1256 }
1257 }
1258 break;
1259 case IdentifierType::IDENTIFIER_UNIFORM:
1260 if (HAS_WARNING(ShaderWarning::UNUSED_UNIFORM_FLAG) && used_uniforms.has(p_identifier)) {
1261 used_uniforms[p_identifier].used = true;
1262 }
1263 break;
1264 case IdentifierType::IDENTIFIER_FUNCTION:
1265 if (HAS_WARNING(ShaderWarning::UNUSED_FUNCTION_FLAG) && used_functions.has(p_identifier)) {
1266 used_functions[p_identifier].used = true;
1267 }
1268 break;
1269 case IdentifierType::IDENTIFIER_LOCAL_VAR:
1270 if (HAS_WARNING(ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG) && used_local_vars.has(p_function) && used_local_vars[p_function].has(p_identifier)) {
1271 used_local_vars[p_function][p_identifier].used = true;
1272 }
1273 break;
1274 default:
1275 break;
1276 }
1277}
1278#endif // DEBUG_ENABLED
1279
1280bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const FunctionInfo &p_function_info, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name, ConstantNode::Value *r_constant_value) {
1281 if (is_shader_inc) {
1282 for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
1283 for (const KeyValue<StringName, FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i))) {
1284 if ((current_function == E.key || E.key == "global" || E.key == "constants") && E.value.built_ins.has(p_identifier)) {
1285 if (r_data_type) {
1286 *r_data_type = E.value.built_ins[p_identifier].type;
1287 }
1288 if (r_is_const) {
1289 *r_is_const = E.value.built_ins[p_identifier].constant;
1290 }
1291 if (r_type) {
1292 *r_type = IDENTIFIER_BUILTIN_VAR;
1293 }
1294 return true;
1295 }
1296 }
1297 }
1298 } else {
1299 if (p_function_info.built_ins.has(p_identifier)) {
1300 if (r_data_type) {
1301 *r_data_type = p_function_info.built_ins[p_identifier].type;
1302 }
1303 if (r_is_const) {
1304 *r_is_const = p_function_info.built_ins[p_identifier].constant;
1305 }
1306 if (r_type) {
1307 *r_type = IDENTIFIER_BUILTIN_VAR;
1308 }
1309 return true;
1310 }
1311 }
1312
1313 if (p_function_info.stage_functions.has(p_identifier)) {
1314 if (r_data_type) {
1315 *r_data_type = p_function_info.stage_functions[p_identifier].return_type;
1316 }
1317 if (r_is_const) {
1318 *r_is_const = true;
1319 }
1320 if (r_type) {
1321 *r_type = IDENTIFIER_FUNCTION;
1322 }
1323 return true;
1324 }
1325
1326 FunctionNode *function = nullptr;
1327
1328 while (p_block) {
1329 if (p_block->variables.has(p_identifier)) {
1330 if (r_data_type) {
1331 *r_data_type = p_block->variables[p_identifier].type;
1332 }
1333 if (r_is_const) {
1334 *r_is_const = p_block->variables[p_identifier].is_const;
1335 }
1336 if (r_array_size) {
1337 *r_array_size = p_block->variables[p_identifier].array_size;
1338 }
1339 if (r_struct_name) {
1340 *r_struct_name = p_block->variables[p_identifier].struct_name;
1341 }
1342 if (r_constant_value) {
1343 *r_constant_value = p_block->variables[p_identifier].value;
1344 }
1345 if (r_type) {
1346 *r_type = IDENTIFIER_LOCAL_VAR;
1347 }
1348 return true;
1349 }
1350
1351 if (p_block->parent_function) {
1352 function = p_block->parent_function;
1353 break;
1354 } else {
1355 if (p_allow_reassign) {
1356 break;
1357 }
1358 ERR_FAIL_COND_V(!p_block->parent_block, false);
1359 p_block = p_block->parent_block;
1360 }
1361 }
1362
1363 if (function) {
1364 for (int i = 0; i < function->arguments.size(); i++) {
1365 if (function->arguments[i].name == p_identifier) {
1366 if (r_data_type) {
1367 *r_data_type = function->arguments[i].type;
1368 }
1369 if (r_struct_name) {
1370 *r_struct_name = function->arguments[i].type_str;
1371 }
1372 if (r_array_size) {
1373 *r_array_size = function->arguments[i].array_size;
1374 }
1375 if (r_is_const) {
1376 *r_is_const = function->arguments[i].is_const;
1377 }
1378 if (r_type) {
1379 *r_type = IDENTIFIER_FUNCTION_ARGUMENT;
1380 }
1381 return true;
1382 }
1383 }
1384 }
1385
1386 if (shader->varyings.has(p_identifier)) {
1387 if (r_data_type) {
1388 *r_data_type = shader->varyings[p_identifier].type;
1389 }
1390 if (r_array_size) {
1391 *r_array_size = shader->varyings[p_identifier].array_size;
1392 }
1393 if (r_type) {
1394 *r_type = IDENTIFIER_VARYING;
1395 }
1396 return true;
1397 }
1398
1399 if (shader->uniforms.has(p_identifier)) {
1400 if (r_data_type) {
1401 *r_data_type = shader->uniforms[p_identifier].type;
1402 }
1403 if (r_array_size) {
1404 *r_array_size = shader->uniforms[p_identifier].array_size;
1405 }
1406 if (r_type) {
1407 *r_type = IDENTIFIER_UNIFORM;
1408 }
1409 return true;
1410 }
1411
1412 if (shader->constants.has(p_identifier)) {
1413 if (r_is_const) {
1414 *r_is_const = true;
1415 }
1416 if (r_data_type) {
1417 *r_data_type = shader->constants[p_identifier].type;
1418 }
1419 if (r_array_size) {
1420 *r_array_size = shader->constants[p_identifier].array_size;
1421 }
1422 if (r_struct_name) {
1423 *r_struct_name = shader->constants[p_identifier].type_str;
1424 }
1425 if (r_constant_value) {
1426 if (shader->constants[p_identifier].initializer && shader->constants[p_identifier].initializer->values.size() == 1) {
1427 *r_constant_value = shader->constants[p_identifier].initializer->values[0];
1428 }
1429 }
1430 if (r_type) {
1431 *r_type = IDENTIFIER_CONSTANT;
1432 }
1433 return true;
1434 }
1435
1436 for (int i = 0; i < shader->functions.size(); i++) {
1437 if (!shader->functions[i].callable) {
1438 continue;
1439 }
1440
1441 if (shader->functions[i].name == p_identifier) {
1442 if (r_data_type) {
1443 *r_data_type = shader->functions[i].function->return_type;
1444 }
1445 if (r_array_size) {
1446 *r_array_size = shader->functions[i].function->return_array_size;
1447 }
1448 if (r_type) {
1449 *r_type = IDENTIFIER_FUNCTION;
1450 }
1451 return true;
1452 }
1453 }
1454
1455 return false;
1456}
1457
1458bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type, int *r_ret_size) {
1459 bool valid = false;
1460 DataType ret_type = TYPE_VOID;
1461 int ret_size = 0;
1462
1463 switch (p_op->op) {
1464 case OP_EQUAL:
1465 case OP_NOT_EQUAL: {
1466 if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) {
1467 break; // don't accept arrays
1468 }
1469
1470 DataType na = p_op->arguments[0]->get_datatype();
1471 DataType nb = p_op->arguments[1]->get_datatype();
1472 valid = na == nb;
1473 ret_type = TYPE_BOOL;
1474 } break;
1475 case OP_LESS:
1476 case OP_LESS_EQUAL:
1477 case OP_GREATER:
1478 case OP_GREATER_EQUAL: {
1479 if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) {
1480 break; // don't accept arrays
1481 }
1482
1483 DataType na = p_op->arguments[0]->get_datatype();
1484 DataType nb = p_op->arguments[1]->get_datatype();
1485
1486 valid = na == nb && (na == TYPE_UINT || na == TYPE_INT || na == TYPE_FLOAT);
1487 ret_type = TYPE_BOOL;
1488
1489 } break;
1490 case OP_AND:
1491 case OP_OR: {
1492 if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) {
1493 break; // don't accept arrays
1494 }
1495
1496 DataType na = p_op->arguments[0]->get_datatype();
1497 DataType nb = p_op->arguments[1]->get_datatype();
1498
1499 valid = na == nb && na == TYPE_BOOL;
1500 ret_type = TYPE_BOOL;
1501
1502 } break;
1503 case OP_NOT: {
1504 if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) {
1505 break; // don't accept arrays
1506 }
1507
1508 DataType na = p_op->arguments[0]->get_datatype();
1509 valid = na == TYPE_BOOL;
1510 ret_type = TYPE_BOOL;
1511
1512 } break;
1513 case OP_INCREMENT:
1514 case OP_DECREMENT:
1515 case OP_POST_INCREMENT:
1516 case OP_POST_DECREMENT:
1517 case OP_NEGATE: {
1518 if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) {
1519 break; // don't accept arrays
1520 }
1521
1522 DataType na = p_op->arguments[0]->get_datatype();
1523 valid = na > TYPE_BOOL && na < TYPE_MAT2;
1524 ret_type = na;
1525 } break;
1526 case OP_ADD:
1527 case OP_SUB:
1528 case OP_MUL:
1529 case OP_DIV: {
1530 if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) {
1531 break; // don't accept arrays
1532 }
1533
1534 DataType na = p_op->arguments[0]->get_datatype();
1535 DataType nb = p_op->arguments[1]->get_datatype();
1536
1537 if (na > nb) {
1538 //make things easier;
1539 SWAP(na, nb);
1540 }
1541
1542 if (na == nb) {
1543 valid = (na > TYPE_BOOL && na <= TYPE_MAT4);
1544 ret_type = na;
1545 } else if (na == TYPE_INT && nb == TYPE_IVEC2) {
1546 valid = true;
1547 ret_type = TYPE_IVEC2;
1548 } else if (na == TYPE_INT && nb == TYPE_IVEC3) {
1549 valid = true;
1550 ret_type = TYPE_IVEC3;
1551 } else if (na == TYPE_INT && nb == TYPE_IVEC4) {
1552 valid = true;
1553 ret_type = TYPE_IVEC4;
1554 } else if (na == TYPE_UINT && nb == TYPE_UVEC2) {
1555 valid = true;
1556 ret_type = TYPE_UVEC2;
1557 } else if (na == TYPE_UINT && nb == TYPE_UVEC3) {
1558 valid = true;
1559 ret_type = TYPE_UVEC3;
1560 } else if (na == TYPE_UINT && nb == TYPE_UVEC4) {
1561 valid = true;
1562 ret_type = TYPE_UVEC4;
1563 } else if (na == TYPE_FLOAT && nb == TYPE_VEC2) {
1564 valid = true;
1565 ret_type = TYPE_VEC2;
1566 } else if (na == TYPE_FLOAT && nb == TYPE_VEC3) {
1567 valid = true;
1568 ret_type = TYPE_VEC3;
1569 } else if (na == TYPE_FLOAT && nb == TYPE_VEC4) {
1570 valid = true;
1571 ret_type = TYPE_VEC4;
1572 } else if (na == TYPE_FLOAT && nb == TYPE_MAT2) {
1573 valid = true;
1574 ret_type = TYPE_MAT2;
1575 } else if (na == TYPE_FLOAT && nb == TYPE_MAT3) {
1576 valid = true;
1577 ret_type = TYPE_MAT3;
1578 } else if (na == TYPE_FLOAT && nb == TYPE_MAT4) {
1579 valid = true;
1580 ret_type = TYPE_MAT4;
1581 } else if (p_op->op == OP_MUL && na == TYPE_VEC2 && nb == TYPE_MAT2) {
1582 valid = true;
1583 ret_type = TYPE_VEC2;
1584 } else if (p_op->op == OP_MUL && na == TYPE_VEC3 && nb == TYPE_MAT3) {
1585 valid = true;
1586 ret_type = TYPE_VEC3;
1587 } else if (p_op->op == OP_MUL && na == TYPE_VEC4 && nb == TYPE_MAT4) {
1588 valid = true;
1589 ret_type = TYPE_VEC4;
1590 }
1591 } break;
1592 case OP_ASSIGN_MOD:
1593 case OP_MOD: {
1594 /*
1595 * The operator modulus (%) operates on signed or unsigned integers or integer vectors. The operand
1596 * types must both be signed or both be unsigned. The operands cannot be vectors of differing size. If
1597 * one operand is a scalar and the other vector, then the scalar is applied component-wise to the vector,
1598 * resulting in the same type as the vector. If both are vectors of the same size, the result is computed
1599 * component-wise.
1600 */
1601
1602 if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) {
1603 break; // don't accept arrays
1604 }
1605
1606 DataType na = p_op->arguments[0]->get_datatype();
1607 DataType nb = p_op->arguments[1]->get_datatype();
1608
1609 if (na == TYPE_INT && nb == TYPE_INT) {
1610 valid = true;
1611 ret_type = TYPE_INT;
1612 } else if (na == TYPE_IVEC2 && nb == TYPE_INT) {
1613 valid = true;
1614 ret_type = TYPE_IVEC2;
1615 } else if (na == TYPE_IVEC3 && nb == TYPE_INT) {
1616 valid = true;
1617 ret_type = TYPE_IVEC3;
1618 } else if (na == TYPE_IVEC4 && nb == TYPE_INT) {
1619 valid = true;
1620 ret_type = TYPE_IVEC4;
1621 } else if (na == TYPE_IVEC2 && nb == TYPE_IVEC2) {
1622 valid = true;
1623 ret_type = TYPE_IVEC2;
1624 } else if (na == TYPE_IVEC3 && nb == TYPE_IVEC3) {
1625 valid = true;
1626 ret_type = TYPE_IVEC3;
1627 } else if (na == TYPE_IVEC4 && nb == TYPE_IVEC4) {
1628 valid = true;
1629 ret_type = TYPE_IVEC4;
1630 /////
1631 } else if (na == TYPE_UINT && nb == TYPE_UINT) {
1632 valid = true;
1633 ret_type = TYPE_UINT;
1634 } else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
1635 valid = true;
1636 ret_type = TYPE_UVEC2;
1637 } else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
1638 valid = true;
1639 ret_type = TYPE_UVEC3;
1640 } else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
1641 valid = true;
1642 ret_type = TYPE_UVEC4;
1643 } else if (na == TYPE_UVEC2 && nb == TYPE_UVEC2) {
1644 valid = true;
1645 ret_type = TYPE_UVEC2;
1646 } else if (na == TYPE_UVEC3 && nb == TYPE_UVEC3) {
1647 valid = true;
1648 ret_type = TYPE_UVEC3;
1649 } else if (na == TYPE_UVEC4 && nb == TYPE_UVEC4) {
1650 valid = true;
1651 ret_type = TYPE_UVEC4;
1652 }
1653 } break;
1654 case OP_ASSIGN_SHIFT_LEFT:
1655 case OP_ASSIGN_SHIFT_RIGHT:
1656 case OP_SHIFT_LEFT:
1657 case OP_SHIFT_RIGHT: {
1658 if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) {
1659 break; // don't accept arrays
1660 }
1661
1662 DataType na = p_op->arguments[0]->get_datatype();
1663 DataType nb = p_op->arguments[1]->get_datatype();
1664
1665 if (na == TYPE_INT && nb == TYPE_INT) {
1666 valid = true;
1667 ret_type = TYPE_INT;
1668 } else if (na == TYPE_IVEC2 && nb == TYPE_INT) {
1669 valid = true;
1670 ret_type = TYPE_IVEC2;
1671 } else if (na == TYPE_IVEC3 && nb == TYPE_INT) {
1672 valid = true;
1673 ret_type = TYPE_IVEC3;
1674 } else if (na == TYPE_IVEC4 && nb == TYPE_INT) {
1675 valid = true;
1676 ret_type = TYPE_IVEC4;
1677 } else if (na == TYPE_IVEC2 && nb == TYPE_IVEC2) {
1678 valid = true;
1679 ret_type = TYPE_IVEC2;
1680 } else if (na == TYPE_IVEC3 && nb == TYPE_IVEC3) {
1681 valid = true;
1682 ret_type = TYPE_IVEC3;
1683 } else if (na == TYPE_IVEC4 && nb == TYPE_IVEC4) {
1684 valid = true;
1685 ret_type = TYPE_IVEC4;
1686 } else if (na == TYPE_UINT && nb == TYPE_UINT) {
1687 valid = true;
1688 ret_type = TYPE_UINT;
1689 } else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
1690 valid = true;
1691 ret_type = TYPE_UVEC2;
1692 } else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
1693 valid = true;
1694 ret_type = TYPE_UVEC3;
1695 } else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
1696 valid = true;
1697 ret_type = TYPE_UVEC4;
1698 } else if (na == TYPE_UVEC2 && nb == TYPE_UVEC2) {
1699 valid = true;
1700 ret_type = TYPE_UVEC2;
1701 } else if (na == TYPE_UVEC3 && nb == TYPE_UVEC3) {
1702 valid = true;
1703 ret_type = TYPE_UVEC3;
1704 } else if (na == TYPE_UVEC4 && nb == TYPE_UVEC4) {
1705 valid = true;
1706 ret_type = TYPE_UVEC4;
1707 }
1708 } break;
1709 case OP_ASSIGN: {
1710 int sa = 0;
1711 int sb = 0;
1712 if (!p_op->arguments[0]->is_indexed()) {
1713 sa = p_op->arguments[0]->get_array_size();
1714 }
1715 if (!p_op->arguments[1]->is_indexed()) {
1716 sb = p_op->arguments[1]->get_array_size();
1717 }
1718 if (sa != sb) {
1719 break; // don't accept arrays if their sizes are not equal
1720 }
1721
1722 DataType na = p_op->arguments[0]->get_datatype();
1723 DataType nb = p_op->arguments[1]->get_datatype();
1724 if (na == TYPE_STRUCT || nb == TYPE_STRUCT) {
1725 valid = p_op->arguments[0]->get_datatype_name() == p_op->arguments[1]->get_datatype_name();
1726 } else {
1727 valid = na == nb;
1728 }
1729 ret_type = na;
1730 ret_size = sa;
1731 } break;
1732 case OP_ASSIGN_ADD:
1733 case OP_ASSIGN_SUB:
1734 case OP_ASSIGN_MUL:
1735 case OP_ASSIGN_DIV: {
1736 int sa = 0;
1737 int sb = 0;
1738 if (!p_op->arguments[0]->is_indexed()) {
1739 sa = p_op->arguments[0]->get_array_size();
1740 }
1741 if (!p_op->arguments[1]->is_indexed()) {
1742 sb = p_op->arguments[1]->get_array_size();
1743 }
1744 if (sa > 0 || sb > 0) {
1745 break; // don't accept arrays
1746 }
1747
1748 DataType na = p_op->arguments[0]->get_datatype();
1749 DataType nb = p_op->arguments[1]->get_datatype();
1750
1751 if (na == nb) {
1752 valid = (na > TYPE_BOOL && na <= TYPE_MAT4);
1753 ret_type = na;
1754 } else if (na == TYPE_IVEC2 && nb == TYPE_INT) {
1755 valid = true;
1756 ret_type = TYPE_IVEC2;
1757 } else if (na == TYPE_IVEC3 && nb == TYPE_INT) {
1758 valid = true;
1759 ret_type = TYPE_IVEC3;
1760 } else if (na == TYPE_IVEC4 && nb == TYPE_INT) {
1761 valid = true;
1762 ret_type = TYPE_IVEC4;
1763 } else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
1764 valid = true;
1765 ret_type = TYPE_UVEC2;
1766 } else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
1767 valid = true;
1768 ret_type = TYPE_UVEC3;
1769 } else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
1770 valid = true;
1771 ret_type = TYPE_UVEC4;
1772 } else if (na == TYPE_VEC2 && nb == TYPE_FLOAT) {
1773 valid = true;
1774 ret_type = TYPE_VEC2;
1775 } else if (na == TYPE_VEC3 && nb == TYPE_FLOAT) {
1776 valid = true;
1777 ret_type = TYPE_VEC3;
1778 } else if (na == TYPE_VEC4 && nb == TYPE_FLOAT) {
1779 valid = true;
1780 ret_type = TYPE_VEC4;
1781 } else if (na == TYPE_MAT2 && nb == TYPE_FLOAT) {
1782 valid = true;
1783 ret_type = TYPE_MAT2;
1784 } else if (na == TYPE_MAT3 && nb == TYPE_FLOAT) {
1785 valid = true;
1786 ret_type = TYPE_MAT3;
1787 } else if (na == TYPE_MAT4 && nb == TYPE_FLOAT) {
1788 valid = true;
1789 ret_type = TYPE_MAT4;
1790 } else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_VEC2 && nb == TYPE_MAT2) {
1791 valid = true;
1792 ret_type = TYPE_VEC2;
1793 } else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_VEC3 && nb == TYPE_MAT3) {
1794 valid = true;
1795 ret_type = TYPE_VEC3;
1796 } else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_VEC4 && nb == TYPE_MAT4) {
1797 valid = true;
1798 ret_type = TYPE_VEC4;
1799 }
1800 } break;
1801 case OP_ASSIGN_BIT_AND:
1802 case OP_ASSIGN_BIT_OR:
1803 case OP_ASSIGN_BIT_XOR:
1804 case OP_BIT_AND:
1805 case OP_BIT_OR:
1806 case OP_BIT_XOR: {
1807 /*
1808 * The bitwise operators and (&), exclusive-or (^), and inclusive-or (|). The operands must be of type
1809 * signed or unsigned integers or integer vectors. The operands cannot be vectors of differing size. If
1810 * one operand is a scalar and the other a vector, the scalar is applied component-wise to the vector,
1811 * resulting in the same type as the vector. The fundamental types of the operands (signed or unsigned)
1812 * must match.
1813 */
1814
1815 int sa = 0;
1816 int sb = 0;
1817 if (!p_op->arguments[0]->is_indexed()) {
1818 sa = p_op->arguments[0]->get_array_size();
1819 }
1820 if (!p_op->arguments[1]->is_indexed()) {
1821 sb = p_op->arguments[1]->get_array_size();
1822 }
1823 if (sa > 0 || sb > 0) {
1824 break; // don't accept arrays
1825 }
1826
1827 DataType na = p_op->arguments[0]->get_datatype();
1828 DataType nb = p_op->arguments[1]->get_datatype();
1829
1830 if (na > nb && p_op->op >= OP_BIT_AND) {
1831 //can swap for non assign
1832 SWAP(na, nb);
1833 }
1834
1835 if (na == TYPE_INT && nb == TYPE_INT) {
1836 valid = true;
1837 ret_type = TYPE_INT;
1838 } else if (na == TYPE_IVEC2 && nb == TYPE_INT) {
1839 valid = true;
1840 ret_type = TYPE_IVEC2;
1841 } else if (na == TYPE_IVEC3 && nb == TYPE_INT) {
1842 valid = true;
1843 ret_type = TYPE_IVEC3;
1844 } else if (na == TYPE_IVEC4 && nb == TYPE_INT) {
1845 valid = true;
1846 ret_type = TYPE_IVEC4;
1847 } else if (na == TYPE_IVEC2 && nb == TYPE_IVEC2) {
1848 valid = true;
1849 ret_type = TYPE_IVEC2;
1850 } else if (na == TYPE_IVEC3 && nb == TYPE_IVEC3) {
1851 valid = true;
1852 ret_type = TYPE_IVEC3;
1853 } else if (na == TYPE_IVEC4 && nb == TYPE_IVEC4) {
1854 valid = true;
1855 ret_type = TYPE_IVEC4;
1856 /////
1857 } else if (na == TYPE_UINT && nb == TYPE_UINT) {
1858 valid = true;
1859 ret_type = TYPE_UINT;
1860 } else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
1861 valid = true;
1862 ret_type = TYPE_UVEC2;
1863 } else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
1864 valid = true;
1865 ret_type = TYPE_UVEC3;
1866 } else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
1867 valid = true;
1868 ret_type = TYPE_UVEC4;
1869 } else if (na == TYPE_UVEC2 && nb == TYPE_UVEC2) {
1870 valid = true;
1871 ret_type = TYPE_UVEC2;
1872 } else if (na == TYPE_UVEC3 && nb == TYPE_UVEC3) {
1873 valid = true;
1874 ret_type = TYPE_UVEC3;
1875 } else if (na == TYPE_UVEC4 && nb == TYPE_UVEC4) {
1876 valid = true;
1877 ret_type = TYPE_UVEC4;
1878 }
1879 } break;
1880 case OP_BIT_INVERT: { //unaries
1881 if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) {
1882 break; // don't accept arrays
1883 }
1884
1885 DataType na = p_op->arguments[0]->get_datatype();
1886 valid = na >= TYPE_INT && na < TYPE_FLOAT;
1887 ret_type = na;
1888 } break;
1889 case OP_SELECT_IF: {
1890 int sa = 0;
1891 int sb = 0;
1892 if (!p_op->arguments[1]->is_indexed()) {
1893 sa = p_op->arguments[1]->get_array_size();
1894 }
1895 if (!p_op->arguments[2]->is_indexed()) {
1896 sb = p_op->arguments[2]->get_array_size();
1897 }
1898 if (sa != sb) {
1899 break; // don't accept arrays if their sizes are not equal
1900 }
1901
1902 DataType na = p_op->arguments[0]->get_datatype();
1903 DataType nb = p_op->arguments[1]->get_datatype();
1904 DataType nc = p_op->arguments[2]->get_datatype();
1905
1906 valid = na == TYPE_BOOL && (nb == nc);
1907 ret_type = nb;
1908 ret_size = sa;
1909 } break;
1910 default: {
1911 ERR_FAIL_V(false);
1912 }
1913 }
1914
1915 if (r_ret_type) {
1916 *r_ret_type = ret_type;
1917 }
1918 if (r_ret_size) {
1919 *r_ret_size = ret_size;
1920 }
1921 return valid;
1922}
1923
1924const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
1925 // Constructors.
1926
1927 { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1928 { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1929 { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1930 { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1931 { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1932 { "bvec3", TYPE_BVEC3, { TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1933 { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1934 { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1935 { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1936 { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1937 { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1938 { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1939 { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1940 { "bvec4", TYPE_BVEC4, { TYPE_BVEC3, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1941 { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1942
1943 { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1944 { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1945 { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1946 { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1947 { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1948 { "vec3", TYPE_VEC3, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1949 { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1950 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1951 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1952 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1953 { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1954 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1955 { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1956 { "vec4", TYPE_VEC4, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1957 { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1958
1959 { "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1960 { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1961 { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1962 { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1963 { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1964 { "ivec3", TYPE_IVEC3, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1965 { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1966 { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1967 { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1968 { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1969 { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1970 { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1971 { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1972 { "ivec4", TYPE_IVEC4, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1973 { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1974
1975 { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1976 { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1977 { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1978 { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1979 { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1980 { "uvec3", TYPE_UVEC3, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1981 { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1982 { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1983 { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1984 { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1985 { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1986 { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1987 { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1988 { "uvec4", TYPE_UVEC4, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1989 { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1990
1991 { "mat2", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1992 { "mat3", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1993 { "mat4", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1994
1995 { "mat2", TYPE_MAT2, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1996 { "mat3", TYPE_MAT3, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1997 { "mat4", TYPE_MAT4, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
1998
1999 // Conversion scalars.
2000
2001 { "int", TYPE_INT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2002 { "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2003 { "int", TYPE_INT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2004 { "int", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2005
2006 { "float", TYPE_FLOAT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2007 { "float", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2008 { "float", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2009 { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2010
2011 { "uint", TYPE_UINT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2012 { "uint", TYPE_UINT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2013 { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2014 { "uint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2015
2016 { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2017 { "bool", TYPE_BOOL, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2018 { "bool", TYPE_BOOL, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2019 { "bool", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2020
2021 // Conversion vectors.
2022
2023 { "ivec2", TYPE_IVEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2024 { "ivec2", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2025 { "ivec2", TYPE_IVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2026 { "ivec2", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2027
2028 { "vec2", TYPE_VEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2029 { "vec2", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2030 { "vec2", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2031 { "vec2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2032
2033 { "uvec2", TYPE_UVEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2034 { "uvec2", TYPE_UVEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2035 { "uvec2", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2036 { "uvec2", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2037
2038 { "bvec2", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2039 { "bvec2", TYPE_BVEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2040 { "bvec2", TYPE_BVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2041 { "bvec2", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2042
2043 { "ivec3", TYPE_IVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2044 { "ivec3", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2045 { "ivec3", TYPE_IVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2046 { "ivec3", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2047
2048 { "vec3", TYPE_VEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2049 { "vec3", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2050 { "vec3", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2051 { "vec3", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2052
2053 { "uvec3", TYPE_UVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2054 { "uvec3", TYPE_UVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2055 { "uvec3", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2056 { "uvec3", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2057
2058 { "bvec3", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2059 { "bvec3", TYPE_BVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2060 { "bvec3", TYPE_BVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2061 { "bvec3", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2062
2063 { "ivec4", TYPE_IVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2064 { "ivec4", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2065 { "ivec4", TYPE_IVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2066 { "ivec4", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2067
2068 { "vec4", TYPE_VEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2069 { "vec4", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2070 { "vec4", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2071 { "vec4", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2072
2073 { "uvec4", TYPE_UVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2074 { "uvec4", TYPE_UVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2075 { "uvec4", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2076 { "uvec4", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2077
2078 { "bvec4", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2079 { "bvec4", TYPE_BVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2080 { "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2081 { "bvec4", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2082
2083 // Conversion between matrixes.
2084
2085 { "mat2", TYPE_MAT2, { TYPE_MAT3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2086 { "mat2", TYPE_MAT2, { TYPE_MAT4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2087 { "mat3", TYPE_MAT3, { TYPE_MAT2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2088 { "mat3", TYPE_MAT3, { TYPE_MAT4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2089 { "mat4", TYPE_MAT4, { TYPE_MAT2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2090 { "mat4", TYPE_MAT4, { TYPE_MAT3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2091
2092 // Built-ins - trigonometric functions.
2093 // radians
2094
2095 { "radians", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "degrees" }, TAG_GLOBAL, false },
2096 { "radians", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "degrees" }, TAG_GLOBAL, false },
2097 { "radians", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "degrees" }, TAG_GLOBAL, false },
2098 { "radians", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "degrees" }, TAG_GLOBAL, false },
2099
2100 // degrees
2101
2102 { "degrees", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "radians" }, TAG_GLOBAL, false },
2103 { "degrees", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "radians" }, TAG_GLOBAL, false },
2104 { "degrees", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "radians" }, TAG_GLOBAL, false },
2105 { "degrees", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "radians" }, TAG_GLOBAL, false },
2106
2107 // sin
2108
2109 { "sin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2110 { "sin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2111 { "sin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2112 { "sin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2113
2114 // cos
2115
2116 { "cos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2117 { "cos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2118 { "cos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2119 { "cos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2120
2121 // tan
2122
2123 { "tan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2124 { "tan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2125 { "tan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2126 { "tan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2127
2128 // asin
2129
2130 { "asin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2131 { "asin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2132 { "asin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2133 { "asin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2134
2135 // acos
2136
2137 { "acos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2138 { "acos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2139 { "acos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2140 { "acos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2141
2142 // atan
2143
2144 { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "y_over_x" }, TAG_GLOBAL, false },
2145 { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "y_over_x" }, TAG_GLOBAL, false },
2146 { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "y_over_x" }, TAG_GLOBAL, false },
2147 { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "y_over_x" }, TAG_GLOBAL, false },
2148 { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "y", "x" }, TAG_GLOBAL, false },
2149 { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "y", "x" }, TAG_GLOBAL, false },
2150 { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "y", "x" }, TAG_GLOBAL, false },
2151 { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "y", "x" }, TAG_GLOBAL, false },
2152
2153 // sinh
2154
2155 { "sinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2156 { "sinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2157 { "sinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2158 { "sinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2159
2160 // cosh
2161
2162 { "cosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2163 { "cosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2164 { "cosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2165 { "cosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2166
2167 // tanh
2168
2169 { "tanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2170 { "tanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2171 { "tanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2172 { "tanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2173
2174 // asinh
2175
2176 { "asinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2177 { "asinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2178 { "asinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2179 { "asinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2180
2181 // acosh
2182
2183 { "acosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2184 { "acosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2185 { "acosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2186 { "acosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2187
2188 // atanh
2189
2190 { "atanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2191 { "atanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2192 { "atanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2193 { "atanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2194
2195 // Builtins - exponential functions.
2196 // pow
2197
2198 { "pow", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2199 { "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2200 { "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2201 { "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2202
2203 // exp
2204
2205 { "exp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2206 { "exp", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2207 { "exp", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2208 { "exp", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2209
2210 // log
2211
2212 { "log", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2213 { "log", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2214 { "log", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2215 { "log", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2216
2217 // exp2
2218
2219 { "exp2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2220 { "exp2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2221 { "exp2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2222 { "exp2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2223
2224 // log2
2225
2226 { "log2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2227 { "log2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2228 { "log2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2229 { "log2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2230
2231 // sqrt
2232
2233 { "sqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2234 { "sqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2235 { "sqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2236 { "sqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2237
2238 // inversesqrt
2239
2240 { "inversesqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2241 { "inversesqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2242 { "inversesqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2243 { "inversesqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2244
2245 // Built-ins - common functions.
2246 // abs
2247
2248 { "abs", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2249 { "abs", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2250 { "abs", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2251 { "abs", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2252
2253 { "abs", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2254 { "abs", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2255 { "abs", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2256 { "abs", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2257
2258 // sign
2259
2260 { "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2261 { "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2262 { "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2263 { "sign", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2264
2265 { "sign", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2266 { "sign", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2267 { "sign", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2268 { "sign", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2269
2270 // floor
2271
2272 { "floor", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2273 { "floor", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2274 { "floor", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2275 { "floor", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2276
2277 // trunc
2278
2279 { "trunc", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2280 { "trunc", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2281 { "trunc", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2282 { "trunc", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2283
2284 // round
2285
2286 { "round", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2287 { "round", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2288 { "round", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2289 { "round", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2290
2291 // roundEven
2292
2293 { "roundEven", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2294 { "roundEven", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2295 { "roundEven", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2296 { "roundEven", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2297
2298 // ceil
2299
2300 { "ceil", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2301 { "ceil", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2302 { "ceil", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2303 { "ceil", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2304
2305 // fract
2306
2307 { "fract", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2308 { "fract", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2309 { "fract", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2310 { "fract", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2311
2312 // mod
2313
2314 { "mod", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2315 { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2316 { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2317 { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2318 { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2319 { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2320 { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2321
2322 // modf
2323
2324 { "modf", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
2325 { "modf", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
2326 { "modf", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
2327 { "modf", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
2328
2329 // min
2330
2331 { "min", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2332 { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2333 { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2334 { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2335 { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2336 { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2337 { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2338
2339 { "min", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2340 { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2341 { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2342 { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2343 { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2344 { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2345 { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2346
2347 { "min", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2348 { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2349 { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2350 { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2351 { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2352 { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2353 { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2354
2355 // max
2356
2357 { "max", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2358 { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2359 { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2360 { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2361 { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2362 { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2363 { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2364
2365 { "max", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2366 { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2367 { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2368 { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2369 { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2370 { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2371 { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2372
2373 { "max", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2374 { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2375 { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2376 { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2377 { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2378 { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2379 { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2380
2381 // clamp
2382
2383 { "clamp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2384 { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2385 { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2386 { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2387 { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2388 { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2389 { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2390
2391 { "clamp", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2392 { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2393 { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2394 { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2395 { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2396 { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2397 { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2398
2399 { "clamp", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2400 { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2401 { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2402 { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2403 { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2404 { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2405 { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2406
2407 // mix
2408
2409 { "mix", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2410 { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2411 { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_BVEC2, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2412 { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2413 { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2414 { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_BVEC3, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2415 { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2416 { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2417 { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC4, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2418 { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2419
2420 // step
2421
2422 { "step", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2423 { "step", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2424 { "step", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2425 { "step", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2426 { "step", TYPE_VEC2, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2427 { "step", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2428 { "step", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2429
2430 // smoothstep
2431
2432 { "smoothstep", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2433 { "smoothstep", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2434 { "smoothstep", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2435 { "smoothstep", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2436 { "smoothstep", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2437 { "smoothstep", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2438 { "smoothstep", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2439
2440 // isnan
2441
2442 { "isnan", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2443 { "isnan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2444 { "isnan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2445 { "isnan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2446
2447 // isinf
2448
2449 { "isinf", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2450 { "isinf", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2451 { "isinf", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2452 { "isinf", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2453
2454 // floatBitsToInt
2455
2456 { "floatBitsToInt", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2457 { "floatBitsToInt", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2458 { "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2459 { "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2460
2461 // floatBitsToUint
2462
2463 { "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2464 { "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2465 { "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2466 { "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2467
2468 // intBitsToFloat
2469
2470 { "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2471 { "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2472 { "intBitsToFloat", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2473 { "intBitsToFloat", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2474
2475 // uintBitsToFloat
2476
2477 { "uintBitsToFloat", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2478 { "uintBitsToFloat", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2479 { "uintBitsToFloat", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2480 { "uintBitsToFloat", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2481
2482 // Built-ins - geometric functions.
2483 // length
2484
2485 { "length", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2486 { "length", TYPE_FLOAT, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2487 { "length", TYPE_FLOAT, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2488 { "length", TYPE_FLOAT, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2489
2490 // distance
2491
2492 { "distance", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2493 { "distance", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2494 { "distance", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2495 { "distance", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2496
2497 // dot
2498
2499 { "dot", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2500 { "dot", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2501 { "dot", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2502 { "dot", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2503
2504 // cross
2505
2506 { "cross", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2507
2508 // normalize
2509
2510 { "normalize", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2511 { "normalize", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2512 { "normalize", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2513 { "normalize", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2514
2515 // reflect
2516
2517 { "reflect", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "I", "N" }, TAG_GLOBAL, false },
2518 { "reflect", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "I", "N" }, TAG_GLOBAL, false },
2519 { "reflect", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "I", "N" }, TAG_GLOBAL, false },
2520
2521 // refract
2522
2523 { "refract", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "I", "N", "eta" }, TAG_GLOBAL, false },
2524 { "refract", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "I", "N", "eta" }, TAG_GLOBAL, false },
2525 { "refract", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "I", "N", "eta" }, TAG_GLOBAL, false },
2526
2527 // faceforward
2528
2529 { "faceforward", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "N", "I", "Nref" }, TAG_GLOBAL, false },
2530 { "faceforward", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "N", "I", "Nref" }, TAG_GLOBAL, false },
2531 { "faceforward", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "N", "I", "Nref" }, TAG_GLOBAL, false },
2532
2533 // matrixCompMult
2534
2535 { "matrixCompMult", TYPE_MAT2, { TYPE_MAT2, TYPE_MAT2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2536 { "matrixCompMult", TYPE_MAT3, { TYPE_MAT3, TYPE_MAT3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2537 { "matrixCompMult", TYPE_MAT4, { TYPE_MAT4, TYPE_MAT4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2538
2539 // outerProduct
2540
2541 { "outerProduct", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "c", "r" }, TAG_GLOBAL, false },
2542 { "outerProduct", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "c", "r" }, TAG_GLOBAL, false },
2543 { "outerProduct", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "c", "r" }, TAG_GLOBAL, false },
2544
2545 // transpose
2546
2547 { "transpose", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
2548 { "transpose", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
2549 { "transpose", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
2550
2551 // determinant
2552
2553 { "determinant", TYPE_FLOAT, { TYPE_MAT2, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
2554 { "determinant", TYPE_FLOAT, { TYPE_MAT3, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
2555 { "determinant", TYPE_FLOAT, { TYPE_MAT4, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
2556
2557 // inverse
2558
2559 { "inverse", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
2560 { "inverse", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
2561 { "inverse", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
2562
2563 // lessThan
2564
2565 { "lessThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2566 { "lessThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2567 { "lessThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2568
2569 { "lessThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2570 { "lessThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2571 { "lessThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2572
2573 { "lessThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2574 { "lessThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2575 { "lessThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2576
2577 // greaterThan
2578
2579 { "greaterThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2580 { "greaterThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2581 { "greaterThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2582
2583 { "greaterThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2584 { "greaterThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2585 { "greaterThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2586
2587 { "greaterThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2588 { "greaterThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2589 { "greaterThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2590
2591 // lessThanEqual
2592
2593 { "lessThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2594 { "lessThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2595 { "lessThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2596
2597 { "lessThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2598 { "lessThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2599 { "lessThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2600
2601 { "lessThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2602 { "lessThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2603 { "lessThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2604
2605 // greaterThanEqual
2606
2607 { "greaterThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2608 { "greaterThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2609 { "greaterThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2610
2611 { "greaterThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2612 { "greaterThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2613 { "greaterThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2614
2615 { "greaterThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2616 { "greaterThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2617 { "greaterThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2618
2619 // equal
2620
2621 { "equal", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2622 { "equal", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2623 { "equal", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2624
2625 { "equal", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2626 { "equal", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2627 { "equal", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2628
2629 { "equal", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2630 { "equal", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2631 { "equal", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2632
2633 { "equal", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2634 { "equal", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2635 { "equal", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2636
2637 // notEqual
2638
2639 { "notEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2640 { "notEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2641 { "notEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2642
2643 { "notEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2644 { "notEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2645 { "notEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2646
2647 { "notEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2648 { "notEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2649 { "notEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2650
2651 { "notEqual", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2652 { "notEqual", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2653 { "notEqual", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2654
2655 // any
2656
2657 { "any", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2658 { "any", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2659 { "any", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2660
2661 // all
2662
2663 { "all", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2664 { "all", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2665 { "all", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2666
2667 // not
2668
2669 { "not", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2670 { "not", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2671 { "not", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2672
2673 // Built-ins: texture functions.
2674 // textureSize
2675
2676 { "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2677 { "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2678 { "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2679 { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2680 { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2681 { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2682 { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2683 { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2684 { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2685 { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2686 { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBEARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
2687
2688 // texture
2689
2690 { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2691 { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2692 { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2693 { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2694 { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2695 { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2696 { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2697 { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2698 { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2699 { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2700 { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2701 { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2702 { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2703 { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2704 { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2705 { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2706 { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2707 { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2708 { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2709 { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2710 { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2711 { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2712
2713 // textureProj
2714
2715 { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2716 { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2717 { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2718 { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2719 { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2720 { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2721 { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2722 { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2723 { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2724 { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2725 { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2726 { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2727 { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2728 { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2729 { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2730 { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2731 { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2732 { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
2733
2734 // textureLod
2735
2736 { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2737 { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2738 { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2739 { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2740 { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2741 { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2742 { "textureLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2743 { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2744 { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2745 { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2746 { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2747
2748 // texelFetch
2749
2750 { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2751 { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2752 { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2753 { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2754 { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2755 { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2756 { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2757 { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2758 { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2759
2760 // textureProjLod
2761
2762 { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2763 { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2764 { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2765 { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2766 { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2767 { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2768 { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2769 { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2770 { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
2771
2772 // textureGrad
2773
2774 { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2775 { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2776 { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2777 { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2778 { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2779 { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2780 { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2781 { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2782 { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2783 { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2784 { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2785
2786 // textureProjGrad
2787
2788 { "textureProjGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2789 { "textureProjGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2790 { "textureProjGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2791 { "textureProjGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2792 { "textureProjGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2793 { "textureProjGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2794 { "textureProjGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2795 { "textureProjGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2796 { "textureProjGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
2797
2798 // textureGather
2799
2800 { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2801 { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2802 { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2803 { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
2804 { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
2805 { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
2806 { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2807 { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2808 { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2809 { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
2810 { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
2811 { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
2812 { "textureGather", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
2813 { "textureGather", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
2814
2815 // textureQueryLod
2816
2817 { "textureQueryLod", TYPE_VEC2, { TYPE_SAMPLER2D, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2818 { "textureQueryLod", TYPE_VEC2, { TYPE_ISAMPLER2D, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2819 { "textureQueryLod", TYPE_VEC2, { TYPE_USAMPLER2D, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2820 { "textureQueryLod", TYPE_VEC2, { TYPE_SAMPLER2DARRAY, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2821 { "textureQueryLod", TYPE_VEC2, { TYPE_ISAMPLER2DARRAY, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2822 { "textureQueryLod", TYPE_VEC2, { TYPE_USAMPLER2DARRAY, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2823 { "textureQueryLod", TYPE_VEC2, { TYPE_SAMPLER3D, TYPE_VEC3 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2824 { "textureQueryLod", TYPE_VEC2, { TYPE_ISAMPLER3D, TYPE_VEC3 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2825 { "textureQueryLod", TYPE_VEC2, { TYPE_USAMPLER3D, TYPE_VEC3 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2826 { "textureQueryLod", TYPE_VEC2, { TYPE_SAMPLERCUBE, TYPE_VEC3 }, { "sampler", "coords" }, TAG_GLOBAL, true },
2827
2828 // textureQueryLevels
2829
2830 { "textureQueryLevels", TYPE_INT, { TYPE_SAMPLER2D }, { "sampler" }, TAG_GLOBAL, true },
2831 { "textureQueryLevels", TYPE_INT, { TYPE_ISAMPLER2D }, { "sampler" }, TAG_GLOBAL, true },
2832 { "textureQueryLevels", TYPE_INT, { TYPE_USAMPLER2D }, { "sampler" }, TAG_GLOBAL, true },
2833 { "textureQueryLevels", TYPE_INT, { TYPE_SAMPLER2DARRAY }, { "sampler" }, TAG_GLOBAL, true },
2834 { "textureQueryLevels", TYPE_INT, { TYPE_ISAMPLER2DARRAY }, { "sampler" }, TAG_GLOBAL, true },
2835 { "textureQueryLevels", TYPE_INT, { TYPE_USAMPLER2DARRAY }, { "sampler" }, TAG_GLOBAL, true },
2836 { "textureQueryLevels", TYPE_INT, { TYPE_SAMPLER3D }, { "sampler" }, TAG_GLOBAL, true },
2837 { "textureQueryLevels", TYPE_INT, { TYPE_ISAMPLER3D }, { "sampler" }, TAG_GLOBAL, true },
2838 { "textureQueryLevels", TYPE_INT, { TYPE_USAMPLER3D }, { "sampler" }, TAG_GLOBAL, true },
2839 { "textureQueryLevels", TYPE_INT, { TYPE_SAMPLERCUBE }, { "sampler" }, TAG_GLOBAL, true },
2840
2841 // dFdx
2842
2843 { "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2844 { "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2845 { "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2846 { "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2847
2848 // dFdxCoarse
2849
2850 { "dFdxCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2851 { "dFdxCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2852 { "dFdxCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2853 { "dFdxCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2854
2855 // dFdxFine
2856
2857 { "dFdxFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2858 { "dFdxFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2859 { "dFdxFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2860 { "dFdxFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2861
2862 // dFdy
2863
2864 { "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2865 { "dFdy", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2866 { "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2867 { "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2868
2869 // dFdyCoarse
2870
2871 { "dFdyCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2872 { "dFdyCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2873 { "dFdyCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2874 { "dFdyCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2875
2876 // dFdyFine
2877
2878 { "dFdyFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2879 { "dFdyFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2880 { "dFdyFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2881 { "dFdyFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2882
2883 // fwidth
2884
2885 { "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2886 { "fwidth", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2887 { "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2888 { "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
2889
2890 // fwidthCoarse
2891
2892 { "fwidthCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2893 { "fwidthCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2894 { "fwidthCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2895 { "fwidthCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2896
2897 // fwidthFine
2898
2899 { "fwidthFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2900 { "fwidthFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2901 { "fwidthFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2902 { "fwidthFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
2903
2904 // Sub-functions.
2905 // array
2906
2907 { "length", TYPE_INT, { TYPE_VOID }, { "" }, TAG_ARRAY, false },
2908
2909 // Modern functions.
2910 // fma
2911
2912 { "fma", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
2913 { "fma", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
2914 { "fma", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
2915 { "fma", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
2916
2917 // Packing/Unpacking functions.
2918
2919 { "packHalf2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2920 { "packUnorm2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2921 { "packSnorm2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2922 { "packUnorm4x8", TYPE_UINT, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2923 { "packSnorm4x8", TYPE_UINT, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2924
2925 { "unpackHalf2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2926 { "unpackUnorm2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2927 { "unpackSnorm2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2928 { "unpackUnorm4x8", TYPE_VEC4, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2929 { "unpackSnorm4x8", TYPE_VEC4, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2930
2931 // bitfieldExtract
2932
2933 { "bitfieldExtract", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
2934 { "bitfieldExtract", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
2935 { "bitfieldExtract", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
2936 { "bitfieldExtract", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
2937
2938 { "bitfieldExtract", TYPE_UINT, { TYPE_UINT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
2939 { "bitfieldExtract", TYPE_UVEC2, { TYPE_UVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
2940 { "bitfieldExtract", TYPE_UVEC3, { TYPE_UVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
2941 { "bitfieldExtract", TYPE_UVEC4, { TYPE_UVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
2942
2943 // bitfieldInsert
2944
2945 { "bitfieldInsert", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
2946 { "bitfieldInsert", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
2947 { "bitfieldInsert", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
2948 { "bitfieldInsert", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
2949
2950 { "bitfieldInsert", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
2951 { "bitfieldInsert", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
2952 { "bitfieldInsert", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
2953 { "bitfieldInsert", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
2954
2955 // bitfieldReverse
2956
2957 { "bitfieldReverse", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2958 { "bitfieldReverse", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2959 { "bitfieldReverse", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2960 { "bitfieldReverse", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2961
2962 { "bitfieldReverse", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2963 { "bitfieldReverse", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2964 { "bitfieldReverse", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2965 { "bitfieldReverse", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2966
2967 // bitCount
2968
2969 { "bitCount", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2970 { "bitCount", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2971 { "bitCount", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2972 { "bitCount", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2973
2974 { "bitCount", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2975 { "bitCount", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2976 { "bitCount", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2977 { "bitCount", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2978
2979 // findLSB
2980
2981 { "findLSB", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2982 { "findLSB", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2983 { "findLSB", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2984 { "findLSB", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2985
2986 { "findLSB", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2987 { "findLSB", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2988 { "findLSB", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2989 { "findLSB", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2990
2991 // findMSB
2992
2993 { "findMSB", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2994 { "findMSB", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2995 { "findMSB", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2996 { "findMSB", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2997
2998 { "findMSB", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
2999 { "findMSB", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3000 { "findMSB", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3001 { "findMSB", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3002
3003 // umulExtended
3004
3005 { "umulExtended", TYPE_VOID, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3006 { "umulExtended", TYPE_VOID, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3007 { "umulExtended", TYPE_VOID, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3008 { "umulExtended", TYPE_VOID, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3009
3010 // imulExtended
3011
3012 { "imulExtended", TYPE_VOID, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3013 { "imulExtended", TYPE_VOID, { TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3014 { "imulExtended", TYPE_VOID, { TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3015 { "imulExtended", TYPE_VOID, { TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3016
3017 // uaddCarry
3018
3019 { "uaddCarry", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "y", "carry" }, TAG_GLOBAL, true },
3020 { "uaddCarry", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "y", "carry" }, TAG_GLOBAL, true },
3021 { "uaddCarry", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "y", "carry" }, TAG_GLOBAL, true },
3022 { "uaddCarry", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "y", "carry" }, TAG_GLOBAL, true },
3023
3024 // usubBorrow
3025
3026 { "usubBorrow", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "y", "borrow" }, TAG_GLOBAL, true },
3027 { "usubBorrow", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "y", "borrow" }, TAG_GLOBAL, true },
3028 { "usubBorrow", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "y", "borrow" }, TAG_GLOBAL, true },
3029 { "usubBorrow", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "y", "borrow" }, TAG_GLOBAL, true },
3030
3031 // ldexp
3032
3033 { "ldexp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_INT, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3034 { "ldexp", TYPE_VEC2, { TYPE_VEC2, TYPE_IVEC2, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3035 { "ldexp", TYPE_VEC3, { TYPE_VEC3, TYPE_IVEC3, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3036 { "ldexp", TYPE_VEC4, { TYPE_VEC4, TYPE_IVEC4, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3037
3038 // frexp
3039
3040 { "frexp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_INT, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3041 { "frexp", TYPE_VEC2, { TYPE_VEC2, TYPE_IVEC2, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3042 { "frexp", TYPE_VEC3, { TYPE_VEC3, TYPE_IVEC3, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3043 { "frexp", TYPE_VEC4, { TYPE_VEC4, TYPE_IVEC4, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3044
3045 { nullptr, TYPE_VOID, { TYPE_VOID }, { "" }, TAG_GLOBAL, false }
3046};
3047
3048const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[] = {
3049 { "modf", { 1, -1 } },
3050 { "umulExtended", { 2, 3 } },
3051 { "imulExtended", { 2, 3 } },
3052 { "uaddCarry", { 2, -1 } },
3053 { "usubBorrow", { 2, -1 } },
3054 { "ldexp", { 1, -1 } },
3055 { "frexp", { 1, -1 } },
3056 { nullptr, { 0, -1 } }
3057};
3058
3059const ShaderLanguage::BuiltinFuncConstArgs ShaderLanguage::builtin_func_const_args[] = {
3060 { "textureGather", 2, 0, 3 },
3061 { nullptr, 0, 0, 0 }
3062};
3063
3064bool ShaderLanguage::is_const_suffix_lut_initialized = false;
3065
3066bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str, bool *r_is_custom_function) {
3067 ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, false);
3068
3069 Vector<DataType> args;
3070 Vector<StringName> args2;
3071 Vector<int> args3;
3072
3073 ERR_FAIL_COND_V(p_func->arguments[0]->type != Node::NODE_TYPE_VARIABLE, false);
3074
3075 StringName name = static_cast<VariableNode *>(p_func->arguments[0])->name.operator String();
3076
3077 for (int i = 1; i < p_func->arguments.size(); i++) {
3078 args.push_back(p_func->arguments[i]->get_datatype());
3079 args2.push_back(p_func->arguments[i]->get_datatype_name());
3080 args3.push_back(p_func->arguments[i]->get_array_size());
3081 }
3082
3083 int argcount = args.size();
3084
3085 if (p_function_info.stage_functions.has(name)) {
3086 //stage based function
3087 const StageFunctionInfo &sf = p_function_info.stage_functions[name];
3088 if (argcount != sf.arguments.size()) {
3089 _set_error(vformat(RTR("Invalid number of arguments when calling stage function '%s', which expects %d arguments."), String(name), sf.arguments.size()));
3090 return false;
3091 }
3092 //validate arguments
3093 for (int i = 0; i < argcount; i++) {
3094 if (args[i] != sf.arguments[i].type) {
3095 _set_error(vformat(RTR("Invalid argument type when calling stage function '%s', type expected is '%s'."), String(name), get_datatype_name(sf.arguments[i].type)));
3096 return false;
3097 }
3098 }
3099
3100 if (r_ret_type) {
3101 *r_ret_type = sf.return_type;
3102 }
3103 if (r_ret_type_str) {
3104 *r_ret_type_str = "";
3105 }
3106 return true;
3107 }
3108
3109 bool failed_builtin = false;
3110 bool unsupported_builtin = false;
3111 int builtin_idx = 0;
3112
3113 if (argcount <= 4) {
3114 // test builtins
3115 int idx = 0;
3116
3117 while (builtin_func_defs[idx].name) {
3118 if (completion_class != builtin_func_defs[idx].tag) {
3119 idx++;
3120 continue;
3121 }
3122
3123 if (name == builtin_func_defs[idx].name) {
3124 failed_builtin = true;
3125 bool fail = false;
3126 for (int i = 0; i < argcount; i++) {
3127 if (p_func->arguments[i + 1]->type == Node::NODE_TYPE_ARRAY) {
3128 const ArrayNode *anode = static_cast<const ArrayNode *>(p_func->arguments[i + 1]);
3129 if (anode->call_expression == nullptr && !anode->is_indexed()) {
3130 fail = true;
3131 break;
3132 }
3133 }
3134 if (get_scalar_type(args[i]) == args[i] && p_func->arguments[i + 1]->type == Node::NODE_TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[i + 1]), builtin_func_defs[idx].args[i])) {
3135 //all good, but needs implicit conversion later
3136 } else if (args[i] != builtin_func_defs[idx].args[i]) {
3137 fail = true;
3138 break;
3139 }
3140 }
3141
3142 if (!fail) {
3143 if (RenderingServer::get_singleton()->is_low_end()) {
3144 if (builtin_func_defs[idx].high_end) {
3145 fail = true;
3146 unsupported_builtin = true;
3147 builtin_idx = idx;
3148 }
3149 }
3150 }
3151
3152 if (!fail && argcount < 4 && builtin_func_defs[idx].args[argcount] != TYPE_VOID) {
3153 fail = true; //make sure the number of arguments matches
3154 }
3155
3156 if (!fail) {
3157 {
3158 int constarg_idx = 0;
3159 while (builtin_func_const_args[constarg_idx].name) {
3160 if (String(name) == builtin_func_const_args[constarg_idx].name) {
3161 int arg = builtin_func_const_args[constarg_idx].arg + 1;
3162 if (p_func->arguments.size() <= arg) {
3163 break;
3164 }
3165
3166 int min = builtin_func_const_args[constarg_idx].min;
3167 int max = builtin_func_const_args[constarg_idx].max;
3168
3169 bool error = false;
3170 if (p_func->arguments[arg]->type == Node::NODE_TYPE_VARIABLE) {
3171 const VariableNode *vn = static_cast<VariableNode *>(p_func->arguments[arg]);
3172
3173 bool is_const = false;
3174 ConstantNode::Value value;
3175 value.sint = -1;
3176
3177 _find_identifier(p_block, false, p_function_info, vn->name, nullptr, nullptr, &is_const, nullptr, nullptr, &value);
3178 if (!is_const || value.sint < min || value.sint > max) {
3179 error = true;
3180 }
3181 } else {
3182 if (p_func->arguments[arg]->type == Node::NODE_TYPE_CONSTANT) {
3183 const ConstantNode *cn = static_cast<ConstantNode *>(p_func->arguments[arg]);
3184
3185 if (cn->get_datatype() == TYPE_INT && cn->values.size() == 1) {
3186 int value = cn->values[0].sint;
3187
3188 if (value < min || value > max) {
3189 error = true;
3190 }
3191 } else {
3192 error = true;
3193 }
3194 } else {
3195 error = true;
3196 }
3197 }
3198 if (error) {
3199 _set_error(vformat(RTR("Expected integer constant within [%d..%d] range."), min, max));
3200 return false;
3201 }
3202 }
3203 constarg_idx++;
3204 }
3205 }
3206
3207 //make sure its not an out argument used in the wrong way
3208 int outarg_idx = 0;
3209 while (builtin_func_out_args[outarg_idx].name) {
3210 if (String(name) == builtin_func_out_args[outarg_idx].name) {
3211 for (int arg = 0; arg < BuiltinFuncOutArgs::MAX_ARGS; arg++) {
3212 int arg_idx = builtin_func_out_args[outarg_idx].arguments[arg];
3213 if (arg_idx == -1) {
3214 break;
3215 }
3216 if (arg_idx < argcount) {
3217 if (p_func->arguments[arg_idx + 1]->type != Node::NODE_TYPE_VARIABLE && p_func->arguments[arg_idx + 1]->type != Node::NODE_TYPE_MEMBER && p_func->arguments[arg_idx + 1]->type != Node::NODE_TYPE_ARRAY) {
3218 _set_error(vformat(RTR("Argument %d of function '%s' is not a variable, array, or member."), arg_idx + 1, String(name)));
3219 return false;
3220 }
3221
3222 if (p_func->arguments[arg_idx + 1]->type == Node::NODE_TYPE_ARRAY) {
3223 ArrayNode *mn = static_cast<ArrayNode *>(p_func->arguments[arg_idx + 1]);
3224 if (mn->is_const) {
3225 fail = true;
3226 }
3227 } else if (p_func->arguments[arg_idx + 1]->type == Node::NODE_TYPE_MEMBER) {
3228 MemberNode *mn = static_cast<MemberNode *>(p_func->arguments[arg_idx + 1]);
3229 if (mn->basetype_const) {
3230 fail = true;
3231 }
3232 } else { // TYPE_VARIABLE
3233 VariableNode *vn = static_cast<VariableNode *>(p_func->arguments[arg_idx + 1]);
3234 if (vn->is_const) {
3235 fail = true;
3236 } else {
3237 StringName varname = vn->name;
3238 if (shader->uniforms.has(varname)) {
3239 fail = true;
3240 } else {
3241 if (shader->varyings.has(varname)) {
3242 _set_error(vformat(RTR("Varyings cannot be passed for the '%s' parameter."), "out"));
3243 return false;
3244 }
3245 if (p_function_info.built_ins.has(varname)) {
3246 BuiltInInfo info = p_function_info.built_ins[varname];
3247 if (info.constant) {
3248 fail = true;
3249 }
3250 }
3251 }
3252 }
3253 }
3254 if (fail) {
3255 _set_error(vformat(RTR("A constant value cannot be passed for the '%s' parameter."), "out"));
3256 return false;
3257 }
3258
3259 StringName var_name;
3260 if (p_func->arguments[arg_idx + 1]->type == Node::NODE_TYPE_ARRAY) {
3261 var_name = static_cast<const ArrayNode *>(p_func->arguments[arg_idx + 1])->name;
3262 } else if (p_func->arguments[arg_idx + 1]->type == Node::NODE_TYPE_MEMBER) {
3263 Node *n = static_cast<const MemberNode *>(p_func->arguments[arg_idx + 1])->owner;
3264 while (n->type == Node::NODE_TYPE_MEMBER) {
3265 n = static_cast<const MemberNode *>(n)->owner;
3266 }
3267 if (n->type != Node::NODE_TYPE_VARIABLE && n->type != Node::NODE_TYPE_ARRAY) {
3268 _set_error(vformat(RTR("Argument %d of function '%s' is not a variable, array, or member."), arg_idx + 1, String(name)));
3269 return false;
3270 }
3271 if (n->type == Node::NODE_TYPE_VARIABLE) {
3272 var_name = static_cast<const VariableNode *>(n)->name;
3273 } else { // TYPE_ARRAY
3274 var_name = static_cast<const ArrayNode *>(n)->name;
3275 }
3276 } else { // TYPE_VARIABLE
3277 var_name = static_cast<const VariableNode *>(p_func->arguments[arg_idx + 1])->name;
3278 }
3279 const BlockNode *b = p_block;
3280 bool valid = false;
3281 while (b) {
3282 if (b->variables.has(var_name) || p_function_info.built_ins.has(var_name)) {
3283 valid = true;
3284 break;
3285 }
3286 if (b->parent_function) {
3287 for (int i = 0; i < b->parent_function->arguments.size(); i++) {
3288 if (b->parent_function->arguments[i].name == var_name) {
3289 valid = true;
3290 break;
3291 }
3292 }
3293 }
3294 b = b->parent_block;
3295 }
3296
3297 if (!valid) {
3298 _set_error(vformat(RTR("Argument %d of function '%s' can only take a local variable, array, or member."), arg_idx + 1, String(name)));
3299 return false;
3300 }
3301 }
3302 }
3303 }
3304 outarg_idx++;
3305 }
3306 //implicitly convert values if possible
3307 for (int i = 0; i < argcount; i++) {
3308 if (get_scalar_type(args[i]) != args[i] || args[i] == builtin_func_defs[idx].args[i] || p_func->arguments[i + 1]->type != Node::NODE_TYPE_CONSTANT) {
3309 //can't do implicit conversion here
3310 continue;
3311 }
3312
3313 //this is an implicit conversion
3314 ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[i + 1]);
3315 ConstantNode *conversion = alloc_node<ConstantNode>();
3316
3317 conversion->datatype = builtin_func_defs[idx].args[i];
3318 conversion->values.resize(1);
3319
3320 convert_constant(constant, builtin_func_defs[idx].args[i], conversion->values.ptrw());
3321 p_func->arguments.write[i + 1] = conversion;
3322 }
3323
3324 if (r_ret_type) {
3325 *r_ret_type = builtin_func_defs[idx].rettype;
3326 }
3327
3328 return true;
3329 }
3330 }
3331
3332 idx++;
3333 }
3334 }
3335
3336 if (unsupported_builtin) {
3337 String arglist = "";
3338 for (int i = 0; i < argcount; i++) {
3339 if (i > 0) {
3340 arglist += ", ";
3341 }
3342 arglist += get_datatype_name(builtin_func_defs[builtin_idx].args[i]);
3343 }
3344
3345 _set_error(vformat(RTR("Built-in function \"%s(%s)\" is only supported on high-end platforms."), String(name), arglist));
3346 return false;
3347 }
3348
3349 if (failed_builtin) {
3350 String arg_list;
3351 for (int i = 0; i < argcount; i++) {
3352 if (i > 0) {
3353 arg_list += ",";
3354 }
3355
3356 String arg_name;
3357 if (args[i] == TYPE_STRUCT) {
3358 arg_name = args2[i];
3359 } else {
3360 arg_name = get_datatype_name(args[i]);
3361 }
3362 if (args3[i] > 0) {
3363 arg_name += "[";
3364 arg_name += itos(args3[i]);
3365 arg_name += "]";
3366 }
3367 arg_list += arg_name;
3368 }
3369 _set_error(vformat(RTR("Invalid arguments for the built-in function: \"%s(%s)\"."), String(name), arg_list));
3370 return false;
3371 }
3372
3373 // try existing functions..
3374
3375 StringName exclude_function;
3376 BlockNode *block = p_block;
3377
3378 while (block) {
3379 if (block->parent_function) {
3380 exclude_function = block->parent_function->name;
3381 }
3382 block = block->parent_block;
3383 }
3384
3385 if (name == exclude_function) {
3386 _set_error(RTR("Recursion is not allowed."));
3387 return false;
3388 }
3389
3390 int last_arg_count = 0;
3391 bool exists = false;
3392 String arg_list = "";
3393
3394 for (int i = 0; i < shader->functions.size(); i++) {
3395 if (name != shader->functions[i].name) {
3396 continue;
3397 }
3398 exists = true;
3399
3400 if (!shader->functions[i].callable) {
3401 _set_error(vformat(RTR("Function '%s' can't be called from source code."), String(name)));
3402 return false;
3403 }
3404
3405 FunctionNode *pfunc = shader->functions[i].function;
3406 if (arg_list.is_empty()) {
3407 for (int j = 0; j < pfunc->arguments.size(); j++) {
3408 if (j > 0) {
3409 arg_list += ", ";
3410 }
3411 String func_arg_name;
3412 if (pfunc->arguments[j].type == TYPE_STRUCT) {
3413 func_arg_name = pfunc->arguments[j].type_str;
3414 } else {
3415 func_arg_name = get_datatype_name(pfunc->arguments[j].type);
3416 }
3417 if (pfunc->arguments[j].array_size > 0) {
3418 func_arg_name += "[";
3419 func_arg_name += itos(pfunc->arguments[j].array_size);
3420 func_arg_name += "]";
3421 }
3422 arg_list += func_arg_name;
3423 }
3424 }
3425
3426 if (pfunc->arguments.size() != args.size()) {
3427 last_arg_count = pfunc->arguments.size();
3428 continue;
3429 }
3430
3431 bool fail = false;
3432
3433 for (int j = 0; j < args.size(); j++) {
3434 if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::NODE_TYPE_CONSTANT && args3[j] == 0 && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) {
3435 //all good, but it needs implicit conversion later
3436 } else if (args[j] != pfunc->arguments[j].type || (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str) || args3[j] != pfunc->arguments[j].array_size) {
3437 String func_arg_name;
3438 if (pfunc->arguments[j].type == TYPE_STRUCT) {
3439 func_arg_name = pfunc->arguments[j].type_str;
3440 } else {
3441 func_arg_name = get_datatype_name(pfunc->arguments[j].type);
3442 }
3443 if (pfunc->arguments[j].array_size > 0) {
3444 func_arg_name += "[";
3445 func_arg_name += itos(pfunc->arguments[j].array_size);
3446 func_arg_name += "]";
3447 }
3448 String arg_name;
3449 if (args[j] == TYPE_STRUCT) {
3450 arg_name = args2[j];
3451 } else {
3452 arg_name = get_datatype_name(args[j]);
3453 }
3454 if (args3[j] > 0) {
3455 arg_name += "[";
3456 arg_name += itos(args3[j]);
3457 arg_name += "]";
3458 }
3459
3460 _set_error(vformat(RTR("Invalid argument for \"%s(%s)\" function: argument %d should be %s but is %s."), String(name), arg_list, j + 1, func_arg_name, arg_name));
3461 fail = true;
3462 break;
3463 }
3464 }
3465
3466 if (!fail) {
3467 //implicitly convert values if possible
3468 for (int k = 0; k < args.size(); k++) {
3469 if (get_scalar_type(args[k]) != args[k] || args[k] == pfunc->arguments[k].type || p_func->arguments[k + 1]->type != Node::NODE_TYPE_CONSTANT) {
3470 //can't do implicit conversion here
3471 continue;
3472 }
3473
3474 //this is an implicit conversion
3475 ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[k + 1]);
3476 ConstantNode *conversion = alloc_node<ConstantNode>();
3477
3478 conversion->datatype = pfunc->arguments[k].type;
3479 conversion->values.resize(1);
3480
3481 convert_constant(constant, pfunc->arguments[k].type, conversion->values.ptrw());
3482 p_func->arguments.write[k + 1] = conversion;
3483 }
3484
3485 if (r_ret_type) {
3486 *r_ret_type = pfunc->return_type;
3487 if (pfunc->return_type == TYPE_STRUCT) {
3488 *r_ret_type_str = pfunc->return_struct_name;
3489 }
3490 }
3491
3492 if (r_is_custom_function) {
3493 *r_is_custom_function = true;
3494 }
3495 return true;
3496 }
3497 }
3498
3499 if (exists) {
3500 if (last_arg_count > args.size()) {
3501 _set_error(vformat(RTR("Too few arguments for \"%s(%s)\" call. Expected at least %d but received %d."), String(name), arg_list, last_arg_count, args.size()));
3502 } else if (last_arg_count < args.size()) {
3503 _set_error(vformat(RTR("Too many arguments for \"%s(%s)\" call. Expected at most %d but received %d."), String(name), arg_list, last_arg_count, args.size()));
3504 }
3505 }
3506
3507 return false;
3508}
3509
3510bool ShaderLanguage::_compare_datatypes(DataType p_datatype_a, String p_datatype_name_a, int p_array_size_a, DataType p_datatype_b, String p_datatype_name_b, int p_array_size_b) {
3511 bool result = true;
3512
3513 if (p_datatype_a == TYPE_STRUCT || p_datatype_b == TYPE_STRUCT) {
3514 if (p_datatype_name_a != p_datatype_name_b) {
3515 result = false;
3516 }
3517 } else {
3518 if (p_datatype_a != p_datatype_b) {
3519 result = false;
3520 }
3521 }
3522
3523 if (p_array_size_a != p_array_size_b) {
3524 result = false;
3525 }
3526
3527 if (!result) {
3528 String type_name = p_datatype_a == TYPE_STRUCT ? p_datatype_name_a : get_datatype_name(p_datatype_a);
3529 if (p_array_size_a > 0) {
3530 type_name += "[";
3531 type_name += itos(p_array_size_a);
3532 type_name += "]";
3533 }
3534
3535 String type_name2 = p_datatype_b == TYPE_STRUCT ? p_datatype_name_b : get_datatype_name(p_datatype_b);
3536 if (p_array_size_b > 0) {
3537 type_name2 += "[";
3538 type_name2 += itos(p_array_size_b);
3539 type_name2 += "]";
3540 }
3541
3542 _set_error(vformat(RTR("Invalid assignment of '%s' to '%s'."), type_name2, type_name));
3543 }
3544 return result;
3545}
3546
3547bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) {
3548 return _compare_datatypes(a->get_datatype(), a->get_datatype_name(), a->get_array_size(), b->get_datatype(), b->get_datatype_name(), b->get_array_size());
3549}
3550
3551bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg) {
3552 TkPos pos = _get_tkpos();
3553 Token tk = _get_token();
3554
3555 if (tk.type == TK_PARENTHESIS_CLOSE) {
3556 return true;
3557 }
3558
3559 _set_tkpos(pos);
3560
3561 while (true) {
3562 if (r_complete_arg) {
3563 pos = _get_tkpos();
3564 tk = _get_token();
3565
3566 if (tk.type == TK_CURSOR) {
3567 *r_complete_arg = p_func->arguments.size() - 1;
3568 } else {
3569 _set_tkpos(pos);
3570 }
3571 }
3572
3573 Node *arg = _parse_and_reduce_expression(p_block, p_function_info);
3574
3575 if (!arg) {
3576 return false;
3577 }
3578
3579 if (is_const_decl && arg->type == Node::NODE_TYPE_VARIABLE) {
3580 const VariableNode *var = static_cast<const VariableNode *>(arg);
3581 if (!var->is_const) {
3582 _set_error(RTR("Expected constant expression."));
3583 return false;
3584 }
3585 }
3586
3587 p_func->arguments.push_back(arg);
3588
3589 tk = _get_token();
3590
3591 if (tk.type == TK_PARENTHESIS_CLOSE) {
3592 return true;
3593 } else if (tk.type != TK_COMMA) {
3594 // something is broken
3595 _set_error(RTR("Expected ',' or ')' after argument."));
3596 return false;
3597 }
3598 }
3599
3600 return true;
3601}
3602
3603bool ShaderLanguage::is_token_operator(TokenType p_type) {
3604 return (p_type == TK_OP_EQUAL ||
3605 p_type == TK_OP_NOT_EQUAL ||
3606 p_type == TK_OP_LESS ||
3607 p_type == TK_OP_LESS_EQUAL ||
3608 p_type == TK_OP_GREATER ||
3609 p_type == TK_OP_GREATER_EQUAL ||
3610 p_type == TK_OP_AND ||
3611 p_type == TK_OP_OR ||
3612 p_type == TK_OP_NOT ||
3613 p_type == TK_OP_ADD ||
3614 p_type == TK_OP_SUB ||
3615 p_type == TK_OP_MUL ||
3616 p_type == TK_OP_DIV ||
3617 p_type == TK_OP_MOD ||
3618 p_type == TK_OP_SHIFT_LEFT ||
3619 p_type == TK_OP_SHIFT_RIGHT ||
3620 p_type == TK_OP_ASSIGN ||
3621 p_type == TK_OP_ASSIGN_ADD ||
3622 p_type == TK_OP_ASSIGN_SUB ||
3623 p_type == TK_OP_ASSIGN_MUL ||
3624 p_type == TK_OP_ASSIGN_DIV ||
3625 p_type == TK_OP_ASSIGN_MOD ||
3626 p_type == TK_OP_ASSIGN_SHIFT_LEFT ||
3627 p_type == TK_OP_ASSIGN_SHIFT_RIGHT ||
3628 p_type == TK_OP_ASSIGN_BIT_AND ||
3629 p_type == TK_OP_ASSIGN_BIT_OR ||
3630 p_type == TK_OP_ASSIGN_BIT_XOR ||
3631 p_type == TK_OP_BIT_AND ||
3632 p_type == TK_OP_BIT_OR ||
3633 p_type == TK_OP_BIT_XOR ||
3634 p_type == TK_OP_BIT_INVERT ||
3635 p_type == TK_OP_INCREMENT ||
3636 p_type == TK_OP_DECREMENT ||
3637 p_type == TK_QUESTION ||
3638 p_type == TK_COLON);
3639}
3640
3641bool ShaderLanguage::is_token_operator_assign(TokenType p_type) {
3642 return (p_type == TK_OP_ASSIGN ||
3643 p_type == TK_OP_ASSIGN_ADD ||
3644 p_type == TK_OP_ASSIGN_SUB ||
3645 p_type == TK_OP_ASSIGN_MUL ||
3646 p_type == TK_OP_ASSIGN_DIV ||
3647 p_type == TK_OP_ASSIGN_MOD ||
3648 p_type == TK_OP_ASSIGN_SHIFT_LEFT ||
3649 p_type == TK_OP_ASSIGN_SHIFT_RIGHT ||
3650 p_type == TK_OP_ASSIGN_BIT_AND ||
3651 p_type == TK_OP_ASSIGN_BIT_OR ||
3652 p_type == TK_OP_ASSIGN_BIT_XOR);
3653}
3654
3655bool ShaderLanguage::is_token_hint(TokenType p_type) {
3656 return int(p_type) > int(TK_RENDER_MODE) && int(p_type) < int(TK_SHADER_TYPE);
3657}
3658
3659bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value) {
3660 if (p_constant->datatype == p_to_type) {
3661 if (p_value) {
3662 for (int i = 0; i < p_constant->values.size(); i++) {
3663 p_value[i] = p_constant->values[i];
3664 }
3665 }
3666 return true;
3667 } else if (p_constant->datatype == TYPE_INT && p_to_type == TYPE_FLOAT) {
3668 if (p_value) {
3669 p_value->real = p_constant->values[0].sint;
3670 }
3671 return true;
3672 } else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_FLOAT) {
3673 if (p_value) {
3674 p_value->real = p_constant->values[0].uint;
3675 }
3676 return true;
3677 } else if (p_constant->datatype == TYPE_INT && p_to_type == TYPE_UINT) {
3678 if (p_constant->values[0].sint < 0) {
3679 return false;
3680 }
3681 if (p_value) {
3682 p_value->uint = p_constant->values[0].sint;
3683 }
3684 return true;
3685 } else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_INT) {
3686 if (p_constant->values[0].uint > 0x7FFFFFFF) {
3687 return false;
3688 }
3689 if (p_value) {
3690 p_value->sint = p_constant->values[0].uint;
3691 }
3692 return true;
3693 } else {
3694 return false;
3695 }
3696}
3697
3698bool ShaderLanguage::is_scalar_type(DataType p_type) {
3699 return p_type == TYPE_BOOL || p_type == TYPE_INT || p_type == TYPE_UINT || p_type == TYPE_FLOAT;
3700}
3701
3702bool ShaderLanguage::is_float_type(DataType p_type) {
3703 switch (p_type) {
3704 case TYPE_FLOAT:
3705 case TYPE_VEC2:
3706 case TYPE_VEC3:
3707 case TYPE_VEC4:
3708 case TYPE_MAT2:
3709 case TYPE_MAT3:
3710 case TYPE_MAT4:
3711 case TYPE_SAMPLER2D:
3712 case TYPE_SAMPLER2DARRAY:
3713 case TYPE_SAMPLER3D:
3714 case TYPE_SAMPLERCUBE:
3715 case TYPE_SAMPLERCUBEARRAY: {
3716 return true;
3717 }
3718 default: {
3719 return false;
3720 }
3721 }
3722}
3723bool ShaderLanguage::is_sampler_type(DataType p_type) {
3724 return p_type > TYPE_MAT4 && p_type < TYPE_STRUCT;
3725}
3726
3727Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
3728 int array_size = p_array_size;
3729
3730 if (p_value.size() > 0) {
3731 Variant value;
3732 switch (p_type) {
3733 case ShaderLanguage::TYPE_BOOL:
3734 if (array_size > 0) {
3735 PackedInt32Array array;
3736 for (int i = 0; i < array_size; i++) {
3737 array.push_back(p_value[i].boolean);
3738 }
3739 value = Variant(array);
3740 } else {
3741 value = Variant(p_value[0].boolean);
3742 }
3743 break;
3744 case ShaderLanguage::TYPE_BVEC2:
3745 array_size *= 2;
3746
3747 if (array_size > 0) {
3748 PackedInt32Array array;
3749 for (int i = 0; i < array_size; i++) {
3750 array.push_back(p_value[i].boolean);
3751 }
3752 value = Variant(array);
3753 } else {
3754 value = Variant(p_value[0].boolean);
3755 }
3756 break;
3757 case ShaderLanguage::TYPE_BVEC3:
3758 array_size *= 3;
3759
3760 if (array_size > 0) {
3761 PackedInt32Array array;
3762 for (int i = 0; i < array_size; i++) {
3763 array.push_back(p_value[i].boolean);
3764 }
3765 value = Variant(array);
3766 } else {
3767 value = Variant(p_value[0].boolean);
3768 }
3769 break;
3770 case ShaderLanguage::TYPE_BVEC4:
3771 array_size *= 4;
3772
3773 if (array_size > 0) {
3774 PackedInt32Array array;
3775 for (int i = 0; i < array_size; i++) {
3776 array.push_back(p_value[i].boolean);
3777 }
3778 value = Variant(array);
3779 } else {
3780 value = Variant(p_value[0].boolean);
3781 }
3782 break;
3783 case ShaderLanguage::TYPE_INT:
3784 if (array_size > 0) {
3785 PackedInt32Array array;
3786 for (int i = 0; i < array_size; i++) {
3787 array.push_back(p_value[i].sint);
3788 }
3789 value = Variant(array);
3790 } else {
3791 value = Variant(p_value[0].sint);
3792 }
3793 break;
3794 case ShaderLanguage::TYPE_IVEC2:
3795 if (array_size > 0) {
3796 array_size *= 2;
3797
3798 PackedInt32Array array;
3799 for (int i = 0; i < array_size; i++) {
3800 array.push_back(p_value[i].sint);
3801 }
3802 value = Variant(array);
3803 } else {
3804 value = Variant(Vector2i(p_value[0].sint, p_value[1].sint));
3805 }
3806 break;
3807 case ShaderLanguage::TYPE_IVEC3:
3808 if (array_size > 0) {
3809 array_size *= 3;
3810
3811 PackedInt32Array array;
3812 for (int i = 0; i < array_size; i++) {
3813 array.push_back(p_value[i].sint);
3814 }
3815 value = Variant(array);
3816 } else {
3817 value = Variant(Vector3i(p_value[0].sint, p_value[1].sint, p_value[2].sint));
3818 }
3819 break;
3820 case ShaderLanguage::TYPE_IVEC4:
3821 if (array_size > 0) {
3822 array_size *= 4;
3823
3824 PackedInt32Array array;
3825 for (int i = 0; i < array_size; i++) {
3826 array.push_back(p_value[i].sint);
3827 }
3828 value = Variant(array);
3829 } else {
3830 value = Variant(Vector4i(p_value[0].sint, p_value[1].sint, p_value[2].sint, p_value[3].sint));
3831 }
3832 break;
3833 case ShaderLanguage::TYPE_UINT:
3834 if (array_size > 0) {
3835 PackedInt32Array array;
3836 for (int i = 0; i < array_size; i++) {
3837 array.push_back(p_value[i].uint);
3838 }
3839 value = Variant(array);
3840 } else {
3841 value = Variant(p_value[0].uint);
3842 }
3843 break;
3844 case ShaderLanguage::TYPE_UVEC2:
3845 if (array_size > 0) {
3846 array_size *= 2;
3847
3848 PackedInt32Array array;
3849 for (int i = 0; i < array_size; i++) {
3850 array.push_back(p_value[i].uint);
3851 }
3852 value = Variant(array);
3853 } else {
3854 value = Variant(Vector2i(p_value[0].uint, p_value[1].uint));
3855 }
3856 break;
3857 case ShaderLanguage::TYPE_UVEC3:
3858 if (array_size > 0) {
3859 array_size *= 3;
3860
3861 PackedInt32Array array;
3862 for (int i = 0; i < array_size; i++) {
3863 array.push_back(p_value[i].uint);
3864 }
3865 value = Variant(array);
3866 } else {
3867 value = Variant(Vector3i(p_value[0].uint, p_value[1].uint, p_value[2].uint));
3868 }
3869 break;
3870 case ShaderLanguage::TYPE_UVEC4:
3871 if (array_size > 0) {
3872 array_size *= 4;
3873
3874 PackedInt32Array array;
3875 for (int i = 0; i < array_size; i++) {
3876 array.push_back(p_value[i].uint);
3877 }
3878 value = Variant(array);
3879 } else {
3880 value = Variant(Vector4i(p_value[0].uint, p_value[1].uint, p_value[2].uint, p_value[3].uint));
3881 }
3882 break;
3883 case ShaderLanguage::TYPE_FLOAT:
3884 if (array_size > 0) {
3885 PackedFloat32Array array;
3886 for (int i = 0; i < array_size; i++) {
3887 array.push_back(p_value[i].real);
3888 }
3889 value = Variant(array);
3890 } else {
3891 value = Variant(p_value[0].real);
3892 }
3893 break;
3894 case ShaderLanguage::TYPE_VEC2:
3895 if (array_size > 0) {
3896 array_size *= 2;
3897
3898 PackedVector2Array array;
3899 for (int i = 0; i < array_size; i += 2) {
3900 array.push_back(Vector2(p_value[i].real, p_value[i + 1].real));
3901 }
3902 value = Variant(array);
3903 } else {
3904 value = Variant(Vector2(p_value[0].real, p_value[1].real));
3905 }
3906 break;
3907 case ShaderLanguage::TYPE_VEC3:
3908 if (array_size > 0) {
3909 array_size *= 3;
3910
3911 if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
3912 PackedColorArray array;
3913 for (int i = 0; i < array_size; i += 3) {
3914 array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
3915 }
3916 value = Variant(array);
3917 } else {
3918 PackedVector3Array array;
3919 for (int i = 0; i < array_size; i += 3) {
3920 array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
3921 }
3922 value = Variant(array);
3923 }
3924 } else {
3925 if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
3926 value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real));
3927 } else {
3928 value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
3929 }
3930 }
3931 break;
3932 case ShaderLanguage::TYPE_VEC4:
3933 if (array_size > 0) {
3934 array_size *= 4;
3935
3936 if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
3937 PackedColorArray array;
3938 for (int i = 0; i < array_size; i += 4) {
3939 array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real, p_value[i + 3].real));
3940 }
3941 value = Variant(array);
3942 } else {
3943 PackedFloat32Array array;
3944 for (int i = 0; i < array_size; i += 4) {
3945 array.push_back(p_value[i].real);
3946 array.push_back(p_value[i + 1].real);
3947 array.push_back(p_value[i + 2].real);
3948 array.push_back(p_value[i + 3].real);
3949 }
3950 value = Variant(array);
3951 }
3952 } else {
3953 if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
3954 value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
3955 } else {
3956 value = Variant(Vector4(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
3957 }
3958 }
3959 break;
3960 case ShaderLanguage::TYPE_MAT2:
3961 if (array_size > 0) {
3962 array_size *= 4;
3963
3964 PackedFloat32Array array;
3965 for (int i = 0; i < array_size; i += 4) {
3966 array.push_back(p_value[i].real);
3967 array.push_back(p_value[i + 1].real);
3968 array.push_back(p_value[i + 2].real);
3969 array.push_back(p_value[i + 3].real);
3970 }
3971 value = Variant(array);
3972 } else {
3973 value = Variant(Transform2D(p_value[0].real, p_value[2].real, p_value[1].real, p_value[3].real, 0.0, 0.0));
3974 }
3975 break;
3976 case ShaderLanguage::TYPE_MAT3: {
3977 if (array_size > 0) {
3978 array_size *= 9;
3979
3980 PackedFloat32Array array;
3981 for (int i = 0; i < array_size; i += 9) {
3982 for (int j = 0; j < 9; j++) {
3983 array.push_back(p_value[i + j].real);
3984 }
3985 }
3986 value = Variant(array);
3987 } else {
3988 Basis p;
3989 p[0][0] = p_value[0].real;
3990 p[0][1] = p_value[1].real;
3991 p[0][2] = p_value[2].real;
3992 p[1][0] = p_value[3].real;
3993 p[1][1] = p_value[4].real;
3994 p[1][2] = p_value[5].real;
3995 p[2][0] = p_value[6].real;
3996 p[2][1] = p_value[7].real;
3997 p[2][2] = p_value[8].real;
3998 value = Variant(p);
3999 }
4000 break;
4001 }
4002 case ShaderLanguage::TYPE_MAT4: {
4003 if (array_size > 0) {
4004 array_size *= 16;
4005
4006 PackedFloat32Array array;
4007 for (int i = 0; i < array_size; i += 16) {
4008 for (int j = 0; j < 16; j++) {
4009 array.push_back(p_value[i + j].real);
4010 }
4011 }
4012 value = Variant(array);
4013 } else {
4014 Projection p = Projection(Vector4(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real),
4015 Vector4(p_value[4].real, p_value[5].real, p_value[6].real, p_value[7].real),
4016 Vector4(p_value[8].real, p_value[9].real, p_value[10].real, p_value[11].real),
4017 Vector4(p_value[12].real, p_value[13].real, p_value[14].real, p_value[15].real));
4018 value = Variant(p);
4019 }
4020 break;
4021 }
4022 case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
4023 case ShaderLanguage::TYPE_ISAMPLER2D:
4024 case ShaderLanguage::TYPE_ISAMPLER3D:
4025 case ShaderLanguage::TYPE_SAMPLER2DARRAY:
4026 case ShaderLanguage::TYPE_SAMPLER2D:
4027 case ShaderLanguage::TYPE_SAMPLER3D:
4028 case ShaderLanguage::TYPE_USAMPLER2DARRAY:
4029 case ShaderLanguage::TYPE_USAMPLER2D:
4030 case ShaderLanguage::TYPE_USAMPLER3D:
4031 case ShaderLanguage::TYPE_SAMPLERCUBE:
4032 case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
4033 // Texture types, likely not relevant here.
4034 break;
4035 }
4036 case ShaderLanguage::TYPE_STRUCT:
4037 break;
4038 case ShaderLanguage::TYPE_VOID:
4039 break;
4040 case ShaderLanguage::TYPE_MAX:
4041 break;
4042 }
4043 return value;
4044 }
4045 return Variant();
4046}
4047
4048PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform &p_uniform) {
4049 PropertyInfo pi;
4050 switch (p_uniform.type) {
4051 case ShaderLanguage::TYPE_VOID:
4052 pi.type = Variant::NIL;
4053 break;
4054 case ShaderLanguage::TYPE_BOOL:
4055 if (p_uniform.array_size > 0) {
4056 pi.type = Variant::PACKED_INT32_ARRAY;
4057 } else {
4058 pi.type = Variant::BOOL;
4059 }
4060 break;
4061 case ShaderLanguage::TYPE_BVEC2:
4062 if (p_uniform.array_size > 0) {
4063 pi.type = Variant::PACKED_INT32_ARRAY;
4064 } else {
4065 pi.type = Variant::INT;
4066 pi.hint = PROPERTY_HINT_FLAGS;
4067 pi.hint_string = "x,y";
4068 }
4069 break;
4070 case ShaderLanguage::TYPE_BVEC3:
4071 if (p_uniform.array_size > 0) {
4072 pi.type = Variant::PACKED_INT32_ARRAY;
4073 } else {
4074 pi.type = Variant::INT;
4075 pi.hint = PROPERTY_HINT_FLAGS;
4076 pi.hint_string = "x,y,z";
4077 }
4078 break;
4079 case ShaderLanguage::TYPE_BVEC4:
4080 if (p_uniform.array_size > 0) {
4081 pi.type = Variant::PACKED_INT32_ARRAY;
4082 } else {
4083 pi.type = Variant::INT;
4084 pi.hint = PROPERTY_HINT_FLAGS;
4085 pi.hint_string = "x,y,z,w";
4086 }
4087 break;
4088 case ShaderLanguage::TYPE_UINT:
4089 case ShaderLanguage::TYPE_INT: {
4090 if (p_uniform.array_size > 0) {
4091 pi.type = Variant::PACKED_INT32_ARRAY;
4092 } else {
4093 pi.type = Variant::INT;
4094 if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
4095 pi.hint = PROPERTY_HINT_RANGE;
4096 pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
4097 }
4098 }
4099 } break;
4100 case ShaderLanguage::TYPE_UVEC2:
4101 case ShaderLanguage::TYPE_IVEC2: {
4102 if (p_uniform.array_size > 0) {
4103 pi.type = Variant::PACKED_INT32_ARRAY;
4104 } else {
4105 pi.type = Variant::VECTOR2I;
4106 }
4107 } break;
4108 case ShaderLanguage::TYPE_UVEC3:
4109 case ShaderLanguage::TYPE_IVEC3: {
4110 if (p_uniform.array_size > 0) {
4111 pi.type = Variant::PACKED_INT32_ARRAY;
4112 } else {
4113 pi.type = Variant::VECTOR3I;
4114 }
4115 } break;
4116 case ShaderLanguage::TYPE_UVEC4:
4117 case ShaderLanguage::TYPE_IVEC4: {
4118 if (p_uniform.array_size > 0) {
4119 pi.type = Variant::PACKED_INT32_ARRAY;
4120 } else {
4121 pi.type = Variant::VECTOR4I;
4122 }
4123 } break;
4124 case ShaderLanguage::TYPE_FLOAT: {
4125 if (p_uniform.array_size > 0) {
4126 pi.type = Variant::PACKED_FLOAT32_ARRAY;
4127 } else {
4128 pi.type = Variant::FLOAT;
4129 if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
4130 pi.hint = PROPERTY_HINT_RANGE;
4131 pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
4132 }
4133 }
4134 } break;
4135 case ShaderLanguage::TYPE_VEC2:
4136 if (p_uniform.array_size > 0) {
4137 pi.type = Variant::PACKED_VECTOR2_ARRAY;
4138 } else {
4139 pi.type = Variant::VECTOR2;
4140 }
4141 break;
4142 case ShaderLanguage::TYPE_VEC3:
4143 if (p_uniform.array_size > 0) {
4144 if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
4145 pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
4146 pi.type = Variant::PACKED_COLOR_ARRAY;
4147 } else {
4148 pi.type = Variant::PACKED_VECTOR3_ARRAY;
4149 }
4150 } else {
4151 if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
4152 pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
4153 pi.type = Variant::COLOR;
4154 } else {
4155 pi.type = Variant::VECTOR3;
4156 }
4157 }
4158 break;
4159 case ShaderLanguage::TYPE_VEC4: {
4160 if (p_uniform.array_size > 0) {
4161 if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
4162 pi.type = Variant::PACKED_COLOR_ARRAY;
4163 } else {
4164 pi.type = Variant::PACKED_FLOAT32_ARRAY;
4165 }
4166 } else {
4167 if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
4168 pi.type = Variant::COLOR;
4169 } else {
4170 pi.type = Variant::VECTOR4;
4171 }
4172 }
4173 } break;
4174 case ShaderLanguage::TYPE_MAT2:
4175 if (p_uniform.array_size > 0) {
4176 pi.type = Variant::PACKED_FLOAT32_ARRAY;
4177 } else {
4178 pi.type = Variant::TRANSFORM2D;
4179 }
4180 break;
4181 case ShaderLanguage::TYPE_MAT3:
4182 if (p_uniform.array_size > 0) {
4183 pi.type = Variant::PACKED_FLOAT32_ARRAY;
4184 } else {
4185 pi.type = Variant::BASIS;
4186 }
4187 break;
4188 case ShaderLanguage::TYPE_MAT4:
4189 if (p_uniform.array_size > 0) {
4190 pi.type = Variant::PACKED_FLOAT32_ARRAY;
4191 } else {
4192 pi.type = Variant::PROJECTION;
4193 }
4194 break;
4195 case ShaderLanguage::TYPE_SAMPLER2D:
4196 case ShaderLanguage::TYPE_ISAMPLER2D:
4197 case ShaderLanguage::TYPE_USAMPLER2D: {
4198 if (p_uniform.array_size > 0) {
4199 pi.type = Variant::ARRAY;
4200 pi.hint = PROPERTY_HINT_ARRAY_TYPE;
4201 pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture2D");
4202 } else {
4203 pi.type = Variant::OBJECT;
4204 pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
4205 pi.hint_string = "Texture2D";
4206 }
4207 } break;
4208 case ShaderLanguage::TYPE_SAMPLER2DARRAY:
4209 case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
4210 case ShaderLanguage::TYPE_USAMPLER2DARRAY:
4211 case ShaderLanguage::TYPE_SAMPLERCUBE:
4212 case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
4213 if (p_uniform.array_size > 0) {
4214 pi.type = Variant::ARRAY;
4215 pi.hint = PROPERTY_HINT_ARRAY_TYPE;
4216 pi.hint_string = MAKE_RESOURCE_TYPE_HINT("TextureLayered");
4217 } else {
4218 pi.type = Variant::OBJECT;
4219 pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
4220 pi.hint_string = "TextureLayered";
4221 }
4222 } break;
4223 case ShaderLanguage::TYPE_SAMPLER3D:
4224 case ShaderLanguage::TYPE_ISAMPLER3D:
4225 case ShaderLanguage::TYPE_USAMPLER3D: {
4226 if (p_uniform.array_size > 0) {
4227 pi.type = Variant::ARRAY;
4228 pi.hint = PROPERTY_HINT_ARRAY_TYPE;
4229 pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture3D");
4230 } else {
4231 pi.type = Variant::OBJECT;
4232 pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
4233 pi.hint_string = "Texture3D";
4234 }
4235 } break;
4236 case ShaderLanguage::TYPE_STRUCT: {
4237 // FIXME: Implement this.
4238 } break;
4239 case ShaderLanguage::TYPE_MAX:
4240 break;
4241 }
4242 return pi;
4243}
4244
4245uint32_t ShaderLanguage::get_datatype_size(ShaderLanguage::DataType p_type) {
4246 switch (p_type) {
4247 case TYPE_VOID:
4248 return 0;
4249 case TYPE_BOOL:
4250 return 4;
4251 case TYPE_BVEC2:
4252 return 8;
4253 case TYPE_BVEC3:
4254 return 12;
4255 case TYPE_BVEC4:
4256 return 16;
4257 case TYPE_INT:
4258 return 4;
4259 case TYPE_IVEC2:
4260 return 8;
4261 case TYPE_IVEC3:
4262 return 12;
4263 case TYPE_IVEC4:
4264 return 16;
4265 case TYPE_UINT:
4266 return 4;
4267 case TYPE_UVEC2:
4268 return 8;
4269 case TYPE_UVEC3:
4270 return 12;
4271 case TYPE_UVEC4:
4272 return 16;
4273 case TYPE_FLOAT:
4274 return 4;
4275 case TYPE_VEC2:
4276 return 8;
4277 case TYPE_VEC3:
4278 return 12;
4279 case TYPE_VEC4:
4280 return 16;
4281 case TYPE_MAT2:
4282 return 32; // 4 * 4 + 4 * 4
4283 case TYPE_MAT3:
4284 return 48; // 4 * 4 + 4 * 4 + 4 * 4
4285 case TYPE_MAT4:
4286 return 64;
4287 case TYPE_SAMPLER2D:
4288 return 16;
4289 case TYPE_ISAMPLER2D:
4290 return 16;
4291 case TYPE_USAMPLER2D:
4292 return 16;
4293 case TYPE_SAMPLER2DARRAY:
4294 return 16;
4295 case TYPE_ISAMPLER2DARRAY:
4296 return 16;
4297 case TYPE_USAMPLER2DARRAY:
4298 return 16;
4299 case TYPE_SAMPLER3D:
4300 return 16;
4301 case TYPE_ISAMPLER3D:
4302 return 16;
4303 case TYPE_USAMPLER3D:
4304 return 16;
4305 case TYPE_SAMPLERCUBE:
4306 return 16;
4307 case TYPE_SAMPLERCUBEARRAY:
4308 return 16;
4309 case TYPE_STRUCT:
4310 return 0;
4311 case TYPE_MAX: {
4312 ERR_FAIL_V(0);
4313 };
4314 }
4315 ERR_FAIL_V(0);
4316}
4317
4318void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
4319 HashSet<String> kws;
4320
4321 int idx = 0;
4322
4323 while (keyword_list[idx].text) {
4324 kws.insert(keyword_list[idx].text);
4325 idx++;
4326 }
4327
4328 idx = 0;
4329
4330 while (builtin_func_defs[idx].name) {
4331 kws.insert(builtin_func_defs[idx].name);
4332
4333 idx++;
4334 }
4335
4336 for (const String &E : kws) {
4337 r_keywords->push_back(E);
4338 }
4339}
4340
4341bool ShaderLanguage::is_control_flow_keyword(String p_keyword) {
4342 return p_keyword == "break" ||
4343 p_keyword == "case" ||
4344 p_keyword == "continue" ||
4345 p_keyword == "default" ||
4346 p_keyword == "do" ||
4347 p_keyword == "else" ||
4348 p_keyword == "for" ||
4349 p_keyword == "if" ||
4350 p_keyword == "return" ||
4351 p_keyword == "switch" ||
4352 p_keyword == "while";
4353}
4354
4355void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) {
4356 HashSet<String> kws;
4357
4358 int idx = 0;
4359
4360 while (builtin_func_defs[idx].name) {
4361 kws.insert(builtin_func_defs[idx].name);
4362
4363 idx++;
4364 }
4365
4366 for (const String &E : kws) {
4367 r_keywords->push_back(E);
4368 }
4369}
4370
4371ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) {
4372 static const DataType scalar_types[] = {
4373 TYPE_VOID,
4374 TYPE_BOOL,
4375 TYPE_BOOL,
4376 TYPE_BOOL,
4377 TYPE_BOOL,
4378 TYPE_INT,
4379 TYPE_INT,
4380 TYPE_INT,
4381 TYPE_INT,
4382 TYPE_UINT,
4383 TYPE_UINT,
4384 TYPE_UINT,
4385 TYPE_UINT,
4386 TYPE_FLOAT,
4387 TYPE_FLOAT,
4388 TYPE_FLOAT,
4389 TYPE_FLOAT,
4390 TYPE_FLOAT,
4391 TYPE_FLOAT,
4392 TYPE_FLOAT,
4393 TYPE_FLOAT,
4394 TYPE_INT,
4395 TYPE_UINT,
4396 TYPE_FLOAT,
4397 TYPE_INT,
4398 TYPE_UINT,
4399 TYPE_FLOAT,
4400 TYPE_INT,
4401 TYPE_UINT,
4402 TYPE_FLOAT,
4403 TYPE_FLOAT,
4404 TYPE_VOID,
4405 };
4406
4407 static_assert(sizeof(scalar_types) / sizeof(*scalar_types) == TYPE_MAX);
4408
4409 return scalar_types[p_type];
4410}
4411
4412int ShaderLanguage::get_cardinality(DataType p_type) {
4413 static const int cardinality_table[] = {
4414 0,
4415 1,
4416 2,
4417 3,
4418 4,
4419 1,
4420 2,
4421 3,
4422 4,
4423 1,
4424 2,
4425 3,
4426 4,
4427 1,
4428 2,
4429 3,
4430 4,
4431 4,
4432 9,
4433 16,
4434 1,
4435 1,
4436 1,
4437 1,
4438 1,
4439 1,
4440 1,
4441 1,
4442 1,
4443 1,
4444 1,
4445 1,
4446 };
4447
4448 static_assert(sizeof(cardinality_table) / sizeof(*cardinality_table) == TYPE_MAX);
4449
4450 return cardinality_table[p_type];
4451}
4452
4453bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier) {
4454 identifier = StringName();
4455
4456 TkPos pos = { 0, 0 };
4457
4458 Token tk = _get_token();
4459
4460 if (tk.type == TK_IDENTIFIER) {
4461 identifier = tk.text;
4462 pos = _get_tkpos();
4463 tk = _get_token();
4464 }
4465
4466 if (tk.type == TK_CURSOR) {
4467 completion_type = p_type;
4468 completion_line = tk_line;
4469 completion_block = p_block;
4470
4471 pos = _get_tkpos();
4472 tk = _get_token();
4473
4474 if (tk.type == TK_IDENTIFIER) {
4475 identifier = identifier.operator String() + tk.text.operator String();
4476 } else {
4477 _set_tkpos(pos);
4478 }
4479 return true;
4480 } else if (identifier != StringName()) {
4481 _set_tkpos(pos);
4482 }
4483
4484 return false;
4485}
4486
4487bool ShaderLanguage::_is_operator_assign(Operator p_op) const {
4488 switch (p_op) {
4489 case OP_ASSIGN:
4490 case OP_ASSIGN_ADD:
4491 case OP_ASSIGN_SUB:
4492 case OP_ASSIGN_MUL:
4493 case OP_ASSIGN_DIV:
4494 case OP_ASSIGN_MOD:
4495 case OP_ASSIGN_SHIFT_LEFT:
4496 case OP_ASSIGN_SHIFT_RIGHT:
4497 case OP_ASSIGN_BIT_AND:
4498 case OP_ASSIGN_BIT_OR:
4499 case OP_ASSIGN_BIT_XOR:
4500 return true;
4501 default:
4502 return false;
4503 }
4504}
4505
4506bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message) {
4507 if (current_function != "vertex" && current_function != "fragment") {
4508 *r_message = vformat(RTR("Varying may not be assigned in the '%s' function."), current_function);
4509 return false;
4510 }
4511 switch (p_varying.stage) {
4512 case ShaderNode::Varying::STAGE_UNKNOWN: // first assign
4513 if (current_function == varying_function_names.vertex) {
4514 if (p_varying.type < TYPE_INT) {
4515 *r_message = vformat(RTR("Varying with '%s' data type may only be assigned in the 'fragment' function."), get_datatype_name(p_varying.type));
4516 return false;
4517 }
4518 p_varying.stage = ShaderNode::Varying::STAGE_VERTEX;
4519 } else if (current_function == varying_function_names.fragment) {
4520 p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT;
4521 }
4522 break;
4523 case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT:
4524 case ShaderNode::Varying::STAGE_VERTEX:
4525 if (current_function == varying_function_names.fragment) {
4526 *r_message = RTR("Varyings which assigned in 'vertex' function may not be reassigned in 'fragment' or 'light'.");
4527 return false;
4528 }
4529 break;
4530 case ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT:
4531 case ShaderNode::Varying::STAGE_FRAGMENT:
4532 if (current_function == varying_function_names.vertex) {
4533 *r_message = RTR("Varyings which assigned in 'fragment' function may not be reassigned in 'vertex' or 'light'.");
4534 return false;
4535 }
4536 break;
4537 default:
4538 break;
4539 }
4540 return true;
4541}
4542
4543bool ShaderLanguage::_check_node_constness(const Node *p_node) const {
4544 switch (p_node->type) {
4545 case Node::NODE_TYPE_OPERATOR: {
4546 const OperatorNode *op_node = static_cast<const OperatorNode *>(p_node);
4547 for (int i = int(op_node->op == OP_CALL); i < op_node->arguments.size(); i++) {
4548 if (!_check_node_constness(op_node->arguments[i])) {
4549 return false;
4550 }
4551 }
4552 } break;
4553 case Node::NODE_TYPE_CONSTANT:
4554 break;
4555 case Node::NODE_TYPE_VARIABLE: {
4556 const VariableNode *var_node = static_cast<const VariableNode *>(p_node);
4557 if (!var_node->is_const) {
4558 return false;
4559 }
4560 } break;
4561 case Node::NODE_TYPE_ARRAY: {
4562 const ArrayNode *arr_node = static_cast<const ArrayNode *>(p_node);
4563 if (!arr_node->is_const) {
4564 return false;
4565 }
4566 } break;
4567 default:
4568 return false;
4569 }
4570 return true;
4571}
4572
4573bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message) {
4574 if (p_node->type == Node::NODE_TYPE_OPERATOR) {
4575 OperatorNode *op = static_cast<OperatorNode *>(p_node);
4576
4577 if (op->op == OP_INDEX) {
4578 return _validate_assign(op->arguments[0], p_function_info, r_message);
4579
4580 } else if (_is_operator_assign(op->op)) {
4581 //chained assignment
4582 return _validate_assign(op->arguments[1], p_function_info, r_message);
4583
4584 } else if (op->op == OP_CALL) {
4585 if (r_message) {
4586 *r_message = RTR("Assignment to function.");
4587 }
4588 return false;
4589 }
4590
4591 } else if (p_node->type == Node::NODE_TYPE_MEMBER) {
4592 MemberNode *member = static_cast<MemberNode *>(p_node);
4593
4594 if (member->has_swizzling_duplicates) {
4595 if (r_message) {
4596 *r_message = RTR("Swizzling assignment contains duplicates.");
4597 }
4598 return false;
4599 }
4600
4601 return _validate_assign(member->owner, p_function_info, r_message);
4602
4603 } else if (p_node->type == Node::NODE_TYPE_VARIABLE) {
4604 VariableNode *var = static_cast<VariableNode *>(p_node);
4605
4606 if (shader->uniforms.has(var->name)) {
4607 if (r_message) {
4608 *r_message = RTR("Assignment to uniform.");
4609 }
4610 return false;
4611 }
4612
4613 if (shader->constants.has(var->name) || var->is_const) {
4614 if (r_message) {
4615 *r_message = RTR("Constants cannot be modified.");
4616 }
4617 return false;
4618 }
4619
4620 if (!(p_function_info.built_ins.has(var->name) && p_function_info.built_ins[var->name].constant)) {
4621 return true;
4622 }
4623 } else if (p_node->type == Node::NODE_TYPE_ARRAY) {
4624 ArrayNode *arr = static_cast<ArrayNode *>(p_node);
4625
4626 if (shader->constants.has(arr->name) || arr->is_const) {
4627 if (r_message) {
4628 *r_message = RTR("Constants cannot be modified.");
4629 }
4630 return false;
4631 }
4632
4633 return true;
4634 }
4635
4636 if (r_message) {
4637 *r_message = "Assignment to constant expression.";
4638 }
4639 return false;
4640}
4641
4642bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat) {
4643 for (int i = 0; i < shader->functions.size(); i++) {
4644 if (shader->functions[i].name == p_name) {
4645 ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
4646 FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
4647 if (arg->tex_builtin_check) {
4648 _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)));
4649 return false;
4650 } else if (arg->tex_argument_check) {
4651 //was checked, verify that filter and repeat are the same
4652 if (arg->tex_argument_filter == p_filter && arg->tex_argument_repeat == p_repeat) {
4653 return true;
4654 } else {
4655 _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)));
4656 return false;
4657 }
4658 } else {
4659 arg->tex_argument_check = true;
4660 arg->tex_argument_filter = p_filter;
4661 arg->tex_argument_repeat = p_repeat;
4662 for (KeyValue<StringName, HashSet<int>> &E : arg->tex_argument_connect) {
4663 for (const int &F : E.value) {
4664 if (!_propagate_function_call_sampler_uniform_settings(E.key, F, p_filter, p_repeat)) {
4665 return false;
4666 }
4667 }
4668 }
4669 return true;
4670 }
4671 }
4672 }
4673 ERR_FAIL_V(false); //bug? function not found
4674}
4675
4676bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin) {
4677 for (int i = 0; i < shader->functions.size(); i++) {
4678 if (shader->functions[i].name == p_name) {
4679 ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
4680 FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
4681 if (arg->tex_argument_check) {
4682 _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)));
4683 return false;
4684 } else if (arg->tex_builtin_check) {
4685 //was checked, verify that the built-in is the same
4686 if (arg->tex_builtin == p_builtin) {
4687 return true;
4688 } else {
4689 _set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using different built-ins. Only calling with the same built-in is supported."), p_argument, String(p_name)));
4690 return false;
4691 }
4692 } else {
4693 arg->tex_builtin_check = true;
4694 arg->tex_builtin = p_builtin;
4695
4696 for (KeyValue<StringName, HashSet<int>> &E : arg->tex_argument_connect) {
4697 for (const int &F : E.value) {
4698 if (!_propagate_function_call_sampler_builtin_reference(E.key, F, p_builtin)) {
4699 return false;
4700 }
4701 }
4702 }
4703 return true;
4704 }
4705 }
4706 }
4707 ERR_FAIL_V(false); //bug? function not found
4708}
4709
4710Error ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_forbid_unknown_size, Node **r_size_expression, int *r_array_size, bool *r_unknown_size) {
4711 bool error = false;
4712 if (r_array_size != nullptr && *r_array_size > 0) {
4713 error = true;
4714 }
4715 if (r_unknown_size != nullptr && *r_unknown_size) {
4716 error = true;
4717 }
4718 if (error) {
4719 _set_error(vformat(RTR("Array size is already defined.")));
4720 return ERR_PARSE_ERROR;
4721 }
4722
4723 TkPos pos = _get_tkpos();
4724 Token tk = _get_token();
4725
4726 if (tk.type == TK_BRACKET_CLOSE) {
4727 if (p_forbid_unknown_size) {
4728 _set_error(vformat(RTR("Unknown array size is forbidden in that context.")));
4729 return ERR_PARSE_ERROR;
4730 }
4731 if (r_unknown_size != nullptr) {
4732 *r_unknown_size = true;
4733 }
4734 } else {
4735 int array_size = 0;
4736
4737 if (!tk.is_integer_constant() || ((int)tk.constant) <= 0) {
4738 _set_tkpos(pos);
4739 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
4740 if (n) {
4741 if (n->type == Node::NODE_TYPE_VARIABLE) {
4742 VariableNode *vn = static_cast<VariableNode *>(n);
4743 if (vn) {
4744 ConstantNode::Value v;
4745 DataType data_type;
4746 bool is_const = false;
4747
4748 _find_identifier(p_block, false, p_function_info, vn->name, &data_type, nullptr, &is_const, nullptr, nullptr, &v);
4749
4750 if (is_const) {
4751 if (data_type == TYPE_INT) {
4752 int32_t value = v.sint;
4753 if (value > 0) {
4754 array_size = value;
4755 }
4756 } else if (data_type == TYPE_UINT) {
4757 uint32_t value = v.uint;
4758 if (value > 0U) {
4759 array_size = value;
4760 }
4761 }
4762 }
4763 }
4764 } else if (n->type == Node::NODE_TYPE_OPERATOR) {
4765 _set_error(vformat(RTR("Array size expressions are not supported.")));
4766 return ERR_PARSE_ERROR;
4767 }
4768 if (r_size_expression != nullptr) {
4769 *r_size_expression = n;
4770 }
4771 }
4772 } else if (((int)tk.constant) > 0) {
4773 array_size = (uint32_t)tk.constant;
4774 }
4775
4776 if (array_size <= 0) {
4777 _set_error(RTR("Expected a positive integer constant."));
4778 return ERR_PARSE_ERROR;
4779 }
4780
4781 tk = _get_token();
4782 if (tk.type != TK_BRACKET_CLOSE) {
4783 _set_expected_error("]");
4784 return ERR_PARSE_ERROR;
4785 }
4786
4787 if (r_array_size != nullptr) {
4788 *r_array_size = array_size;
4789 }
4790 }
4791 return OK;
4792}
4793
4794ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info) {
4795 DataType type = TYPE_VOID;
4796 String struct_name = "";
4797 int array_size = 0;
4798 bool auto_size = false;
4799 bool undefined_size = false;
4800 Token tk = _get_token();
4801
4802 if (tk.type == TK_CURLY_BRACKET_OPEN) {
4803 auto_size = true;
4804 } else {
4805 if (shader->structs.has(tk.text)) {
4806 type = TYPE_STRUCT;
4807 struct_name = tk.text;
4808 } else {
4809 if (!is_token_variable_datatype(tk.type)) {
4810 _set_error(RTR("Invalid data type for the array."));
4811 return nullptr;
4812 }
4813 type = get_token_datatype(tk.type);
4814 }
4815 tk = _get_token();
4816 if (tk.type == TK_BRACKET_OPEN) {
4817 Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size, &undefined_size);
4818 if (error != OK) {
4819 return nullptr;
4820 }
4821 tk = _get_token();
4822 } else {
4823 _set_expected_error("[");
4824 return nullptr;
4825 }
4826 }
4827
4828 ArrayConstructNode *an = alloc_node<ArrayConstructNode>();
4829
4830 if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
4831 int idx = 0;
4832 while (true) {
4833 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
4834 if (!n) {
4835 return nullptr;
4836 }
4837
4838 // define type by using the first member
4839 if (auto_size && idx == 0) {
4840 type = n->get_datatype();
4841 if (type == TYPE_STRUCT) {
4842 struct_name = n->get_datatype_name();
4843 }
4844 } else {
4845 if (!_compare_datatypes(type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) {
4846 return nullptr;
4847 }
4848 }
4849
4850 tk = _get_token();
4851 if (tk.type == TK_COMMA) {
4852 an->initializer.push_back(n);
4853 } else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) {
4854 an->initializer.push_back(n);
4855 break;
4856 } else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) {
4857 an->initializer.push_back(n);
4858 break;
4859 } else {
4860 if (auto_size) {
4861 _set_expected_error("}", ",");
4862 } else {
4863 _set_expected_error(")", ",");
4864 }
4865 return nullptr;
4866 }
4867 idx++;
4868 }
4869 if (!auto_size && !undefined_size && an->initializer.size() != array_size) {
4870 _set_error(RTR("Array size mismatch."));
4871 return nullptr;
4872 }
4873 } else {
4874 _set_error(RTR("Expected array initialization."));
4875 return nullptr;
4876 }
4877
4878 an->datatype = type;
4879 an->struct_name = struct_name;
4880 return an;
4881}
4882
4883ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size) {
4884 DataType type = TYPE_VOID;
4885 String struct_name = "";
4886 int array_size = 0;
4887 bool auto_size = false;
4888 TkPos prev_pos = _get_tkpos();
4889 Token tk = _get_token();
4890
4891 if (tk.type == TK_CURLY_BRACKET_OPEN) {
4892 auto_size = true;
4893 } else {
4894 if (shader->structs.has(tk.text)) {
4895 type = TYPE_STRUCT;
4896 struct_name = tk.text;
4897 } else {
4898 if (!is_token_variable_datatype(tk.type)) {
4899 _set_tkpos(prev_pos);
4900
4901 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
4902
4903 if (!n) {
4904 _set_error(RTR("Invalid data type for the array."));
4905 return nullptr;
4906 }
4907
4908 if (!_compare_datatypes(p_type, p_struct_name, p_array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) {
4909 return nullptr;
4910 }
4911 return n;
4912 }
4913 type = get_token_datatype(tk.type);
4914 }
4915 tk = _get_token();
4916 if (tk.type == TK_BRACKET_OPEN) {
4917 bool is_unknown_size = false;
4918 Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size, &is_unknown_size);
4919 if (error != OK) {
4920 return nullptr;
4921 }
4922 if (is_unknown_size) {
4923 array_size = p_array_size;
4924 }
4925 tk = _get_token();
4926 } else {
4927 _set_expected_error("[");
4928 return nullptr;
4929 }
4930
4931 if (type != p_type || struct_name != p_struct_name || array_size != p_array_size) {
4932 String from;
4933 if (type == TYPE_STRUCT) {
4934 from += struct_name;
4935 } else {
4936 from += get_datatype_name(type);
4937 }
4938 from += "[";
4939 from += itos(array_size);
4940 from += "]'";
4941
4942 String to;
4943 if (type == TYPE_STRUCT) {
4944 to += p_struct_name;
4945 } else {
4946 to += get_datatype_name(p_type);
4947 }
4948 to += "[";
4949 to += itos(p_array_size);
4950 to += "]'";
4951
4952 _set_error(vformat(RTR("Cannot convert from '%s' to '%s'."), from, to));
4953 return nullptr;
4954 }
4955 }
4956
4957 ArrayConstructNode *an = alloc_node<ArrayConstructNode>();
4958 an->datatype = p_type;
4959 an->struct_name = p_struct_name;
4960
4961 if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
4962 while (true) {
4963 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
4964 if (!n) {
4965 return nullptr;
4966 }
4967
4968 if (!_compare_datatypes(p_type, p_struct_name, 0, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) {
4969 return nullptr;
4970 }
4971
4972 tk = _get_token();
4973 if (tk.type == TK_COMMA) {
4974 an->initializer.push_back(n);
4975 } else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) {
4976 an->initializer.push_back(n);
4977 break;
4978 } else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) {
4979 an->initializer.push_back(n);
4980 break;
4981 } else {
4982 if (auto_size) {
4983 _set_expected_error("}", ",");
4984 } else {
4985 _set_expected_error(")", ",");
4986 }
4987 return nullptr;
4988 }
4989 }
4990 if (an->initializer.size() != p_array_size) {
4991 _set_error(RTR("Array size mismatch."));
4992 return nullptr;
4993 }
4994 } else {
4995 _set_error(RTR("Expected array initialization."));
4996 return nullptr;
4997 }
4998
4999 return an;
5000}
5001
5002ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info) {
5003 Vector<Expression> expression;
5004
5005 //Vector<TokenType> operators;
5006
5007 while (true) {
5008 Node *expr = nullptr;
5009 TkPos prepos = _get_tkpos();
5010 Token tk = _get_token();
5011 TkPos pos = _get_tkpos();
5012
5013 bool is_const = false;
5014
5015 if (tk.type == TK_PARENTHESIS_OPEN) {
5016 //handle subexpression
5017
5018 expr = _parse_and_reduce_expression(p_block, p_function_info);
5019 if (!expr) {
5020 return nullptr;
5021 }
5022
5023 tk = _get_token();
5024
5025 if (tk.type != TK_PARENTHESIS_CLOSE) {
5026 _set_error(RTR("Expected ')' in expression."));
5027 return nullptr;
5028 }
5029
5030 } else if (tk.type == TK_FLOAT_CONSTANT) {
5031 ConstantNode *constant = alloc_node<ConstantNode>();
5032 ConstantNode::Value v;
5033 v.real = tk.constant;
5034 constant->values.push_back(v);
5035 constant->datatype = TYPE_FLOAT;
5036 expr = constant;
5037
5038 } else if (tk.type == TK_INT_CONSTANT) {
5039 ConstantNode *constant = alloc_node<ConstantNode>();
5040 ConstantNode::Value v;
5041 v.sint = tk.constant;
5042 constant->values.push_back(v);
5043 constant->datatype = TYPE_INT;
5044 expr = constant;
5045
5046 } else if (tk.type == TK_UINT_CONSTANT) {
5047 ConstantNode *constant = alloc_node<ConstantNode>();
5048 ConstantNode::Value v;
5049 v.uint = tk.constant;
5050 constant->values.push_back(v);
5051 constant->datatype = TYPE_UINT;
5052 expr = constant;
5053
5054 } else if (tk.type == TK_TRUE) {
5055 //handle true constant
5056 ConstantNode *constant = alloc_node<ConstantNode>();
5057 ConstantNode::Value v;
5058 v.boolean = true;
5059 constant->values.push_back(v);
5060 constant->datatype = TYPE_BOOL;
5061 expr = constant;
5062
5063 } else if (tk.type == TK_FALSE) {
5064 //handle false constant
5065 ConstantNode *constant = alloc_node<ConstantNode>();
5066 ConstantNode::Value v;
5067 v.boolean = false;
5068 constant->values.push_back(v);
5069 constant->datatype = TYPE_BOOL;
5070 expr = constant;
5071
5072 } else if (tk.type == TK_TYPE_VOID) {
5073 //make sure void is not used in expression
5074 _set_error(RTR("Void value not allowed in expression."));
5075 return nullptr;
5076 } else if (is_token_nonvoid_datatype(tk.type) || tk.type == TK_CURLY_BRACKET_OPEN) {
5077 if (tk.type == TK_CURLY_BRACKET_OPEN) {
5078 //array constructor
5079
5080 _set_tkpos(prepos);
5081 expr = _parse_array_constructor(p_block, p_function_info);
5082 } else {
5083 DataType datatype;
5084 DataPrecision precision = PRECISION_DEFAULT;
5085
5086 if (is_token_precision(tk.type)) {
5087 precision = get_token_precision(tk.type);
5088 tk = _get_token();
5089 }
5090
5091 datatype = get_token_datatype(tk.type);
5092 if (precision != PRECISION_DEFAULT && _validate_precision(datatype, precision) != OK) {
5093 return nullptr;
5094 }
5095
5096 tk = _get_token();
5097
5098 if (tk.type == TK_BRACKET_OPEN) {
5099 //array constructor
5100
5101 _set_tkpos(prepos);
5102 expr = _parse_array_constructor(p_block, p_function_info);
5103 } else {
5104 if (tk.type != TK_PARENTHESIS_OPEN) {
5105 _set_error(RTR("Expected '(' after the type name."));
5106 return nullptr;
5107 }
5108 //basic type constructor
5109
5110 OperatorNode *func = alloc_node<OperatorNode>();
5111 func->op = OP_CONSTRUCT;
5112
5113 if (precision != PRECISION_DEFAULT) {
5114 func->return_precision_cache = precision;
5115 }
5116
5117 VariableNode *funcname = alloc_node<VariableNode>();
5118 funcname->name = get_datatype_name(datatype);
5119 func->arguments.push_back(funcname);
5120
5121 int carg = -1;
5122
5123 bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg);
5124
5125 if (carg >= 0) {
5126 completion_type = COMPLETION_CALL_ARGUMENTS;
5127 completion_line = tk_line;
5128 completion_block = p_block;
5129 completion_function = funcname->name;
5130 completion_argument = carg;
5131 }
5132
5133 if (!ok) {
5134 return nullptr;
5135 }
5136
5137 if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) {
5138 _set_error(vformat(RTR("No matching constructor found for: '%s'."), String(funcname->name)));
5139 return nullptr;
5140 }
5141
5142 expr = _reduce_expression(p_block, func);
5143 }
5144 }
5145 } else if (tk.type == TK_IDENTIFIER) {
5146 _set_tkpos(prepos);
5147
5148 StringName identifier;
5149
5150 StructNode *pstruct = nullptr;
5151 bool struct_init = false;
5152
5153 _get_completable_identifier(p_block, COMPLETION_IDENTIFIER, identifier);
5154
5155 if (shader->structs.has(identifier)) {
5156 pstruct = shader->structs[identifier].shader_struct;
5157 struct_init = true;
5158 }
5159
5160 tk = _get_token();
5161 if (tk.type == TK_PARENTHESIS_OPEN) {
5162 if (struct_init) { //a struct constructor
5163
5164 const StringName &name = identifier;
5165
5166 OperatorNode *func = alloc_node<OperatorNode>();
5167 func->op = OP_STRUCT;
5168 func->struct_name = name;
5169 func->return_cache = TYPE_STRUCT;
5170 VariableNode *funcname = alloc_node<VariableNode>();
5171 funcname->name = name;
5172 func->arguments.push_back(funcname);
5173
5174 for (int i = 0; i < pstruct->members.size(); i++) {
5175 Node *nexpr;
5176
5177 if (pstruct->members[i]->array_size != 0) {
5178 nexpr = _parse_array_constructor(p_block, p_function_info, pstruct->members[i]->get_datatype(), pstruct->members[i]->struct_name, pstruct->members[i]->array_size);
5179 if (!nexpr) {
5180 return nullptr;
5181 }
5182 } else {
5183 nexpr = _parse_and_reduce_expression(p_block, p_function_info);
5184 if (!nexpr) {
5185 return nullptr;
5186 }
5187 if (!_compare_datatypes_in_nodes(pstruct->members[i], nexpr)) {
5188 return nullptr;
5189 }
5190 }
5191
5192 if (i + 1 < pstruct->members.size()) {
5193 tk = _get_token();
5194 if (tk.type != TK_COMMA) {
5195 _set_expected_error(",");
5196 return nullptr;
5197 }
5198 }
5199 func->arguments.push_back(nexpr);
5200 }
5201 tk = _get_token();
5202 if (tk.type != TK_PARENTHESIS_CLOSE) {
5203 _set_expected_error(")");
5204 return nullptr;
5205 }
5206
5207 expr = func;
5208
5209 } else { //a function call
5210 if (p_block == nullptr) { // Non-constructor function call in global space is forbidden.
5211 if (is_const_decl) {
5212 _set_error(RTR("Expected constant expression."));
5213 }
5214 return nullptr;
5215 }
5216
5217 const StringName &name = identifier;
5218
5219 OperatorNode *func = alloc_node<OperatorNode>();
5220 func->op = OP_CALL;
5221 VariableNode *funcname = alloc_node<VariableNode>();
5222 funcname->name = name;
5223 func->arguments.push_back(funcname);
5224
5225 int carg = -1;
5226
5227 bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg);
5228
5229 // Check if block has a variable with the same name as function to prevent shader crash.
5230 ShaderLanguage::BlockNode *bnode = p_block;
5231 while (bnode) {
5232 if (bnode->variables.has(name)) {
5233 _set_error(RTR("Expected a function name."));
5234 return nullptr;
5235 }
5236 bnode = bnode->parent_block;
5237 }
5238
5239 //test if function was parsed first
5240 int function_index = -1;
5241 for (int i = 0; i < shader->functions.size(); i++) {
5242 if (shader->functions[i].name == name) {
5243 //add to current function as dependency
5244 for (int j = 0; j < shader->functions.size(); j++) {
5245 if (shader->functions[j].name == current_function) {
5246 shader->functions.write[j].uses_function.insert(name);
5247 break;
5248 }
5249 }
5250
5251 //see if texture arguments must connect
5252 function_index = i;
5253 break;
5254 }
5255 }
5256
5257 if (carg >= 0) {
5258 completion_type = COMPLETION_CALL_ARGUMENTS;
5259 completion_line = tk_line;
5260 completion_block = p_block;
5261 completion_function = funcname->name;
5262 completion_argument = carg;
5263 }
5264
5265 if (!ok) {
5266 return nullptr;
5267 }
5268
5269 bool is_custom_func = false;
5270 if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name, &is_custom_func)) {
5271 _set_error(vformat(RTR("No matching function found for: '%s'."), String(funcname->name)));
5272 return nullptr;
5273 }
5274 completion_class = TAG_GLOBAL; // reset sub-class
5275 if (function_index >= 0) {
5276 //connect texture arguments, so we can cache in the
5277 //argument what type of filter and repeat to use
5278
5279 FunctionNode *call_function = shader->functions[function_index].function;
5280 if (call_function) {
5281 func->return_cache = call_function->get_datatype();
5282 func->struct_name = call_function->get_datatype_name();
5283 func->return_array_size = call_function->get_array_size();
5284
5285 //get current base function
5286 FunctionNode *base_function = nullptr;
5287 {
5288 BlockNode *b = p_block;
5289
5290 while (b) {
5291 if (b->parent_function) {
5292 base_function = b->parent_function;
5293 break;
5294 } else {
5295 b = b->parent_block;
5296 }
5297 }
5298 }
5299
5300 ERR_FAIL_COND_V(!base_function, nullptr); //bug, wtf
5301
5302 for (int i = 0; i < call_function->arguments.size(); i++) {
5303 int argidx = i + 1;
5304 if (argidx < func->arguments.size()) {
5305 bool error = false;
5306 Node *n = func->arguments[argidx];
5307 ArgumentQualifier arg_qual = call_function->arguments[i].qualifier;
5308 bool is_out_arg = arg_qual != ArgumentQualifier::ARGUMENT_QUALIFIER_IN;
5309
5310 if (n->type == Node::NODE_TYPE_VARIABLE || n->type == Node::NODE_TYPE_ARRAY) {
5311 StringName varname;
5312
5313 if (n->type == Node::NODE_TYPE_VARIABLE) {
5314 VariableNode *vn = static_cast<VariableNode *>(n);
5315 varname = vn->name;
5316 } else { // TYPE_ARRAY
5317 ArrayNode *an = static_cast<ArrayNode *>(n);
5318 varname = an->name;
5319 }
5320
5321 if (shader->varyings.has(varname)) {
5322 switch (shader->varyings[varname].stage) {
5323 case ShaderNode::Varying::STAGE_UNKNOWN: {
5324 _set_error(vformat(RTR("Varying '%s' must be assigned in the 'vertex' or 'fragment' function first."), varname));
5325 return nullptr;
5326 }
5327 case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT:
5328 [[fallthrough]];
5329 case ShaderNode::Varying::STAGE_VERTEX:
5330 if (is_out_arg && current_function != varying_function_names.vertex) { // inout/out
5331 error = true;
5332 }
5333 break;
5334 case ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT:
5335 [[fallthrough]];
5336 case ShaderNode::Varying::STAGE_FRAGMENT:
5337 if (!is_out_arg) {
5338 if (current_function != varying_function_names.fragment && current_function != varying_function_names.light) {
5339 error = true;
5340 }
5341 } else if (current_function != varying_function_names.fragment) { // inout/out
5342 error = true;
5343 }
5344 break;
5345 default:
5346 break;
5347 }
5348
5349 if (error) {
5350 _set_error(vformat(RTR("Varying '%s' cannot be passed for the '%s' parameter in that context."), varname, _get_qualifier_str(arg_qual)));
5351 return nullptr;
5352 }
5353 }
5354 }
5355
5356 bool is_const_arg = call_function->arguments[i].is_const;
5357
5358 if (is_const_arg || is_out_arg) {
5359 StringName varname;
5360
5361 if (n->type == Node::NODE_TYPE_CONSTANT || n->type == Node::NODE_TYPE_OPERATOR || n->type == Node::NODE_TYPE_ARRAY_CONSTRUCT) {
5362 if (!is_const_arg) {
5363 error = true;
5364 }
5365 } else if (n->type == Node::NODE_TYPE_ARRAY) {
5366 ArrayNode *an = static_cast<ArrayNode *>(n);
5367 if (!is_const_arg && (an->call_expression != nullptr || an->is_const)) {
5368 error = true;
5369 }
5370 varname = an->name;
5371 } else if (n->type == Node::NODE_TYPE_VARIABLE) {
5372 VariableNode *vn = static_cast<VariableNode *>(n);
5373 if (vn->is_const && !is_const_arg) {
5374 error = true;
5375 }
5376 varname = vn->name;
5377 } else if (n->type == Node::NODE_TYPE_MEMBER) {
5378 MemberNode *mn = static_cast<MemberNode *>(n);
5379 if (mn->basetype_const && is_out_arg) {
5380 error = true;
5381 }
5382 }
5383 if (!error && varname != StringName()) {
5384 if (shader->constants.has(varname)) {
5385 error = true;
5386 } else if (shader->uniforms.has(varname)) {
5387 error = true;
5388 } else if (p_function_info.built_ins.has(varname)) {
5389 BuiltInInfo info = p_function_info.built_ins[varname];
5390 if (info.constant) {
5391 error = true;
5392 }
5393 }
5394 }
5395
5396 if (error) {
5397 _set_error(vformat(RTR("A constant value cannot be passed for '%s' parameter."), _get_qualifier_str(arg_qual)));
5398 return nullptr;
5399 }
5400 }
5401 if (is_sampler_type(call_function->arguments[i].type)) {
5402 //let's see where our argument comes from
5403 ERR_CONTINUE(n->type != Node::NODE_TYPE_VARIABLE); //bug? this should always be a variable
5404 VariableNode *vn = static_cast<VariableNode *>(n);
5405 StringName varname = vn->name;
5406 if (shader->uniforms.has(varname)) {
5407 //being sampler, this either comes from a uniform
5408 ShaderNode::Uniform *u = &shader->uniforms[varname];
5409 ERR_CONTINUE(u->type != call_function->arguments[i].type); //this should have been validated previously
5410
5411 if (RendererCompositor::get_singleton()->is_xr_enabled() && is_custom_func) {
5412 ShaderNode::Uniform::Hint hint = u->hint;
5413
5414 if (hint == ShaderNode::Uniform::HINT_DEPTH_TEXTURE || hint == ShaderNode::Uniform::HINT_SCREEN_TEXTURE || hint == ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) {
5415 _set_error(vformat(RTR("Unable to pass a multiview texture sampler as a parameter to custom function. Consider to sample it in the main function and then pass the vector result to it."), get_uniform_hint_name(hint)));
5416 return nullptr;
5417 }
5418 }
5419
5420 //propagate
5421 if (!_propagate_function_call_sampler_uniform_settings(name, i, u->filter, u->repeat)) {
5422 return nullptr;
5423 }
5424 } else if (p_function_info.built_ins.has(varname)) {
5425 //a built-in
5426 if (!_propagate_function_call_sampler_builtin_reference(name, i, varname)) {
5427 return nullptr;
5428 }
5429 } else {
5430 //or this comes from an argument, but nothing else can be a sampler
5431 bool found = false;
5432 for (int j = 0; j < base_function->arguments.size(); j++) {
5433 if (base_function->arguments[j].name == varname) {
5434 if (!base_function->arguments[j].tex_argument_connect.has(call_function->name)) {
5435 base_function->arguments.write[j].tex_argument_connect[call_function->name] = HashSet<int>();
5436 }
5437 base_function->arguments.write[j].tex_argument_connect[call_function->name].insert(i);
5438 found = true;
5439 break;
5440 }
5441 }
5442 ERR_CONTINUE(!found);
5443 }
5444 }
5445 } else {
5446 break;
5447 }
5448 }
5449 }
5450 }
5451 expr = func;
5452#ifdef DEBUG_ENABLED
5453 if (check_warnings) {
5454 StringName func_name;
5455
5456 if (p_block && p_block->parent_function) {
5457 func_name = p_block->parent_function->name;
5458 }
5459
5460 _parse_used_identifier(name, IdentifierType::IDENTIFIER_FUNCTION, func_name);
5461 }
5462#endif // DEBUG_ENABLED
5463 }
5464 } else {
5465 //an identifier
5466
5467 last_name = identifier;
5468 last_type = IDENTIFIER_MAX;
5469 _set_tkpos(pos);
5470
5471 DataType data_type = TYPE_MAX;
5472 IdentifierType ident_type = IDENTIFIER_MAX;
5473 int array_size = 0;
5474 StringName struct_name;
5475 bool is_local = false;
5476
5477 if (p_block && p_block->block_tag != SubClassTag::TAG_GLOBAL) {
5478 int idx = 0;
5479 bool found = false;
5480
5481 while (builtin_func_defs[idx].name) {
5482 if (builtin_func_defs[idx].tag == p_block->block_tag && builtin_func_defs[idx].name == identifier) {
5483 found = true;
5484 break;
5485 }
5486 idx++;
5487 }
5488 if (!found) {
5489 _set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier)));
5490 return nullptr;
5491 }
5492 } else {
5493 if (!_find_identifier(p_block, false, p_function_info, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) {
5494 if (identifier == "SCREEN_TEXTURE" || identifier == "DEPTH_TEXTURE" || identifier == "NORMAL_ROUGHNESS_TEXTURE") {
5495 String name = String(identifier);
5496 String name_lower = name.to_lower();
5497 _set_error(vformat(RTR("%s has been removed in favor of using hint_%s with a uniform.\nTo continue with minimal code changes add 'uniform sampler2D %s : hint_%s, filter_linear_mipmap;' near the top of your shader."), name, name_lower, name, name_lower));
5498 return nullptr;
5499 }
5500 _set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier)));
5501 return nullptr;
5502 }
5503 if (is_const_decl && !is_const) {
5504 _set_error(RTR("Expected constant expression."));
5505 return nullptr;
5506 }
5507 if (ident_type == IDENTIFIER_VARYING) {
5508 TkPos prev_pos = _get_tkpos();
5509 Token next_token = _get_token();
5510
5511 // An array of varyings.
5512 if (next_token.type == TK_BRACKET_OPEN) {
5513 _get_token(); // Pass constant.
5514 _get_token(); // Pass TK_BRACKET_CLOSE.
5515 next_token = _get_token();
5516 }
5517 _set_tkpos(prev_pos);
5518
5519 ShaderNode::Varying &var = shader->varyings[identifier];
5520 String error;
5521 if (is_token_operator_assign(next_token.type)) {
5522 if (!_validate_varying_assign(shader->varyings[identifier], &error)) {
5523 _set_error(error);
5524 return nullptr;
5525 }
5526 } else {
5527 switch (var.stage) {
5528 case ShaderNode::Varying::STAGE_UNKNOWN: {
5529 if (var.type < TYPE_INT) {
5530 if (current_function == varying_function_names.vertex) {
5531 _set_error(vformat(RTR("Varying with '%s' data type may only be used in the 'fragment' function."), get_datatype_name(var.type)));
5532 } else {
5533 _set_error(vformat(RTR("Varying '%s' must be assigned in the 'fragment' function first."), identifier));
5534 }
5535 return nullptr;
5536 }
5537 } break;
5538 case ShaderNode::Varying::STAGE_VERTEX:
5539 if (current_function == varying_function_names.fragment || current_function == varying_function_names.light) {
5540 var.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT;
5541 }
5542 break;
5543 case ShaderNode::Varying::STAGE_FRAGMENT:
5544 if (current_function == varying_function_names.light) {
5545 var.stage = ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT;
5546 }
5547 break;
5548 default:
5549 break;
5550 }
5551 }
5552
5553 if ((var.stage != ShaderNode::Varying::STAGE_FRAGMENT && var.stage != ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT) && var.type < TYPE_FLOAT && var.interpolation != INTERPOLATION_FLAT) {
5554 _set_tkpos(var.tkpos);
5555 _set_error(RTR("Varying with integer data type must be declared with `flat` interpolation qualifier."));
5556 return nullptr;
5557 }
5558 }
5559
5560 if (ident_type == IDENTIFIER_FUNCTION) {
5561 _set_error(vformat(RTR("Can't use function as identifier: '%s'."), String(identifier)));
5562 return nullptr;
5563 }
5564 if (is_const) {
5565 last_type = IDENTIFIER_CONSTANT;
5566 } else {
5567 last_type = ident_type;
5568 }
5569
5570 is_local = ident_type == IDENTIFIER_LOCAL_VAR || ident_type == IDENTIFIER_FUNCTION_ARGUMENT;
5571 }
5572
5573 Node *index_expression = nullptr;
5574 Node *call_expression = nullptr;
5575 Node *assign_expression = nullptr;
5576
5577 if (array_size > 0) {
5578 prepos = _get_tkpos();
5579 tk = _get_token();
5580
5581 if (tk.type == TK_OP_ASSIGN) {
5582 if (is_const) {
5583 _set_error(RTR("Constants cannot be modified."));
5584 return nullptr;
5585 }
5586 assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size);
5587 if (!assign_expression) {
5588 return nullptr;
5589 }
5590 } else if (tk.type == TK_PERIOD) {
5591 completion_class = TAG_ARRAY;
5592 if (p_block != nullptr) {
5593 p_block->block_tag = SubClassTag::TAG_ARRAY;
5594 }
5595 call_expression = _parse_and_reduce_expression(p_block, p_function_info);
5596 if (p_block != nullptr) {
5597 p_block->block_tag = SubClassTag::TAG_GLOBAL;
5598 }
5599 if (!call_expression) {
5600 return nullptr;
5601 }
5602 } else if (tk.type == TK_BRACKET_OPEN) { // indexing
5603 index_expression = _parse_and_reduce_expression(p_block, p_function_info);
5604 if (!index_expression) {
5605 return nullptr;
5606 }
5607
5608 if (index_expression->get_array_size() != 0 || (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT)) {
5609 _set_error(RTR("Only integer expressions are allowed for indexing."));
5610 return nullptr;
5611 }
5612
5613 if (index_expression->type == Node::NODE_TYPE_CONSTANT) {
5614 ConstantNode *cnode = static_cast<ConstantNode *>(index_expression);
5615 if (cnode) {
5616 if (!cnode->values.is_empty()) {
5617 int value = cnode->values[0].sint;
5618 if (value < 0 || value >= array_size) {
5619 _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), value, 0, array_size - 1));
5620 return nullptr;
5621 }
5622 }
5623 }
5624 }
5625
5626 tk = _get_token();
5627 if (tk.type != TK_BRACKET_CLOSE) {
5628 _set_expected_error("]");
5629 return nullptr;
5630 }
5631 } else {
5632 _set_tkpos(prepos);
5633 }
5634
5635 ArrayNode *arrname = alloc_node<ArrayNode>();
5636 arrname->name = identifier;
5637 arrname->datatype_cache = data_type;
5638 arrname->struct_name = struct_name;
5639 arrname->index_expression = index_expression;
5640 arrname->call_expression = call_expression;
5641 arrname->assign_expression = assign_expression;
5642 arrname->is_const = is_const;
5643 arrname->array_size = array_size;
5644 arrname->is_local = is_local;
5645 expr = arrname;
5646 } else {
5647 VariableNode *varname = alloc_node<VariableNode>();
5648 varname->name = identifier;
5649 varname->datatype_cache = data_type;
5650 varname->is_const = is_const;
5651 varname->struct_name = struct_name;
5652 varname->is_local = is_local;
5653 expr = varname;
5654 }
5655#ifdef DEBUG_ENABLED
5656 if (check_warnings) {
5657 StringName func_name;
5658 BlockNode *b = p_block;
5659
5660 while (b) {
5661 if (b->parent_function) {
5662 func_name = b->parent_function->name;
5663 break;
5664 } else {
5665 b = b->parent_block;
5666 }
5667 }
5668
5669 _parse_used_identifier(identifier, ident_type, func_name);
5670 }
5671#endif // DEBUG_ENABLED
5672 }
5673 } else if (tk.type == TK_OP_ADD) {
5674 continue; //this one does nothing
5675 } else if (tk.type == TK_OP_SUB || tk.type == TK_OP_NOT || tk.type == TK_OP_BIT_INVERT || tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) {
5676 Expression e;
5677 e.is_op = true;
5678
5679 switch (tk.type) {
5680 case TK_OP_SUB:
5681 e.op = OP_NEGATE;
5682 break;
5683 case TK_OP_NOT:
5684 e.op = OP_NOT;
5685 break;
5686 case TK_OP_BIT_INVERT:
5687 e.op = OP_BIT_INVERT;
5688 break;
5689 case TK_OP_INCREMENT:
5690 e.op = OP_INCREMENT;
5691 break;
5692 case TK_OP_DECREMENT:
5693 e.op = OP_DECREMENT;
5694 break;
5695 default:
5696 ERR_FAIL_V(nullptr);
5697 }
5698
5699 expression.push_back(e);
5700 continue;
5701 } else {
5702 bool valid = false;
5703 if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_FOR_EXPRESSION && tk.type == TK_PARENTHESIS_CLOSE) {
5704 valid = true;
5705 _set_tkpos(prepos);
5706
5707 OperatorNode *func = alloc_node<OperatorNode>();
5708 func->op = OP_EMPTY;
5709 expr = func;
5710 }
5711 if (!valid) {
5712 if (tk.type != TK_SEMICOLON) {
5713 _set_error(vformat(RTR("Expected expression, found: '%s'."), get_token_text(tk)));
5714 return nullptr;
5715 } else {
5716#ifdef DEBUG_ENABLED
5717 if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_FOR_INIT && p_block->block_type != BlockNode::BLOCK_TYPE_FOR_CONDITION)) {
5718 if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
5719 _add_line_warning(ShaderWarning::FORMATTING_ERROR, RTR("Empty statement. Remove ';' to fix this warning."));
5720 }
5721 }
5722#endif // DEBUG_ENABLED
5723 _set_tkpos(prepos);
5724
5725 OperatorNode *func = alloc_node<OperatorNode>();
5726 func->op = OP_EMPTY;
5727 expr = func;
5728 }
5729 }
5730 }
5731
5732 ERR_FAIL_COND_V(!expr, nullptr);
5733
5734 /* OK now see what's NEXT to the operator.. */
5735
5736 while (true) {
5737 TkPos pos2 = _get_tkpos();
5738 tk = _get_token();
5739
5740 if (tk.type == TK_CURSOR) {
5741 //do nothing
5742 } else if (tk.type == TK_PERIOD) {
5743#ifdef DEBUG_ENABLED
5744 uint32_t prev_keyword_completion_context = keyword_completion_context;
5745 keyword_completion_context = CF_UNSPECIFIED;
5746#endif
5747
5748 DataType dt = expr->get_datatype();
5749 String st = expr->get_datatype_name();
5750
5751 if (!expr->is_indexed() && expr->get_array_size() > 0) {
5752 completion_class = TAG_ARRAY;
5753 if (p_block != nullptr) {
5754 p_block->block_tag = SubClassTag::TAG_ARRAY;
5755 }
5756 Node *call_expression = _parse_and_reduce_expression(p_block, p_function_info);
5757 if (p_block != nullptr) {
5758 p_block->block_tag = SubClassTag::TAG_GLOBAL;
5759 }
5760 if (!call_expression) {
5761 return nullptr;
5762 }
5763 expr = call_expression;
5764 break;
5765 }
5766
5767 StringName identifier;
5768 if (_get_completable_identifier(p_block, dt == TYPE_STRUCT ? COMPLETION_STRUCT : COMPLETION_INDEX, identifier)) {
5769 if (dt == TYPE_STRUCT) {
5770 completion_struct = st;
5771 } else {
5772 completion_base = dt;
5773 }
5774 }
5775
5776 if (identifier == StringName()) {
5777 _set_error(RTR("Expected an identifier as a member."));
5778 return nullptr;
5779 }
5780 String ident = identifier;
5781
5782 bool ok = true;
5783 bool repeated = false;
5784 DataType member_type = TYPE_VOID;
5785 StringName member_struct_name = "";
5786 int array_size = 0;
5787
5788 RBSet<char> position_symbols;
5789 RBSet<char> color_symbols;
5790 RBSet<char> texture_symbols;
5791
5792 bool mix_error = false;
5793
5794 switch (dt) {
5795 case TYPE_STRUCT: {
5796 ok = false;
5797 String member_name = String(ident.ptr());
5798 if (shader->structs.has(st)) {
5799 StructNode *n = shader->structs[st].shader_struct;
5800 for (const MemberNode *E : n->members) {
5801 if (String(E->name) == member_name) {
5802 member_type = E->datatype;
5803 array_size = E->array_size;
5804 if (member_type == TYPE_STRUCT) {
5805 member_struct_name = E->struct_name;
5806 }
5807 ok = true;
5808 break;
5809 }
5810 }
5811 }
5812
5813 } break;
5814 case TYPE_BVEC2:
5815 case TYPE_IVEC2:
5816 case TYPE_UVEC2:
5817 case TYPE_VEC2: {
5818 int l = ident.length();
5819 if (l == 1) {
5820 member_type = DataType(dt - 1);
5821 } else if (l == 2) {
5822 member_type = dt;
5823 } else if (l == 3) {
5824 member_type = DataType(dt + 1);
5825 } else if (l == 4) {
5826 member_type = DataType(dt + 2);
5827 } else {
5828 ok = false;
5829 break;
5830 }
5831
5832 const char32_t *c = ident.ptr();
5833 for (int i = 0; i < l; i++) {
5834 switch (c[i]) {
5835 case 'r':
5836 case 'g':
5837 if (position_symbols.size() > 0 || texture_symbols.size() > 0) {
5838 mix_error = true;
5839 break;
5840 }
5841 if (!color_symbols.has(c[i])) {
5842 color_symbols.insert(c[i]);
5843 } else {
5844 repeated = true;
5845 }
5846 break;
5847 case 'x':
5848 case 'y':
5849 if (color_symbols.size() > 0 || texture_symbols.size() > 0) {
5850 mix_error = true;
5851 break;
5852 }
5853 if (!position_symbols.has(c[i])) {
5854 position_symbols.insert(c[i]);
5855 } else {
5856 repeated = true;
5857 }
5858 break;
5859 case 's':
5860 case 't':
5861 if (color_symbols.size() > 0 || position_symbols.size() > 0) {
5862 mix_error = true;
5863 break;
5864 }
5865 if (!texture_symbols.has(c[i])) {
5866 texture_symbols.insert(c[i]);
5867 } else {
5868 repeated = true;
5869 }
5870 break;
5871 default:
5872 ok = false;
5873 break;
5874 }
5875 }
5876
5877 } break;
5878 case TYPE_BVEC3:
5879 case TYPE_IVEC3:
5880 case TYPE_UVEC3:
5881 case TYPE_VEC3: {
5882 int l = ident.length();
5883 if (l == 1) {
5884 member_type = DataType(dt - 2);
5885 } else if (l == 2) {
5886 member_type = DataType(dt - 1);
5887 } else if (l == 3) {
5888 member_type = dt;
5889 } else if (l == 4) {
5890 member_type = DataType(dt + 1);
5891 } else {
5892 ok = false;
5893 break;
5894 }
5895
5896 const char32_t *c = ident.ptr();
5897 for (int i = 0; i < l; i++) {
5898 switch (c[i]) {
5899 case 'r':
5900 case 'g':
5901 case 'b':
5902 if (position_symbols.size() > 0 || texture_symbols.size() > 0) {
5903 mix_error = true;
5904 break;
5905 }
5906 if (!color_symbols.has(c[i])) {
5907 color_symbols.insert(c[i]);
5908 } else {
5909 repeated = true;
5910 }
5911 break;
5912 case 'x':
5913 case 'y':
5914 case 'z':
5915 if (color_symbols.size() > 0 || texture_symbols.size() > 0) {
5916 mix_error = true;
5917 break;
5918 }
5919 if (!position_symbols.has(c[i])) {
5920 position_symbols.insert(c[i]);
5921 } else {
5922 repeated = true;
5923 }
5924 break;
5925 case 's':
5926 case 't':
5927 case 'p':
5928 if (color_symbols.size() > 0 || position_symbols.size() > 0) {
5929 mix_error = true;
5930 break;
5931 }
5932 if (!texture_symbols.has(c[i])) {
5933 texture_symbols.insert(c[i]);
5934 } else {
5935 repeated = true;
5936 }
5937 break;
5938 default:
5939 ok = false;
5940 break;
5941 }
5942 }
5943
5944 } break;
5945 case TYPE_BVEC4:
5946 case TYPE_IVEC4:
5947 case TYPE_UVEC4:
5948 case TYPE_VEC4: {
5949 int l = ident.length();
5950 if (l == 1) {
5951 member_type = DataType(dt - 3);
5952 } else if (l == 2) {
5953 member_type = DataType(dt - 2);
5954 } else if (l == 3) {
5955 member_type = DataType(dt - 1);
5956 } else if (l == 4) {
5957 member_type = dt;
5958 } else {
5959 ok = false;
5960 break;
5961 }
5962
5963 const char32_t *c = ident.ptr();
5964 for (int i = 0; i < l; i++) {
5965 switch (c[i]) {
5966 case 'r':
5967 case 'g':
5968 case 'b':
5969 case 'a':
5970 if (position_symbols.size() > 0 || texture_symbols.size() > 0) {
5971 mix_error = true;
5972 break;
5973 }
5974 if (!color_symbols.has(c[i])) {
5975 color_symbols.insert(c[i]);
5976 } else {
5977 repeated = true;
5978 }
5979 break;
5980 case 'x':
5981 case 'y':
5982 case 'z':
5983 case 'w':
5984 if (color_symbols.size() > 0 || texture_symbols.size() > 0) {
5985 mix_error = true;
5986 break;
5987 }
5988 if (!position_symbols.has(c[i])) {
5989 position_symbols.insert(c[i]);
5990 } else {
5991 repeated = true;
5992 }
5993 break;
5994 case 's':
5995 case 't':
5996 case 'p':
5997 case 'q':
5998 if (color_symbols.size() > 0 || position_symbols.size() > 0) {
5999 mix_error = true;
6000 break;
6001 }
6002 if (!texture_symbols.has(c[i])) {
6003 texture_symbols.insert(c[i]);
6004 } else {
6005 repeated = true;
6006 }
6007 break;
6008 default:
6009 ok = false;
6010 break;
6011 }
6012 }
6013
6014 } break;
6015
6016 default: {
6017 ok = false;
6018 }
6019 }
6020
6021 if (mix_error) {
6022 _set_error(vformat(RTR("Cannot combine symbols from different sets in expression '.%s'."), ident));
6023 return nullptr;
6024 }
6025
6026 if (!ok) {
6027 _set_error(vformat(RTR("Invalid member for '%s' expression: '.%s'."), (dt == TYPE_STRUCT ? st : get_datatype_name(dt)), ident));
6028 return nullptr;
6029 }
6030
6031 MemberNode *mn = alloc_node<MemberNode>();
6032 mn->basetype = dt;
6033 mn->basetype_const = is_const;
6034 mn->datatype = member_type;
6035 mn->base_struct_name = st;
6036 mn->struct_name = member_struct_name;
6037 mn->array_size = array_size;
6038 mn->name = ident;
6039 mn->owner = expr;
6040 mn->has_swizzling_duplicates = repeated;
6041
6042 if (array_size > 0) {
6043 TkPos prev_pos = _get_tkpos();
6044 tk = _get_token();
6045 if (tk.type == TK_OP_ASSIGN) {
6046 if (last_type == IDENTIFIER_CONSTANT) {
6047 _set_error(RTR("Constants cannot be modified."));
6048 return nullptr;
6049 }
6050 Node *assign_expression = _parse_array_constructor(p_block, p_function_info, member_type, member_struct_name, array_size);
6051 if (!assign_expression) {
6052 return nullptr;
6053 }
6054 mn->assign_expression = assign_expression;
6055 } else if (tk.type == TK_PERIOD) {
6056 completion_class = TAG_ARRAY;
6057 if (p_block != nullptr) {
6058 p_block->block_tag = SubClassTag::TAG_ARRAY;
6059 }
6060 mn->call_expression = _parse_and_reduce_expression(p_block, p_function_info);
6061 if (p_block != nullptr) {
6062 p_block->block_tag = SubClassTag::TAG_GLOBAL;
6063 }
6064 if (!mn->call_expression) {
6065 return nullptr;
6066 }
6067 } else if (tk.type == TK_BRACKET_OPEN) {
6068 Node *index_expression = _parse_and_reduce_expression(p_block, p_function_info);
6069 if (!index_expression) {
6070 return nullptr;
6071 }
6072
6073 if (index_expression->get_array_size() != 0 || (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT)) {
6074 _set_error(RTR("Only integer expressions are allowed for indexing."));
6075 return nullptr;
6076 }
6077
6078 if (index_expression->type == Node::NODE_TYPE_CONSTANT) {
6079 ConstantNode *cnode = static_cast<ConstantNode *>(index_expression);
6080 if (cnode) {
6081 if (!cnode->values.is_empty()) {
6082 int value = cnode->values[0].sint;
6083 if (value < 0 || value >= array_size) {
6084 _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), value, 0, array_size - 1));
6085 return nullptr;
6086 }
6087 }
6088 }
6089 }
6090
6091 tk = _get_token();
6092 if (tk.type != TK_BRACKET_CLOSE) {
6093 _set_expected_error("]");
6094 return nullptr;
6095 }
6096 mn->index_expression = index_expression;
6097 } else {
6098 _set_tkpos(prev_pos);
6099 }
6100 }
6101 expr = mn;
6102
6103#ifdef DEBUG_ENABLED
6104 keyword_completion_context = prev_keyword_completion_context;
6105#endif
6106
6107 //todo
6108 //member (period) has priority over any operator
6109 //creates a subindexing expression in place
6110
6111 /*} else if (tk.type==TK_BRACKET_OPEN) {
6112 //todo
6113 //subindexing has priority over any operator
6114 //creates a subindexing expression in place
6115
6116 */
6117 } else if (tk.type == TK_BRACKET_OPEN) {
6118 Node *index = _parse_and_reduce_expression(p_block, p_function_info);
6119 if (!index) {
6120 return nullptr;
6121 }
6122
6123 if (index->get_array_size() != 0 || (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT)) {
6124 _set_error(RTR("Only integer expressions are allowed for indexing."));
6125 return nullptr;
6126 }
6127
6128 DataType member_type = TYPE_VOID;
6129 String member_struct_name;
6130
6131 if (expr->get_array_size() > 0) {
6132 if (index->type == Node::NODE_TYPE_CONSTANT) {
6133 uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
6134 if (index_constant >= (uint32_t)expr->get_array_size()) {
6135 _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, expr->get_array_size() - 1));
6136 return nullptr;
6137 }
6138 }
6139 member_type = expr->get_datatype();
6140 if (member_type == TYPE_STRUCT) {
6141 member_struct_name = expr->get_datatype_name();
6142 }
6143 } else {
6144 switch (expr->get_datatype()) {
6145 case TYPE_BVEC2:
6146 case TYPE_VEC2:
6147 case TYPE_IVEC2:
6148 case TYPE_UVEC2:
6149 case TYPE_MAT2:
6150 if (index->type == Node::NODE_TYPE_CONSTANT) {
6151 uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
6152 if (index_constant >= 2) {
6153 _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, 1));
6154 return nullptr;
6155 }
6156 }
6157
6158 switch (expr->get_datatype()) {
6159 case TYPE_BVEC2:
6160 member_type = TYPE_BOOL;
6161 break;
6162 case TYPE_VEC2:
6163 member_type = TYPE_FLOAT;
6164 break;
6165 case TYPE_IVEC2:
6166 member_type = TYPE_INT;
6167 break;
6168 case TYPE_UVEC2:
6169 member_type = TYPE_UINT;
6170 break;
6171 case TYPE_MAT2:
6172 member_type = TYPE_VEC2;
6173 break;
6174 default:
6175 break;
6176 }
6177
6178 break;
6179 case TYPE_BVEC3:
6180 case TYPE_VEC3:
6181 case TYPE_IVEC3:
6182 case TYPE_UVEC3:
6183 case TYPE_MAT3:
6184 if (index->type == Node::NODE_TYPE_CONSTANT) {
6185 uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
6186 if (index_constant >= 3) {
6187 _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, 2));
6188 return nullptr;
6189 }
6190 }
6191
6192 switch (expr->get_datatype()) {
6193 case TYPE_BVEC3:
6194 member_type = TYPE_BOOL;
6195 break;
6196 case TYPE_VEC3:
6197 member_type = TYPE_FLOAT;
6198 break;
6199 case TYPE_IVEC3:
6200 member_type = TYPE_INT;
6201 break;
6202 case TYPE_UVEC3:
6203 member_type = TYPE_UINT;
6204 break;
6205 case TYPE_MAT3:
6206 member_type = TYPE_VEC3;
6207 break;
6208 default:
6209 break;
6210 }
6211 break;
6212 case TYPE_BVEC4:
6213 case TYPE_VEC4:
6214 case TYPE_IVEC4:
6215 case TYPE_UVEC4:
6216 case TYPE_MAT4:
6217 if (index->type == Node::NODE_TYPE_CONSTANT) {
6218 uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
6219 if (index_constant >= 4) {
6220 _set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, 3));
6221 return nullptr;
6222 }
6223 }
6224
6225 switch (expr->get_datatype()) {
6226 case TYPE_BVEC4:
6227 member_type = TYPE_BOOL;
6228 break;
6229 case TYPE_VEC4:
6230 member_type = TYPE_FLOAT;
6231 break;
6232 case TYPE_IVEC4:
6233 member_type = TYPE_INT;
6234 break;
6235 case TYPE_UVEC4:
6236 member_type = TYPE_UINT;
6237 break;
6238 case TYPE_MAT4:
6239 member_type = TYPE_VEC4;
6240 break;
6241 default:
6242 break;
6243 }
6244 break;
6245 default: {
6246 _set_error(vformat(RTR("An object of type '%s' can't be indexed."), (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype()))));
6247 return nullptr;
6248 }
6249 }
6250 }
6251 OperatorNode *op = alloc_node<OperatorNode>();
6252 op->op = OP_INDEX;
6253 op->return_cache = member_type;
6254 op->struct_name = member_struct_name;
6255 op->arguments.push_back(expr);
6256 op->arguments.push_back(index);
6257 expr = op;
6258
6259 tk = _get_token();
6260 if (tk.type != TK_BRACKET_CLOSE) {
6261 _set_expected_error("]");
6262 return nullptr;
6263 }
6264
6265 } else if (tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) {
6266 OperatorNode *op = alloc_node<OperatorNode>();
6267 op->op = tk.type == TK_OP_DECREMENT ? OP_POST_DECREMENT : OP_POST_INCREMENT;
6268 op->arguments.push_back(expr);
6269
6270 if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) {
6271 _set_error(RTR("Invalid base type for increment/decrement operator."));
6272 return nullptr;
6273 }
6274
6275 if (!_validate_assign(expr, p_function_info)) {
6276 _set_error(RTR("Invalid use of increment/decrement operator in a constant expression."));
6277 return nullptr;
6278 }
6279 expr = op;
6280 } else {
6281 _set_tkpos(pos2);
6282 break;
6283 }
6284 }
6285
6286 Expression e;
6287 e.is_op = false;
6288 e.node = expr;
6289 expression.push_back(e);
6290
6291 pos = _get_tkpos();
6292 tk = _get_token();
6293
6294 if (is_token_operator(tk.type)) {
6295 Expression o;
6296 o.is_op = true;
6297
6298 switch (tk.type) {
6299 case TK_OP_EQUAL:
6300 o.op = OP_EQUAL;
6301 break;
6302 case TK_OP_NOT_EQUAL:
6303 o.op = OP_NOT_EQUAL;
6304 break;
6305 case TK_OP_LESS:
6306 o.op = OP_LESS;
6307 break;
6308 case TK_OP_LESS_EQUAL:
6309 o.op = OP_LESS_EQUAL;
6310 break;
6311 case TK_OP_GREATER:
6312 o.op = OP_GREATER;
6313 break;
6314 case TK_OP_GREATER_EQUAL:
6315 o.op = OP_GREATER_EQUAL;
6316 break;
6317 case TK_OP_AND:
6318 o.op = OP_AND;
6319 break;
6320 case TK_OP_OR:
6321 o.op = OP_OR;
6322 break;
6323 case TK_OP_ADD:
6324 o.op = OP_ADD;
6325 break;
6326 case TK_OP_SUB:
6327 o.op = OP_SUB;
6328 break;
6329 case TK_OP_MUL:
6330 o.op = OP_MUL;
6331 break;
6332 case TK_OP_DIV:
6333 o.op = OP_DIV;
6334 break;
6335 case TK_OP_MOD:
6336 o.op = OP_MOD;
6337 break;
6338 case TK_OP_SHIFT_LEFT:
6339 o.op = OP_SHIFT_LEFT;
6340 break;
6341 case TK_OP_SHIFT_RIGHT:
6342 o.op = OP_SHIFT_RIGHT;
6343 break;
6344 case TK_OP_ASSIGN:
6345 o.op = OP_ASSIGN;
6346 break;
6347 case TK_OP_ASSIGN_ADD:
6348 o.op = OP_ASSIGN_ADD;
6349 break;
6350 case TK_OP_ASSIGN_SUB:
6351 o.op = OP_ASSIGN_SUB;
6352 break;
6353 case TK_OP_ASSIGN_MUL:
6354 o.op = OP_ASSIGN_MUL;
6355 break;
6356 case TK_OP_ASSIGN_DIV:
6357 o.op = OP_ASSIGN_DIV;
6358 break;
6359 case TK_OP_ASSIGN_MOD:
6360 o.op = OP_ASSIGN_MOD;
6361 break;
6362 case TK_OP_ASSIGN_SHIFT_LEFT:
6363 o.op = OP_ASSIGN_SHIFT_LEFT;
6364 break;
6365 case TK_OP_ASSIGN_SHIFT_RIGHT:
6366 o.op = OP_ASSIGN_SHIFT_RIGHT;
6367 break;
6368 case TK_OP_ASSIGN_BIT_AND:
6369 o.op = OP_ASSIGN_BIT_AND;
6370 break;
6371 case TK_OP_ASSIGN_BIT_OR:
6372 o.op = OP_ASSIGN_BIT_OR;
6373 break;
6374 case TK_OP_ASSIGN_BIT_XOR:
6375 o.op = OP_ASSIGN_BIT_XOR;
6376 break;
6377 case TK_OP_BIT_AND:
6378 o.op = OP_BIT_AND;
6379 break;
6380 case TK_OP_BIT_OR:
6381 o.op = OP_BIT_OR;
6382 break;
6383 case TK_OP_BIT_XOR:
6384 o.op = OP_BIT_XOR;
6385 break;
6386 case TK_QUESTION:
6387 o.op = OP_SELECT_IF;
6388 break;
6389 case TK_COLON:
6390 o.op = OP_SELECT_ELSE;
6391 break;
6392 default: {
6393 _set_error(vformat(RTR("Invalid token for the operator: '%s'."), get_token_text(tk)));
6394 return nullptr;
6395 }
6396 }
6397
6398 expression.push_back(o);
6399
6400 } else {
6401 _set_tkpos(pos); //something else, so rollback and end
6402 break;
6403 }
6404 }
6405
6406 /* Reduce the set set of expressions and place them in an operator tree, respecting precedence */
6407
6408 while (expression.size() > 1) {
6409 int next_op = -1;
6410 int min_priority = 0xFFFFF;
6411 bool is_unary = false;
6412 bool is_ternary = false;
6413
6414 for (int i = 0; i < expression.size(); i++) {
6415 if (!expression[i].is_op) {
6416 continue;
6417 }
6418
6419 bool unary = false;
6420 bool ternary = false;
6421 Operator op = expression[i].op;
6422
6423 int priority;
6424 switch (op) {
6425 case OP_EQUAL:
6426 priority = 8;
6427 break;
6428 case OP_NOT_EQUAL:
6429 priority = 8;
6430 break;
6431 case OP_LESS:
6432 priority = 7;
6433 break;
6434 case OP_LESS_EQUAL:
6435 priority = 7;
6436 break;
6437 case OP_GREATER:
6438 priority = 7;
6439 break;
6440 case OP_GREATER_EQUAL:
6441 priority = 7;
6442 break;
6443 case OP_AND:
6444 priority = 12;
6445 break;
6446 case OP_OR:
6447 priority = 14;
6448 break;
6449 case OP_NOT:
6450 priority = 3;
6451 unary = true;
6452 break;
6453 case OP_NEGATE:
6454 priority = 3;
6455 unary = true;
6456 break;
6457 case OP_ADD:
6458 priority = 5;
6459 break;
6460 case OP_SUB:
6461 priority = 5;
6462 break;
6463 case OP_MUL:
6464 priority = 4;
6465 break;
6466 case OP_DIV:
6467 priority = 4;
6468 break;
6469 case OP_MOD:
6470 priority = 4;
6471 break;
6472 case OP_SHIFT_LEFT:
6473 priority = 6;
6474 break;
6475 case OP_SHIFT_RIGHT:
6476 priority = 6;
6477 break;
6478 case OP_ASSIGN:
6479 priority = 16;
6480 break;
6481 case OP_ASSIGN_ADD:
6482 priority = 16;
6483 break;
6484 case OP_ASSIGN_SUB:
6485 priority = 16;
6486 break;
6487 case OP_ASSIGN_MUL:
6488 priority = 16;
6489 break;
6490 case OP_ASSIGN_DIV:
6491 priority = 16;
6492 break;
6493 case OP_ASSIGN_MOD:
6494 priority = 16;
6495 break;
6496 case OP_ASSIGN_SHIFT_LEFT:
6497 priority = 16;
6498 break;
6499 case OP_ASSIGN_SHIFT_RIGHT:
6500 priority = 16;
6501 break;
6502 case OP_ASSIGN_BIT_AND:
6503 priority = 16;
6504 break;
6505 case OP_ASSIGN_BIT_OR:
6506 priority = 16;
6507 break;
6508 case OP_ASSIGN_BIT_XOR:
6509 priority = 16;
6510 break;
6511 case OP_BIT_AND:
6512 priority = 9;
6513 break;
6514 case OP_BIT_OR:
6515 priority = 11;
6516 break;
6517 case OP_BIT_XOR:
6518 priority = 10;
6519 break;
6520 case OP_BIT_INVERT:
6521 priority = 3;
6522 unary = true;
6523 break;
6524 case OP_INCREMENT:
6525 priority = 3;
6526 unary = true;
6527 break;
6528 case OP_DECREMENT:
6529 priority = 3;
6530 unary = true;
6531 break;
6532 case OP_SELECT_IF:
6533 priority = 15;
6534 ternary = true;
6535 break;
6536 case OP_SELECT_ELSE:
6537 priority = 15;
6538 ternary = true;
6539 break;
6540
6541 default:
6542 ERR_FAIL_V(nullptr); //unexpected operator
6543 }
6544
6545#ifdef DEBUG_ENABLED
6546 if (check_warnings && HAS_WARNING(ShaderWarning::FLOAT_COMPARISON_FLAG) && (op == OP_EQUAL || op == OP_NOT_EQUAL) &&
6547 (!expression[i - 1].is_op && !expression[i + 1].is_op) &&
6548 (expression[i - 1].node->get_datatype() == TYPE_FLOAT && expression[i + 1].node->get_datatype() == TYPE_FLOAT)) {
6549 _add_line_warning(ShaderWarning::FLOAT_COMPARISON);
6550 }
6551#endif // DEBUG_ENABLED
6552
6553 if (priority < min_priority) {
6554 // < is used for left to right (default)
6555 // <= is used for right to left
6556 next_op = i;
6557 min_priority = priority;
6558 is_unary = unary;
6559 is_ternary = ternary;
6560 }
6561 }
6562
6563 ERR_FAIL_COND_V(next_op == -1, nullptr);
6564
6565 // OK! create operator..
6566 if (is_unary) {
6567 int expr_pos = next_op;
6568 while (expression[expr_pos].is_op) {
6569 expr_pos++;
6570 if (expr_pos == expression.size()) {
6571 //can happen..
6572 _set_error(RTR("Unexpected end of expression."));
6573 return nullptr;
6574 }
6575 }
6576
6577 //consecutively do unary operators
6578 for (int i = expr_pos - 1; i >= next_op; i--) {
6579 OperatorNode *op = alloc_node<OperatorNode>();
6580 op->op = expression[i].op;
6581 if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_function_info)) {
6582 _set_error(RTR("Invalid use of increment/decrement operator in a constant expression."));
6583 return nullptr;
6584 }
6585 op->arguments.push_back(expression[i + 1].node);
6586
6587 expression.write[i].is_op = false;
6588 expression.write[i].node = op;
6589
6590 if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) {
6591 String at;
6592 for (int j = 0; j < op->arguments.size(); j++) {
6593 if (j > 0) {
6594 at += ", ";
6595 }
6596 at += get_datatype_name(op->arguments[j]->get_datatype());
6597 if (!op->arguments[j]->is_indexed() && op->arguments[j]->get_array_size() > 0) {
6598 at += "[";
6599 at += itos(op->arguments[j]->get_array_size());
6600 at += "]";
6601 }
6602 }
6603 _set_error(vformat(RTR("Invalid arguments to unary operator '%s': %s."), get_operator_text(op->op), at));
6604 return nullptr;
6605 }
6606 expression.remove_at(i + 1);
6607 }
6608
6609 } else if (is_ternary) {
6610 if (next_op < 1 || next_op >= (expression.size() - 1)) {
6611 _set_parsing_error();
6612 ERR_FAIL_V(nullptr);
6613 }
6614
6615 if (next_op + 2 >= expression.size() || !expression[next_op + 2].is_op || expression[next_op + 2].op != OP_SELECT_ELSE) {
6616 _set_error(RTR("Missing matching ':' for select operator."));
6617 return nullptr;
6618 }
6619
6620 OperatorNode *op = alloc_node<OperatorNode>();
6621 op->op = expression[next_op].op;
6622 op->arguments.push_back(expression[next_op - 1].node);
6623 op->arguments.push_back(expression[next_op + 1].node);
6624 op->arguments.push_back(expression[next_op + 3].node);
6625
6626 expression.write[next_op - 1].is_op = false;
6627 expression.write[next_op - 1].node = op;
6628 if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) {
6629 String at;
6630 for (int i = 0; i < op->arguments.size(); i++) {
6631 if (i > 0) {
6632 at += ", ";
6633 }
6634 at += get_datatype_name(op->arguments[i]->get_datatype());
6635 if (!op->arguments[i]->is_indexed() && op->arguments[i]->get_array_size() > 0) {
6636 at += "[";
6637 at += itos(op->arguments[i]->get_array_size());
6638 at += "]";
6639 }
6640 }
6641 _set_error(vformat(RTR("Invalid argument to ternary operator: '%s'."), at));
6642 return nullptr;
6643 }
6644
6645 for (int i = 0; i < 4; i++) {
6646 expression.remove_at(next_op);
6647 }
6648
6649 } else {
6650 if (next_op < 1 || next_op >= (expression.size() - 1)) {
6651 _set_parsing_error();
6652 ERR_FAIL_V(nullptr);
6653 }
6654
6655 OperatorNode *op = alloc_node<OperatorNode>();
6656 op->op = expression[next_op].op;
6657
6658 if (expression[next_op - 1].is_op) {
6659 _set_parsing_error();
6660 ERR_FAIL_V(nullptr);
6661 }
6662
6663 if (_is_operator_assign(op->op)) {
6664 String assign_message;
6665 if (!_validate_assign(expression[next_op - 1].node, p_function_info, &assign_message)) {
6666 _set_error(assign_message);
6667 return nullptr;
6668 }
6669 }
6670
6671 if (expression[next_op + 1].is_op) {
6672 // this is not invalid and can really appear
6673 // but it becomes invalid anyway because no binary op
6674 // can be followed by a unary op in a valid combination,
6675 // due to how precedence works, unaries will always disappear first
6676
6677 _set_parsing_error();
6678 }
6679
6680 op->arguments.push_back(expression[next_op - 1].node); //expression goes as left
6681 op->arguments.push_back(expression[next_op + 1].node); //next expression goes as right
6682 expression.write[next_op - 1].node = op;
6683
6684 //replace all 3 nodes by this operator and make it an expression
6685
6686 if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) {
6687 String at;
6688 for (int i = 0; i < op->arguments.size(); i++) {
6689 if (i > 0) {
6690 at += ", ";
6691 }
6692 if (op->arguments[i]->get_datatype() == TYPE_STRUCT) {
6693 at += op->arguments[i]->get_datatype_name();
6694 } else {
6695 at += get_datatype_name(op->arguments[i]->get_datatype());
6696 }
6697 if (!op->arguments[i]->is_indexed() && op->arguments[i]->get_array_size() > 0) {
6698 at += "[";
6699 at += itos(op->arguments[i]->get_array_size());
6700 at += "]";
6701 }
6702 }
6703 _set_error(vformat(RTR("Invalid arguments to operator '%s': '%s'."), get_operator_text(op->op), at));
6704 return nullptr;
6705 }
6706
6707 expression.remove_at(next_op);
6708 expression.remove_at(next_op);
6709 }
6710 }
6711
6712 return expression[0].node;
6713}
6714
6715ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node) {
6716 if (p_node->type != Node::NODE_TYPE_OPERATOR) {
6717 return p_node;
6718 }
6719
6720 //for now only reduce simple constructors
6721 OperatorNode *op = static_cast<OperatorNode *>(p_node);
6722
6723 if (op->op == OP_CONSTRUCT) {
6724 ERR_FAIL_COND_V(op->arguments[0]->type != Node::NODE_TYPE_VARIABLE, p_node);
6725
6726 DataType type = op->get_datatype();
6727 DataType base = get_scalar_type(type);
6728 int cardinality = get_cardinality(type);
6729
6730 Vector<ConstantNode::Value> values;
6731
6732 for (int i = 1; i < op->arguments.size(); i++) {
6733 op->arguments.write[i] = _reduce_expression(p_block, op->arguments[i]);
6734 if (op->arguments[i]->type == Node::NODE_TYPE_CONSTANT) {
6735 ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i]);
6736
6737 if (get_scalar_type(cn->datatype) == base) {
6738 for (int j = 0; j < cn->values.size(); j++) {
6739 values.push_back(cn->values[j]);
6740 }
6741 } else if (get_scalar_type(cn->datatype) == cn->datatype) {
6742 ConstantNode::Value v;
6743 if (!convert_constant(cn, base, &v)) {
6744 return p_node;
6745 }
6746 values.push_back(v);
6747 } else {
6748 return p_node;
6749 }
6750
6751 } else {
6752 return p_node;
6753 }
6754 }
6755
6756 if (values.size() == 1) {
6757 if (type >= TYPE_MAT2 && type <= TYPE_MAT4) {
6758 ConstantNode::Value value = values[0];
6759 ConstantNode::Value zero;
6760 zero.real = 0.0f;
6761 int size = 2 + (type - TYPE_MAT2);
6762
6763 values.clear();
6764 for (int i = 0; i < size; i++) {
6765 for (int j = 0; j < size; j++) {
6766 values.push_back(i == j ? value : zero);
6767 }
6768 }
6769 } else {
6770 ConstantNode::Value value = values[0];
6771 for (int i = 1; i < cardinality; i++) {
6772 values.push_back(value);
6773 }
6774 }
6775 } else if (values.size() != cardinality) {
6776 ERR_PRINT("Failed to reduce expression, values and cardinality mismatch.");
6777 return p_node;
6778 }
6779
6780 ConstantNode *cn = alloc_node<ConstantNode>();
6781 cn->datatype = op->get_datatype();
6782 cn->values = values;
6783 return cn;
6784 } else if (op->op == OP_NEGATE) {
6785 op->arguments.write[0] = _reduce_expression(p_block, op->arguments[0]);
6786 if (op->arguments[0]->type == Node::NODE_TYPE_CONSTANT) {
6787 ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[0]);
6788
6789 DataType base = get_scalar_type(cn->datatype);
6790
6791 Vector<ConstantNode::Value> values;
6792
6793 for (int i = 0; i < cn->values.size(); i++) {
6794 ConstantNode::Value nv;
6795 switch (base) {
6796 case TYPE_BOOL: {
6797 nv.boolean = !cn->values[i].boolean;
6798 } break;
6799 case TYPE_INT: {
6800 nv.sint = -cn->values[i].sint;
6801 } break;
6802 case TYPE_UINT: {
6803 // Intentionally wrap the unsigned int value, because GLSL does.
6804 nv.uint = 0 - cn->values[i].uint;
6805 } break;
6806 case TYPE_FLOAT: {
6807 nv.real = -cn->values[i].real;
6808 } break;
6809 default: {
6810 }
6811 }
6812
6813 values.push_back(nv);
6814 }
6815
6816 cn->values = values;
6817 return cn;
6818 }
6819 }
6820
6821 return p_node;
6822}
6823
6824ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const FunctionInfo &p_function_info) {
6825 ShaderLanguage::Node *expr = _parse_expression(p_block, p_function_info);
6826 if (!expr) { //errored
6827 return nullptr;
6828 }
6829
6830 expr = _reduce_expression(p_block, expr);
6831
6832 return expr;
6833}
6834
6835Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_just_one, bool p_can_break, bool p_can_continue) {
6836 while (true) {
6837 TkPos pos = _get_tkpos();
6838 Token tk = _get_token();
6839#ifdef DEBUG_ENABLED
6840 Token next;
6841#endif // DEBUG_ENABLED
6842
6843 if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_SWITCH) {
6844 if (tk.type != TK_CF_CASE && tk.type != TK_CF_DEFAULT && tk.type != TK_CURLY_BRACKET_CLOSE) {
6845 _set_error(vformat(RTR("A switch may only contain '%s' and '%s' blocks."), "case", "default"));
6846 return ERR_PARSE_ERROR;
6847 }
6848 }
6849
6850 bool is_struct = shader->structs.has(tk.text);
6851 bool is_var_init = false;
6852 bool is_condition = false;
6853
6854 if (tk.type == TK_CURLY_BRACKET_CLOSE) { //end of block
6855 if (p_just_one) {
6856 _set_expected_error("}");
6857 return ERR_PARSE_ERROR;
6858 }
6859
6860 return OK;
6861
6862 } else if (tk.type == TK_CONST || is_token_precision(tk.type) || is_token_nonvoid_datatype(tk.type) || is_struct) {
6863 is_var_init = true;
6864
6865 String struct_name = "";
6866 if (is_struct) {
6867 struct_name = tk.text;
6868#ifdef DEBUG_ENABLED
6869 if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(struct_name)) {
6870 used_structs[struct_name].used = true;
6871 }
6872#endif // DEBUG_ENABLED
6873 }
6874#ifdef DEBUG_ENABLED
6875 uint32_t precision_flag = CF_PRECISION_MODIFIER;
6876
6877 keyword_completion_context = CF_DATATYPE;
6878 if (!is_token_precision(tk.type)) {
6879 if (!is_struct) {
6880 keyword_completion_context |= precision_flag;
6881 }
6882 }
6883#endif // DEBUG_ENABLED
6884
6885 bool is_const = false;
6886
6887 if (tk.type == TK_CONST) {
6888 is_const = true;
6889 tk = _get_token();
6890
6891 if (!is_struct) {
6892 is_struct = shader->structs.has(tk.text); // check again.
6893 struct_name = tk.text;
6894 }
6895 }
6896
6897 DataPrecision precision = PRECISION_DEFAULT;
6898 if (is_token_precision(tk.type)) {
6899 precision = get_token_precision(tk.type);
6900 tk = _get_token();
6901
6902 if (!is_struct) {
6903 is_struct = shader->structs.has(tk.text); // check again.
6904 }
6905
6906#ifdef DEBUG_ENABLED
6907 if (keyword_completion_context & precision_flag) {
6908 keyword_completion_context ^= precision_flag;
6909 }
6910#endif // DEBUG_ENABLED
6911 }
6912
6913#ifdef DEBUG_ENABLED
6914 if (is_const && _lookup_next(next)) {
6915 if (is_token_precision(next.type)) {
6916 keyword_completion_context = CF_UNSPECIFIED;
6917 }
6918 if (is_token_datatype(next.type)) {
6919 keyword_completion_context ^= CF_DATATYPE;
6920 }
6921 }
6922#endif // DEBUG_ENABLED
6923
6924 if (precision != PRECISION_DEFAULT) {
6925 if (!is_token_nonvoid_datatype(tk.type)) {
6926 _set_error(RTR("Expected variable type after precision modifier."));
6927 return ERR_PARSE_ERROR;
6928 }
6929 }
6930
6931 if (!is_struct) {
6932 if (!is_token_variable_datatype(tk.type)) {
6933 _set_error(RTR("Invalid variable type (samplers are not allowed)."));
6934 return ERR_PARSE_ERROR;
6935 }
6936 }
6937
6938 DataType type = is_struct ? TYPE_STRUCT : get_token_datatype(tk.type);
6939
6940 if (precision != PRECISION_DEFAULT && _validate_precision(type, precision) != OK) {
6941 return ERR_PARSE_ERROR;
6942 }
6943
6944#ifdef DEBUG_ENABLED
6945 keyword_completion_context = CF_UNSPECIFIED;
6946#endif // DEBUG_ENABLED
6947
6948 int array_size = 0;
6949 bool fixed_array_size = false;
6950 bool first = true;
6951
6952 VariableDeclarationNode *vdnode = alloc_node<VariableDeclarationNode>();
6953 vdnode->precision = precision;
6954 if (is_struct) {
6955 vdnode->struct_name = struct_name;
6956 vdnode->datatype = TYPE_STRUCT;
6957 } else {
6958 vdnode->datatype = type;
6959 };
6960 vdnode->is_const = is_const;
6961
6962 do {
6963 bool unknown_size = false;
6964 VariableDeclarationNode::Declaration decl;
6965
6966 tk = _get_token();
6967
6968 if (first) {
6969 first = false;
6970
6971 if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
6972 _set_error(RTR("Expected an identifier or '[' after type."));
6973 return ERR_PARSE_ERROR;
6974 }
6975
6976 if (tk.type == TK_BRACKET_OPEN) {
6977 Error error = _parse_array_size(p_block, p_function_info, false, &decl.size_expression, &array_size, &unknown_size);
6978 if (error != OK) {
6979 return error;
6980 }
6981 decl.size = array_size;
6982
6983 fixed_array_size = true;
6984 tk = _get_token();
6985 }
6986 }
6987
6988 if (tk.type != TK_IDENTIFIER) {
6989 _set_error(RTR("Expected an identifier."));
6990 return ERR_PARSE_ERROR;
6991 }
6992
6993 StringName name = tk.text;
6994 ShaderLanguage::IdentifierType itype;
6995 if (_find_identifier(p_block, true, p_function_info, name, (ShaderLanguage::DataType *)nullptr, &itype)) {
6996 if (itype != IDENTIFIER_FUNCTION) {
6997 _set_redefinition_error(String(name));
6998 return ERR_PARSE_ERROR;
6999 }
7000 }
7001 decl.name = name;
7002
7003#ifdef DEBUG_ENABLED
7004 if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG) && p_block) {
7005 FunctionNode *parent_function = nullptr;
7006 {
7007 BlockNode *block = p_block;
7008 while (block && !block->parent_function) {
7009 block = block->parent_block;
7010 }
7011 parent_function = block->parent_function;
7012 }
7013 if (parent_function) {
7014 StringName func_name = parent_function->name;
7015
7016 if (!used_local_vars.has(func_name)) {
7017 used_local_vars.insert(func_name, HashMap<StringName, Usage>());
7018 }
7019
7020 used_local_vars[func_name].insert(name, Usage(tk_line));
7021 }
7022 }
7023#endif // DEBUG_ENABLED
7024 is_const_decl = is_const;
7025
7026 BlockNode::Variable var;
7027 var.type = type;
7028 var.precision = precision;
7029 var.line = tk_line;
7030 var.array_size = array_size;
7031 var.is_const = is_const;
7032 var.struct_name = struct_name;
7033
7034 tk = _get_token();
7035
7036 if (tk.type == TK_BRACKET_OPEN) {
7037 Error error = _parse_array_size(p_block, p_function_info, false, &decl.size_expression, &var.array_size, &unknown_size);
7038 if (error != OK) {
7039 return error;
7040 }
7041
7042 decl.size = var.array_size;
7043 array_size = var.array_size;
7044
7045 tk = _get_token();
7046 }
7047#ifdef DEBUG_ENABLED
7048 if (var.type == DataType::TYPE_BOOL) {
7049 keyword_completion_context = CF_BOOLEAN;
7050 }
7051#endif // DEBUG_ENABLED
7052 if (var.array_size > 0 || unknown_size) {
7053 bool full_def = false;
7054
7055 if (tk.type == TK_OP_ASSIGN) {
7056 TkPos prev_pos = _get_tkpos();
7057 tk = _get_token();
7058
7059 if (tk.type == TK_IDENTIFIER) { // a function call array initialization
7060 _set_tkpos(prev_pos);
7061 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
7062
7063 if (!n) {
7064 _set_error(RTR("Expected array initializer."));
7065 return ERR_PARSE_ERROR;
7066 } else {
7067 if (unknown_size) {
7068 decl.size = n->get_array_size();
7069 var.array_size = n->get_array_size();
7070 }
7071
7072 if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) {
7073 return ERR_PARSE_ERROR;
7074 }
7075
7076 decl.single_expression = true;
7077 decl.initializer.push_back(n);
7078 }
7079
7080 tk = _get_token();
7081 } else {
7082 if (tk.type != TK_CURLY_BRACKET_OPEN) {
7083 if (unknown_size) {
7084 _set_expected_error("{");
7085 return ERR_PARSE_ERROR;
7086 }
7087
7088 full_def = true;
7089
7090 DataPrecision precision2 = PRECISION_DEFAULT;
7091 if (is_token_precision(tk.type)) {
7092 precision2 = get_token_precision(tk.type);
7093 tk = _get_token();
7094 if (!is_token_nonvoid_datatype(tk.type)) {
7095 _set_error(RTR("Expected data type after precision modifier."));
7096 return ERR_PARSE_ERROR;
7097 }
7098 }
7099
7100 DataType type2;
7101 StringName struct_name2 = "";
7102
7103 if (shader->structs.has(tk.text)) {
7104 type2 = TYPE_STRUCT;
7105 struct_name2 = tk.text;
7106 } else {
7107 if (!is_token_variable_datatype(tk.type)) {
7108 _set_error(RTR("Invalid data type for the array."));
7109 return ERR_PARSE_ERROR;
7110 }
7111 type2 = get_token_datatype(tk.type);
7112 }
7113
7114 if (precision2 != PRECISION_DEFAULT && _validate_precision(type2, precision2) != OK) {
7115 return ERR_PARSE_ERROR;
7116 }
7117
7118 int array_size2 = 0;
7119
7120 tk = _get_token();
7121 if (tk.type == TK_BRACKET_OPEN) {
7122 bool is_unknown_size = false;
7123 Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size2, &is_unknown_size);
7124 if (error != OK) {
7125 return error;
7126 }
7127 if (is_unknown_size) {
7128 array_size2 = var.array_size;
7129 }
7130 tk = _get_token();
7131 } else {
7132 _set_expected_error("[");
7133 return ERR_PARSE_ERROR;
7134 }
7135
7136 if (precision != precision2 || type != type2 || struct_name != struct_name2 || var.array_size != array_size2) {
7137 String from;
7138 if (precision2 != PRECISION_DEFAULT) {
7139 from += get_precision_name(precision2);
7140 from += " ";
7141 }
7142 if (type2 == TYPE_STRUCT) {
7143 from += struct_name2;
7144 } else {
7145 from += get_datatype_name(type2);
7146 }
7147 from += "[";
7148 from += itos(array_size2);
7149 from += "]'";
7150
7151 String to;
7152 if (precision != PRECISION_DEFAULT) {
7153 to += get_precision_name(precision);
7154 to += " ";
7155 }
7156 if (type == TYPE_STRUCT) {
7157 to += struct_name;
7158 } else {
7159 to += get_datatype_name(type);
7160 }
7161 to += "[";
7162 to += itos(var.array_size);
7163 to += "]'";
7164
7165 _set_error(vformat(RTR("Cannot convert from '%s' to '%s'."), from, to));
7166 return ERR_PARSE_ERROR;
7167 }
7168 }
7169
7170 bool curly = tk.type == TK_CURLY_BRACKET_OPEN;
7171
7172 if (unknown_size) {
7173 if (!curly) {
7174 _set_expected_error("{");
7175 return ERR_PARSE_ERROR;
7176 }
7177 } else {
7178 if (full_def) {
7179 if (curly) {
7180 _set_expected_error("(");
7181 return ERR_PARSE_ERROR;
7182 }
7183 }
7184 }
7185
7186 if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
7187 while (true) {
7188 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
7189 if (!n) {
7190 return ERR_PARSE_ERROR;
7191 }
7192
7193 if (is_const && n->type == Node::NODE_TYPE_OPERATOR && static_cast<OperatorNode *>(n)->op == OP_CALL) {
7194 _set_error(RTR("Expected a constant expression."));
7195 return ERR_PARSE_ERROR;
7196 }
7197
7198 if (!_compare_datatypes(var.type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) {
7199 return ERR_PARSE_ERROR;
7200 }
7201
7202 tk = _get_token();
7203 if (tk.type == TK_COMMA) {
7204 decl.initializer.push_back(n);
7205 continue;
7206 } else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) {
7207 decl.initializer.push_back(n);
7208 break;
7209 } else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) {
7210 decl.initializer.push_back(n);
7211 break;
7212 } else {
7213 if (curly) {
7214 _set_expected_error("}", ",");
7215 } else {
7216 _set_expected_error(")", ",");
7217 }
7218 return ERR_PARSE_ERROR;
7219 }
7220 }
7221 if (unknown_size) {
7222 decl.size = decl.initializer.size();
7223 var.array_size = decl.initializer.size();
7224 } else if (decl.initializer.size() != var.array_size) {
7225 _set_error(RTR("Array size mismatch."));
7226 return ERR_PARSE_ERROR;
7227 }
7228 tk = _get_token();
7229 }
7230 }
7231 } else {
7232 if (unknown_size) {
7233 _set_error(RTR("Expected array initialization."));
7234 return ERR_PARSE_ERROR;
7235 }
7236 if (is_const) {
7237 _set_error(RTR("Expected initialization of constant."));
7238 return ERR_PARSE_ERROR;
7239 }
7240 }
7241
7242 array_size = var.array_size;
7243 } else if (tk.type == TK_OP_ASSIGN) {
7244 //variable created with assignment! must parse an expression
7245 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
7246 if (!n) {
7247 return ERR_PARSE_ERROR;
7248 }
7249 if (is_const && n->type == Node::NODE_TYPE_OPERATOR && static_cast<OperatorNode *>(n)->op == OP_CALL) {
7250 OperatorNode *op = static_cast<OperatorNode *>(n);
7251 for (int i = 1; i < op->arguments.size(); i++) {
7252 if (!_check_node_constness(op->arguments[i])) {
7253 _set_error(vformat(RTR("Expected constant expression for argument %d of function call after '='."), i - 1));
7254 return ERR_PARSE_ERROR;
7255 }
7256 }
7257 }
7258
7259 if (n->type == Node::NODE_TYPE_CONSTANT) {
7260 ConstantNode *const_node = static_cast<ConstantNode *>(n);
7261 if (const_node && const_node->values.size() == 1) {
7262 var.value = const_node->values[0];
7263 }
7264 }
7265
7266 if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) {
7267 return ERR_PARSE_ERROR;
7268 }
7269
7270 decl.initializer.push_back(n);
7271 tk = _get_token();
7272 } else {
7273 if (is_const) {
7274 _set_error(RTR("Expected initialization of constant."));
7275 return ERR_PARSE_ERROR;
7276 }
7277 }
7278
7279 vdnode->declarations.push_back(decl);
7280 p_block->variables[name] = var;
7281 is_const_decl = false;
7282
7283 if (!fixed_array_size) {
7284 array_size = 0;
7285 }
7286
7287 if (tk.type == TK_SEMICOLON) {
7288 break;
7289 } else if (tk.type != TK_COMMA) {
7290 _set_expected_error(",", ";");
7291 return ERR_PARSE_ERROR;
7292 }
7293 } while (tk.type == TK_COMMA); //another variable
7294#ifdef DEBUG_ENABLED
7295 keyword_completion_context = CF_BLOCK;
7296#endif // DEBUG_ENABLED
7297 p_block->statements.push_back(static_cast<Node *>(vdnode));
7298 } else if (tk.type == TK_CURLY_BRACKET_OPEN) {
7299 //a sub block, just because..
7300 BlockNode *block = alloc_node<BlockNode>();
7301 block->parent_block = p_block;
7302 if (_parse_block(block, p_function_info, false, p_can_break, p_can_continue) != OK) {
7303 return ERR_PARSE_ERROR;
7304 }
7305 p_block->statements.push_back(block);
7306 } else if (tk.type == TK_CF_IF) {
7307 //if () {}
7308 tk = _get_token();
7309 if (tk.type != TK_PARENTHESIS_OPEN) {
7310 _set_expected_after_error("(", "if");
7311 return ERR_PARSE_ERROR;
7312 }
7313
7314 ControlFlowNode *cf = alloc_node<ControlFlowNode>();
7315 cf->flow_op = FLOW_OP_IF;
7316#ifdef DEBUG_ENABLED
7317 keyword_completion_context = CF_IF_DECL;
7318#endif // DEBUG_ENABLED
7319 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
7320 if (!n) {
7321 return ERR_PARSE_ERROR;
7322 }
7323#ifdef DEBUG_ENABLED
7324 keyword_completion_context = CF_BLOCK;
7325#endif // DEBUG_ENABLED
7326
7327 if (n->get_datatype() != TYPE_BOOL) {
7328 _set_error(RTR("Expected a boolean expression."));
7329 return ERR_PARSE_ERROR;
7330 }
7331
7332 tk = _get_token();
7333 if (tk.type != TK_PARENTHESIS_CLOSE) {
7334 _set_expected_error(")");
7335 return ERR_PARSE_ERROR;
7336 }
7337
7338 BlockNode *block = alloc_node<BlockNode>();
7339 block->parent_block = p_block;
7340 cf->expressions.push_back(n);
7341 cf->blocks.push_back(block);
7342 p_block->statements.push_back(cf);
7343
7344 Error err = _parse_block(block, p_function_info, true, p_can_break, p_can_continue);
7345 if (err) {
7346 return err;
7347 }
7348
7349 pos = _get_tkpos();
7350 tk = _get_token();
7351 if (tk.type == TK_CF_ELSE) {
7352 block = alloc_node<BlockNode>();
7353 block->parent_block = p_block;
7354 cf->blocks.push_back(block);
7355 err = _parse_block(block, p_function_info, true, p_can_break, p_can_continue);
7356 if (err) {
7357 return err;
7358 }
7359 } else {
7360 _set_tkpos(pos); //rollback
7361 }
7362 } else if (tk.type == TK_CF_SWITCH) {
7363 // switch() {}
7364 tk = _get_token();
7365 if (tk.type != TK_PARENTHESIS_OPEN) {
7366 _set_expected_after_error("(", "switch");
7367 return ERR_PARSE_ERROR;
7368 }
7369 ControlFlowNode *cf = alloc_node<ControlFlowNode>();
7370 cf->flow_op = FLOW_OP_SWITCH;
7371 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
7372 if (!n) {
7373 return ERR_PARSE_ERROR;
7374 }
7375 {
7376 const ShaderLanguage::DataType switch_type = n->get_datatype();
7377 if (switch_type != TYPE_INT && switch_type != TYPE_UINT) {
7378 _set_error(RTR("Expected an integer expression."));
7379 return ERR_PARSE_ERROR;
7380 }
7381 }
7382 tk = _get_token();
7383 if (tk.type != TK_PARENTHESIS_CLOSE) {
7384 _set_expected_error(")");
7385 return ERR_PARSE_ERROR;
7386 }
7387 tk = _get_token();
7388 if (tk.type != TK_CURLY_BRACKET_OPEN) {
7389 _set_expected_after_error("{", "switch");
7390 return ERR_PARSE_ERROR;
7391 }
7392 BlockNode *switch_block = alloc_node<BlockNode>();
7393 switch_block->block_type = BlockNode::BLOCK_TYPE_SWITCH;
7394 switch_block->parent_block = p_block;
7395 cf->expressions.push_back(n);
7396 cf->blocks.push_back(switch_block);
7397 p_block->statements.push_back(cf);
7398
7399 int prev_type = TK_CF_CASE;
7400 while (true) { // Go-through multiple cases.
7401
7402 if (_parse_block(switch_block, p_function_info, true, true, false) != OK) {
7403 return ERR_PARSE_ERROR;
7404 }
7405 pos = _get_tkpos();
7406 tk = _get_token();
7407 if (tk.type == TK_CF_CASE || tk.type == TK_CF_DEFAULT) {
7408 if (prev_type == TK_CF_DEFAULT) {
7409 if (tk.type == TK_CF_CASE) {
7410 _set_error(RTR("Cases must be defined before default case."));
7411 return ERR_PARSE_ERROR;
7412 } else if (prev_type == TK_CF_DEFAULT) {
7413 _set_error(RTR("Default case must be defined only once."));
7414 return ERR_PARSE_ERROR;
7415 }
7416 }
7417 prev_type = tk.type;
7418 _set_tkpos(pos);
7419 continue;
7420 } else {
7421 HashSet<int> constants;
7422 for (int i = 0; i < switch_block->statements.size(); i++) { // Checks for duplicates.
7423 ControlFlowNode *flow = static_cast<ControlFlowNode *>(switch_block->statements[i]);
7424 if (flow) {
7425 if (flow->flow_op == FLOW_OP_CASE) {
7426 if (flow->expressions[0]->type == Node::NODE_TYPE_CONSTANT) {
7427 ConstantNode *cn = static_cast<ConstantNode *>(flow->expressions[0]);
7428 if (!cn || cn->values.is_empty()) {
7429 return ERR_PARSE_ERROR;
7430 }
7431 if (constants.has(cn->values[0].sint)) {
7432 _set_error(vformat(RTR("Duplicated case label: %d."), cn->values[0].sint));
7433 return ERR_PARSE_ERROR;
7434 }
7435 constants.insert(cn->values[0].sint);
7436 } else if (flow->expressions[0]->type == Node::NODE_TYPE_VARIABLE) {
7437 VariableNode *vn = static_cast<VariableNode *>(flow->expressions[0]);
7438 if (!vn) {
7439 return ERR_PARSE_ERROR;
7440 }
7441 ConstantNode::Value v;
7442 _find_identifier(p_block, false, p_function_info, vn->name, nullptr, nullptr, nullptr, nullptr, nullptr, &v);
7443 if (constants.has(v.sint)) {
7444 _set_error(vformat(RTR("Duplicated case label: %d."), v.sint));
7445 return ERR_PARSE_ERROR;
7446 }
7447 constants.insert(v.sint);
7448 }
7449 } else if (flow->flow_op == FLOW_OP_DEFAULT) {
7450 continue;
7451 } else {
7452 return ERR_PARSE_ERROR;
7453 }
7454 } else {
7455 return ERR_PARSE_ERROR;
7456 }
7457 }
7458 break;
7459 }
7460 }
7461
7462 } else if (tk.type == TK_CF_CASE) {
7463 // case x : break; | return;
7464
7465 if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_CASE) {
7466 _set_tkpos(pos);
7467 return OK;
7468 }
7469
7470 if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_SWITCH)) {
7471 _set_error(vformat(RTR("'%s' must be placed within a '%s' block."), "case", "switch"));
7472 return ERR_PARSE_ERROR;
7473 }
7474
7475 tk = _get_token();
7476
7477 int sign = 1;
7478
7479 if (tk.type == TK_OP_SUB) {
7480 sign = -1;
7481 tk = _get_token();
7482 }
7483
7484 Node *n = nullptr;
7485
7486 if (!tk.is_integer_constant()) {
7487 bool correct_constant_expression = false;
7488 DataType data_type;
7489
7490 if (tk.type == TK_IDENTIFIER) {
7491 bool is_const;
7492 _find_identifier(p_block, false, p_function_info, tk.text, &data_type, nullptr, &is_const);
7493 if (is_const) {
7494 if (data_type == TYPE_INT) {
7495 correct_constant_expression = true;
7496 }
7497 }
7498 }
7499 if (!correct_constant_expression) {
7500 _set_error(RTR("Expected an integer constant."));
7501 return ERR_PARSE_ERROR;
7502 }
7503
7504 VariableNode *vn = alloc_node<VariableNode>();
7505 vn->name = tk.text;
7506 n = vn;
7507 } else {
7508 ConstantNode::Value v;
7509 if (tk.type == TK_UINT_CONSTANT) {
7510 v.uint = (uint32_t)tk.constant;
7511 } else {
7512 v.sint = (int)tk.constant * sign;
7513 }
7514
7515 ConstantNode *cn = alloc_node<ConstantNode>();
7516 cn->values.push_back(v);
7517 cn->datatype = (tk.type == TK_UINT_CONSTANT ? TYPE_UINT : TYPE_INT);
7518 n = cn;
7519 }
7520
7521 tk = _get_token();
7522
7523 if (tk.type != TK_COLON) {
7524 _set_expected_error(":");
7525 return ERR_PARSE_ERROR;
7526 }
7527
7528 ControlFlowNode *cf = alloc_node<ControlFlowNode>();
7529 cf->flow_op = FLOW_OP_CASE;
7530
7531 BlockNode *case_block = alloc_node<BlockNode>();
7532 case_block->block_type = BlockNode::BLOCK_TYPE_CASE;
7533 case_block->parent_block = p_block;
7534 cf->expressions.push_back(n);
7535 cf->blocks.push_back(case_block);
7536 p_block->statements.push_back(cf);
7537
7538 Error err = _parse_block(case_block, p_function_info, false, true, false);
7539 if (err) {
7540 return err;
7541 }
7542
7543 return OK;
7544
7545 } else if (tk.type == TK_CF_DEFAULT) {
7546 if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_CASE) {
7547 _set_tkpos(pos);
7548 return OK;
7549 }
7550
7551 if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_SWITCH)) {
7552 _set_error(vformat(RTR("'%s' must be placed within a '%s' block."), "default", "switch"));
7553 return ERR_PARSE_ERROR;
7554 }
7555
7556 tk = _get_token();
7557
7558 if (tk.type != TK_COLON) {
7559 _set_expected_error(":");
7560 return ERR_PARSE_ERROR;
7561 }
7562
7563 ControlFlowNode *cf = alloc_node<ControlFlowNode>();
7564 cf->flow_op = FLOW_OP_DEFAULT;
7565
7566 BlockNode *default_block = alloc_node<BlockNode>();
7567 default_block->block_type = BlockNode::BLOCK_TYPE_DEFAULT;
7568 default_block->parent_block = p_block;
7569 cf->blocks.push_back(default_block);
7570 p_block->statements.push_back(cf);
7571
7572 Error err = _parse_block(default_block, p_function_info, false, true, false);
7573 if (err) {
7574 return err;
7575 }
7576
7577 return OK;
7578
7579 } else if (tk.type == TK_CF_DO || tk.type == TK_CF_WHILE) {
7580 // do {} while()
7581 // while() {}
7582 bool is_do = tk.type == TK_CF_DO;
7583
7584 BlockNode *do_block = nullptr;
7585 if (is_do) {
7586 do_block = alloc_node<BlockNode>();
7587 do_block->parent_block = p_block;
7588
7589 Error err = _parse_block(do_block, p_function_info, true, true, true);
7590 if (err) {
7591 return err;
7592 }
7593
7594 tk = _get_token();
7595 if (tk.type != TK_CF_WHILE) {
7596 _set_expected_after_error("while", "do");
7597 return ERR_PARSE_ERROR;
7598 }
7599 }
7600 tk = _get_token();
7601
7602 if (tk.type != TK_PARENTHESIS_OPEN) {
7603 _set_expected_after_error("(", "while");
7604 return ERR_PARSE_ERROR;
7605 }
7606
7607 ControlFlowNode *cf = alloc_node<ControlFlowNode>();
7608 if (is_do) {
7609 cf->flow_op = FLOW_OP_DO;
7610 } else {
7611 cf->flow_op = FLOW_OP_WHILE;
7612 }
7613 Node *n = _parse_and_reduce_expression(p_block, p_function_info);
7614 if (!n) {
7615 return ERR_PARSE_ERROR;
7616 }
7617
7618 tk = _get_token();
7619 if (tk.type != TK_PARENTHESIS_CLOSE) {
7620 _set_expected_error(")");
7621 return ERR_PARSE_ERROR;
7622 }
7623 if (!is_do) {
7624 BlockNode *block = alloc_node<BlockNode>();
7625 block->parent_block = p_block;
7626 cf->expressions.push_back(n);
7627 cf->blocks.push_back(block);
7628 p_block->statements.push_back(cf);
7629
7630 Error err = _parse_block(block, p_function_info, true, true, true);
7631 if (err) {
7632 return err;
7633 }
7634 } else {
7635 cf->expressions.push_back(n);
7636 cf->blocks.push_back(do_block);
7637 p_block->statements.push_back(cf);
7638
7639 tk = _get_token();
7640 if (tk.type != TK_SEMICOLON) {
7641 _set_expected_error(";");
7642 return ERR_PARSE_ERROR;
7643 }
7644 }
7645 } else if (tk.type == TK_CF_FOR) {
7646 // for() {}
7647 tk = _get_token();
7648 if (tk.type != TK_PARENTHESIS_OPEN) {
7649 _set_expected_after_error("(", "for");
7650 return ERR_PARSE_ERROR;
7651 }
7652
7653 ControlFlowNode *cf = alloc_node<ControlFlowNode>();
7654 cf->flow_op = FLOW_OP_FOR;
7655
7656 BlockNode *init_block = alloc_node<BlockNode>();
7657 init_block->block_type = BlockNode::BLOCK_TYPE_FOR_INIT;
7658 init_block->parent_block = p_block;
7659 init_block->single_statement = true;
7660 cf->blocks.push_back(init_block);
7661
7662#ifdef DEBUG_ENABLED
7663 keyword_completion_context = CF_DATATYPE;
7664#endif // DEBUG_ENABLED
7665 Error err = _parse_block(init_block, p_function_info, true, false, false);
7666 if (err != OK) {
7667 return err;
7668 }
7669#ifdef DEBUG_ENABLED
7670 keyword_completion_context = CF_UNSPECIFIED;
7671#endif // DEBUG_ENABLED
7672
7673 BlockNode *condition_block = alloc_node<BlockNode>();
7674 condition_block->block_type = BlockNode::BLOCK_TYPE_FOR_CONDITION;
7675 condition_block->parent_block = init_block;
7676 condition_block->single_statement = true;
7677 condition_block->use_comma_between_statements = true;
7678 cf->blocks.push_back(condition_block);
7679 err = _parse_block(condition_block, p_function_info, true, false, false);
7680 if (err != OK) {
7681 return err;
7682 }
7683
7684 BlockNode *expression_block = alloc_node<BlockNode>();
7685 expression_block->block_type = BlockNode::BLOCK_TYPE_FOR_EXPRESSION;
7686 expression_block->parent_block = init_block;
7687 expression_block->single_statement = true;
7688 expression_block->use_comma_between_statements = true;
7689 cf->blocks.push_back(expression_block);
7690 err = _parse_block(expression_block, p_function_info, true, false, false);
7691 if (err != OK) {
7692 return err;
7693 }
7694
7695 BlockNode *block = alloc_node<BlockNode>();
7696 block->parent_block = init_block;
7697 cf->blocks.push_back(block);
7698 p_block->statements.push_back(cf);
7699
7700#ifdef DEBUG_ENABLED
7701 keyword_completion_context = CF_BLOCK;
7702#endif // DEBUG_ENABLED
7703 err = _parse_block(block, p_function_info, true, true, true);
7704 if (err != OK) {
7705 return err;
7706 }
7707
7708 } else if (tk.type == TK_CF_RETURN) {
7709 //check return type
7710 BlockNode *b = p_block;
7711
7712 while (b && !b->parent_function) {
7713 b = b->parent_block;
7714 }
7715
7716 if (!b) {
7717 _set_parsing_error();
7718 return ERR_BUG;
7719 }
7720
7721 if (b->parent_function && p_function_info.main_function) {
7722 _set_error(vformat(RTR("Using '%s' in the '%s' processor function is incorrect."), "return", b->parent_function->name));
7723 return ERR_PARSE_ERROR;
7724 }
7725
7726 String return_struct_name = String(b->parent_function->return_struct_name);
7727 String array_size_string;
7728
7729 if (b->parent_function->return_array_size > 0) {
7730 array_size_string = "[" + itos(b->parent_function->return_array_size) + "]";
7731 }
7732
7733 ControlFlowNode *flow = alloc_node<ControlFlowNode>();
7734 flow->flow_op = FLOW_OP_RETURN;
7735
7736 pos = _get_tkpos();
7737 tk = _get_token();
7738 if (tk.type == TK_SEMICOLON) {
7739 //all is good
7740 if (b->parent_function->return_type != TYPE_VOID) {
7741 _set_error(vformat(RTR("Expected '%s' with an expression of type '%s'."), "return", (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string));
7742 return ERR_PARSE_ERROR;
7743 }
7744 } else {
7745 _set_tkpos(pos); //rollback, wants expression
7746
7747#ifdef DEBUG_ENABLED
7748 if (b->parent_function->return_type == DataType::TYPE_BOOL) {
7749 keyword_completion_context = CF_BOOLEAN;
7750 }
7751#endif // DEBUG_ENABLED
7752
7753 Node *expr = _parse_and_reduce_expression(p_block, p_function_info);
7754 if (!expr) {
7755 return ERR_PARSE_ERROR;
7756 }
7757
7758 if (b->parent_function->return_type != expr->get_datatype() || b->parent_function->return_array_size != expr->get_array_size() || return_struct_name != expr->get_datatype_name()) {
7759 _set_error(vformat(RTR("Expected return with an expression of type '%s'."), (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string));
7760 return ERR_PARSE_ERROR;
7761 }
7762
7763 tk = _get_token();
7764 if (tk.type != TK_SEMICOLON) {
7765 _set_expected_after_error(";", "return");
7766 return ERR_PARSE_ERROR;
7767 }
7768
7769#ifdef DEBUG_ENABLED
7770 if (b->parent_function->return_type == DataType::TYPE_BOOL) {
7771 keyword_completion_context = CF_BLOCK;
7772 }
7773#endif // DEBUG_ENABLED
7774
7775 flow->expressions.push_back(expr);
7776 }
7777
7778 p_block->statements.push_back(flow);
7779
7780 BlockNode *block = p_block;
7781 while (block) {
7782 if (block->block_type == BlockNode::BLOCK_TYPE_CASE || block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
7783 return OK;
7784 }
7785 block = block->parent_block;
7786 }
7787 } else if (tk.type == TK_CF_DISCARD) {
7788 //check return type
7789 BlockNode *b = p_block;
7790 while (b && !b->parent_function) {
7791 b = b->parent_block;
7792 }
7793 if (!b) {
7794 _set_parsing_error();
7795 return ERR_BUG;
7796 }
7797
7798 if (!b->parent_function->can_discard) {
7799 _set_error(vformat(RTR("Use of '%s' is not allowed here."), "discard"));
7800 return ERR_PARSE_ERROR;
7801 }
7802
7803 ControlFlowNode *flow = alloc_node<ControlFlowNode>();
7804 flow->flow_op = FLOW_OP_DISCARD;
7805
7806 pos = _get_tkpos();
7807 tk = _get_token();
7808 if (tk.type != TK_SEMICOLON) {
7809 _set_expected_after_error(";", "discard");
7810 return ERR_PARSE_ERROR;
7811 }
7812
7813 p_block->statements.push_back(flow);
7814 } else if (tk.type == TK_CF_BREAK) {
7815 if (!p_can_break) {
7816 _set_error(vformat(RTR("'%s' is not allowed outside of a loop or '%s' statement."), "break", "switch"));
7817 return ERR_PARSE_ERROR;
7818 }
7819
7820 ControlFlowNode *flow = alloc_node<ControlFlowNode>();
7821 flow->flow_op = FLOW_OP_BREAK;
7822
7823 pos = _get_tkpos();
7824 tk = _get_token();
7825 if (tk.type != TK_SEMICOLON) {
7826 _set_expected_after_error(";", "break");
7827 return ERR_PARSE_ERROR;
7828 }
7829
7830 p_block->statements.push_back(flow);
7831
7832 BlockNode *block = p_block;
7833 while (block) {
7834 if (block->block_type == BlockNode::BLOCK_TYPE_CASE || block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
7835 return OK;
7836 }
7837 block = block->parent_block;
7838 }
7839
7840 } else if (tk.type == TK_CF_CONTINUE) {
7841 if (!p_can_continue) {
7842 _set_error(vformat(RTR("'%s' is not allowed outside of a loop."), "continue"));
7843 return ERR_PARSE_ERROR;
7844 }
7845
7846 ControlFlowNode *flow = alloc_node<ControlFlowNode>();
7847 flow->flow_op = FLOW_OP_CONTINUE;
7848
7849 pos = _get_tkpos();
7850 tk = _get_token();
7851 if (tk.type != TK_SEMICOLON) {
7852 //all is good
7853 _set_expected_after_error(";", "continue");
7854 return ERR_PARSE_ERROR;
7855 }
7856
7857 p_block->statements.push_back(flow);
7858
7859 } else {
7860 //nothing else, so expression
7861 _set_tkpos(pos); //rollback
7862 Node *expr = _parse_and_reduce_expression(p_block, p_function_info);
7863 if (!expr) {
7864 return ERR_PARSE_ERROR;
7865 }
7866 is_condition = expr->type == Node::NODE_TYPE_OPERATOR && expr->get_datatype() == TYPE_BOOL;
7867
7868 if (expr->type == Node::NODE_TYPE_OPERATOR) {
7869 OperatorNode *op = static_cast<OperatorNode *>(expr);
7870 if (op->op == OP_EMPTY) {
7871 is_var_init = true;
7872 is_condition = true;
7873 }
7874 }
7875
7876 p_block->statements.push_back(expr);
7877 tk = _get_token();
7878
7879 if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_CONDITION) {
7880 if (tk.type == TK_COMMA) {
7881 if (!is_condition) {
7882 _set_error(RTR("The middle expression is expected to be a boolean operator."));
7883 return ERR_PARSE_ERROR;
7884 }
7885 continue;
7886 }
7887 if (tk.type != TK_SEMICOLON) {
7888 _set_expected_error(",", ";");
7889 return ERR_PARSE_ERROR;
7890 }
7891 } else if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_EXPRESSION) {
7892 if (tk.type == TK_COMMA) {
7893 continue;
7894 }
7895 if (tk.type != TK_PARENTHESIS_CLOSE) {
7896 _set_expected_error(",", ")");
7897 return ERR_PARSE_ERROR;
7898 }
7899 } else if (tk.type != TK_SEMICOLON) {
7900 _set_expected_error(";");
7901 return ERR_PARSE_ERROR;
7902 }
7903 }
7904
7905 if (p_block) {
7906 if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_INIT && !is_var_init) {
7907 _set_error(RTR("The left expression is expected to be a variable declaration."));
7908 return ERR_PARSE_ERROR;
7909 }
7910 if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_CONDITION && !is_condition) {
7911 _set_error(RTR("The middle expression is expected to be a boolean operator."));
7912 return ERR_PARSE_ERROR;
7913 }
7914 }
7915
7916 if (p_just_one) {
7917 break;
7918 }
7919 }
7920
7921 return OK;
7922}
7923
7924String ShaderLanguage::_get_shader_type_list(const HashSet<String> &p_shader_types) const {
7925 // Return a list of shader types as an human-readable string
7926 String valid_types;
7927 for (const String &E : p_shader_types) {
7928 if (!valid_types.is_empty()) {
7929 valid_types += ", ";
7930 }
7931
7932 valid_types += "'" + E + "'";
7933 }
7934
7935 return valid_types;
7936}
7937
7938String ShaderLanguage::_get_qualifier_str(ArgumentQualifier p_qualifier) const {
7939 switch (p_qualifier) {
7940 case ArgumentQualifier::ARGUMENT_QUALIFIER_IN:
7941 return "in";
7942 case ArgumentQualifier::ARGUMENT_QUALIFIER_OUT:
7943 return "out";
7944 case ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT:
7945 return "inout";
7946 }
7947 return "";
7948}
7949
7950Error ShaderLanguage::_validate_precision(DataType p_type, DataPrecision p_precision) {
7951 switch (p_type) {
7952 case TYPE_STRUCT: {
7953 _set_error(RTR("The precision modifier cannot be used on structs."));
7954 return FAILED;
7955 } break;
7956 case TYPE_BOOL:
7957 case TYPE_BVEC2:
7958 case TYPE_BVEC3:
7959 case TYPE_BVEC4: {
7960 _set_error(RTR("The precision modifier cannot be used on boolean types."));
7961 return FAILED;
7962 } break;
7963 default:
7964 break;
7965 }
7966 return OK;
7967}
7968
7969Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const HashSet<String> &p_shader_types) {
7970 Token tk;
7971 TkPos prev_pos;
7972 Token next;
7973
7974 if (!is_shader_inc) {
7975#ifdef DEBUG_ENABLED
7976 keyword_completion_context = CF_SHADER_TYPE;
7977#endif // DEBUG_ENABLED
7978 tk = _get_token();
7979
7980 if (tk.type != TK_SHADER_TYPE) {
7981 _set_error(vformat(RTR("Expected '%s' at the beginning of shader. Valid types are: %s."), "shader_type", _get_shader_type_list(p_shader_types)));
7982 return ERR_PARSE_ERROR;
7983 }
7984#ifdef DEBUG_ENABLED
7985 keyword_completion_context = CF_UNSPECIFIED;
7986#endif // DEBUG_ENABLED
7987
7988 _get_completable_identifier(nullptr, COMPLETION_SHADER_TYPE, shader_type_identifier);
7989 if (shader_type_identifier == StringName()) {
7990 _set_error(vformat(RTR("Expected an identifier after '%s', indicating the type of shader. Valid types are: %s."), "shader_type", _get_shader_type_list(p_shader_types)));
7991 return ERR_PARSE_ERROR;
7992 }
7993 if (!p_shader_types.has(shader_type_identifier)) {
7994 _set_error(vformat(RTR("Invalid shader type. Valid types are: %s"), _get_shader_type_list(p_shader_types)));
7995 return ERR_PARSE_ERROR;
7996 }
7997 prev_pos = _get_tkpos();
7998 tk = _get_token();
7999
8000 if (tk.type != TK_SEMICOLON) {
8001 _set_tkpos(prev_pos);
8002 _set_expected_after_error(";", "shader_type " + String(shader_type_identifier));
8003 return ERR_PARSE_ERROR;
8004 }
8005 }
8006
8007#ifdef DEBUG_ENABLED
8008 keyword_completion_context = CF_GLOBAL_SPACE;
8009#endif // DEBUG_ENABLED
8010 tk = _get_token();
8011
8012 int texture_uniforms = 0;
8013 int texture_binding = 0;
8014 int uniforms = 0;
8015 int instance_index = 0;
8016#ifdef DEBUG_ENABLED
8017 uint64_t uniform_buffer_size = 0;
8018 uint64_t max_uniform_buffer_size = 0;
8019 int uniform_buffer_exceeded_line = -1;
8020
8021 bool check_device_limit_warnings = false;
8022 {
8023 RenderingDevice *device = RenderingDevice::get_singleton();
8024 if (device != nullptr) {
8025 check_device_limit_warnings = check_warnings && HAS_WARNING(ShaderWarning::DEVICE_LIMIT_EXCEEDED_FLAG);
8026
8027 max_uniform_buffer_size = device->limit_get(RenderingDevice::LIMIT_MAX_UNIFORM_BUFFER_SIZE);
8028 }
8029 }
8030#endif // DEBUG_ENABLED
8031 ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
8032
8033 stages = &p_functions;
8034 const FunctionInfo &constants = p_functions.has("constants") ? p_functions["constants"] : FunctionInfo();
8035
8036 HashMap<String, String> defined_modes;
8037
8038 while (tk.type != TK_EOF) {
8039 switch (tk.type) {
8040 case TK_RENDER_MODE: {
8041#ifdef DEBUG_ENABLED
8042 keyword_completion_context = CF_UNSPECIFIED;
8043#endif // DEBUG_ENABLED
8044 while (true) {
8045 StringName mode;
8046 _get_completable_identifier(nullptr, COMPLETION_RENDER_MODE, mode);
8047
8048 if (mode == StringName()) {
8049 _set_error(RTR("Expected an identifier for render mode."));
8050 return ERR_PARSE_ERROR;
8051 }
8052
8053 const String smode = String(mode);
8054
8055 if (shader->render_modes.has(mode)) {
8056 _set_error(vformat(RTR("Duplicated render mode: '%s'."), smode));
8057 return ERR_PARSE_ERROR;
8058 }
8059
8060 bool found = false;
8061
8062 if (is_shader_inc) {
8063 for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
8064 const Vector<ModeInfo> modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(i));
8065
8066 for (int j = 0; j < modes.size(); j++) {
8067 const ModeInfo &info = modes[j];
8068 const String name = String(info.name);
8069
8070 if (smode.begins_with(name)) {
8071 if (!info.options.is_empty()) {
8072 if (info.options.has(smode.substr(name.length() + 1))) {
8073 found = true;
8074
8075 if (defined_modes.has(name)) {
8076 _set_error(vformat(RTR("Redefinition of render mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, defined_modes[name]));
8077 return ERR_PARSE_ERROR;
8078 }
8079 defined_modes.insert(name, smode);
8080 break;
8081 }
8082 } else {
8083 found = true;
8084 break;
8085 }
8086 }
8087 }
8088 }
8089 } else {
8090 for (int i = 0; i < p_render_modes.size(); i++) {
8091 const ModeInfo &info = p_render_modes[i];
8092 const String name = String(info.name);
8093
8094 if (smode.begins_with(name)) {
8095 if (!info.options.is_empty()) {
8096 if (info.options.has(smode.substr(name.length() + 1))) {
8097 found = true;
8098
8099 if (defined_modes.has(name)) {
8100 _set_error(vformat(RTR("Redefinition of render mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, defined_modes[name]));
8101 return ERR_PARSE_ERROR;
8102 }
8103 defined_modes.insert(name, smode);
8104 break;
8105 }
8106 } else {
8107 found = true;
8108 break;
8109 }
8110 }
8111 }
8112 }
8113
8114 if (!found) {
8115 _set_error(vformat(RTR("Invalid render mode: '%s'."), smode));
8116 return ERR_PARSE_ERROR;
8117 }
8118
8119 shader->render_modes.push_back(mode);
8120
8121 tk = _get_token();
8122 if (tk.type == TK_COMMA) {
8123 //all good, do nothing
8124 } else if (tk.type == TK_SEMICOLON) {
8125 break; //done
8126 } else {
8127 _set_error(vformat(RTR("Unexpected token: '%s'."), get_token_text(tk)));
8128 return ERR_PARSE_ERROR;
8129 }
8130 }
8131#ifdef DEBUG_ENABLED
8132 keyword_completion_context = CF_GLOBAL_SPACE;
8133#endif // DEBUG_ENABLED
8134 } break;
8135 case TK_STRUCT: {
8136 ShaderNode::Struct st;
8137 DataType type;
8138#ifdef DEBUG_ENABLED
8139 keyword_completion_context = CF_UNSPECIFIED;
8140#endif // DEBUG_ENABLED
8141 tk = _get_token();
8142 if (tk.type == TK_IDENTIFIER) {
8143 st.name = tk.text;
8144 if (shader->constants.has(st.name) || shader->structs.has(st.name)) {
8145 _set_redefinition_error(String(st.name));
8146 return ERR_PARSE_ERROR;
8147 }
8148 tk = _get_token();
8149 if (tk.type != TK_CURLY_BRACKET_OPEN) {
8150 _set_expected_error("{");
8151 return ERR_PARSE_ERROR;
8152 }
8153 } else {
8154 _set_error(RTR("Expected a struct identifier."));
8155 return ERR_PARSE_ERROR;
8156 }
8157
8158 StructNode *st_node = alloc_node<StructNode>();
8159 st.shader_struct = st_node;
8160
8161 int member_count = 0;
8162 HashSet<String> member_names;
8163
8164 while (true) { // variables list
8165#ifdef DEBUG_ENABLED
8166 keyword_completion_context = CF_DATATYPE | CF_PRECISION_MODIFIER;
8167#endif // DEBUG_ENABLED
8168
8169 tk = _get_token();
8170 if (tk.type == TK_CURLY_BRACKET_CLOSE) {
8171 break;
8172 }
8173 StringName struct_name = "";
8174 bool struct_dt = false;
8175 DataPrecision precision = PRECISION_DEFAULT;
8176
8177 if (tk.type == TK_STRUCT) {
8178 _set_error(RTR("Nested structs are not allowed."));
8179 return ERR_PARSE_ERROR;
8180 }
8181
8182 if (is_token_precision(tk.type)) {
8183 precision = get_token_precision(tk.type);
8184 tk = _get_token();
8185#ifdef DEBUG_ENABLED
8186 keyword_completion_context ^= CF_PRECISION_MODIFIER;
8187#endif // DEBUG_ENABLED
8188 }
8189
8190 if (shader->structs.has(tk.text)) {
8191 struct_name = tk.text;
8192#ifdef DEBUG_ENABLED
8193 if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(struct_name)) {
8194 used_structs[struct_name].used = true;
8195 }
8196#endif // DEBUG_ENABLED
8197 struct_dt = true;
8198 }
8199
8200 if (!is_token_datatype(tk.type) && !struct_dt) {
8201 _set_error(RTR("Expected data type."));
8202 return ERR_PARSE_ERROR;
8203 } else {
8204 type = struct_dt ? TYPE_STRUCT : get_token_datatype(tk.type);
8205
8206 if (precision != PRECISION_DEFAULT && _validate_precision(type, precision) != OK) {
8207 return ERR_PARSE_ERROR;
8208 }
8209
8210 if (type == TYPE_VOID || is_sampler_type(type)) {
8211 _set_error(vformat(RTR("A '%s' data type is not allowed here."), get_datatype_name(type)));
8212 return ERR_PARSE_ERROR;
8213 }
8214#ifdef DEBUG_ENABLED
8215 keyword_completion_context = CF_UNSPECIFIED;
8216#endif // DEBUG_ENABLED
8217
8218 bool first = true;
8219 bool fixed_array_size = false;
8220 int array_size = 0;
8221
8222 do {
8223 tk = _get_token();
8224
8225 if (first) {
8226 first = false;
8227
8228 if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
8229 _set_error(RTR("Expected an identifier or '['."));
8230 return ERR_PARSE_ERROR;
8231 }
8232
8233 if (tk.type == TK_BRACKET_OPEN) {
8234 Error error = _parse_array_size(nullptr, constants, true, nullptr, &array_size, nullptr);
8235 if (error != OK) {
8236 return error;
8237 }
8238 fixed_array_size = true;
8239 tk = _get_token();
8240 }
8241 }
8242
8243 if (tk.type != TK_IDENTIFIER) {
8244 _set_error(RTR("Expected an identifier."));
8245 return ERR_PARSE_ERROR;
8246 }
8247
8248 MemberNode *member = alloc_node<MemberNode>();
8249 member->precision = precision;
8250 member->datatype = type;
8251 member->struct_name = struct_name;
8252 member->name = tk.text;
8253 member->array_size = array_size;
8254
8255 if (member_names.has(member->name)) {
8256 _set_redefinition_error(String(member->name));
8257 return ERR_PARSE_ERROR;
8258 }
8259 member_names.insert(member->name);
8260 tk = _get_token();
8261
8262 if (tk.type == TK_BRACKET_OPEN) {
8263 Error error = _parse_array_size(nullptr, constants, true, nullptr, &member->array_size, nullptr);
8264 if (error != OK) {
8265 return error;
8266 }
8267 tk = _get_token();
8268 }
8269
8270 if (!fixed_array_size) {
8271 array_size = 0;
8272 }
8273
8274 if (tk.type != TK_SEMICOLON && tk.type != TK_COMMA) {
8275 _set_expected_error(",", ";");
8276 return ERR_PARSE_ERROR;
8277 }
8278
8279 st_node->members.push_back(member);
8280 member_count++;
8281 } while (tk.type == TK_COMMA); // another member
8282 }
8283 }
8284 if (member_count == 0) {
8285 _set_error(RTR("Empty structs are not allowed."));
8286 return ERR_PARSE_ERROR;
8287 }
8288#ifdef DEBUG_ENABLED
8289 keyword_completion_context = CF_UNSPECIFIED;
8290#endif // DEBUG_ENABLED
8291
8292 tk = _get_token();
8293 if (tk.type != TK_SEMICOLON) {
8294 _set_expected_error(";");
8295 return ERR_PARSE_ERROR;
8296 }
8297#ifdef DEBUG_ENABLED
8298 keyword_completion_context = CF_GLOBAL_SPACE;
8299#endif // DEBUG_ENABLED
8300
8301 shader->structs[st.name] = st;
8302 shader->vstructs.push_back(st); // struct's order is important!
8303#ifdef DEBUG_ENABLED
8304 if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG)) {
8305 used_structs.insert(st.name, Usage(tk_line));
8306 }
8307#endif // DEBUG_ENABLED
8308 } break;
8309 case TK_GLOBAL: {
8310#ifdef DEBUG_ENABLED
8311 keyword_completion_context = CF_UNIFORM_KEYWORD;
8312 if (_lookup_next(next)) {
8313 if (next.type == TK_UNIFORM) {
8314 keyword_completion_context ^= CF_UNIFORM_KEYWORD;
8315 }
8316 }
8317#endif // DEBUG_ENABLED
8318 tk = _get_token();
8319 if (tk.type != TK_UNIFORM) {
8320 _set_expected_after_error("uniform", "global");
8321 return ERR_PARSE_ERROR;
8322 }
8323 uniform_scope = ShaderNode::Uniform::SCOPE_GLOBAL;
8324 };
8325 [[fallthrough]];
8326 case TK_INSTANCE: {
8327 if (tk.type == TK_INSTANCE) {
8328#ifdef DEBUG_ENABLED
8329 keyword_completion_context = CF_UNIFORM_KEYWORD;
8330 if (_lookup_next(next)) {
8331 if (next.type == TK_UNIFORM) {
8332 keyword_completion_context ^= CF_UNIFORM_KEYWORD;
8333 }
8334 }
8335#endif // DEBUG_ENABLED
8336 if (String(shader_type_identifier) != "spatial") {
8337 _set_error(vformat(RTR("Uniform instances are not yet implemented for '%s' shaders."), shader_type_identifier));
8338 return ERR_PARSE_ERROR;
8339 }
8340 if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") {
8341 _set_error(RTR("Uniform instances are not supported in gl_compatibility shaders."));
8342 return ERR_PARSE_ERROR;
8343 }
8344 if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) {
8345 tk = _get_token();
8346 if (tk.type != TK_UNIFORM) {
8347 _set_expected_after_error("uniform", "instance");
8348 return ERR_PARSE_ERROR;
8349 }
8350 uniform_scope = ShaderNode::Uniform::SCOPE_INSTANCE;
8351 }
8352 }
8353 };
8354 [[fallthrough]];
8355 case TK_UNIFORM:
8356 case TK_VARYING: {
8357 bool is_uniform = tk.type == TK_UNIFORM;
8358#ifdef DEBUG_ENABLED
8359 keyword_completion_context = CF_UNSPECIFIED;
8360#endif // DEBUG_ENABLED
8361 if (!is_uniform) {
8362 if (shader_type_identifier == "particles" || shader_type_identifier == "sky" || shader_type_identifier == "fog") {
8363 _set_error(vformat(RTR("Varyings cannot be used in '%s' shaders."), shader_type_identifier));
8364 return ERR_PARSE_ERROR;
8365 }
8366 }
8367 DataPrecision precision = PRECISION_DEFAULT;
8368 DataInterpolation interpolation = INTERPOLATION_DEFAULT;
8369 DataType type;
8370 StringName name;
8371 int array_size = 0;
8372
8373 tk = _get_token();
8374#ifdef DEBUG_ENABLED
8375 bool temp_error = false;
8376 uint32_t datatype_flag;
8377
8378 if (!is_uniform) {
8379 datatype_flag = CF_VARYING_TYPE;
8380 keyword_completion_context = CF_INTERPOLATION_QUALIFIER | CF_PRECISION_MODIFIER | datatype_flag;
8381
8382 if (_lookup_next(next)) {
8383 if (is_token_interpolation(next.type)) {
8384 keyword_completion_context ^= (CF_INTERPOLATION_QUALIFIER | datatype_flag);
8385 } else if (is_token_precision(next.type)) {
8386 keyword_completion_context ^= (CF_PRECISION_MODIFIER | datatype_flag);
8387 } else if (is_token_datatype(next.type)) {
8388 keyword_completion_context ^= datatype_flag;
8389 }
8390 }
8391 } else {
8392 datatype_flag = CF_UNIFORM_TYPE;
8393 keyword_completion_context = CF_PRECISION_MODIFIER | datatype_flag;
8394
8395 if (_lookup_next(next)) {
8396 if (is_token_precision(next.type)) {
8397 keyword_completion_context ^= (CF_PRECISION_MODIFIER | datatype_flag);
8398 } else if (is_token_datatype(next.type)) {
8399 keyword_completion_context ^= datatype_flag;
8400 }
8401 }
8402 }
8403#endif // DEBUG_ENABLED
8404
8405 if (is_token_interpolation(tk.type)) {
8406 if (is_uniform) {
8407 _set_error(RTR("Interpolation qualifiers are not supported for uniforms."));
8408#ifdef DEBUG_ENABLED
8409 temp_error = true;
8410#else
8411 return ERR_PARSE_ERROR;
8412#endif // DEBUG_ENABLED
8413 }
8414 interpolation = get_token_interpolation(tk.type);
8415 tk = _get_token();
8416#ifdef DEBUG_ENABLED
8417 if (keyword_completion_context & CF_INTERPOLATION_QUALIFIER) {
8418 keyword_completion_context ^= CF_INTERPOLATION_QUALIFIER;
8419 }
8420 if (_lookup_next(next)) {
8421 if (is_token_precision(next.type)) {
8422 keyword_completion_context ^= CF_PRECISION_MODIFIER;
8423 } else if (is_token_datatype(next.type)) {
8424 keyword_completion_context ^= datatype_flag;
8425 }
8426 }
8427 if (temp_error) {
8428 return ERR_PARSE_ERROR;
8429 }
8430#endif // DEBUG_ENABLED
8431 }
8432
8433 if (is_token_precision(tk.type)) {
8434 precision = get_token_precision(tk.type);
8435 tk = _get_token();
8436#ifdef DEBUG_ENABLED
8437 if (keyword_completion_context & CF_INTERPOLATION_QUALIFIER) {
8438 keyword_completion_context ^= CF_INTERPOLATION_QUALIFIER;
8439 }
8440 if (keyword_completion_context & CF_PRECISION_MODIFIER) {
8441 keyword_completion_context ^= CF_PRECISION_MODIFIER;
8442 }
8443 if (_lookup_next(next)) {
8444 if (is_token_datatype(next.type)) {
8445 keyword_completion_context = CF_UNSPECIFIED;
8446 }
8447 }
8448#endif // DEBUG_ENABLED
8449 }
8450
8451 if (shader->structs.has(tk.text)) {
8452 if (is_uniform) {
8453 _set_error(vformat(RTR("The '%s' data type is not supported for uniforms."), "struct"));
8454 return ERR_PARSE_ERROR;
8455 } else {
8456 _set_error(vformat(RTR("The '%s' data type is not allowed here."), "struct"));
8457 return ERR_PARSE_ERROR;
8458 }
8459 }
8460
8461 if (!is_token_datatype(tk.type)) {
8462 _set_error(RTR("Expected data type."));
8463 return ERR_PARSE_ERROR;
8464 }
8465
8466 type = get_token_datatype(tk.type);
8467
8468 if (precision != PRECISION_DEFAULT && _validate_precision(type, precision) != OK) {
8469 return ERR_PARSE_ERROR;
8470 }
8471
8472 if (type == TYPE_VOID) {
8473 _set_error(vformat(RTR("The '%s' data type is not allowed here."), "void"));
8474 return ERR_PARSE_ERROR;
8475 }
8476
8477 if (!is_uniform && interpolation != INTERPOLATION_DEFAULT && type < TYPE_INT) {
8478 _set_error(vformat(RTR("Interpolation modifier '%s' cannot be used with boolean types."), get_interpolation_name(interpolation)));
8479 return ERR_PARSE_ERROR;
8480 }
8481
8482 if (!is_uniform && type > TYPE_MAT4) {
8483 _set_error(RTR("Invalid data type for varying."));
8484 return ERR_PARSE_ERROR;
8485 }
8486
8487#ifdef DEBUG_ENABLED
8488 keyword_completion_context = CF_UNSPECIFIED;
8489#endif // DEBUG_ENABLED
8490 tk = _get_token();
8491
8492 if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
8493 _set_error(RTR("Expected an identifier or '['."));
8494 return ERR_PARSE_ERROR;
8495 }
8496
8497 if (tk.type == TK_BRACKET_OPEN) {
8498 Error error = _parse_array_size(nullptr, constants, true, nullptr, &array_size, nullptr);
8499 if (error != OK) {
8500 return error;
8501 }
8502 tk = _get_token();
8503 }
8504
8505 if (tk.type != TK_IDENTIFIER) {
8506 _set_error(RTR("Expected an identifier."));
8507 return ERR_PARSE_ERROR;
8508 }
8509
8510 prev_pos = _get_tkpos();
8511 name = tk.text;
8512
8513 if (_find_identifier(nullptr, false, constants, name)) {
8514 _set_redefinition_error(String(name));
8515 return ERR_PARSE_ERROR;
8516 }
8517
8518 if (has_builtin(p_functions, name)) {
8519 _set_redefinition_error(String(name));
8520 return ERR_PARSE_ERROR;
8521 }
8522
8523 if (is_uniform) {
8524 if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL && Engine::get_singleton()->is_editor_hint()) { // Type checking for global uniforms is not allowed outside the editor.
8525 //validate global uniform
8526 DataType gvtype = global_shader_uniform_get_type_func(name);
8527 if (gvtype == TYPE_MAX) {
8528 _set_error(vformat(RTR("Global uniform '%s' does not exist. Create it in Project Settings."), String(name)));
8529 return ERR_PARSE_ERROR;
8530 }
8531
8532 if (type != gvtype) {
8533 _set_error(vformat(RTR("Global uniform '%s' must be of type '%s'."), String(name), get_datatype_name(gvtype)));
8534 return ERR_PARSE_ERROR;
8535 }
8536 }
8537 ShaderNode::Uniform uniform;
8538
8539 uniform.type = type;
8540 uniform.scope = uniform_scope;
8541 uniform.precision = precision;
8542 uniform.array_size = array_size;
8543 uniform.group = current_uniform_group_name;
8544 uniform.subgroup = current_uniform_subgroup_name;
8545
8546 tk = _get_token();
8547 if (tk.type == TK_BRACKET_OPEN) {
8548 Error error = _parse_array_size(nullptr, constants, true, nullptr, &uniform.array_size, nullptr);
8549 if (error != OK) {
8550 return error;
8551 }
8552 tk = _get_token();
8553 }
8554
8555 if (is_sampler_type(type)) {
8556 if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
8557 _set_error(vformat(RTR("The '%s' qualifier is not supported for sampler types."), "SCOPE_INSTANCE"));
8558 return ERR_PARSE_ERROR;
8559 }
8560 uniform.texture_order = texture_uniforms++;
8561 uniform.texture_binding = texture_binding;
8562 if (uniform.array_size > 0) {
8563 texture_binding += uniform.array_size;
8564 } else {
8565 ++texture_binding;
8566 }
8567 uniform.order = -1;
8568 } else {
8569 if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) {
8570 _set_error(vformat(RTR("The '%s' qualifier is not supported for matrix types."), "SCOPE_INSTANCE"));
8571 return ERR_PARSE_ERROR;
8572 }
8573 uniform.texture_order = -1;
8574 if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
8575 uniform.order = uniforms++;
8576#ifdef DEBUG_ENABLED
8577 if (check_device_limit_warnings) {
8578 if (uniform.array_size > 0) {
8579 int size = get_datatype_size(uniform.type) * uniform.array_size;
8580 int m = (16 * uniform.array_size);
8581 if ((size % m) != 0U) {
8582 size += m - (size % m);
8583 }
8584 uniform_buffer_size += size;
8585 } else {
8586 uniform_buffer_size += get_datatype_size(uniform.type);
8587 }
8588
8589 if (uniform_buffer_exceeded_line == -1 && uniform_buffer_size > max_uniform_buffer_size) {
8590 uniform_buffer_exceeded_line = tk_line;
8591 }
8592 }
8593#endif // DEBUG_ENABLED
8594 }
8595 }
8596
8597 if (uniform.array_size > 0) {
8598 if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) {
8599 _set_error(vformat(RTR("The '%s' qualifier is not supported for uniform arrays."), "SCOPE_GLOBAL"));
8600 return ERR_PARSE_ERROR;
8601 }
8602 if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
8603 _set_error(vformat(RTR("The '%s' qualifier is not supported for uniform arrays."), "SCOPE_INSTANCE"));
8604 return ERR_PARSE_ERROR;
8605 }
8606 }
8607
8608 int custom_instance_index = -1;
8609
8610 if (tk.type == TK_COLON) {
8611 completion_type = COMPLETION_HINT;
8612 completion_base = type;
8613 completion_base_array = uniform.array_size > 0;
8614
8615 //hint
8616 do {
8617 tk = _get_token();
8618 completion_line = tk.line;
8619
8620 if (!is_token_hint(tk.type)) {
8621 _set_error(RTR("Expected valid type hint after ':'."));
8622 return ERR_PARSE_ERROR;
8623 }
8624
8625 if (uniform.array_size > 0) {
8626 static Vector<int> supported_hints = {
8627 TK_HINT_SOURCE_COLOR, TK_REPEAT_DISABLE, TK_REPEAT_ENABLE,
8628 TK_FILTER_LINEAR, TK_FILTER_LINEAR_MIPMAP, TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC,
8629 TK_FILTER_NEAREST, TK_FILTER_NEAREST_MIPMAP, TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC
8630 };
8631 if (!supported_hints.has(tk.type)) {
8632 _set_error(RTR("This hint is not supported for uniform arrays."));
8633 return ERR_PARSE_ERROR;
8634 }
8635 }
8636
8637 ShaderNode::Uniform::Hint new_hint = ShaderNode::Uniform::HINT_NONE;
8638 TextureFilter new_filter = FILTER_DEFAULT;
8639 TextureRepeat new_repeat = REPEAT_DEFAULT;
8640
8641 switch (tk.type) {
8642 case TK_HINT_SOURCE_COLOR: {
8643 if (type != TYPE_VEC3 && type != TYPE_VEC4 && !is_sampler_type(type)) {
8644 _set_error(vformat(RTR("Source color hint is for '%s', '%s' or sampler types only."), "vec3", "vec4"));
8645 return ERR_PARSE_ERROR;
8646 }
8647
8648 if (is_sampler_type(type)) {
8649 if (uniform.use_color) {
8650 _set_error(vformat(RTR("Duplicated hint: '%s'."), "source_color"));
8651 return ERR_PARSE_ERROR;
8652 }
8653 uniform.use_color = true;
8654 } else {
8655 new_hint = ShaderNode::Uniform::HINT_SOURCE_COLOR;
8656 }
8657 } break;
8658 case TK_HINT_DEFAULT_BLACK_TEXTURE: {
8659 new_hint = ShaderNode::Uniform::HINT_DEFAULT_BLACK;
8660 } break;
8661 case TK_HINT_DEFAULT_WHITE_TEXTURE: {
8662 new_hint = ShaderNode::Uniform::HINT_DEFAULT_WHITE;
8663 } break;
8664 case TK_HINT_DEFAULT_TRANSPARENT_TEXTURE: {
8665 new_hint = ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT;
8666 } break;
8667 case TK_HINT_NORMAL_TEXTURE: {
8668 new_hint = ShaderNode::Uniform::HINT_NORMAL;
8669 } break;
8670 case TK_HINT_ROUGHNESS_NORMAL_TEXTURE: {
8671 new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL;
8672 } break;
8673 case TK_HINT_ROUGHNESS_R: {
8674 new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_R;
8675 } break;
8676 case TK_HINT_ROUGHNESS_G: {
8677 new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_G;
8678 } break;
8679 case TK_HINT_ROUGHNESS_B: {
8680 new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_B;
8681 } break;
8682 case TK_HINT_ROUGHNESS_A: {
8683 new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_A;
8684 } break;
8685 case TK_HINT_ROUGHNESS_GRAY: {
8686 new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_GRAY;
8687 } break;
8688 case TK_HINT_ANISOTROPY_TEXTURE: {
8689 new_hint = ShaderNode::Uniform::HINT_ANISOTROPY;
8690 } break;
8691 case TK_HINT_RANGE: {
8692 if (type != TYPE_FLOAT && type != TYPE_INT) {
8693 _set_error(vformat(RTR("Range hint is for '%s' and '%s' only."), "float", "int"));
8694 return ERR_PARSE_ERROR;
8695 }
8696
8697 tk = _get_token();
8698 if (tk.type != TK_PARENTHESIS_OPEN) {
8699 _set_expected_after_error("(", "hint_range");
8700 return ERR_PARSE_ERROR;
8701 }
8702
8703 tk = _get_token();
8704
8705 float sign = 1.0;
8706
8707 if (tk.type == TK_OP_SUB) {
8708 sign = -1.0;
8709 tk = _get_token();
8710 }
8711
8712 if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
8713 _set_error(RTR("Expected an integer constant."));
8714 return ERR_PARSE_ERROR;
8715 }
8716
8717 uniform.hint_range[0] = tk.constant;
8718 uniform.hint_range[0] *= sign;
8719
8720 tk = _get_token();
8721
8722 if (tk.type != TK_COMMA) {
8723 _set_error(RTR("Expected ',' after integer constant."));
8724 return ERR_PARSE_ERROR;
8725 }
8726
8727 tk = _get_token();
8728
8729 sign = 1.0;
8730
8731 if (tk.type == TK_OP_SUB) {
8732 sign = -1.0;
8733 tk = _get_token();
8734 }
8735
8736 if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
8737 _set_error(RTR("Expected an integer constant after ','."));
8738 return ERR_PARSE_ERROR;
8739 }
8740
8741 uniform.hint_range[1] = tk.constant;
8742 uniform.hint_range[1] *= sign;
8743
8744 tk = _get_token();
8745
8746 if (tk.type == TK_COMMA) {
8747 tk = _get_token();
8748
8749 if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
8750 _set_error(RTR("Expected an integer constant after ','."));
8751 return ERR_PARSE_ERROR;
8752 }
8753
8754 uniform.hint_range[2] = tk.constant;
8755 tk = _get_token();
8756 } else {
8757 if (type == TYPE_INT) {
8758 uniform.hint_range[2] = 1;
8759 } else {
8760 uniform.hint_range[2] = 0.001;
8761 }
8762 }
8763
8764 if (tk.type != TK_PARENTHESIS_CLOSE) {
8765 _set_expected_error(")");
8766 return ERR_PARSE_ERROR;
8767 }
8768
8769 new_hint = ShaderNode::Uniform::HINT_RANGE;
8770 } break;
8771 case TK_HINT_INSTANCE_INDEX: {
8772 if (custom_instance_index != -1) {
8773 _set_error(vformat(RTR("Can only specify '%s' once."), "instance_index"));
8774 return ERR_PARSE_ERROR;
8775 }
8776
8777 tk = _get_token();
8778 if (tk.type != TK_PARENTHESIS_OPEN) {
8779 _set_expected_after_error("(", "instance_index");
8780 return ERR_PARSE_ERROR;
8781 }
8782
8783 tk = _get_token();
8784
8785 if (tk.type == TK_OP_SUB) {
8786 _set_error(RTR("The instance index can't be negative."));
8787 return ERR_PARSE_ERROR;
8788 }
8789
8790 if (!tk.is_integer_constant()) {
8791 _set_error(RTR("Expected an integer constant."));
8792 return ERR_PARSE_ERROR;
8793 }
8794
8795 custom_instance_index = tk.constant;
8796 current_uniform_instance_index_defined = true;
8797
8798 if (custom_instance_index >= MAX_INSTANCE_UNIFORM_INDICES) {
8799 _set_error(vformat(RTR("Allowed instance uniform indices must be within [0..%d] range."), MAX_INSTANCE_UNIFORM_INDICES - 1));
8800 return ERR_PARSE_ERROR;
8801 }
8802
8803 tk = _get_token();
8804
8805 if (tk.type != TK_PARENTHESIS_CLOSE) {
8806 _set_expected_error(")");
8807 return ERR_PARSE_ERROR;
8808 }
8809 } break;
8810 case TK_HINT_SCREEN_TEXTURE: {
8811 new_hint = ShaderNode::Uniform::HINT_SCREEN_TEXTURE;
8812 --texture_uniforms;
8813 --texture_binding;
8814 } break;
8815 case TK_HINT_NORMAL_ROUGHNESS_TEXTURE: {
8816 new_hint = ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE;
8817 --texture_uniforms;
8818 --texture_binding;
8819 if (OS::get_singleton()->get_current_rendering_method() != "forward_plus") {
8820 _set_error(RTR("'hint_normal_roughness_texture' is only available when using the Forward+ backend."));
8821 return ERR_PARSE_ERROR;
8822 }
8823 if (String(shader_type_identifier) != "spatial") {
8824 _set_error(vformat(RTR("'hint_normal_roughness_texture' is not supported in '%s' shaders."), shader_type_identifier));
8825 return ERR_PARSE_ERROR;
8826 }
8827 } break;
8828 case TK_HINT_DEPTH_TEXTURE: {
8829 new_hint = ShaderNode::Uniform::HINT_DEPTH_TEXTURE;
8830 --texture_uniforms;
8831 --texture_binding;
8832 if (String(shader_type_identifier) != "spatial") {
8833 _set_error(vformat(RTR("'hint_depth_texture' is not supported in '%s' shaders."), shader_type_identifier));
8834 return ERR_PARSE_ERROR;
8835 }
8836 } break;
8837 case TK_FILTER_NEAREST: {
8838 new_filter = FILTER_NEAREST;
8839 } break;
8840 case TK_FILTER_LINEAR: {
8841 new_filter = FILTER_LINEAR;
8842 } break;
8843 case TK_FILTER_NEAREST_MIPMAP: {
8844 new_filter = FILTER_NEAREST_MIPMAP;
8845 } break;
8846 case TK_FILTER_LINEAR_MIPMAP: {
8847 new_filter = FILTER_LINEAR_MIPMAP;
8848 } break;
8849 case TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC: {
8850 new_filter = FILTER_NEAREST_MIPMAP_ANISOTROPIC;
8851 } break;
8852 case TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC: {
8853 new_filter = FILTER_LINEAR_MIPMAP_ANISOTROPIC;
8854 } break;
8855 case TK_REPEAT_DISABLE: {
8856 new_repeat = REPEAT_DISABLE;
8857 } break;
8858 case TK_REPEAT_ENABLE: {
8859 new_repeat = REPEAT_ENABLE;
8860 } break;
8861
8862 default:
8863 break;
8864 }
8865 if (((new_filter != FILTER_DEFAULT || new_repeat != REPEAT_DEFAULT) || (new_hint != ShaderNode::Uniform::HINT_NONE && new_hint != ShaderNode::Uniform::HINT_SOURCE_COLOR && new_hint != ShaderNode::Uniform::HINT_RANGE)) && !is_sampler_type(type)) {
8866 _set_error(RTR("This hint is only for sampler types."));
8867 return ERR_PARSE_ERROR;
8868 }
8869
8870 if (new_hint != ShaderNode::Uniform::HINT_NONE) {
8871 if (uniform.hint != ShaderNode::Uniform::HINT_NONE) {
8872 if (uniform.hint == new_hint) {
8873 _set_error(vformat(RTR("Duplicated hint: '%s'."), get_uniform_hint_name(new_hint)));
8874 } else {
8875 _set_error(vformat(RTR("Redefinition of hint: '%s'. The hint has already been set to '%s'."), get_uniform_hint_name(new_hint), get_uniform_hint_name(uniform.hint)));
8876 }
8877 return ERR_PARSE_ERROR;
8878 } else {
8879 uniform.hint = new_hint;
8880 current_uniform_hint = new_hint;
8881 }
8882 }
8883
8884 if (new_filter != FILTER_DEFAULT) {
8885 if (uniform.filter != FILTER_DEFAULT) {
8886 if (uniform.filter == new_filter) {
8887 _set_error(vformat(RTR("Duplicated filter mode: '%s'."), get_texture_filter_name(new_filter)));
8888 } else {
8889 _set_error(vformat(RTR("Redefinition of filter mode: '%s'. The filter mode has already been set to '%s'."), get_texture_filter_name(new_filter), get_texture_filter_name(uniform.filter)));
8890 }
8891 return ERR_PARSE_ERROR;
8892 } else {
8893 uniform.filter = new_filter;
8894 current_uniform_filter = new_filter;
8895 }
8896 }
8897
8898 if (new_repeat != REPEAT_DEFAULT) {
8899 if (uniform.repeat != REPEAT_DEFAULT) {
8900 if (uniform.repeat == new_repeat) {
8901 _set_error(vformat(RTR("Duplicated repeat mode: '%s'."), get_texture_repeat_name(new_repeat)));
8902 } else {
8903 _set_error(vformat(RTR("Redefinition of repeat mode: '%s'. The repeat mode has already been set to '%s'."), get_texture_repeat_name(new_repeat), get_texture_repeat_name(uniform.repeat)));
8904 }
8905 return ERR_PARSE_ERROR;
8906 } else {
8907 uniform.repeat = new_repeat;
8908 current_uniform_repeat = new_repeat;
8909 }
8910 }
8911
8912 tk = _get_token();
8913
8914 } while (tk.type == TK_COMMA);
8915 }
8916
8917 if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
8918 if (custom_instance_index >= 0) {
8919 uniform.instance_index = custom_instance_index;
8920 } else {
8921 uniform.instance_index = instance_index++;
8922 if (instance_index > MAX_INSTANCE_UNIFORM_INDICES) {
8923 _set_error(vformat(RTR("Too many '%s' uniforms in shader, maximum supported is %d."), "instance", MAX_INSTANCE_UNIFORM_INDICES));
8924 return ERR_PARSE_ERROR;
8925 }
8926 }
8927 }
8928
8929 //reset scope for next uniform
8930
8931 if (tk.type == TK_OP_ASSIGN) {
8932 if (uniform.array_size > 0) {
8933 _set_error(RTR("Setting default values to uniform arrays is not supported."));
8934 return ERR_PARSE_ERROR;
8935 }
8936
8937 Node *expr = _parse_and_reduce_expression(nullptr, constants);
8938 if (!expr) {
8939 return ERR_PARSE_ERROR;
8940 }
8941 if (expr->type != Node::NODE_TYPE_CONSTANT) {
8942 _set_error(RTR("Expected constant expression after '='."));
8943 return ERR_PARSE_ERROR;
8944 }
8945
8946 ConstantNode *cn = static_cast<ConstantNode *>(expr);
8947
8948 uniform.default_value.resize(cn->values.size());
8949
8950 if (!convert_constant(cn, uniform.type, uniform.default_value.ptrw())) {
8951 _set_error(vformat(RTR("Can't convert constant to '%s'."), get_datatype_name(uniform.type)));
8952 return ERR_PARSE_ERROR;
8953 }
8954 tk = _get_token();
8955 }
8956
8957 shader->uniforms[name] = uniform;
8958#ifdef DEBUG_ENABLED
8959 if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_UNIFORM_FLAG)) {
8960 used_uniforms.insert(name, Usage(tk_line));
8961 }
8962#endif // DEBUG_ENABLED
8963
8964 //reset scope for next uniform
8965 uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
8966
8967 if (tk.type != TK_SEMICOLON) {
8968 _set_expected_error(";");
8969 return ERR_PARSE_ERROR;
8970 }
8971
8972#ifdef DEBUG_ENABLED
8973 keyword_completion_context = CF_GLOBAL_SPACE;
8974#endif // DEBUG_ENABLED
8975 completion_type = COMPLETION_NONE;
8976
8977 current_uniform_hint = ShaderNode::Uniform::HINT_NONE;
8978 current_uniform_filter = FILTER_DEFAULT;
8979 current_uniform_repeat = REPEAT_DEFAULT;
8980 current_uniform_instance_index_defined = false;
8981 } else { // varying
8982 ShaderNode::Varying varying;
8983 varying.type = type;
8984 varying.precision = precision;
8985 varying.interpolation = interpolation;
8986 varying.tkpos = prev_pos;
8987 varying.array_size = array_size;
8988
8989 tk = _get_token();
8990 if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) {
8991 if (array_size == 0) {
8992 _set_expected_error(";", "[");
8993 } else {
8994 _set_expected_error(";");
8995 }
8996 return ERR_PARSE_ERROR;
8997 }
8998
8999 if (tk.type == TK_BRACKET_OPEN) {
9000 Error error = _parse_array_size(nullptr, constants, true, nullptr, &varying.array_size, nullptr);
9001 if (error != OK) {
9002 return error;
9003 }
9004 tk = _get_token();
9005 }
9006
9007 shader->varyings[name] = varying;
9008#ifdef DEBUG_ENABLED
9009 if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_VARYING_FLAG)) {
9010 used_varyings.insert(name, Usage(tk_line));
9011 }
9012#endif // DEBUG_ENABLED
9013 }
9014
9015 } break;
9016 case TK_UNIFORM_GROUP: {
9017 tk = _get_token();
9018 if (tk.type == TK_IDENTIFIER) {
9019 current_uniform_group_name = tk.text;
9020 tk = _get_token();
9021 if (tk.type == TK_PERIOD) {
9022 tk = _get_token();
9023 if (tk.type == TK_IDENTIFIER) {
9024 current_uniform_subgroup_name = tk.text;
9025 tk = _get_token();
9026 if (tk.type != TK_SEMICOLON) {
9027 _set_expected_error(";");
9028 return ERR_PARSE_ERROR;
9029 }
9030 } else {
9031 _set_error(RTR("Expected an uniform subgroup identifier."));
9032 return ERR_PARSE_ERROR;
9033 }
9034 } else if (tk.type != TK_SEMICOLON) {
9035 _set_expected_error(";", ".");
9036 return ERR_PARSE_ERROR;
9037 }
9038 } else {
9039 if (tk.type != TK_SEMICOLON) {
9040 if (current_uniform_group_name.is_empty()) {
9041 _set_error(RTR("Expected an uniform group identifier."));
9042 } else {
9043 _set_error(RTR("Expected an uniform group identifier or `;`."));
9044 }
9045 return ERR_PARSE_ERROR;
9046 } else if (current_uniform_group_name.is_empty()) {
9047 _set_error(RTR("Group needs to be opened before."));
9048 return ERR_PARSE_ERROR;
9049 } else {
9050 current_uniform_group_name = "";
9051 current_uniform_subgroup_name = "";
9052 }
9053 }
9054 } break;
9055 case TK_SHADER_TYPE: {
9056 _set_error(RTR("Shader type is already defined."));
9057 return ERR_PARSE_ERROR;
9058 } break;
9059 default: {
9060 //function or constant variable
9061
9062 bool is_constant = false;
9063 bool is_struct = false;
9064 StringName struct_name;
9065 DataPrecision precision = PRECISION_DEFAULT;
9066 DataType type;
9067 StringName name;
9068 int array_size = 0;
9069
9070 if (tk.type == TK_CONST) {
9071 is_constant = true;
9072 tk = _get_token();
9073 }
9074
9075 if (is_token_precision(tk.type)) {
9076 precision = get_token_precision(tk.type);
9077 tk = _get_token();
9078 }
9079
9080 if (shader->structs.has(tk.text)) {
9081 is_struct = true;
9082 struct_name = tk.text;
9083 } else {
9084#ifdef DEBUG_ENABLED
9085 if (_lookup_next(next)) {
9086 if (next.type == TK_UNIFORM) {
9087 keyword_completion_context = CF_UNIFORM_QUALIFIER;
9088 }
9089 }
9090#endif // DEBUG_ENABLED
9091 if (!is_token_datatype(tk.type)) {
9092 _set_error(RTR("Expected constant, function, uniform or varying."));
9093 return ERR_PARSE_ERROR;
9094 }
9095
9096 if (!is_token_variable_datatype(tk.type)) {
9097 if (is_constant) {
9098 _set_error(RTR("Invalid constant type (samplers are not allowed)."));
9099 } else {
9100 _set_error(RTR("Invalid function type (samplers are not allowed)."));
9101 }
9102 return ERR_PARSE_ERROR;
9103 }
9104 }
9105
9106 if (is_struct) {
9107 type = TYPE_STRUCT;
9108 } else {
9109 type = get_token_datatype(tk.type);
9110 }
9111
9112 if (precision != PRECISION_DEFAULT && _validate_precision(type, precision) != OK) {
9113 return ERR_PARSE_ERROR;
9114 }
9115
9116 prev_pos = _get_tkpos();
9117 tk = _get_token();
9118
9119#ifdef DEBUG_ENABLED
9120 keyword_completion_context = CF_UNSPECIFIED;
9121#endif // DEBUG_ENABLED
9122
9123 bool unknown_size = false;
9124 bool fixed_array_size = false;
9125
9126 if (tk.type == TK_BRACKET_OPEN) {
9127 Error error = _parse_array_size(nullptr, constants, !is_constant, nullptr, &array_size, &unknown_size);
9128 if (error != OK) {
9129 return error;
9130 }
9131 fixed_array_size = true;
9132 prev_pos = _get_tkpos();
9133 }
9134
9135 _set_tkpos(prev_pos);
9136
9137 _get_completable_identifier(nullptr, COMPLETION_MAIN_FUNCTION, name);
9138
9139 if (name == StringName()) {
9140 if (is_constant) {
9141 _set_error(RTR("Expected an identifier or '[' after type."));
9142 } else {
9143 _set_error(RTR("Expected a function name after type."));
9144 }
9145 return ERR_PARSE_ERROR;
9146 }
9147
9148 if (shader->structs.has(name) || _find_identifier(nullptr, false, constants, name) || has_builtin(p_functions, name)) {
9149 _set_redefinition_error(String(name));
9150 return ERR_PARSE_ERROR;
9151 }
9152
9153 tk = _get_token();
9154 if (tk.type != TK_PARENTHESIS_OPEN) {
9155 if (type == TYPE_VOID) {
9156 _set_error(RTR("Expected '(' after function identifier."));
9157 return ERR_PARSE_ERROR;
9158 }
9159
9160 //variable
9161 while (true) {
9162 ShaderNode::Constant constant;
9163 constant.name = name;
9164 constant.type = is_struct ? TYPE_STRUCT : type;
9165 constant.type_str = struct_name;
9166 constant.precision = precision;
9167 constant.initializer = nullptr;
9168 constant.array_size = array_size;
9169 is_const_decl = true;
9170
9171 if (tk.type == TK_BRACKET_OPEN) {
9172 Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size);
9173 if (error != OK) {
9174 return error;
9175 }
9176 tk = _get_token();
9177 }
9178
9179 if (tk.type == TK_OP_ASSIGN) {
9180 if (!is_constant) {
9181 _set_error(vformat(RTR("Global non-constant variables are not supported. Expected '%s' keyword before constant definition."), "const"));
9182 return ERR_PARSE_ERROR;
9183 }
9184
9185 if (constant.array_size > 0 || unknown_size) {
9186 bool full_def = false;
9187
9188 VariableDeclarationNode::Declaration decl;
9189 decl.name = name;
9190 decl.size = constant.array_size;
9191
9192 tk = _get_token();
9193
9194 if (tk.type != TK_CURLY_BRACKET_OPEN) {
9195 if (unknown_size) {
9196 _set_expected_error("{");
9197 return ERR_PARSE_ERROR;
9198 }
9199
9200 full_def = true;
9201
9202 DataPrecision precision2 = PRECISION_DEFAULT;
9203 if (is_token_precision(tk.type)) {
9204 precision2 = get_token_precision(tk.type);
9205 tk = _get_token();
9206 if (!is_token_nonvoid_datatype(tk.type)) {
9207 _set_error(RTR("Expected data type after precision modifier."));
9208 return ERR_PARSE_ERROR;
9209 }
9210 }
9211
9212 StringName struct_name2;
9213 DataType type2;
9214
9215 if (shader->structs.has(tk.text)) {
9216 type2 = TYPE_STRUCT;
9217 struct_name2 = tk.text;
9218 } else {
9219 if (!is_token_variable_datatype(tk.type)) {
9220 _set_error(RTR("Invalid data type for the array."));
9221 return ERR_PARSE_ERROR;
9222 }
9223 type2 = get_token_datatype(tk.type);
9224 }
9225
9226 int array_size2 = 0;
9227 tk = _get_token();
9228
9229 if (tk.type == TK_BRACKET_OPEN) {
9230 bool is_unknown_size = false;
9231 Error error = _parse_array_size(nullptr, constants, false, nullptr, &array_size2, &is_unknown_size);
9232 if (error != OK) {
9233 return error;
9234 }
9235 if (is_unknown_size) {
9236 array_size2 = constant.array_size;
9237 }
9238 tk = _get_token();
9239 } else {
9240 _set_expected_error("[");
9241 return ERR_PARSE_ERROR;
9242 }
9243
9244 if (constant.precision != precision2 || constant.type != type2 || struct_name != struct_name2 || constant.array_size != array_size2) {
9245 String from;
9246 if (type2 == TYPE_STRUCT) {
9247 from += struct_name2;
9248 } else {
9249 if (precision2 != PRECISION_DEFAULT) {
9250 from += get_precision_name(precision2);
9251 from += " ";
9252 }
9253 from += get_datatype_name(type2);
9254 }
9255 from += "[";
9256 from += itos(array_size2);
9257 from += "]'";
9258
9259 String to;
9260 if (type == TYPE_STRUCT) {
9261 to += struct_name;
9262 } else {
9263 if (precision != PRECISION_DEFAULT) {
9264 to += get_precision_name(precision);
9265 to += " ";
9266 }
9267 to += get_datatype_name(type);
9268 }
9269 to += "[";
9270 to += itos(constant.array_size);
9271 to += "]'";
9272
9273 _set_error(vformat(RTR("Cannot convert from '%s' to '%s'."), from, to));
9274 return ERR_PARSE_ERROR;
9275 }
9276 }
9277
9278 bool curly = tk.type == TK_CURLY_BRACKET_OPEN;
9279
9280 if (unknown_size) {
9281 if (!curly) {
9282 _set_expected_error("{");
9283 return ERR_PARSE_ERROR;
9284 }
9285 } else {
9286 if (full_def) {
9287 if (curly) {
9288 _set_expected_error("(");
9289 return ERR_PARSE_ERROR;
9290 }
9291 }
9292 }
9293
9294 if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
9295 while (true) {
9296 Node *n = _parse_and_reduce_expression(nullptr, constants);
9297 if (!n) {
9298 return ERR_PARSE_ERROR;
9299 }
9300
9301 if (n->type == Node::NODE_TYPE_OPERATOR && static_cast<OperatorNode *>(n)->op == OP_CALL) {
9302 _set_error(RTR("Expected constant expression."));
9303 return ERR_PARSE_ERROR;
9304 }
9305
9306 if (!_compare_datatypes(constant.type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) {
9307 return ERR_PARSE_ERROR;
9308 }
9309
9310 tk = _get_token();
9311 if (tk.type == TK_COMMA) {
9312 decl.initializer.push_back(n);
9313 continue;
9314 } else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) {
9315 decl.initializer.push_back(n);
9316 break;
9317 } else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) {
9318 decl.initializer.push_back(n);
9319 break;
9320 } else {
9321 if (curly) {
9322 _set_expected_error("}", ",");
9323 } else {
9324 _set_expected_error(")", ",");
9325 }
9326 return ERR_PARSE_ERROR;
9327 }
9328 }
9329 if (unknown_size) {
9330 decl.size = decl.initializer.size();
9331 constant.array_size = decl.initializer.size();
9332 } else if (decl.initializer.size() != constant.array_size) {
9333 _set_error(RTR("Array size mismatch."));
9334 return ERR_PARSE_ERROR;
9335 }
9336 }
9337
9338 array_size = constant.array_size;
9339
9340 ConstantNode *expr = memnew(ConstantNode);
9341
9342 expr->datatype = constant.type;
9343
9344 expr->struct_name = constant.type_str;
9345
9346 expr->array_size = constant.array_size;
9347
9348 expr->array_declarations.push_back(decl);
9349
9350 constant.initializer = static_cast<ConstantNode *>(expr);
9351 } else {
9352#ifdef DEBUG_ENABLED
9353 if (constant.type == DataType::TYPE_BOOL) {
9354 keyword_completion_context = CF_BOOLEAN;
9355 }
9356#endif // DEBUG_ENABLED
9357
9358 //variable created with assignment! must parse an expression
9359 Node *expr = _parse_and_reduce_expression(nullptr, constants);
9360 if (!expr) {
9361 return ERR_PARSE_ERROR;
9362 }
9363#ifdef DEBUG_ENABLED
9364 if (constant.type == DataType::TYPE_BOOL) {
9365 keyword_completion_context = CF_GLOBAL_SPACE;
9366 }
9367#endif // DEBUG_ENABLED
9368 if (expr->type == Node::NODE_TYPE_OPERATOR && static_cast<OperatorNode *>(expr)->op == OP_CALL) {
9369 OperatorNode *op = static_cast<OperatorNode *>(expr);
9370 for (int i = 1; i < op->arguments.size(); i++) {
9371 if (!_check_node_constness(op->arguments[i])) {
9372 _set_error(vformat(RTR("Expected constant expression for argument %d of function call after '='."), i - 1));
9373 return ERR_PARSE_ERROR;
9374 }
9375 }
9376 }
9377
9378 constant.initializer = static_cast<ConstantNode *>(expr);
9379
9380 if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), expr->get_array_size())) {
9381 return ERR_PARSE_ERROR;
9382 }
9383 }
9384 tk = _get_token();
9385 } else {
9386 if (constant.array_size > 0 || unknown_size) {
9387 _set_error(RTR("Expected array initialization."));
9388 return ERR_PARSE_ERROR;
9389 } else {
9390 _set_error(RTR("Expected initialization of constant."));
9391 return ERR_PARSE_ERROR;
9392 }
9393 }
9394
9395 shader->constants[name] = constant;
9396 shader->vconstants.push_back(constant);
9397#ifdef DEBUG_ENABLED
9398 if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_CONSTANT_FLAG)) {
9399 used_constants.insert(name, Usage(tk_line));
9400 }
9401#endif // DEBUG_ENABLED
9402
9403 if (tk.type == TK_COMMA) {
9404 tk = _get_token();
9405 if (tk.type != TK_IDENTIFIER) {
9406 _set_error(RTR("Expected an identifier after type."));
9407 return ERR_PARSE_ERROR;
9408 }
9409
9410 name = tk.text;
9411 if (_find_identifier(nullptr, false, constants, name)) {
9412 _set_redefinition_error(String(name));
9413 return ERR_PARSE_ERROR;
9414 }
9415
9416 if (has_builtin(p_functions, name)) {
9417 _set_redefinition_error(String(name));
9418 return ERR_PARSE_ERROR;
9419 }
9420
9421 tk = _get_token();
9422
9423 if (!fixed_array_size) {
9424 array_size = 0;
9425 }
9426 unknown_size = false;
9427
9428 } else if (tk.type == TK_SEMICOLON) {
9429 is_const_decl = false;
9430 break;
9431 } else {
9432 _set_expected_error(",", ";");
9433 return ERR_PARSE_ERROR;
9434 }
9435 }
9436
9437 break;
9438 }
9439
9440 FunctionInfo builtins;
9441 if (p_functions.has(name)) {
9442 builtins = p_functions[name];
9443 }
9444
9445 if (p_functions.has("global")) { // Adds global variables: 'TIME'
9446 for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["global"].built_ins) {
9447 builtins.built_ins.insert(E.key, E.value);
9448 }
9449 }
9450
9451 if (p_functions.has("constants")) { // Adds global constants: 'PI', 'TAU', 'E'
9452 for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["constants"].built_ins) {
9453 builtins.built_ins.insert(E.key, E.value);
9454 }
9455 }
9456
9457 for (int i = 0; i < shader->functions.size(); i++) {
9458 if (!shader->functions[i].callable && shader->functions[i].name == name) {
9459 _set_redefinition_error(String(name));
9460 return ERR_PARSE_ERROR;
9461 }
9462 }
9463
9464 ShaderNode::Function function;
9465
9466 function.callable = !p_functions.has(name);
9467 function.name = name;
9468
9469 FunctionNode *func_node = alloc_node<FunctionNode>();
9470
9471 function.function = func_node;
9472
9473 shader->functions.push_back(function);
9474
9475 func_node->name = name;
9476 func_node->return_type = type;
9477 func_node->return_struct_name = struct_name;
9478 func_node->return_precision = precision;
9479 func_node->return_array_size = array_size;
9480
9481 if (p_functions.has(name)) {
9482 func_node->can_discard = p_functions[name].can_discard;
9483 } else {
9484#ifdef DEBUG_ENABLED
9485 if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_FUNCTION_FLAG)) {
9486 used_functions.insert(name, Usage(tk_line));
9487 }
9488#endif // DEBUG_ENABLED
9489 }
9490
9491 func_node->body = alloc_node<BlockNode>();
9492 func_node->body->parent_function = func_node;
9493
9494 tk = _get_token();
9495
9496 while (true) {
9497 if (tk.type == TK_PARENTHESIS_CLOSE) {
9498 break;
9499 }
9500#ifdef DEBUG_ENABLED
9501 keyword_completion_context = CF_CONST_KEYWORD | CF_FUNC_DECL_PARAM_SPEC | CF_PRECISION_MODIFIER | CF_FUNC_DECL_PARAM_TYPE; // eg. const in mediump float
9502
9503 if (_lookup_next(next)) {
9504 if (next.type == TK_CONST) {
9505 keyword_completion_context = CF_UNSPECIFIED;
9506 } else if (is_token_arg_qual(next.type)) {
9507 keyword_completion_context = CF_CONST_KEYWORD;
9508 } else if (is_token_precision(next.type)) {
9509 keyword_completion_context = (CF_CONST_KEYWORD | CF_FUNC_DECL_PARAM_SPEC | CF_FUNC_DECL_PARAM_TYPE);
9510 } else if (is_token_datatype(next.type)) {
9511 keyword_completion_context = (CF_CONST_KEYWORD | CF_FUNC_DECL_PARAM_SPEC | CF_PRECISION_MODIFIER);
9512 }
9513 }
9514#endif // DEBUG_ENABLED
9515
9516 bool param_is_const = false;
9517 if (tk.type == TK_CONST) {
9518 param_is_const = true;
9519 tk = _get_token();
9520#ifdef DEBUG_ENABLED
9521 if (keyword_completion_context & CF_CONST_KEYWORD) {
9522 keyword_completion_context ^= CF_CONST_KEYWORD;
9523 }
9524
9525 if (_lookup_next(next)) {
9526 if (is_token_arg_qual(next.type)) {
9527 keyword_completion_context = CF_UNSPECIFIED;
9528 } else if (is_token_precision(next.type)) {
9529 keyword_completion_context = (CF_FUNC_DECL_PARAM_SPEC | CF_FUNC_DECL_PARAM_TYPE);
9530 } else if (is_token_datatype(next.type)) {
9531 keyword_completion_context = (CF_FUNC_DECL_PARAM_SPEC | CF_PRECISION_MODIFIER);
9532 }
9533 }
9534#endif // DEBUG_ENABLED
9535 }
9536
9537 ArgumentQualifier param_qualifier = ARGUMENT_QUALIFIER_IN;
9538 if (is_token_arg_qual(tk.type)) {
9539 bool error = false;
9540 switch (tk.type) {
9541 case TK_ARG_IN: {
9542 param_qualifier = ARGUMENT_QUALIFIER_IN;
9543 } break;
9544 case TK_ARG_OUT: {
9545 if (param_is_const) {
9546 _set_error(vformat(RTR("The '%s' qualifier cannot be used within a function parameter declared with '%s'."), "out", "const"));
9547 error = true;
9548 }
9549 param_qualifier = ARGUMENT_QUALIFIER_OUT;
9550 } break;
9551 case TK_ARG_INOUT: {
9552 if (param_is_const) {
9553 _set_error(vformat(RTR("The '%s' qualifier cannot be used within a function parameter declared with '%s'."), "inout", "const"));
9554 error = true;
9555 }
9556 param_qualifier = ARGUMENT_QUALIFIER_INOUT;
9557 } break;
9558 default:
9559 error = true;
9560 break;
9561 }
9562 tk = _get_token();
9563#ifdef DEBUG_ENABLED
9564 if (keyword_completion_context & CF_CONST_KEYWORD) {
9565 keyword_completion_context ^= CF_CONST_KEYWORD;
9566 }
9567 if (keyword_completion_context & CF_FUNC_DECL_PARAM_SPEC) {
9568 keyword_completion_context ^= CF_FUNC_DECL_PARAM_SPEC;
9569 }
9570
9571 if (_lookup_next(next)) {
9572 if (is_token_precision(next.type)) {
9573 keyword_completion_context = CF_FUNC_DECL_PARAM_TYPE;
9574 } else if (is_token_datatype(next.type)) {
9575 keyword_completion_context = CF_PRECISION_MODIFIER;
9576 }
9577 }
9578#endif // DEBUG_ENABLED
9579 if (error) {
9580 return ERR_PARSE_ERROR;
9581 }
9582 }
9583
9584 DataType param_type;
9585 StringName param_name;
9586 StringName param_struct_name;
9587 DataPrecision param_precision = PRECISION_DEFAULT;
9588 int arg_array_size = 0;
9589
9590 if (is_token_precision(tk.type)) {
9591 param_precision = get_token_precision(tk.type);
9592 tk = _get_token();
9593#ifdef DEBUG_ENABLED
9594 if (keyword_completion_context & CF_CONST_KEYWORD) {
9595 keyword_completion_context ^= CF_CONST_KEYWORD;
9596 }
9597 if (keyword_completion_context & CF_FUNC_DECL_PARAM_SPEC) {
9598 keyword_completion_context ^= CF_FUNC_DECL_PARAM_SPEC;
9599 }
9600 if (keyword_completion_context & CF_PRECISION_MODIFIER) {
9601 keyword_completion_context ^= CF_PRECISION_MODIFIER;
9602 }
9603
9604 if (_lookup_next(next)) {
9605 if (is_token_datatype(next.type)) {
9606 keyword_completion_context = CF_UNSPECIFIED;
9607 }
9608 }
9609#endif // DEBUG_ENABLED
9610 }
9611
9612 is_struct = false;
9613
9614 if (shader->structs.has(tk.text)) {
9615 is_struct = true;
9616 param_struct_name = tk.text;
9617#ifdef DEBUG_ENABLED
9618 if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(param_struct_name)) {
9619 used_structs[param_struct_name].used = true;
9620 }
9621#endif // DEBUG_ENABLED
9622 }
9623
9624 if (!is_struct && !is_token_datatype(tk.type)) {
9625 _set_error(RTR("Expected a valid data type for argument."));
9626 return ERR_PARSE_ERROR;
9627 }
9628
9629 if (param_qualifier == ARGUMENT_QUALIFIER_OUT || param_qualifier == ARGUMENT_QUALIFIER_INOUT) {
9630 if (is_sampler_type(get_token_datatype(tk.type))) {
9631 _set_error(RTR("Opaque types cannot be output parameters."));
9632 return ERR_PARSE_ERROR;
9633 }
9634 }
9635
9636 if (is_struct) {
9637 param_type = TYPE_STRUCT;
9638 } else {
9639 param_type = get_token_datatype(tk.type);
9640 if (param_type == TYPE_VOID) {
9641 _set_error(RTR("Void type not allowed as argument."));
9642 return ERR_PARSE_ERROR;
9643 }
9644 }
9645
9646 if (param_precision != PRECISION_DEFAULT && _validate_precision(param_type, param_precision) != OK) {
9647 return ERR_PARSE_ERROR;
9648 }
9649#ifdef DEBUG_ENABLED
9650 keyword_completion_context = CF_UNSPECIFIED;
9651#endif // DEBUG_ENABLED
9652 tk = _get_token();
9653
9654 if (tk.type == TK_BRACKET_OPEN) {
9655 Error error = _parse_array_size(nullptr, constants, true, nullptr, &arg_array_size, nullptr);
9656 if (error != OK) {
9657 return error;
9658 }
9659 tk = _get_token();
9660 }
9661 if (tk.type != TK_IDENTIFIER) {
9662 _set_error(RTR("Expected an identifier for argument name."));
9663 return ERR_PARSE_ERROR;
9664 }
9665
9666 param_name = tk.text;
9667
9668 ShaderLanguage::IdentifierType itype;
9669 if (_find_identifier(func_node->body, false, builtins, param_name, (ShaderLanguage::DataType *)nullptr, &itype)) {
9670 if (itype != IDENTIFIER_FUNCTION) {
9671 _set_redefinition_error(String(param_name));
9672 return ERR_PARSE_ERROR;
9673 }
9674 }
9675
9676 if (has_builtin(p_functions, param_name)) {
9677 _set_redefinition_error(String(param_name));
9678 return ERR_PARSE_ERROR;
9679 }
9680
9681 FunctionNode::Argument arg;
9682 arg.type = param_type;
9683 arg.name = param_name;
9684 arg.type_str = param_struct_name;
9685 arg.precision = param_precision;
9686 arg.qualifier = param_qualifier;
9687 arg.tex_argument_check = false;
9688 arg.tex_builtin_check = false;
9689 arg.tex_argument_filter = FILTER_DEFAULT;
9690 arg.tex_argument_repeat = REPEAT_DEFAULT;
9691 arg.is_const = param_is_const;
9692
9693 tk = _get_token();
9694 if (tk.type == TK_BRACKET_OPEN) {
9695 Error error = _parse_array_size(nullptr, constants, true, nullptr, &arg_array_size, nullptr);
9696 if (error != OK) {
9697 return error;
9698 }
9699 tk = _get_token();
9700 }
9701
9702 arg.array_size = arg_array_size;
9703 func_node->arguments.push_back(arg);
9704
9705 if (tk.type == TK_COMMA) {
9706 tk = _get_token();
9707 //do none and go on
9708 } else if (tk.type != TK_PARENTHESIS_CLOSE) {
9709 _set_expected_error(",", ")");
9710 return ERR_PARSE_ERROR;
9711 }
9712 }
9713
9714 if (p_functions.has(name)) {
9715 //if one of the core functions, make sure they are of the correct form
9716 if (func_node->arguments.size() > 0) {
9717 _set_error(vformat(RTR("Function '%s' expects no arguments."), String(name)));
9718 return ERR_PARSE_ERROR;
9719 }
9720 if (func_node->return_type != TYPE_VOID) {
9721 _set_error(vformat(RTR("Function '%s' must be of '%s' return type."), String(name), "void"));
9722 return ERR_PARSE_ERROR;
9723 }
9724 }
9725
9726 //all good let's parse inside the function!
9727 tk = _get_token();
9728 if (tk.type != TK_CURLY_BRACKET_OPEN) {
9729 _set_error(RTR("Expected a '{' to begin function."));
9730 return ERR_PARSE_ERROR;
9731 }
9732
9733 current_function = name;
9734
9735#ifdef DEBUG_ENABLED
9736 keyword_completion_context = CF_BLOCK;
9737#endif // DEBUG_ENABLED
9738 Error err = _parse_block(func_node->body, builtins);
9739 if (err) {
9740 return err;
9741 }
9742#ifdef DEBUG_ENABLED
9743 keyword_completion_context = CF_GLOBAL_SPACE;
9744#endif // DEBUG_ENABLED
9745 if (func_node->return_type != DataType::TYPE_VOID) {
9746 BlockNode *block = func_node->body;
9747 if (_find_last_flow_op_in_block(block, FlowOperation::FLOW_OP_RETURN) != OK) {
9748 _set_error(vformat(RTR("Expected at least one '%s' statement in a non-void function."), "return"));
9749 return ERR_PARSE_ERROR;
9750 }
9751 }
9752 current_function = StringName();
9753 }
9754 }
9755
9756 tk = _get_token();
9757 }
9758
9759#ifdef DEBUG_ENABLED
9760 if (check_device_limit_warnings && uniform_buffer_exceeded_line != -1) {
9761 _add_warning(ShaderWarning::DEVICE_LIMIT_EXCEEDED, uniform_buffer_exceeded_line, RTR("uniform buffer"), { uniform_buffer_size, max_uniform_buffer_size });
9762 }
9763#endif // DEBUG_ENABLED
9764 return OK;
9765}
9766
9767bool ShaderLanguage::has_builtin(const HashMap<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name) {
9768 for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : p_functions) {
9769 if (E.value.built_ins.has(p_name)) {
9770 return true;
9771 }
9772 }
9773
9774 return false;
9775}
9776
9777Error ShaderLanguage::_find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op) {
9778 bool found = false;
9779
9780 for (int i = p_flow->blocks.size() - 1; i >= 0; i--) {
9781 if (p_flow->blocks[i]->type == Node::NODE_TYPE_BLOCK) {
9782 BlockNode *last_block = static_cast<BlockNode *>(p_flow->blocks[i]);
9783 if (_find_last_flow_op_in_block(last_block, p_op) == OK) {
9784 found = true;
9785 break;
9786 }
9787 }
9788 }
9789 if (found) {
9790 return OK;
9791 }
9792 return FAILED;
9793}
9794
9795Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op) {
9796 bool found = false;
9797
9798 for (int i = p_block->statements.size() - 1; i >= 0; i--) {
9799 if (p_block->statements[i]->type == Node::NODE_TYPE_CONTROL_FLOW) {
9800 ControlFlowNode *flow = static_cast<ControlFlowNode *>(p_block->statements[i]);
9801 if (flow->flow_op == p_op) {
9802 found = true;
9803 break;
9804 } else {
9805 if (_find_last_flow_op_in_op(flow, p_op) == OK) {
9806 found = true;
9807 break;
9808 }
9809 }
9810 } else if (p_block->statements[i]->type == Node::NODE_TYPE_BLOCK) {
9811 BlockNode *block = static_cast<BlockNode *>(p_block->statements[i]);
9812 if (_find_last_flow_op_in_block(block, p_op) == OK) {
9813 found = true;
9814 break;
9815 }
9816 }
9817 }
9818
9819 if (found) {
9820 return OK;
9821 }
9822 return FAILED;
9823}
9824
9825// skips over whitespace and /* */ and // comments
9826static int _get_first_ident_pos(const String &p_code) {
9827 int idx = 0;
9828
9829#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : char32_t(0))
9830
9831 while (true) {
9832 if (GETCHAR(0) == '/' && GETCHAR(1) == '/') {
9833 idx += 2;
9834 while (true) {
9835 if (GETCHAR(0) == 0) {
9836 return 0;
9837 }
9838 if (GETCHAR(0) == '\n') {
9839 idx++;
9840 break; // loop
9841 }
9842 idx++;
9843 }
9844 } else if (GETCHAR(0) == '/' && GETCHAR(1) == '*') {
9845 idx += 2;
9846 while (true) {
9847 if (GETCHAR(0) == 0) {
9848 return 0;
9849 }
9850 if (GETCHAR(0) == '*' && GETCHAR(1) == '/') {
9851 idx += 2;
9852 break; // loop
9853 }
9854 idx++;
9855 }
9856 } else {
9857 switch (GETCHAR(0)) {
9858 case ' ':
9859 case '\t':
9860 case '\r':
9861 case '\n': {
9862 idx++;
9863 } break; // switch
9864 default:
9865 return idx;
9866 }
9867 }
9868 }
9869
9870#undef GETCHAR
9871}
9872
9873String ShaderLanguage::get_shader_type(const String &p_code) {
9874 bool reading_type = false;
9875
9876 String cur_identifier;
9877
9878 for (int i = _get_first_ident_pos(p_code); i < p_code.length(); i++) {
9879 if (p_code[i] == ';') {
9880 break;
9881
9882 } else if (p_code[i] <= 32) {
9883 if (!cur_identifier.is_empty()) {
9884 if (!reading_type) {
9885 if (cur_identifier != "shader_type") {
9886 return String();
9887 }
9888
9889 reading_type = true;
9890 cur_identifier = String();
9891 } else {
9892 return cur_identifier;
9893 }
9894 }
9895 } else {
9896 cur_identifier += String::chr(p_code[i]);
9897 }
9898 }
9899
9900 if (reading_type) {
9901 return cur_identifier;
9902 }
9903
9904 return String();
9905}
9906
9907bool ShaderLanguage::is_builtin_func_out_parameter(const String &p_name, int p_param) {
9908 int i = 0;
9909 while (builtin_func_out_args[i].name) {
9910 if (p_name == builtin_func_out_args[i].name) {
9911 for (int j = 0; j < BuiltinFuncOutArgs::MAX_ARGS; j++) {
9912 int arg = builtin_func_out_args[i].arguments[j];
9913 if (arg == p_param) {
9914 return true;
9915 }
9916 if (arg < 0) {
9917 return false;
9918 }
9919 }
9920 }
9921 i++;
9922 }
9923 return false;
9924}
9925
9926#ifdef DEBUG_ENABLED
9927void ShaderLanguage::_check_warning_accums() {
9928 for (const KeyValue<ShaderWarning::Code, HashMap<StringName, HashMap<StringName, Usage>> *> &E : warnings_check_map2) {
9929 for (const KeyValue<StringName, HashMap<StringName, Usage>> &T : *E.value) {
9930 for (const KeyValue<StringName, Usage> &U : T.value) {
9931 if (!U.value.used) {
9932 _add_warning(E.key, U.value.decl_line, U.key);
9933 }
9934 }
9935 }
9936 }
9937 for (const KeyValue<ShaderWarning::Code, HashMap<StringName, Usage> *> &E : warnings_check_map) {
9938 for (const KeyValue<StringName, Usage> &U : (*E.value)) {
9939 if (!U.value.used) {
9940 _add_warning(E.key, U.value.decl_line, U.key);
9941 }
9942 }
9943 }
9944}
9945List<ShaderWarning>::Element *ShaderLanguage::get_warnings_ptr() {
9946 return warnings.front();
9947}
9948void ShaderLanguage::enable_warning_checking(bool p_enabled) {
9949 check_warnings = p_enabled;
9950}
9951bool ShaderLanguage::is_warning_checking_enabled() const {
9952 return check_warnings;
9953}
9954void ShaderLanguage::set_warning_flags(uint32_t p_flags) {
9955 warning_flags = p_flags;
9956}
9957uint32_t ShaderLanguage::get_warning_flags() const {
9958 return warning_flags;
9959}
9960#endif // DEBUG_ENABLED
9961
9962Error ShaderLanguage::compile(const String &p_code, const ShaderCompileInfo &p_info) {
9963 clear();
9964 is_shader_inc = p_info.is_include;
9965
9966 code = p_code;
9967 global_shader_uniform_get_type_func = p_info.global_shader_uniform_type_func;
9968
9969 varying_function_names = p_info.varying_function_names;
9970
9971 nodes = nullptr;
9972
9973 shader = alloc_node<ShaderNode>();
9974 Error err = _parse_shader(p_info.functions, p_info.render_modes, p_info.shader_types);
9975
9976#ifdef DEBUG_ENABLED
9977 if (check_warnings) {
9978 _check_warning_accums();
9979 }
9980#endif // DEBUG_ENABLED
9981
9982 if (err != OK) {
9983 return err;
9984 }
9985 return OK;
9986}
9987
9988Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_info, List<ScriptLanguage::CodeCompletionOption> *r_options, String &r_call_hint) {
9989 clear();
9990 is_shader_inc = p_info.is_include;
9991
9992 code = p_code;
9993 varying_function_names = p_info.varying_function_names;
9994
9995 nodes = nullptr;
9996 global_shader_uniform_get_type_func = p_info.global_shader_uniform_type_func;
9997
9998 shader = alloc_node<ShaderNode>();
9999 _parse_shader(p_info.functions, p_info.render_modes, p_info.shader_types);
10000
10001#ifdef DEBUG_ENABLED
10002 // Adds context keywords.
10003 if (keyword_completion_context != CF_UNSPECIFIED) {
10004 int sz = sizeof(keyword_list) / sizeof(KeyWord);
10005 for (int i = 0; i < sz; i++) {
10006 if (keyword_list[i].flags == CF_UNSPECIFIED) {
10007 break; // Ignore hint keywords (parsed below).
10008 }
10009 if (keyword_list[i].flags & keyword_completion_context) {
10010 if (keyword_list[i].excluded_shader_types.has(shader_type_identifier)) {
10011 continue;
10012 }
10013 if (!keyword_list[i].functions.is_empty() && !keyword_list[i].functions.has(current_function)) {
10014 continue;
10015 }
10016 ScriptLanguage::CodeCompletionOption option(keyword_list[i].text, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10017 r_options->push_back(option);
10018 }
10019 }
10020 }
10021#endif // DEBUG_ENABLED
10022
10023 switch (completion_type) {
10024 case COMPLETION_NONE: {
10025 //do nothing
10026 return OK;
10027 } break;
10028 case COMPLETION_SHADER_TYPE: {
10029 for (const String &shader_type : p_info.shader_types) {
10030 ScriptLanguage::CodeCompletionOption option(shader_type, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10031 r_options->push_back(option);
10032 }
10033 return OK;
10034 } break;
10035 case COMPLETION_RENDER_MODE: {
10036 if (is_shader_inc) {
10037 for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
10038 const Vector<ModeInfo> modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(i));
10039
10040 for (int j = 0; j < modes.size(); j++) {
10041 const ModeInfo &info = modes[j];
10042
10043 if (!info.options.is_empty()) {
10044 bool found = false;
10045
10046 for (int k = 0; k < info.options.size(); k++) {
10047 if (shader->render_modes.has(String(info.name) + "_" + String(info.options[k]))) {
10048 found = true;
10049 }
10050 }
10051
10052 if (!found) {
10053 for (int k = 0; k < info.options.size(); k++) {
10054 ScriptLanguage::CodeCompletionOption option(String(info.name) + "_" + String(info.options[k]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10055 r_options->push_back(option);
10056 }
10057 }
10058 } else {
10059 const String name = String(info.name);
10060
10061 if (!shader->render_modes.has(name)) {
10062 ScriptLanguage::CodeCompletionOption option(name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10063 r_options->push_back(option);
10064 }
10065 }
10066 }
10067 }
10068 } else {
10069 for (int i = 0; i < p_info.render_modes.size(); i++) {
10070 const ModeInfo &info = p_info.render_modes[i];
10071
10072 if (!info.options.is_empty()) {
10073 bool found = false;
10074
10075 for (int j = 0; j < info.options.size(); j++) {
10076 if (shader->render_modes.has(String(info.name) + "_" + String(info.options[j]))) {
10077 found = true;
10078 }
10079 }
10080
10081 if (!found) {
10082 for (int j = 0; j < info.options.size(); j++) {
10083 ScriptLanguage::CodeCompletionOption option(String(info.name) + "_" + String(info.options[j]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10084 r_options->push_back(option);
10085 }
10086 }
10087 } else {
10088 const String name = String(info.name);
10089
10090 if (!shader->render_modes.has(name)) {
10091 ScriptLanguage::CodeCompletionOption option(name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10092 r_options->push_back(option);
10093 }
10094 }
10095 }
10096 }
10097
10098 return OK;
10099 } break;
10100 case COMPLETION_STRUCT: {
10101 if (shader->structs.has(completion_struct)) {
10102 StructNode *node = shader->structs[completion_struct].shader_struct;
10103 for (int i = 0; i < node->members.size(); i++) {
10104 ScriptLanguage::CodeCompletionOption option(node->members[i]->name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER);
10105 r_options->push_back(option);
10106 }
10107 }
10108
10109 return OK;
10110 } break;
10111 case COMPLETION_MAIN_FUNCTION: {
10112 for (const KeyValue<StringName, FunctionInfo> &E : p_info.functions) {
10113 if (!E.value.main_function) {
10114 continue;
10115 }
10116 bool found = false;
10117 for (int i = 0; i < shader->functions.size(); i++) {
10118 if (shader->functions[i].name == E.key) {
10119 found = true;
10120 break;
10121 }
10122 }
10123 if (found) {
10124 continue;
10125 }
10126 ScriptLanguage::CodeCompletionOption option(E.key, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
10127 r_options->push_back(option);
10128 }
10129
10130 return OK;
10131 } break;
10132 case COMPLETION_IDENTIFIER:
10133 case COMPLETION_FUNCTION_CALL: {
10134 bool comp_ident = completion_type == COMPLETION_IDENTIFIER;
10135 HashMap<String, ScriptLanguage::CodeCompletionKind> matches;
10136 StringName skip_function;
10137 BlockNode *block = completion_block;
10138
10139 if (completion_class == TAG_GLOBAL) {
10140 while (block) {
10141 if (comp_ident) {
10142 for (const KeyValue<StringName, BlockNode::Variable> &E : block->variables) {
10143 if (E.value.line < completion_line) {
10144 matches.insert(E.key, ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE);
10145 }
10146 }
10147 }
10148
10149 if (block->parent_function) {
10150 if (comp_ident) {
10151 for (int i = 0; i < block->parent_function->arguments.size(); i++) {
10152 matches.insert(block->parent_function->arguments[i].name, ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE);
10153 }
10154 }
10155 skip_function = block->parent_function->name;
10156 }
10157 block = block->parent_block;
10158 }
10159
10160 if (comp_ident) {
10161 if (is_shader_inc) {
10162 for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
10163 const HashMap<StringName, ShaderLanguage::FunctionInfo> info = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i));
10164
10165 if (info.has("global")) {
10166 for (const KeyValue<StringName, BuiltInInfo> &E : info["global"].built_ins) {
10167 ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
10168 if (E.value.constant) {
10169 kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
10170 }
10171 matches.insert(E.key, kind);
10172 }
10173 }
10174
10175 if (info.has("constants")) {
10176 for (const KeyValue<StringName, BuiltInInfo> &E : info["constants"].built_ins) {
10177 ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
10178 if (E.value.constant) {
10179 kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
10180 }
10181 matches.insert(E.key, kind);
10182 }
10183 }
10184
10185 if (skip_function != StringName() && info.has(skip_function)) {
10186 for (const KeyValue<StringName, BuiltInInfo> &E : info[skip_function].built_ins) {
10187 ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
10188 if (E.value.constant) {
10189 kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
10190 }
10191 matches.insert(E.key, kind);
10192 }
10193 }
10194 }
10195 } else {
10196 if (p_info.functions.has("global")) {
10197 for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["global"].built_ins) {
10198 ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
10199 if (E.value.constant) {
10200 kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
10201 }
10202 matches.insert(E.key, kind);
10203 }
10204 }
10205
10206 if (p_info.functions.has("constants")) {
10207 for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["constants"].built_ins) {
10208 ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
10209 if (E.value.constant) {
10210 kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
10211 }
10212 matches.insert(E.key, kind);
10213 }
10214 }
10215
10216 if (skip_function != StringName() && p_info.functions.has(skip_function)) {
10217 for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions[skip_function].built_ins) {
10218 ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
10219 if (E.value.constant) {
10220 kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
10221 }
10222 matches.insert(E.key, kind);
10223 }
10224 }
10225 }
10226
10227 for (const KeyValue<StringName, ShaderNode::Constant> &E : shader->constants) {
10228 matches.insert(E.key, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT);
10229 }
10230 for (const KeyValue<StringName, ShaderNode::Varying> &E : shader->varyings) {
10231 matches.insert(E.key, ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE);
10232 }
10233 for (const KeyValue<StringName, ShaderNode::Uniform> &E : shader->uniforms) {
10234 matches.insert(E.key, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER);
10235 }
10236 }
10237
10238 for (int i = 0; i < shader->functions.size(); i++) {
10239 if (!shader->functions[i].callable || shader->functions[i].name == skip_function) {
10240 continue;
10241 }
10242 matches.insert(String(shader->functions[i].name), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
10243 }
10244
10245 int idx = 0;
10246 bool low_end = RenderingServer::get_singleton()->is_low_end();
10247
10248 if (stages && stages->has(skip_function)) {
10249 for (const KeyValue<StringName, StageFunctionInfo> &E : (*stages)[skip_function].stage_functions) {
10250 matches.insert(String(E.key), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
10251 }
10252 }
10253
10254 while (builtin_func_defs[idx].name) {
10255 if (low_end && builtin_func_defs[idx].high_end) {
10256 idx++;
10257 continue;
10258 }
10259 matches.insert(String(builtin_func_defs[idx].name), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
10260 idx++;
10261 }
10262
10263 } else { // sub-class
10264 int idx = 0;
10265 bool low_end = RenderingServer::get_singleton()->is_low_end();
10266
10267 while (builtin_func_defs[idx].name) {
10268 if (low_end && builtin_func_defs[idx].high_end) {
10269 idx++;
10270 continue;
10271 }
10272 if (builtin_func_defs[idx].tag == completion_class) {
10273 matches.insert(String(builtin_func_defs[idx].name), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
10274 }
10275 idx++;
10276 }
10277 }
10278
10279 for (const KeyValue<String, ScriptLanguage::CodeCompletionKind> &E : matches) {
10280 ScriptLanguage::CodeCompletionOption option(E.key, E.value);
10281 if (E.value == ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION) {
10282 option.insert_text += "(";
10283 }
10284 r_options->push_back(option);
10285 }
10286
10287 return OK;
10288 } break;
10289 case COMPLETION_CALL_ARGUMENTS: {
10290 StringName block_function;
10291 BlockNode *block = completion_block;
10292
10293 while (block) {
10294 if (block->parent_function) {
10295 block_function = block->parent_function->name;
10296 }
10297 block = block->parent_block;
10298 }
10299
10300 for (int i = 0; i < shader->functions.size(); i++) {
10301 if (!shader->functions[i].callable) {
10302 continue;
10303 }
10304 if (shader->functions[i].name == completion_function) {
10305 String calltip;
10306
10307 calltip += get_datatype_name(shader->functions[i].function->return_type);
10308
10309 if (shader->functions[i].function->return_array_size > 0) {
10310 calltip += "[";
10311 calltip += itos(shader->functions[i].function->return_array_size);
10312 calltip += "]";
10313 }
10314
10315 calltip += " ";
10316 calltip += shader->functions[i].name;
10317 calltip += "(";
10318
10319 for (int j = 0; j < shader->functions[i].function->arguments.size(); j++) {
10320 if (j > 0) {
10321 calltip += ", ";
10322 } else {
10323 calltip += " ";
10324 }
10325
10326 if (j == completion_argument) {
10327 calltip += char32_t(0xFFFF);
10328 }
10329
10330 if (shader->functions[i].function->arguments[j].is_const) {
10331 calltip += "const ";
10332 }
10333
10334 if (shader->functions[i].function->arguments[j].qualifier != ArgumentQualifier::ARGUMENT_QUALIFIER_IN) {
10335 if (shader->functions[i].function->arguments[j].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT) {
10336 calltip += "out ";
10337 } else { // ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT
10338 calltip += "inout ";
10339 }
10340 }
10341
10342 calltip += get_datatype_name(shader->functions[i].function->arguments[j].type);
10343 calltip += " ";
10344 calltip += shader->functions[i].function->arguments[j].name;
10345
10346 if (shader->functions[i].function->arguments[j].array_size > 0) {
10347 calltip += "[";
10348 calltip += itos(shader->functions[i].function->arguments[j].array_size);
10349 calltip += "]";
10350 }
10351
10352 if (j == completion_argument) {
10353 calltip += char32_t(0xFFFF);
10354 }
10355 }
10356
10357 if (shader->functions[i].function->arguments.size()) {
10358 calltip += " ";
10359 }
10360 calltip += ")";
10361
10362 r_call_hint = calltip;
10363 return OK;
10364 }
10365 }
10366
10367 int idx = 0;
10368
10369 String calltip;
10370 bool low_end = RenderingServer::get_singleton()->is_low_end();
10371
10372 if (stages && stages->has(block_function)) {
10373 for (const KeyValue<StringName, StageFunctionInfo> &E : (*stages)[block_function].stage_functions) {
10374 if (completion_function == E.key) {
10375 calltip += get_datatype_name(E.value.return_type);
10376 calltip += " ";
10377 calltip += E.key;
10378 calltip += "(";
10379
10380 for (int i = 0; i < E.value.arguments.size(); i++) {
10381 if (i > 0) {
10382 calltip += ", ";
10383 } else {
10384 calltip += " ";
10385 }
10386
10387 if (i == completion_argument) {
10388 calltip += char32_t(0xFFFF);
10389 }
10390
10391 calltip += get_datatype_name(E.value.arguments[i].type);
10392 calltip += " ";
10393 calltip += E.value.arguments[i].name;
10394
10395 if (i == completion_argument) {
10396 calltip += char32_t(0xFFFF);
10397 }
10398 }
10399
10400 if (E.value.arguments.size()) {
10401 calltip += " ";
10402 }
10403 calltip += ")";
10404
10405 r_call_hint = calltip;
10406 return OK;
10407 }
10408 }
10409 }
10410
10411 while (builtin_func_defs[idx].name) {
10412 if (low_end && builtin_func_defs[idx].high_end) {
10413 idx++;
10414 continue;
10415 }
10416
10417 int idx2 = 0;
10418 HashSet<int> out_args;
10419 while (builtin_func_out_args[idx2].name != nullptr) {
10420 if (builtin_func_out_args[idx2].name == builtin_func_defs[idx].name) {
10421 for (int i = 0; i < BuiltinFuncOutArgs::MAX_ARGS; i++) {
10422 int arg = builtin_func_out_args[idx2].arguments[i];
10423 if (arg == -1) {
10424 break;
10425 }
10426 out_args.insert(arg);
10427 }
10428 break;
10429 }
10430 idx2++;
10431 }
10432
10433 if (completion_function == builtin_func_defs[idx].name) {
10434 if (builtin_func_defs[idx].tag != completion_class) {
10435 idx++;
10436 continue;
10437 }
10438
10439 if (calltip.length()) {
10440 calltip += "\n";
10441 }
10442
10443 calltip += get_datatype_name(builtin_func_defs[idx].rettype);
10444 calltip += " ";
10445 calltip += builtin_func_defs[idx].name;
10446 calltip += "(";
10447
10448 bool found_arg = false;
10449 for (int i = 0; i < BuiltinFuncDef::MAX_ARGS - 1; i++) {
10450 if (builtin_func_defs[idx].args[i] == TYPE_VOID) {
10451 break;
10452 }
10453
10454 if (i > 0) {
10455 calltip += ", ";
10456 } else {
10457 calltip += " ";
10458 }
10459
10460 if (i == completion_argument) {
10461 calltip += char32_t(0xFFFF);
10462 }
10463
10464 if (out_args.has(i)) {
10465 calltip += "out ";
10466 }
10467
10468 calltip += get_datatype_name(builtin_func_defs[idx].args[i]);
10469
10470 String arg_name = (String)builtin_func_defs[idx].args_names[i];
10471 if (!arg_name.is_empty()) {
10472 calltip += " ";
10473 calltip += arg_name;
10474 }
10475
10476 if (i == completion_argument) {
10477 calltip += char32_t(0xFFFF);
10478 }
10479
10480 found_arg = true;
10481 }
10482
10483 if (found_arg) {
10484 calltip += " ";
10485 }
10486 calltip += ")";
10487 }
10488 idx++;
10489 }
10490
10491 r_call_hint = calltip;
10492
10493 return OK;
10494
10495 } break;
10496 case COMPLETION_INDEX: {
10497 const char colv[4] = { 'r', 'g', 'b', 'a' };
10498 const char coordv[4] = { 'x', 'y', 'z', 'w' };
10499 const char coordt[4] = { 's', 't', 'p', 'q' };
10500 const String theme_color_names[4] = { "axis_x_color", "axis_y_color", "axis_z_color", "axis_w_color" };
10501
10502 int limit = 0;
10503
10504 switch (completion_base) {
10505 case TYPE_BVEC2:
10506 case TYPE_IVEC2:
10507 case TYPE_UVEC2:
10508 case TYPE_VEC2: {
10509 limit = 2;
10510
10511 } break;
10512 case TYPE_BVEC3:
10513 case TYPE_IVEC3:
10514 case TYPE_UVEC3:
10515 case TYPE_VEC3: {
10516 limit = 3;
10517
10518 } break;
10519 case TYPE_BVEC4:
10520 case TYPE_IVEC4:
10521 case TYPE_UVEC4:
10522 case TYPE_VEC4: {
10523 limit = 4;
10524
10525 } break;
10526 default: {
10527 }
10528 }
10529
10530 for (int i = 0; i < limit; i++) {
10531 r_options->push_back(ScriptLanguage::CodeCompletionOption(String::chr(colv[i]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT, ScriptLanguage::LOCATION_OTHER, theme_color_names[i]));
10532 r_options->push_back(ScriptLanguage::CodeCompletionOption(String::chr(coordv[i]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT, ScriptLanguage::LOCATION_OTHER, theme_color_names[i]));
10533 r_options->push_back(ScriptLanguage::CodeCompletionOption(String::chr(coordt[i]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT, ScriptLanguage::LOCATION_OTHER, theme_color_names[i]));
10534 }
10535
10536 } break;
10537 case COMPLETION_HINT: {
10538 if (completion_base == DataType::TYPE_VEC3 || completion_base == DataType::TYPE_VEC4) {
10539 if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
10540 ScriptLanguage::CodeCompletionOption option("source_color", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10541 r_options->push_back(option);
10542 }
10543 } else if ((completion_base == DataType::TYPE_INT || completion_base == DataType::TYPE_FLOAT) && !completion_base_array) {
10544 if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
10545 ScriptLanguage::CodeCompletionOption option("hint_range", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10546
10547 if (completion_base == DataType::TYPE_INT) {
10548 option.insert_text = "hint_range(0, 100, 1)";
10549 } else {
10550 option.insert_text = "hint_range(0.0, 1.0, 0.1)";
10551 }
10552
10553 r_options->push_back(option);
10554 }
10555 } else if ((int(completion_base) > int(TYPE_MAT4) && int(completion_base) < int(TYPE_STRUCT))) {
10556 Vector<String> options;
10557 if (current_uniform_filter == FILTER_DEFAULT) {
10558 options.push_back("filter_linear");
10559 options.push_back("filter_linear_mipmap");
10560 options.push_back("filter_linear_mipmap_anisotropic");
10561 options.push_back("filter_nearest");
10562 options.push_back("filter_nearest_mipmap");
10563 options.push_back("filter_nearest_mipmap_anisotropic");
10564 }
10565 if (current_uniform_repeat == REPEAT_DEFAULT) {
10566 options.push_back("repeat_enable");
10567 options.push_back("repeat_disable");
10568 }
10569 if (completion_base_array) {
10570 if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
10571 options.push_back("source_color");
10572 }
10573 } else {
10574 if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
10575 options.push_back("hint_anisotropy");
10576 options.push_back("hint_default_black");
10577 options.push_back("hint_default_white");
10578 options.push_back("hint_default_transparent");
10579 options.push_back("hint_normal");
10580 options.push_back("hint_roughness_a");
10581 options.push_back("hint_roughness_b");
10582 options.push_back("hint_roughness_g");
10583 options.push_back("hint_roughness_gray");
10584 options.push_back("hint_roughness_normal");
10585 options.push_back("hint_roughness_r");
10586 options.push_back("hint_screen_texture");
10587 options.push_back("hint_normal_roughness_texture");
10588 options.push_back("hint_depth_texture");
10589 options.push_back("source_color");
10590 }
10591 }
10592
10593 for (int i = 0; i < options.size(); i++) {
10594 ScriptLanguage::CodeCompletionOption option(options[i], ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10595 r_options->push_back(option);
10596 }
10597 }
10598 if (!completion_base_array && !current_uniform_instance_index_defined) {
10599 ScriptLanguage::CodeCompletionOption option("instance_index", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
10600 option.insert_text = "instance_index(0)";
10601 r_options->push_back(option);
10602 }
10603 } break;
10604 }
10605
10606 return ERR_PARSE_ERROR;
10607}
10608
10609String ShaderLanguage::get_error_text() {
10610 return error_str;
10611}
10612
10613Vector<ShaderLanguage::FilePosition> ShaderLanguage::get_include_positions() {
10614 return include_positions;
10615}
10616
10617int ShaderLanguage::get_error_line() {
10618 return error_line;
10619}
10620
10621ShaderLanguage::ShaderNode *ShaderLanguage::get_shader() {
10622 return shader;
10623}
10624
10625ShaderLanguage::ShaderLanguage() {
10626 nodes = nullptr;
10627 completion_class = TAG_GLOBAL;
10628
10629#ifdef DEBUG_ENABLED
10630 warnings_check_map.insert(ShaderWarning::UNUSED_CONSTANT, &used_constants);
10631 warnings_check_map.insert(ShaderWarning::UNUSED_FUNCTION, &used_functions);
10632 warnings_check_map.insert(ShaderWarning::UNUSED_STRUCT, &used_structs);
10633 warnings_check_map.insert(ShaderWarning::UNUSED_UNIFORM, &used_uniforms);
10634 warnings_check_map.insert(ShaderWarning::UNUSED_VARYING, &used_varyings);
10635
10636 warnings_check_map2.insert(ShaderWarning::UNUSED_LOCAL_VARIABLE, &used_local_vars);
10637#endif // DEBUG_ENABLED
10638}
10639
10640ShaderLanguage::~ShaderLanguage() {
10641 clear();
10642}
10643