Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/servers/rendering/shader_language.cpp
10746 views
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/templates/local_vector.h"
35
#include "servers/rendering/renderer_compositor.h"
36
#include "servers/rendering/rendering_server_globals.h"
37
#include "servers/rendering_server.h"
38
#include "shader_types.h"
39
40
#define HAS_WARNING(flag) (warning_flags & flag)
41
42
SafeNumeric<int> ShaderLanguage::instance_counter;
43
44
String ShaderLanguage::get_operator_text(Operator p_op) {
45
static const char *op_names[OP_MAX] = { "==",
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
"--",
83
"()",
84
"construct",
85
"index",
86
"empty" };
87
88
return op_names[p_op];
89
}
90
91
const char *ShaderLanguage::token_names[TK_MAX] = {
92
"EMPTY",
93
"IDENTIFIER",
94
"TRUE",
95
"FALSE",
96
"FLOAT_CONSTANT",
97
"INT_CONSTANT",
98
"UINT_CONSTANT",
99
"STRING_CONSTANT",
100
"TYPE_VOID",
101
"TYPE_BOOL",
102
"TYPE_BVEC2",
103
"TYPE_BVEC3",
104
"TYPE_BVEC4",
105
"TYPE_INT",
106
"TYPE_IVEC2",
107
"TYPE_IVEC3",
108
"TYPE_IVEC4",
109
"TYPE_UINT",
110
"TYPE_UVEC2",
111
"TYPE_UVEC3",
112
"TYPE_UVEC4",
113
"TYPE_FLOAT",
114
"TYPE_VEC2",
115
"TYPE_VEC3",
116
"TYPE_VEC4",
117
"TYPE_MAT2",
118
"TYPE_MAT3",
119
"TYPE_MAT4",
120
"TYPE_SAMPLER2D",
121
"TYPE_ISAMPLER2D",
122
"TYPE_USAMPLER2D",
123
"TYPE_SAMPLER2DARRAY",
124
"TYPE_ISAMPLER2DARRAY",
125
"TYPE_USAMPLER2DARRAY",
126
"TYPE_SAMPLER3D",
127
"TYPE_ISAMPLER3D",
128
"TYPE_USAMPLER3D",
129
"TYPE_SAMPLERCUBE",
130
"TYPE_SAMPLERCUBEARRAY",
131
"TYPE_SAMPLEREXT",
132
"INTERPOLATION_FLAT",
133
"INTERPOLATION_SMOOTH",
134
"CONST",
135
"STRUCT",
136
"PRECISION_LOW",
137
"PRECISION_MID",
138
"PRECISION_HIGH",
139
"OP_EQUAL",
140
"OP_NOT_EQUAL",
141
"OP_LESS",
142
"OP_LESS_EQUAL",
143
"OP_GREATER",
144
"OP_GREATER_EQUAL",
145
"OP_AND",
146
"OP_OR",
147
"OP_NOT",
148
"OP_ADD",
149
"OP_SUB",
150
"OP_MUL",
151
"OP_DIV",
152
"OP_MOD",
153
"OP_SHIFT_LEFT",
154
"OP_SHIFT_RIGHT",
155
"OP_ASSIGN",
156
"OP_ASSIGN_ADD",
157
"OP_ASSIGN_SUB",
158
"OP_ASSIGN_MUL",
159
"OP_ASSIGN_DIV",
160
"OP_ASSIGN_MOD",
161
"OP_ASSIGN_SHIFT_LEFT",
162
"OP_ASSIGN_SHIFT_RIGHT",
163
"OP_ASSIGN_BIT_AND",
164
"OP_ASSIGN_BIT_OR",
165
"OP_ASSIGN_BIT_XOR",
166
"OP_BIT_AND",
167
"OP_BIT_OR",
168
"OP_BIT_XOR",
169
"OP_BIT_INVERT",
170
"OP_INCREMENT",
171
"OP_DECREMENT",
172
"CF_IF",
173
"CF_ELSE",
174
"CF_FOR",
175
"CF_WHILE",
176
"CF_DO",
177
"CF_SWITCH",
178
"CF_CASE",
179
"CF_DEFAULT",
180
"CF_BREAK",
181
"CF_CONTINUE",
182
"CF_RETURN",
183
"CF_DISCARD",
184
"BRACKET_OPEN",
185
"BRACKET_CLOSE",
186
"CURLY_BRACKET_OPEN",
187
"CURLY_BRACKET_CLOSE",
188
"PARENTHESIS_OPEN",
189
"PARENTHESIS_CLOSE",
190
"QUESTION",
191
"COMMA",
192
"COLON",
193
"SEMICOLON",
194
"PERIOD",
195
"UNIFORM",
196
"UNIFORM_GROUP",
197
"INSTANCE",
198
"GLOBAL",
199
"VARYING",
200
"ARG_IN",
201
"ARG_OUT",
202
"ARG_INOUT",
203
"RENDER_MODE",
204
"HINT_DEFAULT_WHITE_TEXTURE",
205
"HINT_DEFAULT_BLACK_TEXTURE",
206
"HINT_DEFAULT_TRANSPARENT_TEXTURE",
207
"HINT_NORMAL_TEXTURE",
208
"HINT_ROUGHNESS_NORMAL_TEXTURE",
209
"HINT_ROUGHNESS_R",
210
"HINT_ROUGHNESS_G",
211
"HINT_ROUGHNESS_B",
212
"HINT_ROUGHNESS_A",
213
"HINT_ROUGHNESS_GRAY",
214
"HINT_ANISOTROPY_TEXTURE",
215
"HINT_SOURCE_COLOR",
216
"HINT_COLOR_CONVERSION_DISABLED",
217
"HINT_RANGE",
218
"HINT_ENUM",
219
"HINT_INSTANCE_INDEX",
220
"HINT_SCREEN_TEXTURE",
221
"HINT_NORMAL_ROUGHNESS_TEXTURE",
222
"HINT_DEPTH_TEXTURE",
223
"FILTER_NEAREST",
224
"FILTER_LINEAR",
225
"FILTER_NEAREST_MIPMAP",
226
"FILTER_LINEAR_MIPMAP",
227
"FILTER_NEAREST_MIPMAP_ANISOTROPIC",
228
"FILTER_LINEAR_MIPMAP_ANISOTROPIC",
229
"REPEAT_ENABLE",
230
"REPEAT_DISABLE",
231
"SHADER_TYPE",
232
"CURSOR",
233
"ERROR",
234
"EOF",
235
};
236
237
String ShaderLanguage::get_token_text(Token p_token) {
238
String name = token_names[p_token.type];
239
if (p_token.is_integer_constant() || p_token.type == TK_FLOAT_CONSTANT) {
240
name += "(" + rtos(p_token.constant) + ")";
241
} else if (p_token.type == TK_IDENTIFIER) {
242
name += "(" + String(p_token.text) + ")";
243
} else if (p_token.type == TK_ERROR) {
244
name += "(" + String(p_token.text) + ")";
245
}
246
247
return name;
248
}
249
250
ShaderLanguage::Token ShaderLanguage::_make_token(TokenType p_type, const StringName &p_text) {
251
Token tk;
252
tk.type = p_type;
253
tk.text = p_text;
254
tk.line = tk_line;
255
if (tk.type == TK_ERROR) {
256
_set_error(p_text);
257
}
258
return tk;
259
}
260
261
enum ContextFlag : uint32_t {
262
CF_UNSPECIFIED = 0U,
263
CF_BLOCK = 1U, // "void test() { <x> }"
264
CF_FUNC_DECL_PARAM_SPEC = 2U, // "void test(<x> int param) {}"
265
CF_FUNC_DECL_PARAM_TYPE = 4U, // "void test(<x> param) {}"
266
CF_IF_DECL = 8U, // "if(<x>) {}"
267
CF_BOOLEAN = 16U, // "bool t = <x>;"
268
CF_GLOBAL_SPACE = 32U, // "struct", "const", "void" etc.
269
CF_DATATYPE = 64U, // "<x> value;"
270
CF_UNIFORM_TYPE = 128U, // "uniform <x> myUniform;"
271
CF_VARYING_TYPE = 256U, // "varying <x> myVarying;"
272
CF_PRECISION_MODIFIER = 512U, // "<x> vec4 a = vec4(0.0, 1.0, 2.0, 3.0);"
273
CF_INTERPOLATION_QUALIFIER = 1024U, // "varying <x> vec3 myColor;"
274
CF_UNIFORM_KEYWORD = 2048U, // "uniform"
275
CF_CONST_KEYWORD = 4096U, // "const"
276
CF_UNIFORM_QUALIFIER = 8192U, // "<x> uniform float t;"
277
CF_SHADER_TYPE = 16384U, // "shader_type"
278
};
279
280
const uint32_t KCF_DATATYPE = CF_BLOCK | CF_GLOBAL_SPACE | CF_DATATYPE | CF_FUNC_DECL_PARAM_TYPE | CF_UNIFORM_TYPE;
281
const uint32_t KCF_SAMPLER_DATATYPE = CF_FUNC_DECL_PARAM_TYPE | CF_UNIFORM_TYPE;
282
283
const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
284
{ TK_TRUE, "true", CF_BLOCK | CF_IF_DECL | CF_BOOLEAN, {}, {} },
285
{ TK_FALSE, "false", CF_BLOCK | CF_IF_DECL | CF_BOOLEAN, {}, {} },
286
287
// data types
288
289
{ TK_TYPE_VOID, "void", CF_GLOBAL_SPACE, {}, {} },
290
{ TK_TYPE_BOOL, "bool", KCF_DATATYPE, {}, {} },
291
{ TK_TYPE_BVEC2, "bvec2", KCF_DATATYPE, {}, {} },
292
{ TK_TYPE_BVEC3, "bvec3", KCF_DATATYPE, {}, {} },
293
{ TK_TYPE_BVEC4, "bvec4", KCF_DATATYPE, {}, {} },
294
{ TK_TYPE_INT, "int", KCF_DATATYPE, {}, {} },
295
{ TK_TYPE_IVEC2, "ivec2", KCF_DATATYPE, {}, {} },
296
{ TK_TYPE_IVEC3, "ivec3", KCF_DATATYPE, {}, {} },
297
{ TK_TYPE_IVEC4, "ivec4", KCF_DATATYPE, {}, {} },
298
{ TK_TYPE_UINT, "uint", KCF_DATATYPE, {}, {} },
299
{ TK_TYPE_UVEC2, "uvec2", KCF_DATATYPE, {}, {} },
300
{ TK_TYPE_UVEC3, "uvec3", KCF_DATATYPE, {}, {} },
301
{ TK_TYPE_UVEC4, "uvec4", KCF_DATATYPE, {}, {} },
302
{ TK_TYPE_FLOAT, "float", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
303
{ TK_TYPE_VEC2, "vec2", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
304
{ TK_TYPE_VEC3, "vec3", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
305
{ TK_TYPE_VEC4, "vec4", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
306
{ TK_TYPE_MAT2, "mat2", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
307
{ TK_TYPE_MAT3, "mat3", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
308
{ TK_TYPE_MAT4, "mat4", KCF_DATATYPE | CF_VARYING_TYPE, {}, {} },
309
{ TK_TYPE_SAMPLER2D, "sampler2D", KCF_SAMPLER_DATATYPE, {}, {} },
310
{ TK_TYPE_ISAMPLER2D, "isampler2D", KCF_SAMPLER_DATATYPE, {}, {} },
311
{ TK_TYPE_USAMPLER2D, "usampler2D", KCF_SAMPLER_DATATYPE, {}, {} },
312
{ TK_TYPE_SAMPLER2DARRAY, "sampler2DArray", KCF_SAMPLER_DATATYPE, {}, {} },
313
{ TK_TYPE_ISAMPLER2DARRAY, "isampler2DArray", KCF_SAMPLER_DATATYPE, {}, {} },
314
{ TK_TYPE_USAMPLER2DARRAY, "usampler2DArray", KCF_SAMPLER_DATATYPE, {}, {} },
315
{ TK_TYPE_SAMPLER3D, "sampler3D", KCF_SAMPLER_DATATYPE, {}, {} },
316
{ TK_TYPE_ISAMPLER3D, "isampler3D", KCF_SAMPLER_DATATYPE, {}, {} },
317
{ TK_TYPE_USAMPLER3D, "usampler3D", KCF_SAMPLER_DATATYPE, {}, {} },
318
{ TK_TYPE_SAMPLERCUBE, "samplerCube", KCF_SAMPLER_DATATYPE, {}, {} },
319
{ TK_TYPE_SAMPLERCUBEARRAY, "samplerCubeArray", KCF_SAMPLER_DATATYPE, {}, {} },
320
{ TK_TYPE_SAMPLEREXT, "samplerExternalOES", KCF_SAMPLER_DATATYPE, {}, {} },
321
322
// interpolation qualifiers
323
324
{ TK_INTERPOLATION_FLAT, "flat", CF_INTERPOLATION_QUALIFIER, {}, {} },
325
{ TK_INTERPOLATION_SMOOTH, "smooth", CF_INTERPOLATION_QUALIFIER, {}, {} },
326
327
// precision modifiers
328
329
{ TK_PRECISION_LOW, "lowp", CF_BLOCK | CF_PRECISION_MODIFIER, {}, {} },
330
{ TK_PRECISION_MID, "mediump", CF_BLOCK | CF_PRECISION_MODIFIER, {}, {} },
331
{ TK_PRECISION_HIGH, "highp", CF_BLOCK | CF_PRECISION_MODIFIER, {}, {} },
332
333
// global space keywords
334
335
{ TK_UNIFORM, "uniform", CF_GLOBAL_SPACE | CF_UNIFORM_KEYWORD, {}, {} },
336
{ TK_UNIFORM_GROUP, "group_uniforms", CF_GLOBAL_SPACE, {}, {} },
337
{ TK_VARYING, "varying", CF_GLOBAL_SPACE, { "particles", "sky", "fog" }, {} },
338
{ TK_CONST, "const", CF_BLOCK | CF_GLOBAL_SPACE | CF_CONST_KEYWORD, {}, {} },
339
{ TK_STRUCT, "struct", CF_GLOBAL_SPACE, {}, {} },
340
{ TK_SHADER_TYPE, "shader_type", CF_SHADER_TYPE, {}, {} },
341
{ TK_RENDER_MODE, "render_mode", CF_GLOBAL_SPACE, {}, {} },
342
{ TK_STENCIL_MODE, "stencil_mode", CF_GLOBAL_SPACE, {}, {} },
343
344
// uniform qualifiers
345
346
{ TK_INSTANCE, "instance", CF_GLOBAL_SPACE | CF_UNIFORM_QUALIFIER, {}, {} },
347
{ TK_GLOBAL, "global", CF_GLOBAL_SPACE | CF_UNIFORM_QUALIFIER, {}, {} },
348
349
// block keywords
350
351
{ TK_CF_IF, "if", CF_BLOCK, {}, {} },
352
{ TK_CF_ELSE, "else", CF_BLOCK, {}, {} },
353
{ TK_CF_FOR, "for", CF_BLOCK, {}, {} },
354
{ TK_CF_WHILE, "while", CF_BLOCK, {}, {} },
355
{ TK_CF_DO, "do", CF_BLOCK, {}, {} },
356
{ TK_CF_SWITCH, "switch", CF_BLOCK, {}, {} },
357
{ TK_CF_CASE, "case", CF_BLOCK, {}, {} },
358
{ TK_CF_DEFAULT, "default", CF_BLOCK, {}, {} },
359
{ TK_CF_BREAK, "break", CF_BLOCK, {}, {} },
360
{ TK_CF_CONTINUE, "continue", CF_BLOCK, {}, {} },
361
{ TK_CF_RETURN, "return", CF_BLOCK, {}, {} },
362
{ TK_CF_DISCARD, "discard", CF_BLOCK, { "particles", "sky", "fog" }, { "vertex" } },
363
364
// function specifier keywords
365
366
{ TK_ARG_IN, "in", CF_FUNC_DECL_PARAM_SPEC, {}, {} },
367
{ TK_ARG_OUT, "out", CF_FUNC_DECL_PARAM_SPEC, {}, {} },
368
{ TK_ARG_INOUT, "inout", CF_FUNC_DECL_PARAM_SPEC, {}, {} },
369
370
// hints
371
372
{ TK_HINT_SOURCE_COLOR, "source_color", CF_UNSPECIFIED, {}, {} },
373
{ TK_HINT_COLOR_CONVERSION_DISABLED, "color_conversion_disabled", CF_UNSPECIFIED, {}, {} },
374
{ TK_HINT_RANGE, "hint_range", CF_UNSPECIFIED, {}, {} },
375
{ TK_HINT_ENUM, "hint_enum", CF_UNSPECIFIED, {}, {} },
376
{ TK_HINT_INSTANCE_INDEX, "instance_index", CF_UNSPECIFIED, {}, {} },
377
378
// sampler hints
379
380
{ TK_HINT_NORMAL_TEXTURE, "hint_normal", CF_UNSPECIFIED, {}, {} },
381
{ TK_HINT_DEFAULT_WHITE_TEXTURE, "hint_default_white", CF_UNSPECIFIED, {}, {} },
382
{ TK_HINT_DEFAULT_BLACK_TEXTURE, "hint_default_black", CF_UNSPECIFIED, {}, {} },
383
{ TK_HINT_DEFAULT_TRANSPARENT_TEXTURE, "hint_default_transparent", CF_UNSPECIFIED, {}, {} },
384
{ TK_HINT_ANISOTROPY_TEXTURE, "hint_anisotropy", CF_UNSPECIFIED, {}, {} },
385
{ TK_HINT_ROUGHNESS_R, "hint_roughness_r", CF_UNSPECIFIED, {}, {} },
386
{ TK_HINT_ROUGHNESS_G, "hint_roughness_g", CF_UNSPECIFIED, {}, {} },
387
{ TK_HINT_ROUGHNESS_B, "hint_roughness_b", CF_UNSPECIFIED, {}, {} },
388
{ TK_HINT_ROUGHNESS_A, "hint_roughness_a", CF_UNSPECIFIED, {}, {} },
389
{ TK_HINT_ROUGHNESS_NORMAL_TEXTURE, "hint_roughness_normal", CF_UNSPECIFIED, {}, {} },
390
{ TK_HINT_ROUGHNESS_GRAY, "hint_roughness_gray", CF_UNSPECIFIED, {}, {} },
391
{ TK_HINT_SCREEN_TEXTURE, "hint_screen_texture", CF_UNSPECIFIED, {}, {} },
392
{ TK_HINT_NORMAL_ROUGHNESS_TEXTURE, "hint_normal_roughness_texture", CF_UNSPECIFIED, {}, {} },
393
{ TK_HINT_DEPTH_TEXTURE, "hint_depth_texture", CF_UNSPECIFIED, {}, {} },
394
395
{ TK_FILTER_NEAREST, "filter_nearest", CF_UNSPECIFIED, {}, {} },
396
{ TK_FILTER_LINEAR, "filter_linear", CF_UNSPECIFIED, {}, {} },
397
{ TK_FILTER_NEAREST_MIPMAP, "filter_nearest_mipmap", CF_UNSPECIFIED, {}, {} },
398
{ TK_FILTER_LINEAR_MIPMAP, "filter_linear_mipmap", CF_UNSPECIFIED, {}, {} },
399
{ TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC, "filter_nearest_mipmap_anisotropic", CF_UNSPECIFIED, {}, {} },
400
{ TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC, "filter_linear_mipmap_anisotropic", CF_UNSPECIFIED, {}, {} },
401
{ TK_REPEAT_ENABLE, "repeat_enable", CF_UNSPECIFIED, {}, {} },
402
{ TK_REPEAT_DISABLE, "repeat_disable", CF_UNSPECIFIED, {}, {} },
403
404
{ TK_ERROR, nullptr, CF_UNSPECIFIED, {}, {} }
405
};
406
407
ShaderLanguage::Token ShaderLanguage::_get_token() {
408
#define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : char32_t(0))
409
410
while (true) {
411
char_idx++;
412
switch (GETCHAR(-1)) {
413
case 0:
414
return _make_token(TK_EOF);
415
case 0xFFFF:
416
return _make_token(TK_CURSOR); //for completion
417
case '\t':
418
case '\r':
419
case ' ':
420
continue;
421
case '\n':
422
tk_line++;
423
continue;
424
case '/': {
425
switch (GETCHAR(0)) {
426
case '*': { // block comment
427
428
char_idx++;
429
while (true) {
430
if (GETCHAR(0) == 0) {
431
return _make_token(TK_EOF);
432
}
433
if (GETCHAR(0) == '*' && GETCHAR(1) == '/') {
434
char_idx += 2;
435
break;
436
} else if (GETCHAR(0) == '\n') {
437
tk_line++;
438
}
439
440
char_idx++;
441
}
442
443
} break;
444
case '/': { // line comment skip
445
446
while (true) {
447
if (GETCHAR(0) == '\n') {
448
tk_line++;
449
char_idx++;
450
break;
451
}
452
if (GETCHAR(0) == 0) {
453
return _make_token(TK_EOF);
454
}
455
char_idx++;
456
}
457
458
} break;
459
case '=': { // diveq
460
461
char_idx++;
462
return _make_token(TK_OP_ASSIGN_DIV);
463
464
} break;
465
default:
466
return _make_token(TK_OP_DIV);
467
}
468
469
continue; //a comment, continue to next token
470
} break;
471
case '=': {
472
if (GETCHAR(0) == '=') {
473
char_idx++;
474
return _make_token(TK_OP_EQUAL);
475
}
476
477
return _make_token(TK_OP_ASSIGN);
478
479
} break;
480
case '<': {
481
if (GETCHAR(0) == '=') {
482
char_idx++;
483
return _make_token(TK_OP_LESS_EQUAL);
484
} else if (GETCHAR(0) == '<') {
485
char_idx++;
486
if (GETCHAR(0) == '=') {
487
char_idx++;
488
return _make_token(TK_OP_ASSIGN_SHIFT_LEFT);
489
}
490
491
return _make_token(TK_OP_SHIFT_LEFT);
492
}
493
494
return _make_token(TK_OP_LESS);
495
496
} break;
497
case '>': {
498
if (GETCHAR(0) == '=') {
499
char_idx++;
500
return _make_token(TK_OP_GREATER_EQUAL);
501
} else if (GETCHAR(0) == '>') {
502
char_idx++;
503
if (GETCHAR(0) == '=') {
504
char_idx++;
505
return _make_token(TK_OP_ASSIGN_SHIFT_RIGHT);
506
}
507
508
return _make_token(TK_OP_SHIFT_RIGHT);
509
}
510
511
return _make_token(TK_OP_GREATER);
512
513
} break;
514
case '!': {
515
if (GETCHAR(0) == '=') {
516
char_idx++;
517
return _make_token(TK_OP_NOT_EQUAL);
518
}
519
520
return _make_token(TK_OP_NOT);
521
522
} break;
523
case '"': {
524
String _content = "";
525
bool _previous_backslash = false;
526
527
while (true) {
528
bool _ended = false;
529
char32_t c = GETCHAR(0);
530
if (c == 0) {
531
return _make_token(TK_ERROR, "EOF reached before string termination.");
532
}
533
switch (c) {
534
case '"': {
535
if (_previous_backslash) {
536
_content += '"';
537
_previous_backslash = false;
538
} else {
539
_ended = true;
540
}
541
break;
542
}
543
case '\\': {
544
if (_previous_backslash) {
545
_content += '\\';
546
}
547
_previous_backslash = !_previous_backslash;
548
break;
549
}
550
case '\n': {
551
return _make_token(TK_ERROR, "Unexpected end of string.");
552
}
553
default: {
554
if (!_previous_backslash) {
555
_content += c;
556
} else {
557
return _make_token(TK_ERROR, "Only \\\" and \\\\ escape characters supported.");
558
}
559
break;
560
}
561
}
562
563
char_idx++;
564
if (_ended) {
565
break;
566
}
567
}
568
569
return _make_token(TK_STRING_CONSTANT, _content);
570
} break;
571
//case '\'' //string - no strings in shader
572
case '{':
573
return _make_token(TK_CURLY_BRACKET_OPEN);
574
case '}':
575
return _make_token(TK_CURLY_BRACKET_CLOSE);
576
case '[':
577
return _make_token(TK_BRACKET_OPEN);
578
case ']':
579
return _make_token(TK_BRACKET_CLOSE);
580
case '(':
581
return _make_token(TK_PARENTHESIS_OPEN);
582
case ')':
583
return _make_token(TK_PARENTHESIS_CLOSE);
584
case ',':
585
return _make_token(TK_COMMA);
586
case ';':
587
return _make_token(TK_SEMICOLON);
588
case '?':
589
return _make_token(TK_QUESTION);
590
case ':':
591
return _make_token(TK_COLON);
592
case '^':
593
if (GETCHAR(0) == '=') {
594
char_idx++;
595
return _make_token(TK_OP_ASSIGN_BIT_XOR);
596
}
597
return _make_token(TK_OP_BIT_XOR);
598
case '~':
599
return _make_token(TK_OP_BIT_INVERT);
600
case '&': {
601
if (GETCHAR(0) == '=') {
602
char_idx++;
603
return _make_token(TK_OP_ASSIGN_BIT_AND);
604
} else if (GETCHAR(0) == '&') {
605
char_idx++;
606
return _make_token(TK_OP_AND);
607
}
608
return _make_token(TK_OP_BIT_AND);
609
} break;
610
case '|': {
611
if (GETCHAR(0) == '=') {
612
char_idx++;
613
return _make_token(TK_OP_ASSIGN_BIT_OR);
614
} else if (GETCHAR(0) == '|') {
615
char_idx++;
616
return _make_token(TK_OP_OR);
617
}
618
return _make_token(TK_OP_BIT_OR);
619
620
} break;
621
case '*': {
622
if (GETCHAR(0) == '=') {
623
char_idx++;
624
return _make_token(TK_OP_ASSIGN_MUL);
625
}
626
return _make_token(TK_OP_MUL);
627
} break;
628
case '+': {
629
if (GETCHAR(0) == '=') {
630
char_idx++;
631
return _make_token(TK_OP_ASSIGN_ADD);
632
} else if (GETCHAR(0) == '+') {
633
char_idx++;
634
return _make_token(TK_OP_INCREMENT);
635
}
636
637
return _make_token(TK_OP_ADD);
638
} break;
639
case '-': {
640
if (GETCHAR(0) == '=') {
641
char_idx++;
642
return _make_token(TK_OP_ASSIGN_SUB);
643
} else if (GETCHAR(0) == '-') {
644
char_idx++;
645
return _make_token(TK_OP_DECREMENT);
646
}
647
648
return _make_token(TK_OP_SUB);
649
} break;
650
case '%': {
651
if (GETCHAR(0) == '=') {
652
char_idx++;
653
return _make_token(TK_OP_ASSIGN_MOD);
654
}
655
656
return _make_token(TK_OP_MOD);
657
} break;
658
case '@': {
659
if (GETCHAR(0) == '@' && GETCHAR(1) == '>') {
660
char_idx += 2;
661
662
LocalVector<char32_t> incp;
663
while (GETCHAR(0) != '\n') {
664
incp.push_back(GETCHAR(0));
665
char_idx++;
666
}
667
incp.push_back(0); // Zero end it.
668
String include_path(incp.ptr());
669
include_positions.write[include_positions.size() - 1].line = tk_line;
670
671
String marker = ">>" + include_path;
672
if (!include_markers_handled.has(marker)) {
673
include_markers_handled.insert(marker);
674
675
FilePosition fp;
676
fp.file = include_path;
677
fp.line = 0;
678
tk_line = 0;
679
include_positions.push_back(fp);
680
}
681
682
} else if (GETCHAR(0) == '@' && GETCHAR(1) == '<') {
683
char_idx += 2;
684
685
LocalVector<char32_t> incp;
686
while (GETCHAR(0) != '\n') {
687
incp.push_back(GETCHAR(0));
688
char_idx++;
689
}
690
incp.push_back(0); // Zero end it.
691
String include_path(incp.ptr());
692
693
String marker = "<<" + include_path;
694
if (!include_markers_handled.has(marker)) {
695
include_markers_handled.insert(marker);
696
697
if (include_positions.size() == 1) {
698
return _make_token(TK_ERROR, "Invalid include exit hint @@< without matching enter hint.");
699
}
700
include_positions.resize(include_positions.size() - 1); // Pop back.
701
}
702
703
tk_line = include_positions[include_positions.size() - 1].line - 1; // Restore line.
704
705
} else {
706
return _make_token(TK_ERROR, "Invalid include enter/exit hint token (@@> and @@<)");
707
}
708
} break;
709
default: {
710
char_idx--; //go back one, since we have no idea what this is
711
712
if (is_digit(GETCHAR(0)) || (GETCHAR(0) == '.' && is_digit(GETCHAR(1)))) {
713
// parse number
714
bool hexa_found = false;
715
bool period_found = false;
716
bool exponent_found = false;
717
bool float_suffix_found = false;
718
bool uint_suffix_found = false;
719
bool end_suffix_found = false;
720
721
enum {
722
CASE_ALL,
723
CASE_HEXA_PERIOD,
724
CASE_EXPONENT,
725
CASE_SIGN_AFTER_EXPONENT,
726
CASE_NONE,
727
CASE_MAX,
728
} lut_case = CASE_ALL;
729
730
static bool suffix_lut[CASE_MAX][127];
731
732
if (!is_const_suffix_lut_initialized) {
733
is_const_suffix_lut_initialized = true;
734
735
for (int i = 0; i < 127; i++) {
736
char t = char(i);
737
738
suffix_lut[CASE_ALL][i] = t == '.' || t == 'x' || t == 'e' || t == 'f' || t == 'u' || t == '-' || t == '+';
739
suffix_lut[CASE_HEXA_PERIOD][i] = t == 'e' || t == 'f' || t == 'u';
740
suffix_lut[CASE_EXPONENT][i] = t == 'f' || t == '-' || t == '+';
741
suffix_lut[CASE_SIGN_AFTER_EXPONENT][i] = t == 'f';
742
suffix_lut[CASE_NONE][i] = false;
743
}
744
}
745
746
String str;
747
int i = 0;
748
bool digit_after_exp = false;
749
750
while (true) {
751
const char32_t symbol = String::char_lowercase(GETCHAR(i));
752
bool error = false;
753
754
if (is_digit(symbol)) {
755
if (exponent_found) {
756
digit_after_exp = true;
757
}
758
if (end_suffix_found) {
759
error = true;
760
}
761
} else {
762
if (symbol < 0x7F && suffix_lut[lut_case][symbol]) {
763
if (symbol == 'x') {
764
hexa_found = true;
765
lut_case = CASE_HEXA_PERIOD;
766
} else if (symbol == '.') {
767
period_found = true;
768
lut_case = CASE_HEXA_PERIOD;
769
} else if (symbol == 'e' && !hexa_found) {
770
exponent_found = true;
771
lut_case = CASE_EXPONENT;
772
} else if (symbol == 'f' && !hexa_found) {
773
if (!period_found && !exponent_found) {
774
error = true;
775
}
776
float_suffix_found = true;
777
end_suffix_found = true;
778
lut_case = CASE_NONE;
779
} else if (symbol == 'u') {
780
uint_suffix_found = true;
781
end_suffix_found = true;
782
lut_case = CASE_NONE;
783
} else if (symbol == '-' || symbol == '+') {
784
if (exponent_found) {
785
lut_case = CASE_SIGN_AFTER_EXPONENT;
786
} else {
787
break;
788
}
789
}
790
} else if (!hexa_found || !is_hex_digit(symbol)) {
791
if (is_ascii_identifier_char(symbol)) {
792
error = true;
793
} else {
794
break;
795
}
796
}
797
}
798
799
if (error) {
800
if (hexa_found) {
801
return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant");
802
}
803
if (period_found || exponent_found || float_suffix_found) {
804
return _make_token(TK_ERROR, "Invalid (float) numeric constant");
805
}
806
if (uint_suffix_found) {
807
return _make_token(TK_ERROR, "Invalid (unsigned integer) numeric constant");
808
}
809
return _make_token(TK_ERROR, "Invalid (integer) numeric constant");
810
}
811
str += symbol;
812
i++;
813
}
814
815
char32_t last_char = str[str.length() - 1];
816
817
if (hexa_found) { // Integer (hex).
818
if (uint_suffix_found) {
819
// Strip the suffix.
820
str = str.left(str.length() - 1);
821
822
// Compensate reading cursor position.
823
char_idx += 1;
824
}
825
if (str.size() > 11 || !str.is_valid_hex_number(true)) { // > 0xFFFFFFFF
826
return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant");
827
}
828
} else if (period_found || exponent_found || float_suffix_found) { // Float
829
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).
830
return _make_token(TK_ERROR, "Invalid (float) numeric constant");
831
}
832
if (period_found) {
833
if (float_suffix_found) {
834
//checks for eg "1.f" or "1.99f" notations
835
if (last_char != 'f') {
836
return _make_token(TK_ERROR, "Invalid (float) numeric constant");
837
}
838
} else {
839
//checks for eg. "1." or "1.99" notations
840
if (last_char != '.' && !is_digit(last_char)) {
841
return _make_token(TK_ERROR, "Invalid (float) numeric constant");
842
}
843
}
844
} else if (float_suffix_found) {
845
// if no period found the float suffix must be the last character, like in "2f" for "2.0"
846
if (last_char != 'f') {
847
return _make_token(TK_ERROR, "Invalid (float) numeric constant");
848
}
849
}
850
851
if (float_suffix_found) {
852
// Strip the suffix.
853
str = str.left(str.length() - 1);
854
// Compensate reading cursor position.
855
char_idx += 1;
856
}
857
858
if (!str.is_valid_float()) {
859
return _make_token(TK_ERROR, "Invalid (float) numeric constant");
860
}
861
} else { // Integer
862
if (uint_suffix_found) {
863
// Strip the suffix.
864
str = str.left(str.length() - 1);
865
// Compensate reading cursor position.
866
char_idx += 1;
867
}
868
if (!str.is_valid_int()) {
869
if (uint_suffix_found) {
870
return _make_token(TK_ERROR, "Invalid (unsigned integer) numeric constant");
871
} else {
872
return _make_token(TK_ERROR, "Invalid (integer) numeric constant");
873
}
874
}
875
}
876
877
char_idx += str.length();
878
Token tk;
879
if (period_found || exponent_found || float_suffix_found) {
880
tk.type = TK_FLOAT_CONSTANT;
881
} else if (uint_suffix_found) {
882
tk.type = TK_UINT_CONSTANT;
883
} else {
884
tk.type = TK_INT_CONSTANT;
885
}
886
887
if (hexa_found) {
888
tk.constant = (double)str.hex_to_int();
889
} else {
890
tk.constant = str.to_float();
891
}
892
tk.line = tk_line;
893
894
return tk;
895
}
896
897
if (GETCHAR(0) == '.') {
898
//parse period
899
char_idx++;
900
return _make_token(TK_PERIOD);
901
}
902
903
if (is_ascii_identifier_char(GETCHAR(0))) {
904
// parse identifier
905
String str;
906
907
while (is_ascii_identifier_char(GETCHAR(0))) {
908
str += char32_t(GETCHAR(0));
909
char_idx++;
910
}
911
912
//see if keyword
913
//should be converted to a static map
914
int idx = 0;
915
916
while (keyword_list[idx].text) {
917
if (str == keyword_list[idx].text) {
918
return _make_token(keyword_list[idx].token);
919
}
920
idx++;
921
}
922
923
str = str.replace("dus_", "_");
924
925
return _make_token(TK_IDENTIFIER, str);
926
}
927
928
if (GETCHAR(0) > 32) {
929
return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)) + ": '" + String::chr(GETCHAR(0)) + "'");
930
} else {
931
return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)));
932
}
933
934
} break;
935
}
936
}
937
ERR_PRINT("BUG");
938
return Token();
939
940
#undef GETCHAR
941
}
942
943
bool ShaderLanguage::_lookup_next(Token &r_tk) {
944
TkPos pre_pos = _get_tkpos();
945
int line = pre_pos.tk_line;
946
_get_token();
947
Token tk = _get_token();
948
_set_tkpos(pre_pos);
949
if (tk.line == line) {
950
r_tk = tk;
951
return true;
952
}
953
return false;
954
}
955
956
ShaderLanguage::Token ShaderLanguage::_peek() {
957
TkPos pre_pos = _get_tkpos();
958
Token tk = _get_token();
959
_set_tkpos(pre_pos);
960
return tk;
961
}
962
963
String ShaderLanguage::token_debug(const String &p_code) {
964
clear();
965
966
code = p_code;
967
968
String output;
969
970
Token tk = _get_token();
971
while (tk.type != TK_EOF && tk.type != TK_ERROR) {
972
output += itos(tk_line) + ": " + get_token_text(tk) + "\n";
973
tk = _get_token();
974
}
975
976
return output;
977
}
978
979
bool ShaderLanguage::is_token_variable_datatype(TokenType p_type) {
980
return (
981
p_type == TK_TYPE_VOID ||
982
p_type == TK_TYPE_BOOL ||
983
p_type == TK_TYPE_BVEC2 ||
984
p_type == TK_TYPE_BVEC3 ||
985
p_type == TK_TYPE_BVEC4 ||
986
p_type == TK_TYPE_INT ||
987
p_type == TK_TYPE_IVEC2 ||
988
p_type == TK_TYPE_IVEC3 ||
989
p_type == TK_TYPE_IVEC4 ||
990
p_type == TK_TYPE_UINT ||
991
p_type == TK_TYPE_UVEC2 ||
992
p_type == TK_TYPE_UVEC3 ||
993
p_type == TK_TYPE_UVEC4 ||
994
p_type == TK_TYPE_FLOAT ||
995
p_type == TK_TYPE_VEC2 ||
996
p_type == TK_TYPE_VEC3 ||
997
p_type == TK_TYPE_VEC4 ||
998
p_type == TK_TYPE_MAT2 ||
999
p_type == TK_TYPE_MAT3 ||
1000
p_type == TK_TYPE_MAT4);
1001
}
1002
1003
bool ShaderLanguage::is_token_datatype(TokenType p_type) {
1004
return (
1005
p_type == TK_TYPE_VOID ||
1006
p_type == TK_TYPE_BOOL ||
1007
p_type == TK_TYPE_BVEC2 ||
1008
p_type == TK_TYPE_BVEC3 ||
1009
p_type == TK_TYPE_BVEC4 ||
1010
p_type == TK_TYPE_INT ||
1011
p_type == TK_TYPE_IVEC2 ||
1012
p_type == TK_TYPE_IVEC3 ||
1013
p_type == TK_TYPE_IVEC4 ||
1014
p_type == TK_TYPE_UINT ||
1015
p_type == TK_TYPE_UVEC2 ||
1016
p_type == TK_TYPE_UVEC3 ||
1017
p_type == TK_TYPE_UVEC4 ||
1018
p_type == TK_TYPE_FLOAT ||
1019
p_type == TK_TYPE_VEC2 ||
1020
p_type == TK_TYPE_VEC3 ||
1021
p_type == TK_TYPE_VEC4 ||
1022
p_type == TK_TYPE_MAT2 ||
1023
p_type == TK_TYPE_MAT3 ||
1024
p_type == TK_TYPE_MAT4 ||
1025
p_type == TK_TYPE_SAMPLER2D ||
1026
p_type == TK_TYPE_ISAMPLER2D ||
1027
p_type == TK_TYPE_USAMPLER2D ||
1028
p_type == TK_TYPE_SAMPLER2DARRAY ||
1029
p_type == TK_TYPE_ISAMPLER2DARRAY ||
1030
p_type == TK_TYPE_USAMPLER2DARRAY ||
1031
p_type == TK_TYPE_SAMPLER3D ||
1032
p_type == TK_TYPE_ISAMPLER3D ||
1033
p_type == TK_TYPE_USAMPLER3D ||
1034
p_type == TK_TYPE_SAMPLERCUBE ||
1035
p_type == TK_TYPE_SAMPLERCUBEARRAY ||
1036
p_type == TK_TYPE_SAMPLEREXT);
1037
}
1038
1039
ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) {
1040
return DataType(p_type - TK_TYPE_VOID);
1041
}
1042
1043
bool ShaderLanguage::is_token_interpolation(TokenType p_type) {
1044
return (
1045
p_type == TK_INTERPOLATION_FLAT ||
1046
p_type == TK_INTERPOLATION_SMOOTH);
1047
}
1048
1049
ShaderLanguage::DataInterpolation ShaderLanguage::get_token_interpolation(TokenType p_type) {
1050
if (p_type == TK_INTERPOLATION_FLAT) {
1051
return INTERPOLATION_FLAT;
1052
} else {
1053
return INTERPOLATION_SMOOTH;
1054
}
1055
}
1056
1057
bool ShaderLanguage::is_token_precision(TokenType p_type) {
1058
return (
1059
p_type == TK_PRECISION_LOW ||
1060
p_type == TK_PRECISION_MID ||
1061
p_type == TK_PRECISION_HIGH);
1062
}
1063
1064
bool ShaderLanguage::is_token_arg_qual(TokenType p_type) {
1065
return (
1066
p_type == TK_ARG_IN ||
1067
p_type == TK_ARG_OUT ||
1068
p_type == TK_ARG_INOUT);
1069
}
1070
1071
ShaderLanguage::DataPrecision ShaderLanguage::get_token_precision(TokenType p_type) {
1072
if (p_type == TK_PRECISION_LOW) {
1073
return PRECISION_LOWP;
1074
} else if (p_type == TK_PRECISION_HIGH) {
1075
return PRECISION_HIGHP;
1076
} else {
1077
return PRECISION_MEDIUMP;
1078
}
1079
}
1080
1081
String ShaderLanguage::get_precision_name(DataPrecision p_type) {
1082
switch (p_type) {
1083
case PRECISION_LOWP:
1084
return "lowp";
1085
case PRECISION_MEDIUMP:
1086
return "mediump";
1087
case PRECISION_HIGHP:
1088
return "highp";
1089
default:
1090
break;
1091
}
1092
return "";
1093
}
1094
1095
String ShaderLanguage::get_interpolation_name(DataInterpolation p_interpolation) {
1096
switch (p_interpolation) {
1097
case INTERPOLATION_FLAT:
1098
return "flat";
1099
case INTERPOLATION_SMOOTH:
1100
return "smooth";
1101
default:
1102
break;
1103
}
1104
return "";
1105
}
1106
1107
String ShaderLanguage::get_datatype_name(DataType p_type) {
1108
switch (p_type) {
1109
case TYPE_VOID:
1110
return "void";
1111
case TYPE_BOOL:
1112
return "bool";
1113
case TYPE_BVEC2:
1114
return "bvec2";
1115
case TYPE_BVEC3:
1116
return "bvec3";
1117
case TYPE_BVEC4:
1118
return "bvec4";
1119
case TYPE_INT:
1120
return "int";
1121
case TYPE_IVEC2:
1122
return "ivec2";
1123
case TYPE_IVEC3:
1124
return "ivec3";
1125
case TYPE_IVEC4:
1126
return "ivec4";
1127
case TYPE_UINT:
1128
return "uint";
1129
case TYPE_UVEC2:
1130
return "uvec2";
1131
case TYPE_UVEC3:
1132
return "uvec3";
1133
case TYPE_UVEC4:
1134
return "uvec4";
1135
case TYPE_FLOAT:
1136
return "float";
1137
case TYPE_VEC2:
1138
return "vec2";
1139
case TYPE_VEC3:
1140
return "vec3";
1141
case TYPE_VEC4:
1142
return "vec4";
1143
case TYPE_MAT2:
1144
return "mat2";
1145
case TYPE_MAT3:
1146
return "mat3";
1147
case TYPE_MAT4:
1148
return "mat4";
1149
case TYPE_SAMPLER2D:
1150
return "sampler2D";
1151
case TYPE_ISAMPLER2D:
1152
return "isampler2D";
1153
case TYPE_USAMPLER2D:
1154
return "usampler2D";
1155
case TYPE_SAMPLER2DARRAY:
1156
return "sampler2DArray";
1157
case TYPE_ISAMPLER2DARRAY:
1158
return "isampler2DArray";
1159
case TYPE_USAMPLER2DARRAY:
1160
return "usampler2DArray";
1161
case TYPE_SAMPLER3D:
1162
return "sampler3D";
1163
case TYPE_ISAMPLER3D:
1164
return "isampler3D";
1165
case TYPE_USAMPLER3D:
1166
return "usampler3D";
1167
case TYPE_SAMPLERCUBE:
1168
return "samplerCube";
1169
case TYPE_SAMPLERCUBEARRAY:
1170
return "samplerCubeArray";
1171
case TYPE_SAMPLEREXT:
1172
return "samplerExternalOES";
1173
case TYPE_STRUCT:
1174
return "struct";
1175
case TYPE_MAX:
1176
return "invalid";
1177
}
1178
1179
return "";
1180
}
1181
1182
String ShaderLanguage::get_uniform_hint_name(ShaderNode::Uniform::Hint p_hint) {
1183
String result;
1184
switch (p_hint) {
1185
case ShaderNode::Uniform::HINT_RANGE: {
1186
result = "hint_range";
1187
} break;
1188
case ShaderNode::Uniform::HINT_ENUM: {
1189
result = "hint_enum";
1190
} break;
1191
case ShaderNode::Uniform::HINT_SOURCE_COLOR: {
1192
result = "source_color";
1193
} break;
1194
case ShaderNode::Uniform::HINT_COLOR_CONVERSION_DISABLED: {
1195
result = "color_conversion_disabled";
1196
} break;
1197
case ShaderNode::Uniform::HINT_NORMAL: {
1198
result = "hint_normal";
1199
} break;
1200
case ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL: {
1201
result = "hint_roughness_normal";
1202
} break;
1203
case ShaderNode::Uniform::HINT_ROUGHNESS_R: {
1204
result = "hint_roughness_r";
1205
} break;
1206
case ShaderNode::Uniform::HINT_ROUGHNESS_G: {
1207
result = "hint_roughness_g";
1208
} break;
1209
case ShaderNode::Uniform::HINT_ROUGHNESS_B: {
1210
result = "hint_roughness_b";
1211
} break;
1212
case ShaderNode::Uniform::HINT_ROUGHNESS_A: {
1213
result = "hint_roughness_a";
1214
} break;
1215
case ShaderNode::Uniform::HINT_ROUGHNESS_GRAY: {
1216
result = "hint_roughness_gray";
1217
} break;
1218
case ShaderNode::Uniform::HINT_DEFAULT_BLACK: {
1219
result = "hint_default_black";
1220
} break;
1221
case ShaderNode::Uniform::HINT_DEFAULT_WHITE: {
1222
result = "hint_default_white";
1223
} break;
1224
case ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT: {
1225
result = "hint_default_transparent";
1226
} break;
1227
case ShaderNode::Uniform::HINT_ANISOTROPY: {
1228
result = "hint_anisotropy";
1229
} break;
1230
case ShaderNode::Uniform::HINT_SCREEN_TEXTURE: {
1231
result = "hint_screen_texture";
1232
} break;
1233
case ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE: {
1234
result = "hint_normal_roughness_texture";
1235
} break;
1236
case ShaderNode::Uniform::HINT_DEPTH_TEXTURE: {
1237
result = "hint_depth_texture";
1238
} break;
1239
default:
1240
break;
1241
}
1242
return result;
1243
}
1244
1245
String ShaderLanguage::get_texture_filter_name(TextureFilter p_filter) {
1246
String result;
1247
switch (p_filter) {
1248
case FILTER_NEAREST: {
1249
result = "filter_nearest";
1250
} break;
1251
case FILTER_LINEAR: {
1252
result = "filter_linear";
1253
} break;
1254
case FILTER_NEAREST_MIPMAP: {
1255
result = "filter_nearest_mipmap";
1256
} break;
1257
case FILTER_LINEAR_MIPMAP: {
1258
result = "filter_linear_mipmap";
1259
} break;
1260
case FILTER_NEAREST_MIPMAP_ANISOTROPIC: {
1261
result = "filter_nearest_mipmap_anisotropic";
1262
} break;
1263
case FILTER_LINEAR_MIPMAP_ANISOTROPIC: {
1264
result = "filter_linear_mipmap_anisotropic";
1265
} break;
1266
default: {
1267
} break;
1268
}
1269
return result;
1270
}
1271
1272
String ShaderLanguage::get_texture_repeat_name(TextureRepeat p_repeat) {
1273
String result;
1274
switch (p_repeat) {
1275
case REPEAT_DISABLE: {
1276
result = "repeat_disable";
1277
} break;
1278
case REPEAT_ENABLE: {
1279
result = "repeat_enable";
1280
} break;
1281
default: {
1282
} break;
1283
}
1284
return result;
1285
}
1286
1287
bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) {
1288
return is_token_datatype(p_type) && p_type != TK_TYPE_VOID;
1289
}
1290
1291
void ShaderLanguage::clear() {
1292
current_function = StringName();
1293
last_name = StringName();
1294
last_type = IDENTIFIER_MAX;
1295
current_uniform_group_name = "";
1296
current_uniform_subgroup_name = "";
1297
current_uniform_hint = ShaderNode::Uniform::HINT_NONE;
1298
current_uniform_filter = FILTER_DEFAULT;
1299
current_uniform_repeat = REPEAT_DEFAULT;
1300
current_uniform_instance_index_defined = false;
1301
1302
completion_type = COMPLETION_NONE;
1303
completion_block = nullptr;
1304
completion_function = StringName();
1305
completion_class = TAG_GLOBAL;
1306
completion_struct = StringName();
1307
completion_base = TYPE_VOID;
1308
completion_base_array = false;
1309
1310
include_positions.clear();
1311
include_positions.push_back(FilePosition());
1312
1313
include_markers_handled.clear();
1314
calls_info.clear();
1315
function_overload_count.clear();
1316
1317
#ifdef DEBUG_ENABLED
1318
keyword_completion_context = CF_UNSPECIFIED;
1319
used_constants.clear();
1320
used_varyings.clear();
1321
used_uniforms.clear();
1322
used_functions.clear();
1323
used_structs.clear();
1324
used_local_vars.clear();
1325
warnings.clear();
1326
#endif // DEBUG_ENABLED
1327
1328
error_line = 0;
1329
tk_line = 1;
1330
char_idx = 0;
1331
error_set = false;
1332
error_str = "";
1333
is_const_decl = false;
1334
while (nodes) {
1335
Node *n = nodes;
1336
nodes = nodes->next;
1337
memdelete(n);
1338
}
1339
}
1340
1341
#ifdef DEBUG_ENABLED
1342
void ShaderLanguage::_parse_used_identifier(const StringName &p_identifier, IdentifierType p_type, const StringName &p_function) {
1343
switch (p_type) {
1344
case IdentifierType::IDENTIFIER_CONSTANT:
1345
if (HAS_WARNING(ShaderWarning::UNUSED_CONSTANT_FLAG) && used_constants.has(p_identifier)) {
1346
used_constants[p_identifier].used = true;
1347
}
1348
break;
1349
case IdentifierType::IDENTIFIER_VARYING:
1350
if (HAS_WARNING(ShaderWarning::UNUSED_VARYING_FLAG) && used_varyings.has(p_identifier)) {
1351
if (shader->varyings[p_identifier].stage == ShaderNode::Varying::STAGE_UNKNOWN) {
1352
used_varyings[p_identifier].used = true;
1353
}
1354
}
1355
break;
1356
case IdentifierType::IDENTIFIER_UNIFORM:
1357
if (HAS_WARNING(ShaderWarning::UNUSED_UNIFORM_FLAG) && used_uniforms.has(p_identifier)) {
1358
used_uniforms[p_identifier].used = true;
1359
}
1360
break;
1361
case IdentifierType::IDENTIFIER_FUNCTION:
1362
if (HAS_WARNING(ShaderWarning::UNUSED_FUNCTION_FLAG) && used_functions.has(p_identifier)) {
1363
used_functions[p_identifier].used = true;
1364
}
1365
break;
1366
case IdentifierType::IDENTIFIER_LOCAL_VAR:
1367
if (HAS_WARNING(ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG) && used_local_vars.has(p_function) && used_local_vars[p_function].has(p_identifier)) {
1368
used_local_vars[p_function][p_identifier].used = true;
1369
}
1370
break;
1371
default:
1372
break;
1373
}
1374
}
1375
#endif // DEBUG_ENABLED
1376
1377
bool 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, Vector<Scalar> *r_constant_values) {
1378
if (is_shader_inc) {
1379
for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
1380
for (const KeyValue<StringName, FunctionInfo> &E : ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i))) {
1381
if ((current_function == E.key || E.key == "global" || E.key == "constants") && E.value.built_ins.has(p_identifier)) {
1382
if (r_data_type) {
1383
*r_data_type = E.value.built_ins[p_identifier].type;
1384
}
1385
if (r_is_const) {
1386
*r_is_const = E.value.built_ins[p_identifier].constant;
1387
}
1388
if (r_type) {
1389
*r_type = IDENTIFIER_BUILTIN_VAR;
1390
}
1391
return true;
1392
}
1393
}
1394
}
1395
} else {
1396
if (p_function_info.built_ins.has(p_identifier)) {
1397
if (r_data_type) {
1398
*r_data_type = p_function_info.built_ins[p_identifier].type;
1399
}
1400
if (r_is_const) {
1401
*r_is_const = p_function_info.built_ins[p_identifier].constant;
1402
}
1403
if (r_constant_values) {
1404
*r_constant_values = p_function_info.built_ins[p_identifier].values;
1405
}
1406
if (r_type) {
1407
*r_type = IDENTIFIER_BUILTIN_VAR;
1408
}
1409
return true;
1410
}
1411
}
1412
1413
if (p_function_info.stage_functions.has(p_identifier)) {
1414
if (r_data_type) {
1415
*r_data_type = p_function_info.stage_functions[p_identifier].return_type;
1416
}
1417
if (r_is_const) {
1418
*r_is_const = true;
1419
}
1420
if (r_type) {
1421
*r_type = IDENTIFIER_FUNCTION;
1422
}
1423
return true;
1424
}
1425
1426
FunctionNode *function = nullptr;
1427
1428
while (p_block) {
1429
if (p_block->variables.has(p_identifier)) {
1430
if (r_data_type) {
1431
*r_data_type = p_block->variables[p_identifier].type;
1432
}
1433
if (r_is_const) {
1434
*r_is_const = p_block->variables[p_identifier].is_const;
1435
}
1436
if (r_array_size) {
1437
*r_array_size = p_block->variables[p_identifier].array_size;
1438
}
1439
if (r_struct_name) {
1440
*r_struct_name = p_block->variables[p_identifier].struct_name;
1441
}
1442
if (r_constant_values && !p_block->variables[p_identifier].values.is_empty()) {
1443
*r_constant_values = p_block->variables[p_identifier].values;
1444
}
1445
if (r_type) {
1446
*r_type = IDENTIFIER_LOCAL_VAR;
1447
}
1448
return true;
1449
}
1450
1451
if (p_block->parent_function) {
1452
function = p_block->parent_function;
1453
break;
1454
} else {
1455
if (p_allow_reassign) {
1456
break;
1457
}
1458
ERR_FAIL_NULL_V(p_block->parent_block, false);
1459
p_block = p_block->parent_block;
1460
}
1461
}
1462
1463
if (function) {
1464
for (int i = 0; i < function->arguments.size(); i++) {
1465
if (function->arguments[i].name == p_identifier) {
1466
if (r_data_type) {
1467
*r_data_type = function->arguments[i].type;
1468
}
1469
if (r_struct_name) {
1470
*r_struct_name = function->arguments[i].struct_name;
1471
}
1472
if (r_array_size) {
1473
*r_array_size = function->arguments[i].array_size;
1474
}
1475
if (r_is_const) {
1476
*r_is_const = function->arguments[i].is_const;
1477
}
1478
if (r_type) {
1479
*r_type = IDENTIFIER_FUNCTION_ARGUMENT;
1480
}
1481
return true;
1482
}
1483
}
1484
}
1485
1486
if (shader->varyings.has(p_identifier)) {
1487
if (r_data_type) {
1488
*r_data_type = shader->varyings[p_identifier].type;
1489
}
1490
if (r_array_size) {
1491
*r_array_size = shader->varyings[p_identifier].array_size;
1492
}
1493
if (r_type) {
1494
*r_type = IDENTIFIER_VARYING;
1495
}
1496
return true;
1497
}
1498
1499
if (shader->uniforms.has(p_identifier)) {
1500
if (r_data_type) {
1501
*r_data_type = shader->uniforms[p_identifier].type;
1502
}
1503
if (r_array_size) {
1504
*r_array_size = shader->uniforms[p_identifier].array_size;
1505
}
1506
if (r_type) {
1507
*r_type = IDENTIFIER_UNIFORM;
1508
}
1509
return true;
1510
}
1511
1512
if (shader->constants.has(p_identifier)) {
1513
if (r_is_const) {
1514
*r_is_const = true;
1515
}
1516
if (r_data_type) {
1517
*r_data_type = shader->constants[p_identifier].type;
1518
}
1519
if (r_array_size) {
1520
*r_array_size = shader->constants[p_identifier].array_size;
1521
}
1522
if (r_struct_name) {
1523
*r_struct_name = shader->constants[p_identifier].struct_name;
1524
}
1525
if (r_constant_values) {
1526
if (shader->constants[p_identifier].initializer && !shader->constants[p_identifier].initializer->get_values().is_empty()) {
1527
*r_constant_values = shader->constants[p_identifier].initializer->get_values();
1528
}
1529
}
1530
if (r_type) {
1531
*r_type = IDENTIFIER_CONSTANT;
1532
}
1533
return true;
1534
}
1535
1536
for (int i = 0; i < shader->vfunctions.size(); i++) {
1537
if (!shader->vfunctions[i].callable) {
1538
continue;
1539
}
1540
1541
if (shader->vfunctions[i].name == p_identifier) {
1542
if (r_data_type) {
1543
*r_data_type = shader->vfunctions[i].function->return_type;
1544
}
1545
if (r_array_size) {
1546
*r_array_size = shader->vfunctions[i].function->return_array_size;
1547
}
1548
if (r_type) {
1549
*r_type = IDENTIFIER_FUNCTION;
1550
}
1551
return true;
1552
}
1553
}
1554
1555
return false;
1556
}
1557
1558
bool ShaderLanguage::_validate_operator(const BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_op, DataType *r_ret_type, int *r_ret_size) {
1559
bool valid = false;
1560
DataType ret_type = TYPE_VOID;
1561
int ret_size = 0;
1562
1563
switch (p_op->op) {
1564
case OP_EQUAL:
1565
case OP_NOT_EQUAL: {
1566
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)) {
1567
break; // don't accept arrays
1568
}
1569
1570
DataType na = p_op->arguments[0]->get_datatype();
1571
DataType nb = p_op->arguments[1]->get_datatype();
1572
valid = na == nb;
1573
ret_type = TYPE_BOOL;
1574
} break;
1575
case OP_LESS:
1576
case OP_LESS_EQUAL:
1577
case OP_GREATER:
1578
case OP_GREATER_EQUAL: {
1579
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)) {
1580
break; // don't accept arrays
1581
}
1582
1583
DataType na = p_op->arguments[0]->get_datatype();
1584
DataType nb = p_op->arguments[1]->get_datatype();
1585
1586
valid = na == nb && (na == TYPE_UINT || na == TYPE_INT || na == TYPE_FLOAT);
1587
ret_type = TYPE_BOOL;
1588
1589
} break;
1590
case OP_AND:
1591
case OP_OR: {
1592
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)) {
1593
break; // don't accept arrays
1594
}
1595
1596
DataType na = p_op->arguments[0]->get_datatype();
1597
DataType nb = p_op->arguments[1]->get_datatype();
1598
1599
valid = na == nb && na == TYPE_BOOL;
1600
ret_type = TYPE_BOOL;
1601
1602
} break;
1603
case OP_NOT: {
1604
if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) {
1605
break; // don't accept arrays
1606
}
1607
1608
DataType na = p_op->arguments[0]->get_datatype();
1609
valid = na == TYPE_BOOL;
1610
ret_type = TYPE_BOOL;
1611
1612
} break;
1613
case OP_INCREMENT:
1614
case OP_DECREMENT:
1615
case OP_POST_INCREMENT:
1616
case OP_POST_DECREMENT:
1617
case OP_NEGATE: {
1618
if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) {
1619
break; // don't accept arrays
1620
}
1621
1622
DataType na = p_op->arguments[0]->get_datatype();
1623
valid = na > TYPE_BVEC4 && na < TYPE_MAT2;
1624
ret_type = na;
1625
} break;
1626
case OP_ADD:
1627
case OP_SUB:
1628
case OP_MUL:
1629
case OP_DIV: {
1630
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)) {
1631
break; // don't accept arrays
1632
}
1633
1634
DataType na = p_op->arguments[0]->get_datatype();
1635
DataType nb = p_op->arguments[1]->get_datatype();
1636
1637
if (na > nb) {
1638
//make things easier;
1639
SWAP(na, nb);
1640
}
1641
1642
if (na == nb) {
1643
valid = (na > TYPE_BVEC4 && na <= TYPE_MAT4);
1644
ret_type = na;
1645
} else if (na == TYPE_INT && nb == TYPE_IVEC2) {
1646
valid = true;
1647
ret_type = TYPE_IVEC2;
1648
} else if (na == TYPE_INT && nb == TYPE_IVEC3) {
1649
valid = true;
1650
ret_type = TYPE_IVEC3;
1651
} else if (na == TYPE_INT && nb == TYPE_IVEC4) {
1652
valid = true;
1653
ret_type = TYPE_IVEC4;
1654
} else if (na == TYPE_UINT && nb == TYPE_UVEC2) {
1655
valid = true;
1656
ret_type = TYPE_UVEC2;
1657
} else if (na == TYPE_UINT && nb == TYPE_UVEC3) {
1658
valid = true;
1659
ret_type = TYPE_UVEC3;
1660
} else if (na == TYPE_UINT && nb == TYPE_UVEC4) {
1661
valid = true;
1662
ret_type = TYPE_UVEC4;
1663
} else if (na == TYPE_FLOAT && nb == TYPE_VEC2) {
1664
valid = true;
1665
ret_type = TYPE_VEC2;
1666
} else if (na == TYPE_FLOAT && nb == TYPE_VEC3) {
1667
valid = true;
1668
ret_type = TYPE_VEC3;
1669
} else if (na == TYPE_FLOAT && nb == TYPE_VEC4) {
1670
valid = true;
1671
ret_type = TYPE_VEC4;
1672
} else if (na == TYPE_FLOAT && nb == TYPE_MAT2) {
1673
valid = true;
1674
ret_type = TYPE_MAT2;
1675
} else if (na == TYPE_FLOAT && nb == TYPE_MAT3) {
1676
valid = true;
1677
ret_type = TYPE_MAT3;
1678
} else if (na == TYPE_FLOAT && nb == TYPE_MAT4) {
1679
valid = true;
1680
ret_type = TYPE_MAT4;
1681
} else if (p_op->op == OP_MUL && na == TYPE_VEC2 && nb == TYPE_MAT2) {
1682
valid = true;
1683
ret_type = TYPE_VEC2;
1684
} else if (p_op->op == OP_MUL && na == TYPE_VEC3 && nb == TYPE_MAT3) {
1685
valid = true;
1686
ret_type = TYPE_VEC3;
1687
} else if (p_op->op == OP_MUL && na == TYPE_VEC4 && nb == TYPE_MAT4) {
1688
valid = true;
1689
ret_type = TYPE_VEC4;
1690
}
1691
} break;
1692
case OP_ASSIGN_MOD:
1693
case OP_MOD: {
1694
/*
1695
* The operator modulus (%) operates on signed or unsigned integers or integer vectors. The operand
1696
* types must both be signed or both be unsigned. The operands cannot be vectors of differing size. If
1697
* one operand is a scalar and the other vector, then the scalar is applied component-wise to the vector,
1698
* resulting in the same type as the vector. If both are vectors of the same size, the result is computed
1699
* component-wise.
1700
*/
1701
1702
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)) {
1703
break; // don't accept arrays
1704
}
1705
1706
DataType na = p_op->arguments[0]->get_datatype();
1707
DataType nb = p_op->arguments[1]->get_datatype();
1708
1709
if (na == TYPE_INT && nb == TYPE_INT) {
1710
valid = true;
1711
ret_type = TYPE_INT;
1712
} else if (na == TYPE_IVEC2 && nb == TYPE_INT) {
1713
valid = true;
1714
ret_type = TYPE_IVEC2;
1715
} else if (na == TYPE_IVEC3 && nb == TYPE_INT) {
1716
valid = true;
1717
ret_type = TYPE_IVEC3;
1718
} else if (na == TYPE_IVEC4 && nb == TYPE_INT) {
1719
valid = true;
1720
ret_type = TYPE_IVEC4;
1721
} else if (na == TYPE_IVEC2 && nb == TYPE_IVEC2) {
1722
valid = true;
1723
ret_type = TYPE_IVEC2;
1724
} else if (na == TYPE_IVEC3 && nb == TYPE_IVEC3) {
1725
valid = true;
1726
ret_type = TYPE_IVEC3;
1727
} else if (na == TYPE_IVEC4 && nb == TYPE_IVEC4) {
1728
valid = true;
1729
ret_type = TYPE_IVEC4;
1730
/////
1731
} else if (na == TYPE_UINT && nb == TYPE_UINT) {
1732
valid = true;
1733
ret_type = TYPE_UINT;
1734
} else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
1735
valid = true;
1736
ret_type = TYPE_UVEC2;
1737
} else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
1738
valid = true;
1739
ret_type = TYPE_UVEC3;
1740
} else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
1741
valid = true;
1742
ret_type = TYPE_UVEC4;
1743
} else if (na == TYPE_UVEC2 && nb == TYPE_UVEC2) {
1744
valid = true;
1745
ret_type = TYPE_UVEC2;
1746
} else if (na == TYPE_UVEC3 && nb == TYPE_UVEC3) {
1747
valid = true;
1748
ret_type = TYPE_UVEC3;
1749
} else if (na == TYPE_UVEC4 && nb == TYPE_UVEC4) {
1750
valid = true;
1751
ret_type = TYPE_UVEC4;
1752
}
1753
} break;
1754
case OP_ASSIGN_SHIFT_LEFT:
1755
case OP_ASSIGN_SHIFT_RIGHT:
1756
case OP_SHIFT_LEFT:
1757
case OP_SHIFT_RIGHT: {
1758
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)) {
1759
break; // don't accept arrays
1760
}
1761
1762
DataType na = p_op->arguments[0]->get_datatype();
1763
DataType nb = p_op->arguments[1]->get_datatype();
1764
1765
if (na == TYPE_INT && nb == TYPE_INT) {
1766
valid = true;
1767
ret_type = TYPE_INT;
1768
} else if (na == TYPE_IVEC2 && nb == TYPE_INT) {
1769
valid = true;
1770
ret_type = TYPE_IVEC2;
1771
} else if (na == TYPE_IVEC3 && nb == TYPE_INT) {
1772
valid = true;
1773
ret_type = TYPE_IVEC3;
1774
} else if (na == TYPE_IVEC4 && nb == TYPE_INT) {
1775
valid = true;
1776
ret_type = TYPE_IVEC4;
1777
} else if (na == TYPE_IVEC2 && nb == TYPE_IVEC2) {
1778
valid = true;
1779
ret_type = TYPE_IVEC2;
1780
} else if (na == TYPE_IVEC3 && nb == TYPE_IVEC3) {
1781
valid = true;
1782
ret_type = TYPE_IVEC3;
1783
} else if (na == TYPE_IVEC4 && nb == TYPE_IVEC4) {
1784
valid = true;
1785
ret_type = TYPE_IVEC4;
1786
} else if (na == TYPE_UINT && nb == TYPE_UINT) {
1787
valid = true;
1788
ret_type = TYPE_UINT;
1789
} else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
1790
valid = true;
1791
ret_type = TYPE_UVEC2;
1792
} else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
1793
valid = true;
1794
ret_type = TYPE_UVEC3;
1795
} else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
1796
valid = true;
1797
ret_type = TYPE_UVEC4;
1798
} else if (na == TYPE_UVEC2 && nb == TYPE_UVEC2) {
1799
valid = true;
1800
ret_type = TYPE_UVEC2;
1801
} else if (na == TYPE_UVEC3 && nb == TYPE_UVEC3) {
1802
valid = true;
1803
ret_type = TYPE_UVEC3;
1804
} else if (na == TYPE_UVEC4 && nb == TYPE_UVEC4) {
1805
valid = true;
1806
ret_type = TYPE_UVEC4;
1807
}
1808
} break;
1809
case OP_ASSIGN: {
1810
int sa = 0;
1811
int sb = 0;
1812
if (!p_op->arguments[0]->is_indexed()) {
1813
sa = p_op->arguments[0]->get_array_size();
1814
}
1815
if (!p_op->arguments[1]->is_indexed()) {
1816
sb = p_op->arguments[1]->get_array_size();
1817
}
1818
if (sa != sb) {
1819
break; // don't accept arrays if their sizes are not equal
1820
}
1821
1822
DataType na = p_op->arguments[0]->get_datatype();
1823
DataType nb = p_op->arguments[1]->get_datatype();
1824
if (na == TYPE_STRUCT || nb == TYPE_STRUCT) {
1825
valid = p_op->arguments[0]->get_datatype_name() == p_op->arguments[1]->get_datatype_name();
1826
} else {
1827
valid = na == nb;
1828
}
1829
ret_type = na;
1830
ret_size = sa;
1831
} break;
1832
case OP_ASSIGN_ADD:
1833
case OP_ASSIGN_SUB:
1834
case OP_ASSIGN_MUL:
1835
case OP_ASSIGN_DIV: {
1836
int sa = 0;
1837
int sb = 0;
1838
if (!p_op->arguments[0]->is_indexed()) {
1839
sa = p_op->arguments[0]->get_array_size();
1840
}
1841
if (!p_op->arguments[1]->is_indexed()) {
1842
sb = p_op->arguments[1]->get_array_size();
1843
}
1844
if (sa > 0 || sb > 0) {
1845
break; // don't accept arrays
1846
}
1847
1848
DataType na = p_op->arguments[0]->get_datatype();
1849
DataType nb = p_op->arguments[1]->get_datatype();
1850
1851
if (na == nb) {
1852
valid = (na > TYPE_BVEC4 && na <= TYPE_MAT4);
1853
ret_type = na;
1854
} else if (na == TYPE_IVEC2 && nb == TYPE_INT) {
1855
valid = true;
1856
ret_type = TYPE_IVEC2;
1857
} else if (na == TYPE_IVEC3 && nb == TYPE_INT) {
1858
valid = true;
1859
ret_type = TYPE_IVEC3;
1860
} else if (na == TYPE_IVEC4 && nb == TYPE_INT) {
1861
valid = true;
1862
ret_type = TYPE_IVEC4;
1863
} else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
1864
valid = true;
1865
ret_type = TYPE_UVEC2;
1866
} else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
1867
valid = true;
1868
ret_type = TYPE_UVEC3;
1869
} else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
1870
valid = true;
1871
ret_type = TYPE_UVEC4;
1872
} else if (na == TYPE_VEC2 && nb == TYPE_FLOAT) {
1873
valid = true;
1874
ret_type = TYPE_VEC2;
1875
} else if (na == TYPE_VEC3 && nb == TYPE_FLOAT) {
1876
valid = true;
1877
ret_type = TYPE_VEC3;
1878
} else if (na == TYPE_VEC4 && nb == TYPE_FLOAT) {
1879
valid = true;
1880
ret_type = TYPE_VEC4;
1881
} else if (na == TYPE_MAT2 && nb == TYPE_FLOAT) {
1882
valid = true;
1883
ret_type = TYPE_MAT2;
1884
} else if (na == TYPE_MAT3 && nb == TYPE_FLOAT) {
1885
valid = true;
1886
ret_type = TYPE_MAT3;
1887
} else if (na == TYPE_MAT4 && nb == TYPE_FLOAT) {
1888
valid = true;
1889
ret_type = TYPE_MAT4;
1890
} else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_VEC2 && nb == TYPE_MAT2) {
1891
valid = true;
1892
ret_type = TYPE_VEC2;
1893
} else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_VEC3 && nb == TYPE_MAT3) {
1894
valid = true;
1895
ret_type = TYPE_VEC3;
1896
} else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_VEC4 && nb == TYPE_MAT4) {
1897
valid = true;
1898
ret_type = TYPE_VEC4;
1899
}
1900
} break;
1901
case OP_ASSIGN_BIT_AND:
1902
case OP_ASSIGN_BIT_OR:
1903
case OP_ASSIGN_BIT_XOR:
1904
case OP_BIT_AND:
1905
case OP_BIT_OR:
1906
case OP_BIT_XOR: {
1907
/*
1908
* The bitwise operators and (&), exclusive-or (^), and inclusive-or (|). The operands must be of type
1909
* signed or unsigned integers or integer vectors. The operands cannot be vectors of differing size. If
1910
* one operand is a scalar and the other a vector, the scalar is applied component-wise to the vector,
1911
* resulting in the same type as the vector. The fundamental types of the operands (signed or unsigned)
1912
* must match.
1913
*/
1914
1915
int sa = 0;
1916
int sb = 0;
1917
if (!p_op->arguments[0]->is_indexed()) {
1918
sa = p_op->arguments[0]->get_array_size();
1919
}
1920
if (!p_op->arguments[1]->is_indexed()) {
1921
sb = p_op->arguments[1]->get_array_size();
1922
}
1923
if (sa > 0 || sb > 0) {
1924
break; // don't accept arrays
1925
}
1926
1927
DataType na = p_op->arguments[0]->get_datatype();
1928
DataType nb = p_op->arguments[1]->get_datatype();
1929
1930
if (na > nb && p_op->op >= OP_BIT_AND) {
1931
//can swap for non assign
1932
SWAP(na, nb);
1933
}
1934
1935
if (na == TYPE_INT && nb == TYPE_INT) {
1936
valid = true;
1937
ret_type = TYPE_INT;
1938
} else if (na == TYPE_IVEC2 && nb == TYPE_INT) {
1939
valid = true;
1940
ret_type = TYPE_IVEC2;
1941
} else if (na == TYPE_IVEC3 && nb == TYPE_INT) {
1942
valid = true;
1943
ret_type = TYPE_IVEC3;
1944
} else if (na == TYPE_IVEC4 && nb == TYPE_INT) {
1945
valid = true;
1946
ret_type = TYPE_IVEC4;
1947
} else if (na == TYPE_IVEC2 && nb == TYPE_IVEC2) {
1948
valid = true;
1949
ret_type = TYPE_IVEC2;
1950
} else if (na == TYPE_IVEC3 && nb == TYPE_IVEC3) {
1951
valid = true;
1952
ret_type = TYPE_IVEC3;
1953
} else if (na == TYPE_IVEC4 && nb == TYPE_IVEC4) {
1954
valid = true;
1955
ret_type = TYPE_IVEC4;
1956
/////
1957
} else if (na == TYPE_UINT && nb == TYPE_UINT) {
1958
valid = true;
1959
ret_type = TYPE_UINT;
1960
} else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
1961
valid = true;
1962
ret_type = TYPE_UVEC2;
1963
} else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
1964
valid = true;
1965
ret_type = TYPE_UVEC3;
1966
} else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
1967
valid = true;
1968
ret_type = TYPE_UVEC4;
1969
} else if (na == TYPE_UVEC2 && nb == TYPE_UVEC2) {
1970
valid = true;
1971
ret_type = TYPE_UVEC2;
1972
} else if (na == TYPE_UVEC3 && nb == TYPE_UVEC3) {
1973
valid = true;
1974
ret_type = TYPE_UVEC3;
1975
} else if (na == TYPE_UVEC4 && nb == TYPE_UVEC4) {
1976
valid = true;
1977
ret_type = TYPE_UVEC4;
1978
}
1979
} break;
1980
case OP_BIT_INVERT: { //unaries
1981
if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) {
1982
break; // don't accept arrays
1983
}
1984
1985
DataType na = p_op->arguments[0]->get_datatype();
1986
valid = na >= TYPE_INT && na < TYPE_FLOAT;
1987
ret_type = na;
1988
} break;
1989
case OP_SELECT_IF: {
1990
int sa = 0;
1991
int sb = 0;
1992
if (!p_op->arguments[1]->is_indexed()) {
1993
sa = p_op->arguments[1]->get_array_size();
1994
}
1995
if (!p_op->arguments[2]->is_indexed()) {
1996
sb = p_op->arguments[2]->get_array_size();
1997
}
1998
if (sa != sb) {
1999
break; // don't accept arrays if their sizes are not equal
2000
}
2001
2002
DataType na = p_op->arguments[0]->get_datatype();
2003
DataType nb = p_op->arguments[1]->get_datatype();
2004
DataType nc = p_op->arguments[2]->get_datatype();
2005
2006
valid = na == TYPE_BOOL && (nb == nc) && !is_sampler_type(nb);
2007
ret_type = nb;
2008
ret_size = sa;
2009
} break;
2010
default: {
2011
ERR_FAIL_V(false);
2012
}
2013
}
2014
2015
if (r_ret_type) {
2016
*r_ret_type = ret_type;
2017
}
2018
if (r_ret_size) {
2019
*r_ret_size = ret_size;
2020
}
2021
2022
if (valid && (!p_block || p_block->use_op_eval)) {
2023
// Need to be placed here and not in the `_reduce_expression` because otherwise expressions like `1 + 2 / 2` will not work correctly.
2024
valid = _eval_operator(p_block, p_function_info, p_op);
2025
}
2026
2027
return valid;
2028
}
2029
2030
Vector<ShaderLanguage::Scalar> ShaderLanguage::_get_node_values(const BlockNode *p_block, const FunctionInfo &p_function_info, Node *p_node) {
2031
Vector<Scalar> result;
2032
2033
switch (p_node->type) {
2034
case Node::NODE_TYPE_VARIABLE: {
2035
_find_identifier(p_block, false, p_function_info, static_cast<VariableNode *>(p_node)->name, nullptr, nullptr, nullptr, nullptr, nullptr, &result);
2036
} break;
2037
default: {
2038
result = p_node->get_values();
2039
} break;
2040
}
2041
2042
return result;
2043
}
2044
2045
bool ShaderLanguage::_eval_operator(const BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_op) {
2046
bool is_valid = true;
2047
2048
switch (p_op->op) {
2049
case OP_EQUAL:
2050
case OP_NOT_EQUAL:
2051
case OP_LESS:
2052
case OP_LESS_EQUAL:
2053
case OP_GREATER:
2054
case OP_GREATER_EQUAL:
2055
case OP_AND:
2056
case OP_OR:
2057
case OP_ADD:
2058
case OP_SUB:
2059
case OP_MUL:
2060
case OP_DIV:
2061
case OP_MOD:
2062
case OP_SHIFT_LEFT:
2063
case OP_SHIFT_RIGHT:
2064
case OP_BIT_AND:
2065
case OP_BIT_OR:
2066
case OP_BIT_XOR: {
2067
DataType a = p_op->arguments[0]->get_datatype();
2068
DataType b = p_op->arguments[1]->get_datatype();
2069
2070
bool is_op_vec_transform = false;
2071
if (p_op->op == OP_MUL) {
2072
DataType ta = a;
2073
DataType tb = b;
2074
2075
if (ta > tb) {
2076
SWAP(ta, tb);
2077
}
2078
if (ta == TYPE_VEC2 && tb == TYPE_MAT2) {
2079
is_op_vec_transform = true;
2080
} else if (ta == TYPE_VEC3 && tb == TYPE_MAT3) {
2081
is_op_vec_transform = true;
2082
} else if (ta == TYPE_VEC4 && tb == TYPE_MAT4) {
2083
is_op_vec_transform = true;
2084
}
2085
}
2086
2087
Vector<Scalar> va = _get_node_values(p_block, p_function_info, p_op->arguments[0]);
2088
Vector<Scalar> vb = _get_node_values(p_block, p_function_info, p_op->arguments[1]);
2089
2090
if (is_op_vec_transform) {
2091
p_op->values = _eval_vector_transform(va, vb, a, b, p_op->get_datatype());
2092
} else {
2093
p_op->values = _eval_vector(va, vb, a, b, p_op->get_datatype(), p_op->op, is_valid);
2094
}
2095
} break;
2096
case OP_NOT:
2097
case OP_NEGATE:
2098
case OP_BIT_INVERT: {
2099
p_op->values = _eval_unary_vector(_get_node_values(p_block, p_function_info, p_op->arguments[0]), p_op->get_datatype(), p_op->op);
2100
} break;
2101
default: {
2102
} break;
2103
}
2104
2105
return is_valid;
2106
}
2107
2108
ShaderLanguage::Scalar ShaderLanguage::_eval_unary_scalar(const Scalar &p_a, Operator p_op, DataType p_ret_type) {
2109
Scalar scalar;
2110
2111
switch (p_op) {
2112
case OP_NOT: {
2113
scalar.boolean = !p_a.boolean;
2114
} break;
2115
case OP_NEGATE: {
2116
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2117
scalar.sint = -p_a.sint;
2118
} else if (p_ret_type >= TYPE_UINT && p_ret_type <= TYPE_UVEC4) {
2119
// Intentionally wrap the unsigned int value, because GLSL does.
2120
scalar.uint = 0 - p_a.uint;
2121
} else { // float types
2122
scalar.real = -scalar.real;
2123
}
2124
} break;
2125
case OP_BIT_INVERT: {
2126
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2127
scalar.sint = ~p_a.sint;
2128
} else { // uint types
2129
scalar.uint = ~p_a.uint;
2130
}
2131
} break;
2132
default: {
2133
} break;
2134
}
2135
2136
return scalar;
2137
}
2138
2139
ShaderLanguage::Scalar ShaderLanguage::_eval_scalar(const Scalar &p_a, const Scalar &p_b, Operator p_op, DataType p_ret_type, bool &r_is_valid) {
2140
Scalar scalar;
2141
2142
switch (p_op) {
2143
case OP_EQUAL: {
2144
scalar.boolean = p_a.boolean == p_b.boolean;
2145
} break;
2146
case OP_NOT_EQUAL: {
2147
scalar.boolean = p_a.boolean != p_b.boolean;
2148
} break;
2149
case OP_LESS: {
2150
if (p_ret_type == TYPE_INT) {
2151
scalar.boolean = p_a.sint < p_b.sint;
2152
} else if (p_ret_type == TYPE_UINT) {
2153
scalar.boolean = p_a.uint < p_b.uint;
2154
} else { // float type
2155
scalar.boolean = p_a.real < p_b.real;
2156
}
2157
} break;
2158
case OP_LESS_EQUAL: {
2159
if (p_ret_type == TYPE_INT) {
2160
scalar.boolean = p_a.sint <= p_b.sint;
2161
} else if (p_ret_type == TYPE_UINT) {
2162
scalar.boolean = p_a.uint <= p_b.uint;
2163
} else { // float type
2164
scalar.boolean = p_a.real <= p_b.real;
2165
}
2166
} break;
2167
case OP_GREATER: {
2168
if (p_ret_type == TYPE_INT) {
2169
scalar.boolean = p_a.sint > p_b.sint;
2170
} else if (p_ret_type == TYPE_UINT) {
2171
scalar.boolean = p_a.uint > p_b.uint;
2172
} else { // float type
2173
scalar.boolean = p_a.real > p_b.real;
2174
}
2175
} break;
2176
case OP_GREATER_EQUAL: {
2177
if (p_ret_type == TYPE_INT) {
2178
scalar.boolean = p_a.sint >= p_b.sint;
2179
} else if (p_ret_type == TYPE_UINT) {
2180
scalar.boolean = p_a.uint >= p_b.uint;
2181
} else { // float type
2182
scalar.boolean = p_a.real >= p_b.real;
2183
}
2184
} break;
2185
case OP_AND: {
2186
scalar.boolean = p_a.boolean && p_b.boolean;
2187
} break;
2188
case OP_OR: {
2189
scalar.boolean = p_a.boolean || p_b.boolean;
2190
} break;
2191
case OP_ADD: {
2192
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2193
scalar.sint = p_a.sint + p_b.sint;
2194
} else if (p_ret_type >= TYPE_UINT && p_ret_type <= TYPE_UVEC4) {
2195
scalar.uint = p_a.uint + p_b.uint;
2196
} else { // float + matrix types
2197
scalar.real = p_a.real + p_b.real;
2198
}
2199
} break;
2200
case OP_SUB: {
2201
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2202
scalar.sint = p_a.sint - p_b.sint;
2203
} else if (p_ret_type >= TYPE_UINT && p_ret_type <= TYPE_UVEC4) {
2204
scalar.uint = p_a.uint - p_b.uint;
2205
} else { // float + matrix types
2206
scalar.real = p_a.real - p_b.real;
2207
}
2208
} break;
2209
case OP_MUL: {
2210
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2211
scalar.sint = p_a.sint * p_b.sint;
2212
} else if (p_ret_type >= TYPE_UINT && p_ret_type <= TYPE_UVEC4) {
2213
scalar.uint = p_a.uint * p_b.uint;
2214
} else { // float + matrix types
2215
scalar.real = p_a.real * p_b.real;
2216
}
2217
} break;
2218
case OP_DIV: {
2219
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2220
if (p_b.sint == 0) {
2221
_set_error(RTR("Division by zero error."));
2222
r_is_valid = false;
2223
break;
2224
}
2225
scalar.sint = p_a.sint / p_b.sint;
2226
} else if (p_ret_type == TYPE_UINT && p_ret_type <= TYPE_UVEC4) {
2227
if (p_b.uint == 0U) {
2228
_set_error(RTR("Division by zero error."));
2229
r_is_valid = false;
2230
break;
2231
}
2232
scalar.uint = p_a.uint / p_b.uint;
2233
} else { // float + matrix types
2234
scalar.real = p_a.real / p_b.real;
2235
}
2236
} break;
2237
case OP_MOD: {
2238
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2239
if (p_b.sint == 0) {
2240
_set_error(RTR("Modulo by zero error."));
2241
r_is_valid = false;
2242
break;
2243
}
2244
scalar.sint = p_a.sint % p_b.sint;
2245
} else { // uint types
2246
if (p_b.uint == 0U) {
2247
_set_error(RTR("Modulo by zero error."));
2248
r_is_valid = false;
2249
break;
2250
}
2251
scalar.uint = p_a.uint % p_b.uint;
2252
}
2253
} break;
2254
case OP_SHIFT_LEFT: {
2255
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2256
scalar.sint = p_a.sint << p_b.sint;
2257
} else { // uint types
2258
scalar.uint = p_a.uint << p_b.uint;
2259
}
2260
} break;
2261
case OP_SHIFT_RIGHT: {
2262
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2263
scalar.sint = p_a.sint >> p_b.sint;
2264
} else { // uint types
2265
scalar.uint = p_a.uint >> p_b.uint;
2266
}
2267
} break;
2268
case OP_BIT_AND: {
2269
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2270
scalar.sint = p_a.sint & p_b.sint;
2271
} else { // uint types
2272
scalar.uint = p_a.uint & p_b.uint;
2273
}
2274
} break;
2275
case OP_BIT_OR: {
2276
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2277
scalar.sint = p_a.sint | p_b.sint;
2278
} else { // uint types
2279
scalar.uint = p_a.uint | p_b.uint;
2280
}
2281
} break;
2282
case OP_BIT_XOR: {
2283
if (p_ret_type >= TYPE_INT && p_ret_type <= TYPE_IVEC4) {
2284
scalar.sint = p_a.sint ^ p_b.sint;
2285
} else { // uint types
2286
scalar.uint = p_a.uint ^ p_b.uint;
2287
}
2288
} break;
2289
default: {
2290
} break;
2291
}
2292
2293
return scalar;
2294
}
2295
2296
Vector<ShaderLanguage::Scalar> ShaderLanguage::_eval_unary_vector(const Vector<Scalar> &p_va, DataType p_ret_type, Operator p_op) {
2297
uint32_t size = get_datatype_component_count(p_ret_type);
2298
if (p_va.size() != p_ret_type) {
2299
return Vector<Scalar>(); // Non-evaluable values should not be parsed further.
2300
}
2301
Vector<Scalar> value;
2302
value.resize(size);
2303
2304
Scalar *w = value.ptrw();
2305
for (uint32_t i = 0U; i < size; i++) {
2306
w[i] = _eval_unary_scalar(p_va[i], p_op, p_ret_type);
2307
}
2308
return value;
2309
}
2310
2311
Vector<ShaderLanguage::Scalar> ShaderLanguage::_eval_vector(const Vector<Scalar> &p_va, const Vector<Scalar> &p_vb, DataType p_left_type, DataType p_right_type, DataType p_ret_type, Operator p_op, bool &r_is_valid) {
2312
uint32_t left_size = get_datatype_component_count(p_left_type);
2313
uint32_t right_size = get_datatype_component_count(p_right_type);
2314
2315
if (p_va.size() != left_size || p_vb.size() != right_size) {
2316
return Vector<Scalar>(); // Non-evaluable values should not be parsed further.
2317
}
2318
2319
uint32_t ret_size = get_datatype_component_count(p_ret_type);
2320
Vector<Scalar> value;
2321
value.resize(ret_size);
2322
2323
Scalar *w = value.ptrw();
2324
for (uint32_t i = 0U; i < ret_size; i++) {
2325
w[i] = _eval_scalar(p_va[MIN(i, left_size - 1)], p_vb[MIN(i, right_size - 1)], p_op, p_ret_type, r_is_valid);
2326
if (!r_is_valid) {
2327
return value;
2328
}
2329
}
2330
return value;
2331
}
2332
2333
Vector<ShaderLanguage::Scalar> ShaderLanguage::_eval_vector_transform(const Vector<Scalar> &p_va, const Vector<Scalar> &p_vb, DataType p_left_type, DataType p_right_type, DataType p_ret_type) {
2334
uint32_t left_size = get_datatype_component_count(p_left_type);
2335
uint32_t right_size = get_datatype_component_count(p_right_type);
2336
2337
if (p_va.size() != left_size || p_vb.size() != right_size) {
2338
return Vector<Scalar>(); // Non-evaluable values should not be parsed further.
2339
}
2340
2341
uint32_t ret_size = get_datatype_component_count(p_ret_type);
2342
Vector<Scalar> value;
2343
value.resize_initialized(ret_size);
2344
2345
Scalar *w = value.ptrw();
2346
switch (p_ret_type) {
2347
case TYPE_VEC2: {
2348
if (left_size == 2) { // v * m
2349
Vector2 v = Vector2(p_va[0].real, p_va[1].real);
2350
2351
w[0].real = (p_vb[0].real * v.x + p_vb[1].real * v.y);
2352
w[1].real = (p_vb[2].real * v.x + p_vb[3].real * v.y);
2353
} else { // m * v
2354
Vector2 v = Vector2(p_vb[0].real, p_vb[1].real);
2355
2356
w[0].real = (p_va[0].real * v.x + p_va[2].real * v.y);
2357
w[1].real = (p_va[1].real * v.x + p_va[3].real * v.y);
2358
}
2359
} break;
2360
case TYPE_VEC3: {
2361
if (left_size == 3) { // v * m
2362
Vector3 v = Vector3(p_va[0].real, p_va[1].real, p_va[2].real);
2363
2364
w[0].real = (p_vb[0].real * v.x + p_vb[1].real * v.y + p_vb[2].real * v.z);
2365
w[1].real = (p_vb[3].real * v.x + p_vb[4].real * v.y + p_vb[5].real * v.z);
2366
w[2].real = (p_vb[6].real * v.x + p_vb[7].real * v.y + p_vb[8].real * v.z);
2367
} else { // m * v
2368
Vector3 v = Vector3(p_vb[0].real, p_vb[1].real, p_vb[2].real);
2369
2370
w[0].real = (p_va[0].real * v.x + p_va[3].real * v.y + p_va[6].real * v.z);
2371
w[1].real = (p_va[1].real * v.x + p_va[4].real * v.y + p_va[7].real * v.z);
2372
w[2].real = (p_va[2].real * v.x + p_va[5].real * v.y + p_va[8].real * v.z);
2373
}
2374
} break;
2375
case TYPE_VEC4: {
2376
if (left_size == 4) { // v * m
2377
Vector4 v = Vector4(p_va[0].real, p_va[1].real, p_va[2].real, p_va[3].real);
2378
2379
w[0].real = (p_vb[0].real * v.x + p_vb[1].real * v.y + p_vb[2].real * v.z + p_vb[3].real * v.w);
2380
w[1].real = (p_vb[4].real * v.x + p_vb[5].real * v.y + p_vb[6].real * v.z + p_vb[7].real * v.w);
2381
w[2].real = (p_vb[8].real * v.x + p_vb[9].real * v.y + p_vb[10].real * v.z + p_vb[11].real * v.w);
2382
w[3].real = (p_vb[12].real * v.x + p_vb[13].real * v.y + p_vb[14].real * v.z + p_vb[15].real * v.w);
2383
} else { // m * v
2384
Vector4 v = Vector4(p_vb[0].real, p_vb[1].real, p_vb[2].real, p_vb[3].real);
2385
2386
w[0].real = (p_vb[0].real * v.x + p_vb[4].real * v.y + p_vb[8].real * v.z + p_vb[12].real * v.w);
2387
w[1].real = (p_vb[1].real * v.x + p_vb[5].real * v.y + p_vb[9].real * v.z + p_vb[13].real * v.w);
2388
w[2].real = (p_vb[2].real * v.x + p_vb[6].real * v.y + p_vb[10].real * v.z + p_vb[14].real * v.w);
2389
w[3].real = (p_vb[3].real * v.x + p_vb[7].real * v.y + p_vb[11].real * v.z + p_vb[15].real * v.w);
2390
}
2391
} break;
2392
default: {
2393
} break;
2394
}
2395
2396
return value;
2397
}
2398
2399
const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
2400
// Constructors.
2401
2402
{ "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2403
{ "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2404
{ "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2405
{ "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2406
{ "bvec3", TYPE_BVEC3, { TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2407
{ "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2408
{ "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2409
{ "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2410
{ "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2411
{ "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2412
{ "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2413
{ "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2414
{ "bvec4", TYPE_BVEC4, { TYPE_BVEC3, TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2415
{ "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2416
2417
{ "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2418
{ "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2419
{ "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2420
{ "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2421
{ "vec3", TYPE_VEC3, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2422
{ "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2423
{ "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2424
{ "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2425
{ "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2426
{ "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2427
{ "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2428
{ "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2429
{ "vec4", TYPE_VEC4, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2430
{ "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2431
2432
{ "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2433
{ "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2434
{ "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2435
{ "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2436
{ "ivec3", TYPE_IVEC3, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2437
{ "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2438
{ "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2439
{ "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2440
{ "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2441
{ "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2442
{ "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2443
{ "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2444
{ "ivec4", TYPE_IVEC4, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2445
{ "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2446
2447
{ "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2448
{ "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2449
{ "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2450
{ "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2451
{ "uvec3", TYPE_UVEC3, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2452
{ "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2453
{ "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2454
{ "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2455
{ "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2456
{ "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2457
{ "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2458
{ "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2459
{ "uvec4", TYPE_UVEC4, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2460
{ "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2461
2462
{ "mat2", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2463
{ "mat3", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2464
{ "mat4", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2465
2466
{ "mat2", TYPE_MAT2, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2467
{ "mat3", TYPE_MAT3, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2468
{ "mat4", TYPE_MAT4, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2469
2470
// Conversion scalars.
2471
2472
{ "int", TYPE_INT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2473
{ "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2474
{ "int", TYPE_INT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2475
{ "int", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2476
2477
{ "float", TYPE_FLOAT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2478
{ "float", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2479
{ "float", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2480
{ "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2481
2482
{ "uint", TYPE_UINT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2483
{ "uint", TYPE_UINT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2484
{ "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2485
{ "uint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2486
2487
{ "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2488
{ "bool", TYPE_BOOL, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2489
{ "bool", TYPE_BOOL, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2490
{ "bool", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2491
2492
// Conversion vectors.
2493
2494
{ "ivec2", TYPE_IVEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2495
{ "ivec2", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2496
{ "ivec2", TYPE_IVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2497
{ "ivec2", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2498
2499
{ "vec2", TYPE_VEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2500
{ "vec2", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2501
{ "vec2", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2502
{ "vec2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2503
2504
{ "uvec2", TYPE_UVEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2505
{ "uvec2", TYPE_UVEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2506
{ "uvec2", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2507
{ "uvec2", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2508
2509
{ "bvec2", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2510
{ "bvec2", TYPE_BVEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2511
{ "bvec2", TYPE_BVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2512
{ "bvec2", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2513
2514
{ "ivec3", TYPE_IVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2515
{ "ivec3", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2516
{ "ivec3", TYPE_IVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2517
{ "ivec3", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2518
2519
{ "vec3", TYPE_VEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2520
{ "vec3", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2521
{ "vec3", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2522
{ "vec3", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2523
2524
{ "uvec3", TYPE_UVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2525
{ "uvec3", TYPE_UVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2526
{ "uvec3", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2527
{ "uvec3", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2528
2529
{ "bvec3", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2530
{ "bvec3", TYPE_BVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2531
{ "bvec3", TYPE_BVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2532
{ "bvec3", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2533
2534
{ "ivec4", TYPE_IVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2535
{ "ivec4", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2536
{ "ivec4", TYPE_IVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2537
{ "ivec4", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2538
2539
{ "vec4", TYPE_VEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2540
{ "vec4", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2541
{ "vec4", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2542
{ "vec4", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2543
2544
{ "uvec4", TYPE_UVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2545
{ "uvec4", TYPE_UVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2546
{ "uvec4", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2547
{ "uvec4", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2548
2549
{ "bvec4", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2550
{ "bvec4", TYPE_BVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2551
{ "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2552
{ "bvec4", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2553
2554
// Conversion between matrixes.
2555
2556
{ "mat2", TYPE_MAT2, { TYPE_MAT3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2557
{ "mat2", TYPE_MAT2, { TYPE_MAT4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2558
{ "mat3", TYPE_MAT3, { TYPE_MAT2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2559
{ "mat3", TYPE_MAT3, { TYPE_MAT4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2560
{ "mat4", TYPE_MAT4, { TYPE_MAT2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2561
{ "mat4", TYPE_MAT4, { TYPE_MAT3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
2562
2563
// Built-ins - trigonometric functions.
2564
// radians
2565
2566
{ "radians", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "degrees" }, TAG_GLOBAL, false },
2567
{ "radians", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "degrees" }, TAG_GLOBAL, false },
2568
{ "radians", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "degrees" }, TAG_GLOBAL, false },
2569
{ "radians", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "degrees" }, TAG_GLOBAL, false },
2570
2571
// degrees
2572
2573
{ "degrees", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "radians" }, TAG_GLOBAL, false },
2574
{ "degrees", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "radians" }, TAG_GLOBAL, false },
2575
{ "degrees", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "radians" }, TAG_GLOBAL, false },
2576
{ "degrees", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "radians" }, TAG_GLOBAL, false },
2577
2578
// sin
2579
2580
{ "sin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2581
{ "sin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2582
{ "sin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2583
{ "sin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2584
2585
// cos
2586
2587
{ "cos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2588
{ "cos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2589
{ "cos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2590
{ "cos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2591
2592
// tan
2593
2594
{ "tan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2595
{ "tan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2596
{ "tan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2597
{ "tan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "angle" }, TAG_GLOBAL, false },
2598
2599
// asin
2600
2601
{ "asin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2602
{ "asin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2603
{ "asin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2604
{ "asin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2605
2606
// acos
2607
2608
{ "acos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2609
{ "acos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2610
{ "acos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2611
{ "acos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2612
2613
// atan
2614
2615
{ "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "y_over_x" }, TAG_GLOBAL, false },
2616
{ "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "y_over_x" }, TAG_GLOBAL, false },
2617
{ "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "y_over_x" }, TAG_GLOBAL, false },
2618
{ "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "y_over_x" }, TAG_GLOBAL, false },
2619
{ "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "y", "x" }, TAG_GLOBAL, false },
2620
{ "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "y", "x" }, TAG_GLOBAL, false },
2621
{ "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "y", "x" }, TAG_GLOBAL, false },
2622
{ "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "y", "x" }, TAG_GLOBAL, false },
2623
2624
// sinh
2625
2626
{ "sinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2627
{ "sinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2628
{ "sinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2629
{ "sinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2630
2631
// cosh
2632
2633
{ "cosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2634
{ "cosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2635
{ "cosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2636
{ "cosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2637
2638
// tanh
2639
2640
{ "tanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2641
{ "tanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2642
{ "tanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2643
{ "tanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2644
2645
// asinh
2646
2647
{ "asinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2648
{ "asinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2649
{ "asinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2650
{ "asinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2651
2652
// acosh
2653
2654
{ "acosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2655
{ "acosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2656
{ "acosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2657
{ "acosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2658
2659
// atanh
2660
2661
{ "atanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2662
{ "atanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2663
{ "atanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2664
{ "atanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2665
2666
// Builtins - exponential functions.
2667
// pow
2668
2669
{ "pow", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2670
{ "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2671
{ "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2672
{ "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2673
2674
// exp
2675
2676
{ "exp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2677
{ "exp", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2678
{ "exp", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2679
{ "exp", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2680
2681
// log
2682
2683
{ "log", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2684
{ "log", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2685
{ "log", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2686
{ "log", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2687
2688
// exp2
2689
2690
{ "exp2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2691
{ "exp2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2692
{ "exp2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2693
{ "exp2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2694
2695
// log2
2696
2697
{ "log2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2698
{ "log2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2699
{ "log2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2700
{ "log2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2701
2702
// sqrt
2703
2704
{ "sqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2705
{ "sqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2706
{ "sqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2707
{ "sqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2708
2709
// inversesqrt
2710
2711
{ "inversesqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2712
{ "inversesqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2713
{ "inversesqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2714
{ "inversesqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2715
2716
// Built-ins - common functions.
2717
// abs
2718
2719
{ "abs", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2720
{ "abs", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2721
{ "abs", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2722
{ "abs", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2723
2724
{ "abs", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2725
{ "abs", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2726
{ "abs", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2727
{ "abs", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2728
2729
// sign
2730
2731
{ "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2732
{ "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2733
{ "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2734
{ "sign", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2735
2736
{ "sign", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2737
{ "sign", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2738
{ "sign", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2739
{ "sign", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2740
2741
// floor
2742
2743
{ "floor", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2744
{ "floor", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2745
{ "floor", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2746
{ "floor", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2747
2748
// trunc
2749
2750
{ "trunc", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2751
{ "trunc", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2752
{ "trunc", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2753
{ "trunc", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2754
2755
// round
2756
2757
{ "round", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2758
{ "round", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2759
{ "round", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2760
{ "round", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2761
2762
// roundEven
2763
2764
{ "roundEven", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2765
{ "roundEven", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2766
{ "roundEven", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2767
{ "roundEven", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2768
2769
// ceil
2770
2771
{ "ceil", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2772
{ "ceil", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2773
{ "ceil", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2774
{ "ceil", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2775
2776
// fract
2777
2778
{ "fract", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2779
{ "fract", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2780
{ "fract", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2781
{ "fract", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2782
2783
// mod
2784
2785
{ "mod", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2786
{ "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2787
{ "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2788
{ "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2789
{ "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2790
{ "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2791
{ "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "x", "y" }, TAG_GLOBAL, false },
2792
2793
// modf
2794
2795
{ "modf", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
2796
{ "modf", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
2797
{ "modf", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
2798
{ "modf", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
2799
2800
// min
2801
2802
{ "min", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2803
{ "min", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2804
{ "min", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2805
{ "min", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2806
{ "min", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2807
{ "min", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2808
{ "min", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2809
2810
{ "min", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2811
{ "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2812
{ "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2813
{ "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2814
{ "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2815
{ "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2816
{ "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2817
2818
{ "min", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2819
{ "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2820
{ "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2821
{ "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2822
{ "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2823
{ "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2824
{ "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2825
2826
// max
2827
2828
{ "max", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2829
{ "max", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2830
{ "max", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2831
{ "max", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2832
{ "max", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2833
{ "max", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2834
{ "max", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2835
2836
{ "max", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2837
{ "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2838
{ "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2839
{ "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2840
{ "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2841
{ "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2842
{ "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2843
2844
{ "max", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2845
{ "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2846
{ "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2847
{ "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2848
{ "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2849
{ "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2850
{ "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2851
2852
// clamp
2853
2854
{ "clamp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2855
{ "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2856
{ "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2857
{ "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2858
{ "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2859
{ "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2860
{ "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2861
2862
{ "clamp", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2863
{ "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2864
{ "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2865
{ "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2866
{ "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2867
{ "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2868
{ "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2869
2870
{ "clamp", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2871
{ "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2872
{ "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2873
{ "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2874
{ "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2875
{ "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2876
{ "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
2877
2878
// mix
2879
2880
{ "mix", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2881
{ "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2882
{ "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_BVEC2, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2883
{ "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2884
{ "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2885
{ "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_BVEC3, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2886
{ "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2887
{ "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2888
{ "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC4, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2889
{ "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b", "value" }, TAG_GLOBAL, false },
2890
2891
// step
2892
2893
{ "step", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2894
{ "step", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2895
{ "step", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2896
{ "step", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2897
{ "step", TYPE_VEC2, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2898
{ "step", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2899
{ "step", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, { "edge", "x" }, TAG_GLOBAL, false },
2900
2901
// smoothstep
2902
2903
{ "smoothstep", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2904
{ "smoothstep", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2905
{ "smoothstep", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2906
{ "smoothstep", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2907
{ "smoothstep", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2908
{ "smoothstep", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2909
{ "smoothstep", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, { "edge0", "edge1", "value" }, TAG_GLOBAL, false },
2910
2911
// isnan
2912
2913
{ "isnan", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2914
{ "isnan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2915
{ "isnan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2916
{ "isnan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2917
2918
// isinf
2919
2920
{ "isinf", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2921
{ "isinf", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2922
{ "isinf", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2923
{ "isinf", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2924
2925
// floatBitsToInt
2926
2927
{ "floatBitsToInt", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2928
{ "floatBitsToInt", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2929
{ "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2930
{ "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2931
2932
// floatBitsToUint
2933
2934
{ "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2935
{ "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2936
{ "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2937
{ "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2938
2939
// intBitsToFloat
2940
2941
{ "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2942
{ "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2943
{ "intBitsToFloat", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2944
{ "intBitsToFloat", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2945
2946
// uintBitsToFloat
2947
2948
{ "uintBitsToFloat", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2949
{ "uintBitsToFloat", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2950
{ "uintBitsToFloat", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2951
{ "uintBitsToFloat", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2952
2953
// Built-ins - geometric functions.
2954
// length
2955
2956
{ "length", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2957
{ "length", TYPE_FLOAT, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2958
{ "length", TYPE_FLOAT, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2959
{ "length", TYPE_FLOAT, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
2960
2961
// distance
2962
2963
{ "distance", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2964
{ "distance", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2965
{ "distance", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2966
{ "distance", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2967
2968
// dot
2969
2970
{ "dot", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2971
{ "dot", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2972
{ "dot", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2973
{ "dot", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2974
2975
// cross
2976
2977
{ "cross", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
2978
2979
// normalize
2980
2981
{ "normalize", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2982
{ "normalize", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2983
{ "normalize", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2984
{ "normalize", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
2985
2986
// reflect
2987
2988
{ "reflect", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "I", "N" }, TAG_GLOBAL, false },
2989
{ "reflect", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "I", "N" }, TAG_GLOBAL, false },
2990
{ "reflect", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "I", "N" }, TAG_GLOBAL, false },
2991
2992
// refract
2993
2994
{ "refract", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "I", "N", "eta" }, TAG_GLOBAL, false },
2995
{ "refract", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "I", "N", "eta" }, TAG_GLOBAL, false },
2996
{ "refract", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "I", "N", "eta" }, TAG_GLOBAL, false },
2997
2998
// faceforward
2999
3000
{ "faceforward", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "N", "I", "Nref" }, TAG_GLOBAL, false },
3001
{ "faceforward", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "N", "I", "Nref" }, TAG_GLOBAL, false },
3002
{ "faceforward", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "N", "I", "Nref" }, TAG_GLOBAL, false },
3003
3004
// matrixCompMult
3005
3006
{ "matrixCompMult", TYPE_MAT2, { TYPE_MAT2, TYPE_MAT2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3007
{ "matrixCompMult", TYPE_MAT3, { TYPE_MAT3, TYPE_MAT3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3008
{ "matrixCompMult", TYPE_MAT4, { TYPE_MAT4, TYPE_MAT4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3009
3010
// outerProduct
3011
3012
{ "outerProduct", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "c", "r" }, TAG_GLOBAL, false },
3013
{ "outerProduct", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "c", "r" }, TAG_GLOBAL, false },
3014
{ "outerProduct", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "c", "r" }, TAG_GLOBAL, false },
3015
3016
// transpose
3017
3018
{ "transpose", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
3019
{ "transpose", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
3020
{ "transpose", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
3021
3022
// determinant
3023
3024
{ "determinant", TYPE_FLOAT, { TYPE_MAT2, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
3025
{ "determinant", TYPE_FLOAT, { TYPE_MAT3, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
3026
{ "determinant", TYPE_FLOAT, { TYPE_MAT4, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
3027
3028
// inverse
3029
3030
{ "inverse", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
3031
{ "inverse", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
3032
{ "inverse", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, { "m" }, TAG_GLOBAL, false },
3033
3034
// lessThan
3035
3036
{ "lessThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3037
{ "lessThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3038
{ "lessThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3039
3040
{ "lessThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3041
{ "lessThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3042
{ "lessThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3043
3044
{ "lessThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3045
{ "lessThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3046
{ "lessThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3047
3048
// greaterThan
3049
3050
{ "greaterThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3051
{ "greaterThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3052
{ "greaterThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3053
3054
{ "greaterThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3055
{ "greaterThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3056
{ "greaterThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3057
3058
{ "greaterThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3059
{ "greaterThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3060
{ "greaterThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3061
3062
// lessThanEqual
3063
3064
{ "lessThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3065
{ "lessThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3066
{ "lessThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3067
3068
{ "lessThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3069
{ "lessThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3070
{ "lessThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3071
3072
{ "lessThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3073
{ "lessThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3074
{ "lessThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3075
3076
// greaterThanEqual
3077
3078
{ "greaterThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3079
{ "greaterThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3080
{ "greaterThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3081
3082
{ "greaterThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3083
{ "greaterThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3084
{ "greaterThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3085
3086
{ "greaterThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3087
{ "greaterThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3088
{ "greaterThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3089
3090
// equal
3091
3092
{ "equal", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3093
{ "equal", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3094
{ "equal", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3095
3096
{ "equal", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3097
{ "equal", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3098
{ "equal", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3099
3100
{ "equal", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3101
{ "equal", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3102
{ "equal", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3103
3104
{ "equal", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3105
{ "equal", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3106
{ "equal", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3107
3108
// notEqual
3109
3110
{ "notEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3111
{ "notEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3112
{ "notEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3113
3114
{ "notEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3115
{ "notEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3116
{ "notEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3117
3118
{ "notEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3119
{ "notEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3120
{ "notEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3121
3122
{ "notEqual", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3123
{ "notEqual", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3124
{ "notEqual", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
3125
3126
// any
3127
3128
{ "any", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
3129
{ "any", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
3130
{ "any", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
3131
3132
// all
3133
3134
{ "all", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
3135
{ "all", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
3136
{ "all", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
3137
3138
// not
3139
3140
{ "not", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
3141
{ "not", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
3142
{ "not", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
3143
3144
// Built-ins: texture functions.
3145
// textureSize
3146
3147
{ "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3148
{ "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3149
{ "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3150
{ "textureSize", TYPE_IVEC3, { TYPE_SAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3151
{ "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3152
{ "textureSize", TYPE_IVEC3, { TYPE_USAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3153
{ "textureSize", TYPE_IVEC3, { TYPE_SAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3154
{ "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3155
{ "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3156
{ "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3157
{ "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBEARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
3158
3159
// texture
3160
3161
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3162
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3163
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3164
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3165
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3166
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3167
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3168
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3169
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3170
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3171
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3172
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3173
{ "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3174
{ "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3175
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3176
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3177
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3178
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3179
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3180
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3181
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3182
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3183
{ "texture", TYPE_VEC4, { TYPE_SAMPLEREXT, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3184
{ "texture", TYPE_VEC4, { TYPE_SAMPLEREXT, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3185
3186
// textureProj
3187
3188
{ "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3189
{ "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3190
{ "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3191
{ "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3192
{ "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3193
{ "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3194
{ "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3195
{ "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3196
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3197
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3198
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3199
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3200
{ "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3201
{ "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3202
{ "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3203
{ "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3204
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3205
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
3206
3207
// textureLod
3208
3209
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3210
{ "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3211
{ "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3212
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3213
{ "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3214
{ "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3215
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3216
{ "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3217
{ "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3218
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3219
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3220
3221
// texelFetch
3222
3223
{ "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3224
{ "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3225
{ "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3226
{ "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3227
{ "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3228
{ "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3229
{ "texelFetch", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3230
{ "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3231
{ "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3232
3233
// textureProjLod
3234
3235
{ "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3236
{ "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3237
{ "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3238
{ "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3239
{ "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3240
{ "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3241
{ "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3242
{ "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3243
{ "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
3244
3245
// textureGrad
3246
3247
{ "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3248
{ "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3249
{ "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3250
{ "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3251
{ "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3252
{ "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3253
{ "textureGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3254
{ "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3255
{ "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3256
{ "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3257
{ "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3258
3259
// textureProjGrad
3260
3261
{ "textureProjGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3262
{ "textureProjGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3263
{ "textureProjGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3264
{ "textureProjGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3265
{ "textureProjGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3266
{ "textureProjGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3267
{ "textureProjGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3268
{ "textureProjGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3269
{ "textureProjGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
3270
3271
// textureGather
3272
3273
{ "textureGather", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3274
{ "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3275
{ "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3276
{ "textureGather", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
3277
{ "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
3278
{ "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
3279
{ "textureGather", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3280
{ "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3281
{ "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3282
{ "textureGather", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
3283
{ "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
3284
{ "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
3285
{ "textureGather", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
3286
{ "textureGather", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
3287
3288
// textureQueryLod
3289
3290
{ "textureQueryLod", TYPE_VEC2, { TYPE_SAMPLER2D, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3291
{ "textureQueryLod", TYPE_VEC2, { TYPE_ISAMPLER2D, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3292
{ "textureQueryLod", TYPE_VEC2, { TYPE_USAMPLER2D, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3293
{ "textureQueryLod", TYPE_VEC2, { TYPE_SAMPLER2DARRAY, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3294
{ "textureQueryLod", TYPE_VEC2, { TYPE_ISAMPLER2DARRAY, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3295
{ "textureQueryLod", TYPE_VEC2, { TYPE_USAMPLER2DARRAY, TYPE_VEC2 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3296
{ "textureQueryLod", TYPE_VEC2, { TYPE_SAMPLER3D, TYPE_VEC3 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3297
{ "textureQueryLod", TYPE_VEC2, { TYPE_ISAMPLER3D, TYPE_VEC3 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3298
{ "textureQueryLod", TYPE_VEC2, { TYPE_USAMPLER3D, TYPE_VEC3 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3299
{ "textureQueryLod", TYPE_VEC2, { TYPE_SAMPLERCUBE, TYPE_VEC3 }, { "sampler", "coords" }, TAG_GLOBAL, true },
3300
3301
// textureQueryLevels
3302
3303
{ "textureQueryLevels", TYPE_INT, { TYPE_SAMPLER2D }, { "sampler" }, TAG_GLOBAL, true },
3304
{ "textureQueryLevels", TYPE_INT, { TYPE_ISAMPLER2D }, { "sampler" }, TAG_GLOBAL, true },
3305
{ "textureQueryLevels", TYPE_INT, { TYPE_USAMPLER2D }, { "sampler" }, TAG_GLOBAL, true },
3306
{ "textureQueryLevels", TYPE_INT, { TYPE_SAMPLER2DARRAY }, { "sampler" }, TAG_GLOBAL, true },
3307
{ "textureQueryLevels", TYPE_INT, { TYPE_ISAMPLER2DARRAY }, { "sampler" }, TAG_GLOBAL, true },
3308
{ "textureQueryLevels", TYPE_INT, { TYPE_USAMPLER2DARRAY }, { "sampler" }, TAG_GLOBAL, true },
3309
{ "textureQueryLevels", TYPE_INT, { TYPE_SAMPLER3D }, { "sampler" }, TAG_GLOBAL, true },
3310
{ "textureQueryLevels", TYPE_INT, { TYPE_ISAMPLER3D }, { "sampler" }, TAG_GLOBAL, true },
3311
{ "textureQueryLevels", TYPE_INT, { TYPE_USAMPLER3D }, { "sampler" }, TAG_GLOBAL, true },
3312
{ "textureQueryLevels", TYPE_INT, { TYPE_SAMPLERCUBE }, { "sampler" }, TAG_GLOBAL, true },
3313
3314
// dFdx
3315
3316
{ "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3317
{ "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3318
{ "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3319
{ "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3320
3321
// dFdxCoarse
3322
3323
{ "dFdxCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3324
{ "dFdxCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3325
{ "dFdxCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3326
{ "dFdxCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3327
3328
// dFdxFine
3329
3330
{ "dFdxFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3331
{ "dFdxFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3332
{ "dFdxFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3333
{ "dFdxFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3334
3335
// dFdy
3336
3337
{ "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3338
{ "dFdy", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3339
{ "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3340
{ "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3341
3342
// dFdyCoarse
3343
3344
{ "dFdyCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3345
{ "dFdyCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3346
{ "dFdyCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3347
{ "dFdyCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3348
3349
// dFdyFine
3350
3351
{ "dFdyFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3352
{ "dFdyFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3353
{ "dFdyFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3354
{ "dFdyFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3355
3356
// fwidth
3357
3358
{ "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3359
{ "fwidth", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3360
{ "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3361
{ "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
3362
3363
// fwidthCoarse
3364
3365
{ "fwidthCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3366
{ "fwidthCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3367
{ "fwidthCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3368
{ "fwidthCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3369
3370
// fwidthFine
3371
3372
{ "fwidthFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3373
{ "fwidthFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3374
{ "fwidthFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3375
{ "fwidthFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
3376
3377
// Sub-functions.
3378
// array
3379
3380
{ "length", TYPE_INT, { TYPE_VOID }, { "" }, TAG_ARRAY, false },
3381
3382
// Modern functions.
3383
// fma
3384
3385
{ "fma", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
3386
{ "fma", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
3387
{ "fma", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
3388
{ "fma", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "a", "b", "c" }, TAG_GLOBAL, true },
3389
3390
// Packing/Unpacking functions.
3391
3392
{ "packHalf2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3393
{ "packUnorm2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3394
{ "packSnorm2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3395
{ "packUnorm4x8", TYPE_UINT, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3396
{ "packSnorm4x8", TYPE_UINT, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3397
3398
{ "unpackHalf2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3399
{ "unpackUnorm2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3400
{ "unpackSnorm2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3401
{ "unpackUnorm4x8", TYPE_VEC4, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3402
{ "unpackSnorm4x8", TYPE_VEC4, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
3403
3404
// bitfieldExtract
3405
3406
{ "bitfieldExtract", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
3407
{ "bitfieldExtract", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
3408
{ "bitfieldExtract", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
3409
{ "bitfieldExtract", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
3410
3411
{ "bitfieldExtract", TYPE_UINT, { TYPE_UINT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
3412
{ "bitfieldExtract", TYPE_UVEC2, { TYPE_UVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
3413
{ "bitfieldExtract", TYPE_UVEC3, { TYPE_UVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
3414
{ "bitfieldExtract", TYPE_UVEC4, { TYPE_UVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "value", "offset", "bits" }, TAG_GLOBAL, true },
3415
3416
// bitfieldInsert
3417
3418
{ "bitfieldInsert", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
3419
{ "bitfieldInsert", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
3420
{ "bitfieldInsert", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
3421
{ "bitfieldInsert", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
3422
3423
{ "bitfieldInsert", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
3424
{ "bitfieldInsert", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
3425
{ "bitfieldInsert", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
3426
{ "bitfieldInsert", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "base", "insert", "offset", "bits" }, TAG_GLOBAL, true },
3427
3428
// bitfieldReverse
3429
3430
{ "bitfieldReverse", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3431
{ "bitfieldReverse", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3432
{ "bitfieldReverse", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3433
{ "bitfieldReverse", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3434
3435
{ "bitfieldReverse", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3436
{ "bitfieldReverse", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3437
{ "bitfieldReverse", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3438
{ "bitfieldReverse", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3439
3440
// bitCount
3441
3442
{ "bitCount", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3443
{ "bitCount", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3444
{ "bitCount", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3445
{ "bitCount", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3446
3447
{ "bitCount", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3448
{ "bitCount", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3449
{ "bitCount", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3450
{ "bitCount", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3451
3452
// findLSB
3453
3454
{ "findLSB", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3455
{ "findLSB", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3456
{ "findLSB", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3457
{ "findLSB", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3458
3459
{ "findLSB", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3460
{ "findLSB", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3461
{ "findLSB", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3462
{ "findLSB", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3463
3464
// findMSB
3465
3466
{ "findMSB", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3467
{ "findMSB", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3468
{ "findMSB", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3469
{ "findMSB", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3470
3471
{ "findMSB", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3472
{ "findMSB", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3473
{ "findMSB", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3474
{ "findMSB", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "value" }, TAG_GLOBAL, true },
3475
3476
// umulExtended
3477
3478
{ "umulExtended", TYPE_VOID, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3479
{ "umulExtended", TYPE_VOID, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3480
{ "umulExtended", TYPE_VOID, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3481
{ "umulExtended", TYPE_VOID, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3482
3483
// imulExtended
3484
3485
{ "imulExtended", TYPE_VOID, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3486
{ "imulExtended", TYPE_VOID, { TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3487
{ "imulExtended", TYPE_VOID, { TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3488
{ "imulExtended", TYPE_VOID, { TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "x", "y", "msb", "lsb" }, TAG_GLOBAL, true },
3489
3490
// uaddCarry
3491
3492
{ "uaddCarry", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "y", "carry" }, TAG_GLOBAL, true },
3493
{ "uaddCarry", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "y", "carry" }, TAG_GLOBAL, true },
3494
{ "uaddCarry", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "y", "carry" }, TAG_GLOBAL, true },
3495
{ "uaddCarry", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "y", "carry" }, TAG_GLOBAL, true },
3496
3497
// usubBorrow
3498
3499
{ "usubBorrow", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "y", "borrow" }, TAG_GLOBAL, true },
3500
{ "usubBorrow", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "y", "borrow" }, TAG_GLOBAL, true },
3501
{ "usubBorrow", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "y", "borrow" }, TAG_GLOBAL, true },
3502
{ "usubBorrow", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "y", "borrow" }, TAG_GLOBAL, true },
3503
3504
// ldexp
3505
3506
{ "ldexp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_INT, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3507
{ "ldexp", TYPE_VEC2, { TYPE_VEC2, TYPE_IVEC2, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3508
{ "ldexp", TYPE_VEC3, { TYPE_VEC3, TYPE_IVEC3, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3509
{ "ldexp", TYPE_VEC4, { TYPE_VEC4, TYPE_IVEC4, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3510
3511
// frexp
3512
3513
{ "frexp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_INT, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3514
{ "frexp", TYPE_VEC2, { TYPE_VEC2, TYPE_IVEC2, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3515
{ "frexp", TYPE_VEC3, { TYPE_VEC3, TYPE_IVEC3, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3516
{ "frexp", TYPE_VEC4, { TYPE_VEC4, TYPE_IVEC4, TYPE_VOID }, { "x", "exp" }, TAG_GLOBAL, true },
3517
3518
{ nullptr, TYPE_VOID, { TYPE_VOID }, { "" }, TAG_GLOBAL, false }
3519
};
3520
3521
HashSet<StringName> global_func_set;
3522
3523
const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[] = {
3524
{ "modf", { 1, -1 } },
3525
{ "umulExtended", { 2, 3 } },
3526
{ "imulExtended", { 2, 3 } },
3527
{ "uaddCarry", { 2, -1 } },
3528
{ "usubBorrow", { 2, -1 } },
3529
{ "ldexp", { 1, -1 } },
3530
{ "frexp", { 1, -1 } },
3531
{ nullptr, { 0, -1 } }
3532
};
3533
3534
const ShaderLanguage::BuiltinFuncConstArgs ShaderLanguage::builtin_func_const_args[] = {
3535
{ "textureGather", 2, 0, 3 },
3536
{ nullptr, 0, 0, 0 }
3537
};
3538
3539
const ShaderLanguage::BuiltinEntry ShaderLanguage::frag_only_func_defs[] = {
3540
{ "dFdx" },
3541
{ "dFdxCoarse" },
3542
{ "dFdxFine" },
3543
{ "dFdy" },
3544
{ "dFdyCoarse" },
3545
{ "dFdyFine" },
3546
{ "fwidth" },
3547
{ "fwidthCoarse" },
3548
{ "fwidthFine" },
3549
{ nullptr }
3550
};
3551
3552
bool ShaderLanguage::is_const_suffix_lut_initialized = false;
3553
3554
bool 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) {
3555
ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, false);
3556
3557
Vector<DataType> args;
3558
Vector<StringName> args2;
3559
Vector<int> args3;
3560
3561
ERR_FAIL_COND_V(p_func->arguments[0]->type != Node::NODE_TYPE_VARIABLE, false);
3562
3563
StringName name = static_cast<VariableNode *>(p_func->arguments[0])->name.operator String();
3564
StringName rname = static_cast<VariableNode *>(p_func->arguments[0])->rname.operator String();
3565
3566
for (int i = 1; i < p_func->arguments.size(); i++) {
3567
args.push_back(p_func->arguments[i]->get_datatype());
3568
args2.push_back(p_func->arguments[i]->get_datatype_name());
3569
args3.push_back(p_func->arguments[i]->get_array_size());
3570
}
3571
3572
int argcount = args.size();
3573
3574
if (stages) {
3575
// Stage functions can be used in custom functions as well, that why need to check them all.
3576
for (const KeyValue<StringName, FunctionInfo> &E : *stages) {
3577
if (E.value.stage_functions.has(name)) {
3578
// Stage-based function.
3579
const StageFunctionInfo &sf = E.value.stage_functions[name];
3580
if (argcount != sf.arguments.size()) {
3581
_set_error(vformat(RTR("Invalid number of arguments when calling stage function '%s', which expects %d argument(s)."), String(name), sf.arguments.size()));
3582
return false;
3583
}
3584
// Validate arguments.
3585
for (int i = 0; i < argcount; i++) {
3586
if (args[i] != sf.arguments[i].type) {
3587
_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)));
3588
return false;
3589
}
3590
}
3591
3592
if (r_ret_type) {
3593
*r_ret_type = sf.return_type;
3594
}
3595
if (r_ret_type_str) {
3596
*r_ret_type_str = "";
3597
}
3598
return true;
3599
}
3600
}
3601
}
3602
3603
bool failed_builtin = false;
3604
bool unsupported_builtin = false;
3605
int builtin_idx = 0;
3606
3607
if (argcount <= 4) {
3608
// test builtins
3609
int idx = 0;
3610
3611
while (builtin_func_defs[idx].name) {
3612
if (completion_class != builtin_func_defs[idx].tag) {
3613
idx++;
3614
continue;
3615
}
3616
3617
if (name == builtin_func_defs[idx].name) {
3618
failed_builtin = true;
3619
bool fail = false;
3620
for (int i = 0; i < argcount; i++) {
3621
if (p_func->arguments[i + 1]->type == Node::NODE_TYPE_ARRAY) {
3622
const ArrayNode *anode = static_cast<const ArrayNode *>(p_func->arguments[i + 1]);
3623
if (anode->call_expression == nullptr && !anode->is_indexed()) {
3624
fail = true;
3625
break;
3626
}
3627
}
3628
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])) {
3629
//all good, but needs implicit conversion later
3630
} else if (args[i] != builtin_func_defs[idx].args[i]) {
3631
fail = true;
3632
break;
3633
}
3634
}
3635
3636
if (!fail) {
3637
if (RenderingServer::get_singleton()->is_low_end()) {
3638
if (builtin_func_defs[idx].high_end) {
3639
fail = true;
3640
unsupported_builtin = true;
3641
builtin_idx = idx;
3642
}
3643
}
3644
}
3645
3646
if (!fail && argcount < 4 && builtin_func_defs[idx].args[argcount] != TYPE_VOID) {
3647
fail = true; //make sure the number of arguments matches
3648
}
3649
3650
if (!fail) {
3651
{
3652
int constarg_idx = 0;
3653
while (builtin_func_const_args[constarg_idx].name) {
3654
if (String(name) == builtin_func_const_args[constarg_idx].name) {
3655
int arg = builtin_func_const_args[constarg_idx].arg + 1;
3656
if (p_func->arguments.size() <= arg) {
3657
break;
3658
}
3659
3660
int min = builtin_func_const_args[constarg_idx].min;
3661
int max = builtin_func_const_args[constarg_idx].max;
3662
3663
bool error = false;
3664
Vector<Scalar> values = _get_node_values(p_block, p_function_info, p_func->arguments[arg]);
3665
if (p_func->arguments[arg]->get_datatype() == TYPE_INT && !values.is_empty()) {
3666
if (values[0].sint < min || values[0].sint > max) {
3667
error = true;
3668
}
3669
} else {
3670
error = true;
3671
}
3672
3673
if (error) {
3674
_set_error(vformat(RTR("Expected integer constant within [%d..%d] range."), min, max));
3675
return false;
3676
}
3677
}
3678
constarg_idx++;
3679
}
3680
}
3681
3682
//make sure its not an out argument used in the wrong way
3683
int outarg_idx = 0;
3684
while (builtin_func_out_args[outarg_idx].name) {
3685
if (String(name) == builtin_func_out_args[outarg_idx].name) {
3686
for (int arg = 0; arg < BuiltinFuncOutArgs::MAX_ARGS; arg++) {
3687
int arg_idx = builtin_func_out_args[outarg_idx].arguments[arg];
3688
if (arg_idx == -1) {
3689
break;
3690
}
3691
if (arg_idx < argcount) {
3692
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) {
3693
_set_error(vformat(RTR("Argument %d of function '%s' is not a variable, array, or member."), arg_idx + 1, String(name)));
3694
return false;
3695
}
3696
3697
if (p_func->arguments[arg_idx + 1]->type == Node::NODE_TYPE_ARRAY) {
3698
ArrayNode *mn = static_cast<ArrayNode *>(p_func->arguments[arg_idx + 1]);
3699
if (mn->is_const) {
3700
fail = true;
3701
}
3702
} else if (p_func->arguments[arg_idx + 1]->type == Node::NODE_TYPE_MEMBER) {
3703
MemberNode *mn = static_cast<MemberNode *>(p_func->arguments[arg_idx + 1]);
3704
if (mn->basetype_const) {
3705
fail = true;
3706
}
3707
} else { // TYPE_VARIABLE
3708
VariableNode *vn = static_cast<VariableNode *>(p_func->arguments[arg_idx + 1]);
3709
if (vn->is_const) {
3710
fail = true;
3711
} else {
3712
StringName varname = vn->name;
3713
if (shader->uniforms.has(varname)) {
3714
fail = true;
3715
} else {
3716
if (shader->varyings.has(varname)) {
3717
_set_error(vformat(RTR("Varyings cannot be passed for the '%s' parameter."), "out"));
3718
return false;
3719
}
3720
if (p_function_info.built_ins.has(varname)) {
3721
BuiltInInfo info = p_function_info.built_ins[varname];
3722
if (info.constant) {
3723
fail = true;
3724
}
3725
}
3726
}
3727
}
3728
}
3729
if (fail) {
3730
_set_error(vformat(RTR("A constant value cannot be passed for the '%s' parameter."), "out"));
3731
return false;
3732
}
3733
3734
StringName var_name;
3735
if (p_func->arguments[arg_idx + 1]->type == Node::NODE_TYPE_ARRAY) {
3736
var_name = static_cast<const ArrayNode *>(p_func->arguments[arg_idx + 1])->name;
3737
} else if (p_func->arguments[arg_idx + 1]->type == Node::NODE_TYPE_MEMBER) {
3738
Node *n = static_cast<const MemberNode *>(p_func->arguments[arg_idx + 1])->owner;
3739
while (n->type == Node::NODE_TYPE_MEMBER) {
3740
n = static_cast<const MemberNode *>(n)->owner;
3741
}
3742
if (n->type != Node::NODE_TYPE_VARIABLE && n->type != Node::NODE_TYPE_ARRAY) {
3743
_set_error(vformat(RTR("Argument %d of function '%s' is not a variable, array, or member."), arg_idx + 1, String(name)));
3744
return false;
3745
}
3746
if (n->type == Node::NODE_TYPE_VARIABLE) {
3747
var_name = static_cast<const VariableNode *>(n)->name;
3748
} else { // TYPE_ARRAY
3749
var_name = static_cast<const ArrayNode *>(n)->name;
3750
}
3751
} else { // TYPE_VARIABLE
3752
var_name = static_cast<const VariableNode *>(p_func->arguments[arg_idx + 1])->name;
3753
}
3754
const BlockNode *b = p_block;
3755
bool valid = false;
3756
while (b) {
3757
if (b->variables.has(var_name) || p_function_info.built_ins.has(var_name)) {
3758
valid = true;
3759
break;
3760
}
3761
if (b->parent_function) {
3762
for (int i = 0; i < b->parent_function->arguments.size(); i++) {
3763
if (b->parent_function->arguments[i].name == var_name) {
3764
valid = true;
3765
break;
3766
}
3767
}
3768
}
3769
b = b->parent_block;
3770
}
3771
3772
if (!valid) {
3773
_set_error(vformat(RTR("Argument %d of function '%s' can only take a local variable, array, or member."), arg_idx + 1, String(name)));
3774
return false;
3775
}
3776
}
3777
}
3778
}
3779
outarg_idx++;
3780
}
3781
//implicitly convert values if possible
3782
for (int i = 0; i < argcount; i++) {
3783
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) {
3784
//can't do implicit conversion here
3785
continue;
3786
}
3787
3788
//this is an implicit conversion
3789
ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[i + 1]);
3790
ConstantNode *conversion = alloc_node<ConstantNode>();
3791
3792
conversion->datatype = builtin_func_defs[idx].args[i];
3793
conversion->values.resize(1);
3794
3795
convert_constant(constant, builtin_func_defs[idx].args[i], conversion->values.ptrw());
3796
p_func->arguments.write[i + 1] = conversion;
3797
}
3798
3799
if (r_ret_type) {
3800
*r_ret_type = builtin_func_defs[idx].rettype;
3801
}
3802
3803
return true;
3804
}
3805
}
3806
3807
idx++;
3808
}
3809
}
3810
3811
if (unsupported_builtin) {
3812
String arglist = "";
3813
for (int i = 0; i < argcount; i++) {
3814
if (i > 0) {
3815
arglist += ", ";
3816
}
3817
arglist += get_datatype_name(builtin_func_defs[builtin_idx].args[i]);
3818
}
3819
3820
_set_error(vformat(RTR("Built-in function \"%s(%s)\" is only supported on high-end platforms."), String(name), arglist));
3821
return false;
3822
}
3823
3824
if (failed_builtin) {
3825
String arg_list;
3826
for (int i = 0; i < argcount; i++) {
3827
if (i > 0) {
3828
arg_list += ",";
3829
}
3830
3831
String arg_name;
3832
if (args[i] == TYPE_STRUCT) {
3833
arg_name = args2[i];
3834
} else {
3835
arg_name = get_datatype_name(args[i]);
3836
}
3837
if (args3[i] > 0) {
3838
arg_name += "[";
3839
arg_name += itos(args3[i]);
3840
arg_name += "]";
3841
}
3842
arg_list += arg_name;
3843
}
3844
_set_error(vformat(RTR("Invalid arguments for the built-in function: \"%s(%s)\"."), String(name), arg_list));
3845
return false;
3846
}
3847
3848
// try existing functions..
3849
3850
StringName exclude_function;
3851
BlockNode *block = p_block;
3852
3853
while (block) {
3854
if (block->parent_function) {
3855
exclude_function = block->parent_function->name;
3856
}
3857
block = block->parent_block;
3858
}
3859
3860
if (name == exclude_function) {
3861
_set_error(RTR("Recursion is not allowed."));
3862
return false;
3863
}
3864
3865
int last_arg_count = 0;
3866
bool exists = false;
3867
String arg_list = "";
3868
bool overload_fail = false;
3869
struct OverloadErrorInfo {
3870
String arg_list;
3871
int index = 0;
3872
String func_arg_name;
3873
String arg_name;
3874
};
3875
Vector<OverloadErrorInfo> overload_errors;
3876
3877
for (int i = 0; i < shader->vfunctions.size(); i++) {
3878
if (rname != shader->vfunctions[i].rname) {
3879
continue;
3880
}
3881
exists = true;
3882
3883
if (!shader->vfunctions[i].callable) {
3884
_set_error(vformat(RTR("Function '%s' can't be called from source code."), String(name)));
3885
return false;
3886
}
3887
3888
FunctionNode *pfunc = shader->vfunctions[i].function;
3889
arg_list.clear();
3890
for (int j = 0; j < pfunc->arguments.size(); j++) {
3891
if (j > 0) {
3892
arg_list += ", ";
3893
}
3894
String func_arg_name;
3895
if (pfunc->arguments[j].type == TYPE_STRUCT) {
3896
func_arg_name = pfunc->arguments[j].struct_name;
3897
} else {
3898
func_arg_name = get_datatype_name(pfunc->arguments[j].type);
3899
}
3900
if (pfunc->arguments[j].array_size > 0) {
3901
func_arg_name += "[";
3902
func_arg_name += itos(pfunc->arguments[j].array_size);
3903
func_arg_name += "]";
3904
}
3905
arg_list += func_arg_name;
3906
}
3907
3908
if (pfunc->arguments.size() != args.size()) {
3909
last_arg_count = pfunc->arguments.size();
3910
continue;
3911
}
3912
3913
bool fail = false;
3914
bool use_constant_conversion = function_overload_count[rname] == 0;
3915
3916
for (int j = 0; j < args.size(); j++) {
3917
if (use_constant_conversion && 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)) {
3918
//all good, but it needs implicit conversion later
3919
} else if (args[j] != pfunc->arguments[j].type || (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].struct_name) || args3[j] != pfunc->arguments[j].array_size) {
3920
String func_arg_name;
3921
if (pfunc->arguments[j].type == TYPE_STRUCT) {
3922
func_arg_name = pfunc->arguments[j].struct_name;
3923
} else {
3924
func_arg_name = get_datatype_name(pfunc->arguments[j].type);
3925
}
3926
if (pfunc->arguments[j].array_size > 0) {
3927
func_arg_name += "[";
3928
func_arg_name += itos(pfunc->arguments[j].array_size);
3929
func_arg_name += "]";
3930
}
3931
String arg_name;
3932
if (args[j] == TYPE_STRUCT) {
3933
arg_name = args2[j];
3934
} else {
3935
arg_name = get_datatype_name(args[j]);
3936
}
3937
if (args3[j] > 0) {
3938
arg_name += "[";
3939
arg_name += itos(args3[j]);
3940
arg_name += "]";
3941
}
3942
3943
fail = true;
3944
OverloadErrorInfo err_info;
3945
err_info.arg_list = arg_list;
3946
err_info.index = j + 1;
3947
err_info.func_arg_name = func_arg_name;
3948
err_info.arg_name = arg_name;
3949
overload_errors.push_back(err_info);
3950
overload_fail = true;
3951
break;
3952
} else {
3953
overload_fail = false;
3954
}
3955
}
3956
3957
if (!fail) {
3958
//implicitly convert values if possible
3959
for (int k = 0; k < args.size(); k++) {
3960
if (get_scalar_type(args[k]) != args[k] || args[k] == pfunc->arguments[k].type || p_func->arguments[k + 1]->type != Node::NODE_TYPE_CONSTANT) {
3961
//can't do implicit conversion here
3962
continue;
3963
}
3964
3965
//this is an implicit conversion
3966
ConstantNode *constant = static_cast<ConstantNode *>(p_func->arguments[k + 1]);
3967
ConstantNode *conversion = alloc_node<ConstantNode>();
3968
3969
conversion->datatype = pfunc->arguments[k].type;
3970
conversion->values.resize(1);
3971
3972
convert_constant(constant, pfunc->arguments[k].type, conversion->values.ptrw());
3973
p_func->arguments.write[k + 1] = conversion;
3974
}
3975
3976
if (r_ret_type) {
3977
*r_ret_type = pfunc->return_type;
3978
if (pfunc->return_type == TYPE_STRUCT) {
3979
*r_ret_type_str = pfunc->return_struct_name;
3980
}
3981
}
3982
3983
if (r_is_custom_function) {
3984
*r_is_custom_function = true;
3985
}
3986
return true;
3987
}
3988
}
3989
if (overload_fail) {
3990
String err_str;
3991
if (overload_errors.size() == 1) {
3992
const OverloadErrorInfo &err_info = overload_errors[0];
3993
err_str = vformat("No matching function for \"%s(%s)\" call: argument %d should be %s but is %s.", String(rname), err_info.arg_list, err_info.index, err_info.func_arg_name, err_info.arg_name);
3994
} else {
3995
err_str = vformat(RTR("No matching function for \"%s\" call:"), String(rname));
3996
for (const OverloadErrorInfo &err_info : overload_errors) {
3997
err_str += "\n\t" + vformat(RTR("candidate function \"%s(%s)\" not viable, argument %d should be %s but is %s."), String(rname), err_info.arg_list, err_info.index, err_info.func_arg_name, err_info.arg_name);
3998
}
3999
}
4000
_set_error(err_str);
4001
}
4002
4003
if (exists) {
4004
if (last_arg_count > args.size()) {
4005
_set_error(vformat(RTR("Too few arguments for \"%s(%s)\" call. Expected at least %d but received %d."), String(rname), arg_list, last_arg_count, args.size()));
4006
} else if (last_arg_count < args.size()) {
4007
_set_error(vformat(RTR("Too many arguments for \"%s(%s)\" call. Expected at most %d but received %d."), String(rname), arg_list, last_arg_count, args.size()));
4008
}
4009
}
4010
4011
return false;
4012
}
4013
4014
bool 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) {
4015
bool result = true;
4016
4017
if (p_datatype_a == TYPE_STRUCT || p_datatype_b == TYPE_STRUCT) {
4018
if (p_datatype_name_a != p_datatype_name_b) {
4019
result = false;
4020
}
4021
} else {
4022
if (p_datatype_a != p_datatype_b) {
4023
result = false;
4024
}
4025
}
4026
4027
if (p_array_size_a != p_array_size_b) {
4028
result = false;
4029
}
4030
4031
if (!result) {
4032
String type_name = p_datatype_a == TYPE_STRUCT ? p_datatype_name_a : get_datatype_name(p_datatype_a);
4033
if (p_array_size_a > 0) {
4034
type_name += "[";
4035
type_name += itos(p_array_size_a);
4036
type_name += "]";
4037
}
4038
4039
String type_name2 = p_datatype_b == TYPE_STRUCT ? p_datatype_name_b : get_datatype_name(p_datatype_b);
4040
if (p_array_size_b > 0) {
4041
type_name2 += "[";
4042
type_name2 += itos(p_array_size_b);
4043
type_name2 += "]";
4044
}
4045
4046
_set_error(vformat(RTR("Invalid assignment of '%s' to '%s'."), type_name2, type_name));
4047
}
4048
return result;
4049
}
4050
4051
bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) {
4052
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());
4053
}
4054
4055
bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg) {
4056
TkPos pos = _get_tkpos();
4057
Token tk = _get_token();
4058
4059
if (tk.type == TK_PARENTHESIS_CLOSE) {
4060
return true;
4061
}
4062
4063
_set_tkpos(pos);
4064
4065
while (true) {
4066
if (r_complete_arg) {
4067
pos = _get_tkpos();
4068
tk = _get_token();
4069
4070
if (tk.type == TK_CURSOR) {
4071
*r_complete_arg = p_func->arguments.size() - 1;
4072
} else {
4073
_set_tkpos(pos);
4074
}
4075
}
4076
4077
Node *arg = _parse_and_reduce_expression(p_block, p_function_info);
4078
4079
if (!arg) {
4080
return false;
4081
}
4082
4083
if (is_const_decl && arg->type == Node::NODE_TYPE_VARIABLE) {
4084
const VariableNode *var = static_cast<const VariableNode *>(arg);
4085
if (!var->is_const) {
4086
_set_error(RTR("Expected constant expression."));
4087
return false;
4088
}
4089
}
4090
4091
p_func->arguments.push_back(arg);
4092
4093
tk = _get_token();
4094
4095
if (tk.type == TK_PARENTHESIS_CLOSE) {
4096
return true;
4097
} else if (tk.type != TK_COMMA) {
4098
// something is broken
4099
_set_error(RTR("Expected ',' or ')' after argument."));
4100
return false;
4101
}
4102
}
4103
4104
return true;
4105
}
4106
4107
bool ShaderLanguage::is_token_operator(TokenType p_type) {
4108
return (p_type == TK_OP_EQUAL ||
4109
p_type == TK_OP_NOT_EQUAL ||
4110
p_type == TK_OP_LESS ||
4111
p_type == TK_OP_LESS_EQUAL ||
4112
p_type == TK_OP_GREATER ||
4113
p_type == TK_OP_GREATER_EQUAL ||
4114
p_type == TK_OP_AND ||
4115
p_type == TK_OP_OR ||
4116
p_type == TK_OP_NOT ||
4117
p_type == TK_OP_ADD ||
4118
p_type == TK_OP_SUB ||
4119
p_type == TK_OP_MUL ||
4120
p_type == TK_OP_DIV ||
4121
p_type == TK_OP_MOD ||
4122
p_type == TK_OP_SHIFT_LEFT ||
4123
p_type == TK_OP_SHIFT_RIGHT ||
4124
p_type == TK_OP_ASSIGN ||
4125
p_type == TK_OP_ASSIGN_ADD ||
4126
p_type == TK_OP_ASSIGN_SUB ||
4127
p_type == TK_OP_ASSIGN_MUL ||
4128
p_type == TK_OP_ASSIGN_DIV ||
4129
p_type == TK_OP_ASSIGN_MOD ||
4130
p_type == TK_OP_ASSIGN_SHIFT_LEFT ||
4131
p_type == TK_OP_ASSIGN_SHIFT_RIGHT ||
4132
p_type == TK_OP_ASSIGN_BIT_AND ||
4133
p_type == TK_OP_ASSIGN_BIT_OR ||
4134
p_type == TK_OP_ASSIGN_BIT_XOR ||
4135
p_type == TK_OP_BIT_AND ||
4136
p_type == TK_OP_BIT_OR ||
4137
p_type == TK_OP_BIT_XOR ||
4138
p_type == TK_OP_BIT_INVERT ||
4139
p_type == TK_OP_INCREMENT ||
4140
p_type == TK_OP_DECREMENT ||
4141
p_type == TK_QUESTION ||
4142
p_type == TK_COLON);
4143
}
4144
4145
bool ShaderLanguage::is_token_operator_assign(TokenType p_type) {
4146
return (p_type == TK_OP_ASSIGN ||
4147
p_type == TK_OP_ASSIGN_ADD ||
4148
p_type == TK_OP_ASSIGN_SUB ||
4149
p_type == TK_OP_ASSIGN_MUL ||
4150
p_type == TK_OP_ASSIGN_DIV ||
4151
p_type == TK_OP_ASSIGN_MOD ||
4152
p_type == TK_OP_ASSIGN_SHIFT_LEFT ||
4153
p_type == TK_OP_ASSIGN_SHIFT_RIGHT ||
4154
p_type == TK_OP_ASSIGN_BIT_AND ||
4155
p_type == TK_OP_ASSIGN_BIT_OR ||
4156
p_type == TK_OP_ASSIGN_BIT_XOR);
4157
}
4158
4159
bool ShaderLanguage::is_token_hint(TokenType p_type) {
4160
return int(p_type) > int(TK_STENCIL_MODE) && int(p_type) < int(TK_SHADER_TYPE);
4161
}
4162
4163
bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_type, Scalar *p_value) {
4164
if (p_constant->datatype == p_to_type) {
4165
if (p_value) {
4166
for (int i = 0; i < p_constant->values.size(); i++) {
4167
p_value[i] = p_constant->values[i];
4168
}
4169
}
4170
return true;
4171
} else if (p_constant->datatype == TYPE_INT && p_to_type == TYPE_FLOAT) {
4172
if (p_value) {
4173
p_value->real = p_constant->values[0].sint;
4174
}
4175
return true;
4176
} else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_FLOAT) {
4177
if (p_value) {
4178
p_value->real = p_constant->values[0].uint;
4179
}
4180
return true;
4181
} else if (p_constant->datatype == TYPE_INT && p_to_type == TYPE_UINT) {
4182
if (p_constant->values[0].sint < 0) {
4183
return false;
4184
}
4185
if (p_value) {
4186
p_value->uint = p_constant->values[0].sint;
4187
}
4188
return true;
4189
} else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_INT) {
4190
if (p_constant->values[0].uint > 0x7FFFFFFF) {
4191
return false;
4192
}
4193
if (p_value) {
4194
p_value->sint = p_constant->values[0].uint;
4195
}
4196
return true;
4197
} else {
4198
return false;
4199
}
4200
}
4201
4202
bool ShaderLanguage::is_scalar_type(DataType p_type) {
4203
return p_type == TYPE_BOOL || p_type == TYPE_INT || p_type == TYPE_UINT || p_type == TYPE_FLOAT;
4204
}
4205
4206
bool ShaderLanguage::is_float_type(DataType p_type) {
4207
switch (p_type) {
4208
case TYPE_FLOAT:
4209
case TYPE_VEC2:
4210
case TYPE_VEC3:
4211
case TYPE_VEC4:
4212
case TYPE_MAT2:
4213
case TYPE_MAT3:
4214
case TYPE_MAT4:
4215
case TYPE_SAMPLER2D:
4216
case TYPE_SAMPLER2DARRAY:
4217
case TYPE_SAMPLER3D:
4218
case TYPE_SAMPLERCUBE:
4219
case TYPE_SAMPLERCUBEARRAY: {
4220
return true;
4221
}
4222
default: {
4223
return false;
4224
}
4225
}
4226
}
4227
bool ShaderLanguage::is_sampler_type(DataType p_type) {
4228
return p_type > TYPE_MAT4 && p_type < TYPE_STRUCT;
4229
}
4230
4231
bool ShaderLanguage::ShaderLanguage::is_hint_color(ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
4232
return p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR || p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR_CONVERSION_DISABLED;
4233
}
4234
4235
Variant ShaderLanguage::constant_value_to_variant(const Vector<Scalar> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
4236
int array_size = p_array_size;
4237
4238
if (p_value.size() > 0) {
4239
Variant value;
4240
switch (p_type) {
4241
case ShaderLanguage::TYPE_BOOL:
4242
if (array_size > 0) {
4243
PackedInt32Array array;
4244
for (int i = 0; i < array_size; i++) {
4245
array.push_back(p_value[i].boolean);
4246
}
4247
value = Variant(array);
4248
} else {
4249
value = Variant(p_value[0].boolean);
4250
}
4251
break;
4252
case ShaderLanguage::TYPE_BVEC2:
4253
array_size *= 2;
4254
4255
if (array_size > 0) {
4256
PackedInt32Array array;
4257
for (int i = 0; i < array_size; i++) {
4258
array.push_back(p_value[i].boolean);
4259
}
4260
value = Variant(array);
4261
} else {
4262
value = Variant(p_value[0].sint | (p_value[1].sint << 1));
4263
}
4264
break;
4265
case ShaderLanguage::TYPE_BVEC3:
4266
array_size *= 3;
4267
4268
if (array_size > 0) {
4269
PackedInt32Array array;
4270
for (int i = 0; i < array_size; i++) {
4271
array.push_back(p_value[i].boolean);
4272
}
4273
value = Variant(array);
4274
} else {
4275
value = Variant(p_value[0].sint | (p_value[1].sint << 1) | (p_value[2].sint << 2));
4276
}
4277
break;
4278
case ShaderLanguage::TYPE_BVEC4:
4279
array_size *= 4;
4280
4281
if (array_size > 0) {
4282
PackedInt32Array array;
4283
for (int i = 0; i < array_size; i++) {
4284
array.push_back(p_value[i].boolean);
4285
}
4286
value = Variant(array);
4287
} else {
4288
value = Variant(p_value[0].sint | (p_value[1].sint << 1) | (p_value[2].sint << 2) | (p_value[3].sint << 3));
4289
}
4290
break;
4291
case ShaderLanguage::TYPE_INT:
4292
if (array_size > 0) {
4293
PackedInt32Array array;
4294
for (int i = 0; i < array_size; i++) {
4295
array.push_back(p_value[i].sint);
4296
}
4297
value = Variant(array);
4298
} else {
4299
value = Variant(p_value[0].sint);
4300
}
4301
break;
4302
case ShaderLanguage::TYPE_IVEC2:
4303
if (array_size > 0) {
4304
array_size *= 2;
4305
4306
PackedInt32Array array;
4307
for (int i = 0; i < array_size; i++) {
4308
array.push_back(p_value[i].sint);
4309
}
4310
value = Variant(array);
4311
} else {
4312
value = Variant(Vector2i(p_value[0].sint, p_value[1].sint));
4313
}
4314
break;
4315
case ShaderLanguage::TYPE_IVEC3:
4316
if (array_size > 0) {
4317
array_size *= 3;
4318
4319
PackedInt32Array array;
4320
for (int i = 0; i < array_size; i++) {
4321
array.push_back(p_value[i].sint);
4322
}
4323
value = Variant(array);
4324
} else {
4325
value = Variant(Vector3i(p_value[0].sint, p_value[1].sint, p_value[2].sint));
4326
}
4327
break;
4328
case ShaderLanguage::TYPE_IVEC4:
4329
if (array_size > 0) {
4330
array_size *= 4;
4331
4332
PackedInt32Array array;
4333
for (int i = 0; i < array_size; i++) {
4334
array.push_back(p_value[i].sint);
4335
}
4336
value = Variant(array);
4337
} else {
4338
value = Variant(Vector4i(p_value[0].sint, p_value[1].sint, p_value[2].sint, p_value[3].sint));
4339
}
4340
break;
4341
case ShaderLanguage::TYPE_UINT:
4342
if (array_size > 0) {
4343
PackedInt32Array array;
4344
for (int i = 0; i < array_size; i++) {
4345
array.push_back(p_value[i].uint);
4346
}
4347
value = Variant(array);
4348
} else {
4349
value = Variant(p_value[0].uint);
4350
}
4351
break;
4352
case ShaderLanguage::TYPE_UVEC2:
4353
if (array_size > 0) {
4354
array_size *= 2;
4355
4356
PackedInt32Array array;
4357
for (int i = 0; i < array_size; i++) {
4358
array.push_back(p_value[i].uint);
4359
}
4360
value = Variant(array);
4361
} else {
4362
value = Variant(Vector2i(p_value[0].uint, p_value[1].uint));
4363
}
4364
break;
4365
case ShaderLanguage::TYPE_UVEC3:
4366
if (array_size > 0) {
4367
array_size *= 3;
4368
4369
PackedInt32Array array;
4370
for (int i = 0; i < array_size; i++) {
4371
array.push_back(p_value[i].uint);
4372
}
4373
value = Variant(array);
4374
} else {
4375
value = Variant(Vector3i(p_value[0].uint, p_value[1].uint, p_value[2].uint));
4376
}
4377
break;
4378
case ShaderLanguage::TYPE_UVEC4:
4379
if (array_size > 0) {
4380
array_size *= 4;
4381
4382
PackedInt32Array array;
4383
for (int i = 0; i < array_size; i++) {
4384
array.push_back(p_value[i].uint);
4385
}
4386
value = Variant(array);
4387
} else {
4388
value = Variant(Vector4i(p_value[0].uint, p_value[1].uint, p_value[2].uint, p_value[3].uint));
4389
}
4390
break;
4391
case ShaderLanguage::TYPE_FLOAT:
4392
if (array_size > 0) {
4393
PackedFloat32Array array;
4394
for (int i = 0; i < array_size; i++) {
4395
array.push_back(p_value[i].real);
4396
}
4397
value = Variant(array);
4398
} else {
4399
value = Variant(p_value[0].real);
4400
}
4401
break;
4402
case ShaderLanguage::TYPE_VEC2:
4403
if (array_size > 0) {
4404
array_size *= 2;
4405
4406
PackedVector2Array array;
4407
for (int i = 0; i < array_size; i += 2) {
4408
array.push_back(Vector2(p_value[i].real, p_value[i + 1].real));
4409
}
4410
value = Variant(array);
4411
} else {
4412
value = Variant(Vector2(p_value[0].real, p_value[1].real));
4413
}
4414
break;
4415
case ShaderLanguage::TYPE_VEC3:
4416
if (array_size > 0) {
4417
array_size *= 3;
4418
4419
if (ShaderLanguage::is_hint_color(p_hint)) {
4420
PackedColorArray array;
4421
for (int i = 0; i < array_size; i += 3) {
4422
array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
4423
}
4424
value = Variant(array);
4425
} else {
4426
PackedVector3Array array;
4427
for (int i = 0; i < array_size; i += 3) {
4428
array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
4429
}
4430
value = Variant(array);
4431
}
4432
} else {
4433
if (ShaderLanguage::is_hint_color(p_hint)) {
4434
value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real));
4435
} else {
4436
value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
4437
}
4438
}
4439
break;
4440
case ShaderLanguage::TYPE_VEC4:
4441
if (array_size > 0) {
4442
array_size *= 4;
4443
4444
if (ShaderLanguage::is_hint_color(p_hint)) {
4445
PackedColorArray array;
4446
for (int i = 0; i < array_size; i += 4) {
4447
array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real, p_value[i + 3].real));
4448
}
4449
value = Variant(array);
4450
} else {
4451
PackedVector4Array array;
4452
for (int i = 0; i < array_size; i += 4) {
4453
array.push_back(Vector4(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real, p_value[i + 3].real));
4454
}
4455
value = Variant(array);
4456
}
4457
} else {
4458
if (ShaderLanguage::is_hint_color(p_hint)) {
4459
value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
4460
} else {
4461
value = Variant(Vector4(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
4462
}
4463
}
4464
break;
4465
case ShaderLanguage::TYPE_MAT2:
4466
if (array_size > 0) {
4467
array_size *= 4;
4468
4469
PackedFloat32Array array;
4470
for (int i = 0; i < array_size; i += 4) {
4471
array.push_back(p_value[i].real);
4472
array.push_back(p_value[i + 1].real);
4473
array.push_back(p_value[i + 2].real);
4474
array.push_back(p_value[i + 3].real);
4475
}
4476
value = Variant(array);
4477
} else {
4478
value = Variant(Transform2D(p_value[0].real, p_value[2].real, p_value[1].real, p_value[3].real, 0.0, 0.0));
4479
}
4480
break;
4481
case ShaderLanguage::TYPE_MAT3: {
4482
if (array_size > 0) {
4483
array_size *= 9;
4484
4485
PackedFloat32Array array;
4486
for (int i = 0; i < array_size; i += 9) {
4487
for (int j = 0; j < 9; j++) {
4488
array.push_back(p_value[i + j].real);
4489
}
4490
}
4491
value = Variant(array);
4492
} else {
4493
Basis p;
4494
p[0][0] = p_value[0].real;
4495
p[0][1] = p_value[1].real;
4496
p[0][2] = p_value[2].real;
4497
p[1][0] = p_value[3].real;
4498
p[1][1] = p_value[4].real;
4499
p[1][2] = p_value[5].real;
4500
p[2][0] = p_value[6].real;
4501
p[2][1] = p_value[7].real;
4502
p[2][2] = p_value[8].real;
4503
value = Variant(p);
4504
}
4505
break;
4506
}
4507
case ShaderLanguage::TYPE_MAT4: {
4508
if (array_size > 0) {
4509
array_size *= 16;
4510
4511
PackedFloat32Array array;
4512
for (int i = 0; i < array_size; i += 16) {
4513
for (int j = 0; j < 16; j++) {
4514
array.push_back(p_value[i + j].real);
4515
}
4516
}
4517
value = Variant(array);
4518
} else {
4519
Projection p = Projection(Vector4(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real),
4520
Vector4(p_value[4].real, p_value[5].real, p_value[6].real, p_value[7].real),
4521
Vector4(p_value[8].real, p_value[9].real, p_value[10].real, p_value[11].real),
4522
Vector4(p_value[12].real, p_value[13].real, p_value[14].real, p_value[15].real));
4523
value = Variant(p);
4524
}
4525
break;
4526
}
4527
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
4528
case ShaderLanguage::TYPE_ISAMPLER2D:
4529
case ShaderLanguage::TYPE_ISAMPLER3D:
4530
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
4531
case ShaderLanguage::TYPE_SAMPLER2D:
4532
case ShaderLanguage::TYPE_SAMPLER3D:
4533
case ShaderLanguage::TYPE_USAMPLER2DARRAY:
4534
case ShaderLanguage::TYPE_USAMPLER2D:
4535
case ShaderLanguage::TYPE_USAMPLER3D:
4536
case ShaderLanguage::TYPE_SAMPLERCUBE:
4537
case ShaderLanguage::TYPE_SAMPLERCUBEARRAY:
4538
case ShaderLanguage::TYPE_SAMPLEREXT: {
4539
// Texture types, likely not relevant here.
4540
break;
4541
}
4542
case ShaderLanguage::TYPE_STRUCT:
4543
break;
4544
case ShaderLanguage::TYPE_VOID:
4545
break;
4546
case ShaderLanguage::TYPE_MAX:
4547
break;
4548
}
4549
return value;
4550
}
4551
return Variant();
4552
}
4553
4554
Variant ShaderLanguage::get_default_datatype_value(DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
4555
int array_size = p_array_size;
4556
4557
Variant value;
4558
switch (p_type) {
4559
case ShaderLanguage::TYPE_BOOL:
4560
if (array_size > 0) {
4561
PackedInt32Array array;
4562
for (int i = 0; i < array_size; i++) {
4563
array.push_back(false);
4564
}
4565
value = Variant(array);
4566
} else {
4567
VariantInitializer<bool>::init(&value);
4568
VariantDefaultInitializer<bool>::init(&value);
4569
}
4570
break;
4571
case ShaderLanguage::TYPE_BVEC2:
4572
array_size *= 2;
4573
4574
if (array_size > 0) {
4575
PackedInt32Array array;
4576
for (int i = 0; i < array_size; i++) {
4577
array.push_back(false);
4578
}
4579
value = Variant(array);
4580
} else {
4581
VariantInitializer<int64_t>::init(&value);
4582
VariantDefaultInitializer<int64_t>::init(&value);
4583
}
4584
break;
4585
case ShaderLanguage::TYPE_BVEC3:
4586
array_size *= 3;
4587
4588
if (array_size > 0) {
4589
PackedInt32Array array;
4590
for (int i = 0; i < array_size; i++) {
4591
array.push_back(false);
4592
}
4593
value = Variant(array);
4594
} else {
4595
VariantInitializer<int64_t>::init(&value);
4596
VariantDefaultInitializer<int64_t>::init(&value);
4597
}
4598
break;
4599
case ShaderLanguage::TYPE_BVEC4:
4600
array_size *= 4;
4601
4602
if (array_size > 0) {
4603
PackedInt32Array array;
4604
for (int i = 0; i < array_size; i++) {
4605
array.push_back(false);
4606
}
4607
value = Variant(array);
4608
} else {
4609
VariantInitializer<int64_t>::init(&value);
4610
VariantDefaultInitializer<int64_t>::init(&value);
4611
}
4612
break;
4613
case ShaderLanguage::TYPE_INT:
4614
if (array_size > 0) {
4615
PackedInt32Array array;
4616
for (int i = 0; i < array_size; i++) {
4617
array.push_back(0);
4618
}
4619
value = Variant(array);
4620
} else {
4621
VariantInitializer<int64_t>::init(&value);
4622
VariantDefaultInitializer<int64_t>::init(&value);
4623
}
4624
break;
4625
case ShaderLanguage::TYPE_IVEC2:
4626
if (array_size > 0) {
4627
array_size *= 2;
4628
4629
PackedInt32Array array;
4630
for (int i = 0; i < array_size; i++) {
4631
array.push_back(0);
4632
}
4633
value = Variant(array);
4634
} else {
4635
VariantInitializer<Vector2i>::init(&value);
4636
VariantDefaultInitializer<Vector2i>::init(&value);
4637
}
4638
break;
4639
case ShaderLanguage::TYPE_IVEC3:
4640
if (array_size > 0) {
4641
array_size *= 3;
4642
4643
PackedInt32Array array;
4644
for (int i = 0; i < array_size; i++) {
4645
array.push_back(0);
4646
}
4647
value = Variant(array);
4648
} else {
4649
VariantInitializer<Vector3i>::init(&value);
4650
VariantDefaultInitializer<Vector3i>::init(&value);
4651
}
4652
break;
4653
case ShaderLanguage::TYPE_IVEC4:
4654
if (array_size > 0) {
4655
array_size *= 4;
4656
4657
PackedInt32Array array;
4658
for (int i = 0; i < array_size; i++) {
4659
array.push_back(0);
4660
}
4661
value = Variant(array);
4662
} else {
4663
VariantInitializer<Vector4i>::init(&value);
4664
VariantDefaultInitializer<Vector4i>::init(&value);
4665
}
4666
break;
4667
case ShaderLanguage::TYPE_UINT:
4668
if (array_size > 0) {
4669
PackedInt32Array array;
4670
for (int i = 0; i < array_size; i++) {
4671
array.push_back(0U);
4672
}
4673
value = Variant(array);
4674
} else {
4675
VariantInitializer<int64_t>::init(&value);
4676
VariantDefaultInitializer<int64_t>::init(&value);
4677
}
4678
break;
4679
case ShaderLanguage::TYPE_UVEC2:
4680
if (array_size > 0) {
4681
array_size *= 2;
4682
4683
PackedInt32Array array;
4684
for (int i = 0; i < array_size; i++) {
4685
array.push_back(0U);
4686
}
4687
value = Variant(array);
4688
} else {
4689
VariantInitializer<Vector2i>::init(&value);
4690
VariantDefaultInitializer<Vector2i>::init(&value);
4691
}
4692
break;
4693
case ShaderLanguage::TYPE_UVEC3:
4694
if (array_size > 0) {
4695
array_size *= 3;
4696
4697
PackedInt32Array array;
4698
for (int i = 0; i < array_size; i++) {
4699
array.push_back(0U);
4700
}
4701
value = Variant(array);
4702
} else {
4703
VariantInitializer<Vector3i>::init(&value);
4704
VariantDefaultInitializer<Vector3i>::init(&value);
4705
}
4706
break;
4707
case ShaderLanguage::TYPE_UVEC4:
4708
if (array_size > 0) {
4709
array_size *= 4;
4710
4711
PackedInt32Array array;
4712
for (int i = 0; i < array_size; i++) {
4713
array.push_back(0U);
4714
}
4715
value = Variant(array);
4716
} else {
4717
VariantInitializer<Vector4i>::init(&value);
4718
VariantDefaultInitializer<Vector4i>::init(&value);
4719
}
4720
break;
4721
case ShaderLanguage::TYPE_FLOAT:
4722
if (array_size > 0) {
4723
PackedFloat32Array array;
4724
for (int i = 0; i < array_size; i++) {
4725
array.push_back(0.0f);
4726
}
4727
value = Variant(array);
4728
} else {
4729
VariantInitializer<double>::init(&value);
4730
VariantDefaultInitializer<double>::init(&value);
4731
}
4732
break;
4733
case ShaderLanguage::TYPE_VEC2:
4734
if (array_size > 0) {
4735
PackedVector2Array array;
4736
for (int i = 0; i < array_size; i++) {
4737
array.push_back(Vector2(0.0f, 0.0f));
4738
}
4739
value = Variant(array);
4740
} else {
4741
VariantInitializer<Vector2>::init(&value);
4742
VariantDefaultInitializer<Vector2>::init(&value);
4743
}
4744
break;
4745
case ShaderLanguage::TYPE_VEC3:
4746
if (array_size > 0) {
4747
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
4748
PackedColorArray array;
4749
for (int i = 0; i < array_size; i++) {
4750
array.push_back(Color(0.0f, 0.0f, 0.0f));
4751
}
4752
value = Variant(array);
4753
} else {
4754
PackedVector3Array array;
4755
for (int i = 0; i < array_size; i++) {
4756
array.push_back(Vector3(0.0f, 0.0f, 0.0f));
4757
}
4758
value = Variant(array);
4759
}
4760
} else {
4761
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
4762
VariantInitializer<Color>::init(&value);
4763
VariantDefaultInitializer<Color>::init(&value);
4764
} else {
4765
VariantInitializer<Vector3>::init(&value);
4766
VariantDefaultInitializer<Vector3>::init(&value);
4767
}
4768
}
4769
break;
4770
case ShaderLanguage::TYPE_VEC4:
4771
if (array_size > 0) {
4772
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
4773
PackedColorArray array;
4774
for (int i = 0; i < array_size; i++) {
4775
array.push_back(Color(0.0f, 0.0f, 0.0f, 0.0f));
4776
}
4777
value = Variant(array);
4778
} else {
4779
PackedVector4Array array;
4780
for (int i = 0; i < array_size; i++) {
4781
array.push_back(Vector4(0.0f, 0.0f, 0.0f, 0.0f));
4782
}
4783
value = Variant(array);
4784
}
4785
} else {
4786
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
4787
VariantInitializer<Color>::init(&value);
4788
VariantDefaultInitializer<Color>::init(&value);
4789
} else {
4790
VariantInitializer<Vector4>::init(&value);
4791
VariantDefaultInitializer<Vector4>::init(&value);
4792
}
4793
}
4794
break;
4795
case ShaderLanguage::TYPE_MAT2:
4796
if (array_size > 0) {
4797
PackedFloat32Array array;
4798
for (int i = 0; i < array_size; i++) {
4799
for (int j = 0; j < 4; j++) {
4800
array.push_back(0.0f);
4801
}
4802
}
4803
value = Variant(array);
4804
} else {
4805
VariantInitializer<Transform2D>::init(&value);
4806
VariantDefaultInitializer<Transform2D>::init(&value);
4807
}
4808
break;
4809
case ShaderLanguage::TYPE_MAT3: {
4810
if (array_size > 0) {
4811
PackedFloat32Array array;
4812
for (int i = 0; i < array_size; i++) {
4813
for (int j = 0; j < 9; j++) {
4814
array.push_back(0.0f);
4815
}
4816
}
4817
value = Variant(array);
4818
} else {
4819
VariantInitializer<Basis>::init(&value);
4820
VariantDefaultInitializer<Basis>::init(&value);
4821
}
4822
break;
4823
}
4824
case ShaderLanguage::TYPE_MAT4: {
4825
if (array_size > 0) {
4826
PackedFloat32Array array;
4827
for (int i = 0; i < array_size; i++) {
4828
for (int j = 0; j < 16; j++) {
4829
array.push_back(0.0f);
4830
}
4831
}
4832
value = Variant(array);
4833
} else {
4834
VariantInitializer<Projection>::init(&value);
4835
VariantDefaultInitializer<Projection>::init(&value);
4836
}
4837
break;
4838
}
4839
default: {
4840
} break;
4841
}
4842
return value;
4843
}
4844
4845
PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform &p_uniform) {
4846
PropertyInfo pi;
4847
switch (p_uniform.type) {
4848
case ShaderLanguage::TYPE_VOID:
4849
pi.type = Variant::NIL;
4850
break;
4851
case ShaderLanguage::TYPE_BOOL:
4852
if (p_uniform.array_size > 0) {
4853
pi.type = Variant::PACKED_INT32_ARRAY;
4854
pi.hint = PROPERTY_HINT_TYPE_STRING;
4855
pi.hint_string = itos(Variant::INT) + "/" + itos(PROPERTY_HINT_FLAGS) + ":" + RTR("On");
4856
} else {
4857
pi.type = Variant::BOOL;
4858
}
4859
break;
4860
case ShaderLanguage::TYPE_BVEC2:
4861
if (p_uniform.array_size > 0) {
4862
pi.type = Variant::PACKED_INT32_ARRAY;
4863
pi.hint = PROPERTY_HINT_TYPE_STRING;
4864
pi.hint_string = itos(Variant::INT) + "/" + itos(PROPERTY_HINT_FLAGS) + ":x,y";
4865
} else {
4866
pi.type = Variant::INT;
4867
pi.hint = PROPERTY_HINT_FLAGS;
4868
pi.hint_string = "x,y";
4869
}
4870
break;
4871
case ShaderLanguage::TYPE_BVEC3:
4872
if (p_uniform.array_size > 0) {
4873
pi.type = Variant::PACKED_INT32_ARRAY;
4874
pi.hint = PROPERTY_HINT_TYPE_STRING;
4875
pi.hint_string = itos(Variant::INT) + "/" + itos(PROPERTY_HINT_FLAGS) + ":x,y,z";
4876
} else {
4877
pi.type = Variant::INT;
4878
pi.hint = PROPERTY_HINT_FLAGS;
4879
pi.hint_string = "x,y,z";
4880
}
4881
break;
4882
case ShaderLanguage::TYPE_BVEC4:
4883
if (p_uniform.array_size > 0) {
4884
pi.type = Variant::PACKED_INT32_ARRAY;
4885
pi.hint = PROPERTY_HINT_TYPE_STRING;
4886
pi.hint_string = itos(Variant::INT) + "/" + itos(PROPERTY_HINT_FLAGS) + ":x,y,z,w";
4887
} else {
4888
pi.type = Variant::INT;
4889
pi.hint = PROPERTY_HINT_FLAGS;
4890
pi.hint_string = "x,y,z,w";
4891
}
4892
break;
4893
case ShaderLanguage::TYPE_UINT:
4894
case ShaderLanguage::TYPE_INT: {
4895
if (p_uniform.array_size > 0) {
4896
pi.type = Variant::PACKED_INT32_ARRAY;
4897
// TODO: Handle range and encoding for for unsigned values.
4898
} else if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_ENUM) {
4899
pi.type = Variant::INT;
4900
pi.hint = PROPERTY_HINT_ENUM;
4901
String hint_string;
4902
pi.hint_string = String(",").join(p_uniform.hint_enum_names);
4903
} else {
4904
pi.type = Variant::INT;
4905
pi.hint = PROPERTY_HINT_RANGE;
4906
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
4907
pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
4908
} else if (p_uniform.type == ShaderLanguage::TYPE_UINT) {
4909
pi.hint_string = "0," + itos(UINT32_MAX);
4910
} else {
4911
pi.hint_string = itos(INT32_MIN) + "," + itos(INT32_MAX);
4912
}
4913
}
4914
} break;
4915
case ShaderLanguage::TYPE_UVEC2:
4916
case ShaderLanguage::TYPE_IVEC2: {
4917
if (p_uniform.array_size > 0) {
4918
pi.type = Variant::PACKED_INT32_ARRAY;
4919
// TODO: Handle vector pairs?
4920
} else {
4921
pi.type = Variant::VECTOR2I;
4922
}
4923
} break;
4924
case ShaderLanguage::TYPE_UVEC3:
4925
case ShaderLanguage::TYPE_IVEC3: {
4926
if (p_uniform.array_size > 0) {
4927
pi.type = Variant::PACKED_INT32_ARRAY;
4928
// TODO: Handle vector pairs?
4929
} else {
4930
pi.type = Variant::VECTOR3I;
4931
}
4932
} break;
4933
case ShaderLanguage::TYPE_UVEC4:
4934
case ShaderLanguage::TYPE_IVEC4: {
4935
if (p_uniform.array_size > 0) {
4936
pi.type = Variant::PACKED_INT32_ARRAY;
4937
// TODO: Handle vector pairs?
4938
} else {
4939
pi.type = Variant::VECTOR4I;
4940
}
4941
} break;
4942
case ShaderLanguage::TYPE_FLOAT: {
4943
if (p_uniform.array_size > 0) {
4944
pi.type = Variant::PACKED_FLOAT32_ARRAY;
4945
} else {
4946
pi.type = Variant::FLOAT;
4947
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_RANGE) {
4948
pi.hint = PROPERTY_HINT_RANGE;
4949
pi.hint_string = rtos(p_uniform.hint_range[0]) + "," + rtos(p_uniform.hint_range[1]) + "," + rtos(p_uniform.hint_range[2]);
4950
}
4951
}
4952
} break;
4953
case ShaderLanguage::TYPE_VEC2:
4954
if (p_uniform.array_size > 0) {
4955
pi.type = Variant::PACKED_VECTOR2_ARRAY;
4956
} else {
4957
pi.type = Variant::VECTOR2;
4958
}
4959
break;
4960
case ShaderLanguage::TYPE_VEC3:
4961
if (p_uniform.array_size > 0) {
4962
if (ShaderLanguage::is_hint_color(p_uniform.hint)) {
4963
pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
4964
pi.type = Variant::PACKED_COLOR_ARRAY;
4965
} else {
4966
pi.type = Variant::PACKED_VECTOR3_ARRAY;
4967
}
4968
} else {
4969
if (ShaderLanguage::is_hint_color(p_uniform.hint)) {
4970
pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
4971
pi.type = Variant::COLOR;
4972
} else {
4973
pi.type = Variant::VECTOR3;
4974
}
4975
}
4976
break;
4977
case ShaderLanguage::TYPE_VEC4: {
4978
if (p_uniform.array_size > 0) {
4979
if (ShaderLanguage::is_hint_color(p_uniform.hint)) {
4980
pi.type = Variant::PACKED_COLOR_ARRAY;
4981
} else {
4982
pi.type = Variant::PACKED_VECTOR4_ARRAY;
4983
}
4984
} else {
4985
if (ShaderLanguage::is_hint_color(p_uniform.hint)) {
4986
pi.type = Variant::COLOR;
4987
} else {
4988
pi.type = Variant::VECTOR4;
4989
}
4990
}
4991
} break;
4992
case ShaderLanguage::TYPE_MAT2:
4993
if (p_uniform.array_size > 0) {
4994
pi.type = Variant::PACKED_FLOAT32_ARRAY;
4995
} else {
4996
pi.type = Variant::TRANSFORM2D;
4997
}
4998
break;
4999
case ShaderLanguage::TYPE_MAT3:
5000
if (p_uniform.array_size > 0) {
5001
pi.type = Variant::PACKED_FLOAT32_ARRAY;
5002
} else {
5003
pi.type = Variant::BASIS;
5004
}
5005
break;
5006
case ShaderLanguage::TYPE_MAT4:
5007
if (p_uniform.array_size > 0) {
5008
pi.type = Variant::PACKED_FLOAT32_ARRAY;
5009
} else {
5010
pi.type = Variant::PROJECTION;
5011
}
5012
break;
5013
case ShaderLanguage::TYPE_SAMPLER2D:
5014
case ShaderLanguage::TYPE_ISAMPLER2D:
5015
case ShaderLanguage::TYPE_USAMPLER2D: {
5016
if (p_uniform.array_size > 0) {
5017
pi.type = Variant::ARRAY;
5018
pi.hint = PROPERTY_HINT_ARRAY_TYPE;
5019
pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture2D");
5020
} else {
5021
pi.type = Variant::OBJECT;
5022
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
5023
pi.hint_string = "Texture2D";
5024
}
5025
} break;
5026
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
5027
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
5028
case ShaderLanguage::TYPE_USAMPLER2DARRAY:
5029
case ShaderLanguage::TYPE_SAMPLERCUBE:
5030
case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
5031
if (p_uniform.array_size > 0) {
5032
pi.type = Variant::ARRAY;
5033
pi.hint = PROPERTY_HINT_ARRAY_TYPE;
5034
pi.hint_string = MAKE_RESOURCE_TYPE_HINT("TextureLayered");
5035
} else {
5036
pi.type = Variant::OBJECT;
5037
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
5038
pi.hint_string = "TextureLayered";
5039
}
5040
} break;
5041
case ShaderLanguage::TYPE_SAMPLER3D:
5042
case ShaderLanguage::TYPE_ISAMPLER3D:
5043
case ShaderLanguage::TYPE_USAMPLER3D: {
5044
if (p_uniform.array_size > 0) {
5045
pi.type = Variant::ARRAY;
5046
pi.hint = PROPERTY_HINT_ARRAY_TYPE;
5047
pi.hint_string = MAKE_RESOURCE_TYPE_HINT("Texture3D");
5048
} else {
5049
pi.type = Variant::OBJECT;
5050
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
5051
pi.hint_string = "Texture3D";
5052
}
5053
} break;
5054
case ShaderLanguage::TYPE_SAMPLEREXT: {
5055
if (p_uniform.array_size > 0) {
5056
pi.type = Variant::ARRAY;
5057
pi.hint = PROPERTY_HINT_ARRAY_TYPE;
5058
pi.hint_string = MAKE_RESOURCE_TYPE_HINT("ExternalTexture");
5059
} else {
5060
pi.type = Variant::OBJECT;
5061
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
5062
pi.hint_string = "ExternalTexture";
5063
}
5064
} break;
5065
case ShaderLanguage::TYPE_STRUCT: {
5066
// FIXME: Implement this.
5067
} break;
5068
case ShaderLanguage::TYPE_MAX:
5069
break;
5070
}
5071
return pi;
5072
}
5073
5074
uint32_t ShaderLanguage::get_datatype_size(ShaderLanguage::DataType p_type) {
5075
switch (p_type) {
5076
case TYPE_VOID:
5077
return 0;
5078
case TYPE_BOOL:
5079
return 4;
5080
case TYPE_BVEC2:
5081
return 8;
5082
case TYPE_BVEC3:
5083
return 12;
5084
case TYPE_BVEC4:
5085
return 16;
5086
case TYPE_INT:
5087
return 4;
5088
case TYPE_IVEC2:
5089
return 8;
5090
case TYPE_IVEC3:
5091
return 12;
5092
case TYPE_IVEC4:
5093
return 16;
5094
case TYPE_UINT:
5095
return 4;
5096
case TYPE_UVEC2:
5097
return 8;
5098
case TYPE_UVEC3:
5099
return 12;
5100
case TYPE_UVEC4:
5101
return 16;
5102
case TYPE_FLOAT:
5103
return 4;
5104
case TYPE_VEC2:
5105
return 8;
5106
case TYPE_VEC3:
5107
return 12;
5108
case TYPE_VEC4:
5109
return 16;
5110
case TYPE_MAT2:
5111
return 32; // 4 * 4 + 4 * 4
5112
case TYPE_MAT3:
5113
return 48; // 4 * 4 + 4 * 4 + 4 * 4
5114
case TYPE_MAT4:
5115
return 64;
5116
case TYPE_SAMPLER2D:
5117
return 16;
5118
case TYPE_ISAMPLER2D:
5119
return 16;
5120
case TYPE_USAMPLER2D:
5121
return 16;
5122
case TYPE_SAMPLER2DARRAY:
5123
return 16;
5124
case TYPE_ISAMPLER2DARRAY:
5125
return 16;
5126
case TYPE_USAMPLER2DARRAY:
5127
return 16;
5128
case TYPE_SAMPLER3D:
5129
return 16;
5130
case TYPE_ISAMPLER3D:
5131
return 16;
5132
case TYPE_USAMPLER3D:
5133
return 16;
5134
case TYPE_SAMPLERCUBE:
5135
return 16;
5136
case TYPE_SAMPLERCUBEARRAY:
5137
return 16;
5138
case TYPE_SAMPLEREXT:
5139
return 16;
5140
case TYPE_STRUCT:
5141
return 0;
5142
case TYPE_MAX: {
5143
ERR_FAIL_V(0);
5144
};
5145
}
5146
ERR_FAIL_V(0);
5147
}
5148
5149
uint32_t ShaderLanguage::get_datatype_component_count(ShaderLanguage::DataType p_type) {
5150
switch (p_type) {
5151
case TYPE_BOOL:
5152
return 1U;
5153
case TYPE_BVEC2:
5154
return 2U;
5155
case TYPE_BVEC3:
5156
return 3U;
5157
case TYPE_BVEC4:
5158
return 4U;
5159
case TYPE_INT:
5160
return 1U;
5161
case TYPE_IVEC2:
5162
return 2U;
5163
case TYPE_IVEC3:
5164
return 3U;
5165
case TYPE_IVEC4:
5166
return 4U;
5167
case TYPE_UINT:
5168
return 1U;
5169
case TYPE_UVEC2:
5170
return 2U;
5171
case TYPE_UVEC3:
5172
return 3U;
5173
case TYPE_UVEC4:
5174
return 4U;
5175
case TYPE_FLOAT:
5176
return 1U;
5177
case TYPE_VEC2:
5178
return 2U;
5179
case TYPE_VEC3:
5180
return 3U;
5181
case TYPE_VEC4:
5182
return 4U;
5183
case TYPE_MAT2:
5184
return 4U;
5185
case TYPE_MAT3:
5186
return 9U;
5187
case TYPE_MAT4:
5188
return 16U;
5189
default:
5190
break;
5191
}
5192
return 0U;
5193
}
5194
5195
void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
5196
HashSet<String> kws;
5197
5198
int idx = 0;
5199
5200
while (keyword_list[idx].text) {
5201
kws.insert(keyword_list[idx].text);
5202
idx++;
5203
}
5204
5205
idx = 0;
5206
5207
while (builtin_func_defs[idx].name) {
5208
kws.insert(builtin_func_defs[idx].name);
5209
5210
idx++;
5211
}
5212
5213
for (const String &E : kws) {
5214
r_keywords->push_back(E);
5215
}
5216
}
5217
5218
bool ShaderLanguage::is_control_flow_keyword(String p_keyword) {
5219
return p_keyword == "break" ||
5220
p_keyword == "case" ||
5221
p_keyword == "continue" ||
5222
p_keyword == "default" ||
5223
p_keyword == "do" ||
5224
p_keyword == "else" ||
5225
p_keyword == "for" ||
5226
p_keyword == "if" ||
5227
p_keyword == "return" ||
5228
p_keyword == "switch" ||
5229
p_keyword == "while";
5230
}
5231
5232
void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) {
5233
HashSet<String> kws;
5234
5235
int idx = 0;
5236
5237
while (builtin_func_defs[idx].name) {
5238
kws.insert(builtin_func_defs[idx].name);
5239
5240
idx++;
5241
}
5242
5243
for (const String &E : kws) {
5244
r_keywords->push_back(E);
5245
}
5246
}
5247
5248
ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) {
5249
static const DataType scalar_types[] = {
5250
TYPE_VOID,
5251
TYPE_BOOL,
5252
TYPE_BOOL,
5253
TYPE_BOOL,
5254
TYPE_BOOL,
5255
TYPE_INT,
5256
TYPE_INT,
5257
TYPE_INT,
5258
TYPE_INT,
5259
TYPE_UINT,
5260
TYPE_UINT,
5261
TYPE_UINT,
5262
TYPE_UINT,
5263
TYPE_FLOAT,
5264
TYPE_FLOAT,
5265
TYPE_FLOAT,
5266
TYPE_FLOAT,
5267
TYPE_FLOAT,
5268
TYPE_FLOAT,
5269
TYPE_FLOAT,
5270
TYPE_FLOAT,
5271
TYPE_INT,
5272
TYPE_UINT,
5273
TYPE_FLOAT,
5274
TYPE_INT,
5275
TYPE_UINT,
5276
TYPE_FLOAT,
5277
TYPE_INT,
5278
TYPE_UINT,
5279
TYPE_FLOAT,
5280
TYPE_FLOAT,
5281
TYPE_FLOAT,
5282
TYPE_VOID,
5283
};
5284
5285
static_assert(std::size(scalar_types) == TYPE_MAX);
5286
5287
return scalar_types[p_type];
5288
}
5289
5290
int ShaderLanguage::get_cardinality(DataType p_type) {
5291
static const int cardinality_table[] = {
5292
0,
5293
1,
5294
2,
5295
3,
5296
4,
5297
1,
5298
2,
5299
3,
5300
4,
5301
1,
5302
2,
5303
3,
5304
4,
5305
1,
5306
2,
5307
3,
5308
4,
5309
4,
5310
9,
5311
16,
5312
1,
5313
1,
5314
1,
5315
1,
5316
1,
5317
1,
5318
1,
5319
1,
5320
1,
5321
1,
5322
1,
5323
1,
5324
1,
5325
};
5326
5327
static_assert(std::size(cardinality_table) == TYPE_MAX);
5328
5329
return cardinality_table[p_type];
5330
}
5331
5332
bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier) {
5333
identifier = StringName();
5334
5335
TkPos pos = { 0, 0 };
5336
5337
Token tk = _get_token();
5338
5339
if (tk.type == TK_IDENTIFIER) {
5340
identifier = tk.text;
5341
pos = _get_tkpos();
5342
tk = _get_token();
5343
}
5344
5345
if (tk.type == TK_CURSOR) {
5346
completion_type = p_type;
5347
completion_line = tk_line;
5348
completion_block = p_block;
5349
5350
pos = _get_tkpos();
5351
tk = _get_token();
5352
5353
if (tk.type == TK_IDENTIFIER) {
5354
identifier = identifier.operator String() + tk.text.operator String();
5355
} else {
5356
_set_tkpos(pos);
5357
}
5358
return true;
5359
} else if (identifier != StringName()) {
5360
_set_tkpos(pos);
5361
}
5362
5363
return false;
5364
}
5365
5366
bool ShaderLanguage::_is_operator_assign(Operator p_op) const {
5367
switch (p_op) {
5368
case OP_ASSIGN:
5369
case OP_ASSIGN_ADD:
5370
case OP_ASSIGN_SUB:
5371
case OP_ASSIGN_MUL:
5372
case OP_ASSIGN_DIV:
5373
case OP_ASSIGN_MOD:
5374
case OP_ASSIGN_SHIFT_LEFT:
5375
case OP_ASSIGN_SHIFT_RIGHT:
5376
case OP_ASSIGN_BIT_AND:
5377
case OP_ASSIGN_BIT_OR:
5378
case OP_ASSIGN_BIT_XOR:
5379
return true;
5380
default:
5381
return false;
5382
}
5383
}
5384
5385
bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message) {
5386
if (current_function != "vertex" && current_function != "fragment") {
5387
*r_message = vformat(RTR("Varying may not be assigned in the '%s' function."), current_function);
5388
return false;
5389
}
5390
switch (p_varying.stage) {
5391
case ShaderNode::Varying::STAGE_UNKNOWN: // first assign
5392
if (current_function == varying_function_names.vertex) {
5393
if (p_varying.type < TYPE_INT) {
5394
*r_message = vformat(RTR("Varying with '%s' data type may only be assigned in the '%s' function."), get_datatype_name(p_varying.type), "fragment");
5395
return false;
5396
}
5397
p_varying.stage = ShaderNode::Varying::STAGE_VERTEX;
5398
} else if (current_function == varying_function_names.fragment) {
5399
p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT;
5400
}
5401
break;
5402
case ShaderNode::Varying::STAGE_VERTEX:
5403
if (current_function == varying_function_names.fragment) {
5404
*r_message = vformat(RTR("Varyings which assigned in '%s' function may not be reassigned in '%s' or '%s'."), "vertex", "fragment", "light");
5405
return false;
5406
}
5407
break;
5408
case ShaderNode::Varying::STAGE_FRAGMENT:
5409
if (current_function == varying_function_names.vertex) {
5410
*r_message = vformat(RTR("Varyings which assigned in '%s' function may not be reassigned in '%s' or '%s'."), "fragment", "vertex", "light");
5411
return false;
5412
}
5413
break;
5414
default:
5415
break;
5416
}
5417
return true;
5418
}
5419
5420
bool ShaderLanguage::_check_node_constness(const Node *p_node) const {
5421
switch (p_node->type) {
5422
case Node::NODE_TYPE_OPERATOR: {
5423
const OperatorNode *op_node = static_cast<const OperatorNode *>(p_node);
5424
for (int i = int(op_node->op == OP_CALL); i < op_node->arguments.size(); i++) {
5425
if (!_check_node_constness(op_node->arguments[i])) {
5426
return false;
5427
}
5428
}
5429
} break;
5430
case Node::NODE_TYPE_CONSTANT:
5431
break;
5432
case Node::NODE_TYPE_VARIABLE: {
5433
const VariableNode *var_node = static_cast<const VariableNode *>(p_node);
5434
if (!var_node->is_const) {
5435
return false;
5436
}
5437
} break;
5438
case Node::NODE_TYPE_ARRAY: {
5439
const ArrayNode *arr_node = static_cast<const ArrayNode *>(p_node);
5440
if (!arr_node->is_const) {
5441
return false;
5442
}
5443
} break;
5444
default:
5445
return false;
5446
}
5447
return true;
5448
}
5449
5450
bool ShaderLanguage::_check_restricted_func(const StringName &p_name, const StringName &p_current_function) const {
5451
int idx = 0;
5452
5453
while (frag_only_func_defs[idx].name) {
5454
if (StringName(frag_only_func_defs[idx].name) == p_name) {
5455
if (is_supported_frag_only_funcs) {
5456
if (p_current_function == "vertex" && stages->has(p_current_function)) {
5457
return true;
5458
}
5459
} else {
5460
return true;
5461
}
5462
break;
5463
}
5464
idx++;
5465
}
5466
5467
return false;
5468
}
5469
5470
bool ShaderLanguage::_validate_restricted_func(const StringName &p_name, const CallInfo *p_func_info, bool p_is_builtin_hint) {
5471
const bool is_in_restricted_function = p_func_info->name == "vertex";
5472
5473
// No need to check up the hierarchy if it's a built-in.
5474
if (!p_is_builtin_hint) {
5475
for (const CallInfo *func_info : p_func_info->calls) {
5476
if (is_in_restricted_function && func_info->name != p_name) {
5477
// Skips check for non-called method.
5478
continue;
5479
}
5480
5481
if (!_validate_restricted_func(p_name, func_info)) {
5482
return false;
5483
}
5484
}
5485
}
5486
5487
if (!p_func_info->uses_restricted_items.is_empty()) {
5488
const Pair<StringName, CallInfo::Item> &first_element = p_func_info->uses_restricted_items.get(0);
5489
5490
if (first_element.second.type == CallInfo::Item::ITEM_TYPE_VARYING) {
5491
const ShaderNode::Varying &varying = shader->varyings[first_element.first];
5492
5493
if (varying.stage == ShaderNode::Varying::STAGE_VERTEX) {
5494
return true;
5495
}
5496
}
5497
5498
_set_tkpos(first_element.second.pos);
5499
5500
if (is_in_restricted_function) {
5501
_set_error(vformat(RTR("'%s' cannot be used within the '%s' processor function."), first_element.first, "vertex"));
5502
} else {
5503
_set_error(vformat(RTR("'%s' cannot be used here, because '%s' is called by the '%s' processor function (which is not allowed)."), first_element.first, p_func_info->name, "vertex"));
5504
}
5505
return false;
5506
}
5507
5508
return true;
5509
}
5510
5511
bool ShaderLanguage::_validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message) {
5512
if (p_node->type == Node::NODE_TYPE_OPERATOR) {
5513
OperatorNode *op = static_cast<OperatorNode *>(p_node);
5514
5515
if (op->op == OP_INDEX) {
5516
return _validate_assign(op->arguments[0], p_function_info, r_message);
5517
5518
} else if (_is_operator_assign(op->op)) {
5519
//chained assignment
5520
return _validate_assign(op->arguments[1], p_function_info, r_message);
5521
5522
} else if (op->op == OP_CALL) {
5523
if (r_message) {
5524
*r_message = RTR("Assignment to function.");
5525
}
5526
return false;
5527
}
5528
5529
} else if (p_node->type == Node::NODE_TYPE_MEMBER) {
5530
MemberNode *member = static_cast<MemberNode *>(p_node);
5531
5532
if (member->has_swizzling_duplicates) {
5533
if (r_message) {
5534
*r_message = RTR("Swizzling assignment contains duplicates.");
5535
}
5536
return false;
5537
}
5538
5539
return _validate_assign(member->owner, p_function_info, r_message);
5540
5541
} else if (p_node->type == Node::NODE_TYPE_VARIABLE) {
5542
VariableNode *var = static_cast<VariableNode *>(p_node);
5543
5544
if (shader->uniforms.has(var->name)) {
5545
if (r_message) {
5546
*r_message = RTR("Assignment to uniform.");
5547
}
5548
return false;
5549
}
5550
5551
if (shader->constants.has(var->name) || var->is_const) {
5552
if (r_message) {
5553
*r_message = RTR("Constants cannot be modified.");
5554
}
5555
return false;
5556
}
5557
5558
if (shader->varyings.has(var->name)) {
5559
return _validate_varying_assign(shader->varyings[var->name], r_message);
5560
}
5561
5562
if (!(p_function_info.built_ins.has(var->name) && p_function_info.built_ins[var->name].constant)) {
5563
return true;
5564
}
5565
} else if (p_node->type == Node::NODE_TYPE_ARRAY) {
5566
ArrayNode *arr = static_cast<ArrayNode *>(p_node);
5567
5568
if (shader->constants.has(arr->name) || arr->is_const) {
5569
if (r_message) {
5570
*r_message = RTR("Constants cannot be modified.");
5571
}
5572
return false;
5573
}
5574
5575
return true;
5576
}
5577
5578
if (r_message) {
5579
*r_message = "Assignment to constant expression.";
5580
}
5581
return false;
5582
}
5583
5584
ShaderLanguage::ShaderNode::Uniform::Hint ShaderLanguage::_sanitize_hint(ShaderNode::Uniform::Hint p_hint) {
5585
if (p_hint == ShaderNode::Uniform::HINT_SCREEN_TEXTURE ||
5586
p_hint == ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE ||
5587
p_hint == ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
5588
return p_hint;
5589
}
5590
return ShaderNode::Uniform::HINT_NONE;
5591
}
5592
5593
bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(const StringName &p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat, ShaderNode::Uniform::Hint p_hint) {
5594
for (int i = 0; i < shader->vfunctions.size(); i++) {
5595
if (shader->vfunctions[i].name == p_name) {
5596
ERR_FAIL_INDEX_V(p_argument, shader->vfunctions[i].function->arguments.size(), false);
5597
FunctionNode::Argument *arg = &shader->vfunctions[i].function->arguments.write[p_argument];
5598
if (arg->tex_builtin_check) {
5599
_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)));
5600
return false;
5601
} else if (arg->tex_argument_check) {
5602
// Was checked, verify that filter, repeat, and hint are the same.
5603
if (arg->tex_argument_filter == p_filter && arg->tex_argument_repeat == p_repeat && arg->tex_hint == _sanitize_hint(p_hint)) {
5604
return true;
5605
} else {
5606
_set_error(vformat(RTR("Sampler argument %d of function '%s' called more than once using textures that differ in either filter, repeat, or texture hint setting."), p_argument, String(p_name)));
5607
return false;
5608
}
5609
} else {
5610
arg->tex_argument_check = true;
5611
arg->tex_argument_filter = p_filter;
5612
arg->tex_argument_repeat = p_repeat;
5613
arg->tex_hint = _sanitize_hint(p_hint);
5614
for (KeyValue<StringName, HashSet<int>> &E : arg->tex_argument_connect) {
5615
for (const int &F : E.value) {
5616
if (!_propagate_function_call_sampler_uniform_settings(E.key, F, p_filter, p_repeat, p_hint)) {
5617
return false;
5618
}
5619
}
5620
}
5621
return true;
5622
}
5623
}
5624
}
5625
ERR_FAIL_V(false); //bug? function not found
5626
}
5627
5628
bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(const StringName &p_name, int p_argument, const StringName &p_builtin) {
5629
for (int i = 0; i < shader->vfunctions.size(); i++) {
5630
if (shader->vfunctions[i].name == p_name) {
5631
ERR_FAIL_INDEX_V(p_argument, shader->vfunctions[i].function->arguments.size(), false);
5632
FunctionNode::Argument *arg = &shader->vfunctions[i].function->arguments.write[p_argument];
5633
if (arg->tex_argument_check) {
5634
_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)));
5635
return false;
5636
} else if (arg->tex_builtin_check) {
5637
//was checked, verify that the built-in is the same
5638
if (arg->tex_builtin == p_builtin) {
5639
return true;
5640
} else {
5641
_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)));
5642
return false;
5643
}
5644
} else {
5645
arg->tex_builtin_check = true;
5646
arg->tex_builtin = p_builtin;
5647
5648
for (KeyValue<StringName, HashSet<int>> &E : arg->tex_argument_connect) {
5649
for (const int &F : E.value) {
5650
if (!_propagate_function_call_sampler_builtin_reference(E.key, F, p_builtin)) {
5651
return false;
5652
}
5653
}
5654
}
5655
return true;
5656
}
5657
}
5658
}
5659
ERR_FAIL_V(false); //bug? function not found
5660
}
5661
5662
Error 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) {
5663
bool error = false;
5664
if (r_array_size != nullptr && *r_array_size > 0) {
5665
error = true;
5666
}
5667
if (r_unknown_size != nullptr && *r_unknown_size) {
5668
error = true;
5669
}
5670
if (error) {
5671
_set_error(vformat(RTR("Array size is already defined.")));
5672
return ERR_PARSE_ERROR;
5673
}
5674
5675
TkPos pos = _get_tkpos();
5676
Token tk = _get_token();
5677
5678
if (tk.type == TK_BRACKET_CLOSE) {
5679
if (p_forbid_unknown_size) {
5680
_set_error(vformat(RTR("Unknown array size is forbidden in that context.")));
5681
return ERR_PARSE_ERROR;
5682
}
5683
if (r_unknown_size != nullptr) {
5684
*r_unknown_size = true;
5685
}
5686
} else {
5687
_set_tkpos(pos);
5688
5689
int array_size = 0;
5690
Node *expr = _parse_and_reduce_expression(p_block, p_function_info);
5691
5692
if (expr) {
5693
Vector<Scalar> values = _get_node_values(p_block, p_function_info, expr);
5694
5695
if (!values.is_empty()) {
5696
switch (expr->get_datatype()) {
5697
case TYPE_INT: {
5698
array_size = values[0].sint;
5699
} break;
5700
case TYPE_UINT: {
5701
array_size = (int)values[0].uint;
5702
} break;
5703
default: {
5704
} break;
5705
}
5706
}
5707
5708
if (r_size_expression != nullptr) {
5709
*r_size_expression = expr;
5710
}
5711
}
5712
5713
if (array_size <= 0) {
5714
_set_error(RTR("Expected a positive integer constant."));
5715
return ERR_PARSE_ERROR;
5716
}
5717
5718
tk = _get_token();
5719
if (tk.type != TK_BRACKET_CLOSE) {
5720
_set_expected_error("]");
5721
return ERR_PARSE_ERROR;
5722
}
5723
5724
if (r_array_size != nullptr) {
5725
*r_array_size = array_size;
5726
}
5727
}
5728
return OK;
5729
}
5730
5731
ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info) {
5732
DataType type = TYPE_VOID;
5733
String struct_name = "";
5734
int array_size = 0;
5735
bool auto_size = false;
5736
bool undefined_size = false;
5737
Token tk = _get_token();
5738
5739
if (tk.type == TK_CURLY_BRACKET_OPEN) {
5740
auto_size = true;
5741
} else {
5742
if (shader->structs.has(tk.text)) {
5743
type = TYPE_STRUCT;
5744
struct_name = tk.text;
5745
} else {
5746
if (!is_token_variable_datatype(tk.type)) {
5747
_set_error(RTR("Invalid data type for the array."));
5748
return nullptr;
5749
}
5750
type = get_token_datatype(tk.type);
5751
}
5752
tk = _get_token();
5753
if (tk.type == TK_BRACKET_OPEN) {
5754
Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size, &undefined_size);
5755
if (error != OK) {
5756
return nullptr;
5757
}
5758
tk = _get_token();
5759
} else {
5760
_set_expected_error("[");
5761
return nullptr;
5762
}
5763
}
5764
5765
ArrayConstructNode *an = alloc_node<ArrayConstructNode>();
5766
5767
if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
5768
int idx = 0;
5769
while (true) {
5770
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
5771
if (!n) {
5772
return nullptr;
5773
}
5774
5775
// define type by using the first member
5776
if (auto_size && idx == 0) {
5777
type = n->get_datatype();
5778
if (type == TYPE_STRUCT) {
5779
struct_name = n->get_datatype_name();
5780
}
5781
} else {
5782
if (!_compare_datatypes(type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) {
5783
return nullptr;
5784
}
5785
}
5786
5787
tk = _get_token();
5788
if (tk.type == TK_COMMA) {
5789
an->initializer.push_back(n);
5790
} else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) {
5791
an->initializer.push_back(n);
5792
break;
5793
} else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) {
5794
an->initializer.push_back(n);
5795
break;
5796
} else {
5797
if (auto_size) {
5798
_set_expected_error("}", ",");
5799
} else {
5800
_set_expected_error(")", ",");
5801
}
5802
return nullptr;
5803
}
5804
idx++;
5805
}
5806
if (!auto_size && !undefined_size && an->initializer.size() != array_size) {
5807
_set_error(vformat(RTR("Array size mismatch. Expected %d elements (found %d)."), array_size, an->initializer.size()));
5808
return nullptr;
5809
}
5810
} else {
5811
_set_error(RTR("Expected array initialization."));
5812
return nullptr;
5813
}
5814
5815
an->datatype = type;
5816
an->struct_name = struct_name;
5817
return an;
5818
}
5819
5820
ShaderLanguage::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) {
5821
DataType type = TYPE_VOID;
5822
String struct_name = "";
5823
int array_size = 0;
5824
bool auto_size = false;
5825
TkPos prev_pos = _get_tkpos();
5826
Token tk = _get_token();
5827
5828
if (tk.type == TK_CURLY_BRACKET_OPEN) {
5829
auto_size = true;
5830
} else {
5831
if (shader->structs.has(tk.text)) {
5832
type = TYPE_STRUCT;
5833
struct_name = tk.text;
5834
} else {
5835
if (!is_token_variable_datatype(tk.type)) {
5836
_set_tkpos(prev_pos);
5837
5838
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
5839
5840
if (!n) {
5841
_set_error(RTR("Invalid data type for the array."));
5842
return nullptr;
5843
}
5844
5845
if (!_compare_datatypes(p_type, p_struct_name, p_array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) {
5846
return nullptr;
5847
}
5848
return n;
5849
}
5850
type = get_token_datatype(tk.type);
5851
}
5852
tk = _get_token();
5853
if (tk.type == TK_BRACKET_OPEN) {
5854
bool is_unknown_size = false;
5855
Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size, &is_unknown_size);
5856
if (error != OK) {
5857
return nullptr;
5858
}
5859
if (is_unknown_size) {
5860
array_size = p_array_size;
5861
}
5862
tk = _get_token();
5863
} else {
5864
_set_expected_error("[");
5865
return nullptr;
5866
}
5867
5868
if (type != p_type || struct_name != p_struct_name || array_size != p_array_size) {
5869
String from;
5870
if (type == TYPE_STRUCT) {
5871
from += struct_name;
5872
} else {
5873
from += get_datatype_name(type);
5874
}
5875
from += "[";
5876
from += itos(array_size);
5877
from += "]'";
5878
5879
String to;
5880
if (type == TYPE_STRUCT) {
5881
to += p_struct_name;
5882
} else {
5883
to += get_datatype_name(p_type);
5884
}
5885
to += "[";
5886
to += itos(p_array_size);
5887
to += "]'";
5888
5889
_set_error(vformat(RTR("Cannot convert from '%s' to '%s'."), from, to));
5890
return nullptr;
5891
}
5892
}
5893
5894
ArrayConstructNode *an = alloc_node<ArrayConstructNode>();
5895
an->datatype = p_type;
5896
an->struct_name = p_struct_name;
5897
5898
if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
5899
while (true) {
5900
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
5901
if (!n) {
5902
return nullptr;
5903
}
5904
5905
if (!_compare_datatypes(p_type, p_struct_name, 0, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) {
5906
return nullptr;
5907
}
5908
5909
tk = _get_token();
5910
if (tk.type == TK_COMMA) {
5911
an->initializer.push_back(n);
5912
} else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) {
5913
an->initializer.push_back(n);
5914
break;
5915
} else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) {
5916
an->initializer.push_back(n);
5917
break;
5918
} else {
5919
if (auto_size) {
5920
_set_expected_error("}", ",");
5921
} else {
5922
_set_expected_error(")", ",");
5923
}
5924
return nullptr;
5925
}
5926
}
5927
if (an->initializer.size() != p_array_size) {
5928
_set_error(vformat(RTR("Array size mismatch. Expected %d elements (found %d)."), p_array_size, an->initializer.size()));
5929
return nullptr;
5930
}
5931
} else {
5932
_set_error(RTR("Expected array initialization."));
5933
return nullptr;
5934
}
5935
5936
return an;
5937
}
5938
5939
ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info, const ExpressionInfo *p_previous_expression_info) {
5940
Vector<Expression> expression;
5941
5942
//Vector<TokenType> operators;
5943
#ifdef DEBUG_ENABLED
5944
bool check_position_write = check_warnings && HAS_WARNING(ShaderWarning::MAGIC_POSITION_WRITE_FLAG);
5945
check_position_write = check_position_write && String(shader_type_identifier) == "spatial" && current_function == "vertex";
5946
#endif
5947
5948
while (true) {
5949
Node *expr = nullptr;
5950
TkPos prepos = _get_tkpos();
5951
Token tk = _get_token();
5952
TkPos pos = _get_tkpos();
5953
5954
bool is_const = false;
5955
5956
if (tk.type == TK_PARENTHESIS_OPEN) {
5957
//handle subexpression
5958
5959
expr = _parse_and_reduce_expression(p_block, p_function_info);
5960
if (!expr) {
5961
return nullptr;
5962
}
5963
5964
tk = _get_token();
5965
5966
if (tk.type != TK_PARENTHESIS_CLOSE) {
5967
_set_error(RTR("Expected ')' in expression."));
5968
return nullptr;
5969
}
5970
5971
} else if (tk.type == TK_FLOAT_CONSTANT) {
5972
ConstantNode *constant = alloc_node<ConstantNode>();
5973
Scalar v;
5974
v.real = tk.constant;
5975
constant->values.push_back(v);
5976
constant->datatype = TYPE_FLOAT;
5977
expr = constant;
5978
5979
} else if (tk.type == TK_INT_CONSTANT) {
5980
ConstantNode *constant = alloc_node<ConstantNode>();
5981
Scalar v;
5982
v.sint = tk.constant;
5983
constant->values.push_back(v);
5984
constant->datatype = TYPE_INT;
5985
expr = constant;
5986
5987
} else if (tk.type == TK_UINT_CONSTANT) {
5988
ConstantNode *constant = alloc_node<ConstantNode>();
5989
Scalar v;
5990
v.uint = tk.constant;
5991
constant->values.push_back(v);
5992
constant->datatype = TYPE_UINT;
5993
expr = constant;
5994
5995
} else if (tk.type == TK_TRUE) {
5996
//handle true constant
5997
ConstantNode *constant = alloc_node<ConstantNode>();
5998
Scalar v;
5999
v.boolean = true;
6000
constant->values.push_back(v);
6001
constant->datatype = TYPE_BOOL;
6002
expr = constant;
6003
6004
} else if (tk.type == TK_FALSE) {
6005
//handle false constant
6006
ConstantNode *constant = alloc_node<ConstantNode>();
6007
Scalar v;
6008
v.boolean = false;
6009
constant->values.push_back(v);
6010
constant->datatype = TYPE_BOOL;
6011
expr = constant;
6012
6013
} else if (tk.type == TK_TYPE_VOID) {
6014
//make sure void is not used in expression
6015
_set_error(RTR("Void value not allowed in expression."));
6016
return nullptr;
6017
} else if (is_token_nonvoid_datatype(tk.type) || tk.type == TK_CURLY_BRACKET_OPEN) {
6018
if (tk.type == TK_CURLY_BRACKET_OPEN) {
6019
//array constructor
6020
6021
_set_tkpos(prepos);
6022
expr = _parse_array_constructor(p_block, p_function_info);
6023
} else {
6024
DataType datatype;
6025
DataPrecision precision = PRECISION_DEFAULT;
6026
6027
if (is_token_precision(tk.type)) {
6028
precision = get_token_precision(tk.type);
6029
tk = _get_token();
6030
}
6031
6032
datatype = get_token_datatype(tk.type);
6033
if (precision != PRECISION_DEFAULT && _validate_precision(datatype, precision) != OK) {
6034
return nullptr;
6035
}
6036
6037
tk = _get_token();
6038
6039
if (tk.type == TK_BRACKET_OPEN) {
6040
//array constructor
6041
6042
_set_tkpos(prepos);
6043
expr = _parse_array_constructor(p_block, p_function_info);
6044
} else {
6045
if (tk.type != TK_PARENTHESIS_OPEN) {
6046
_set_error(RTR("Expected '(' after the type name."));
6047
return nullptr;
6048
}
6049
//basic type constructor
6050
6051
OperatorNode *func = alloc_node<OperatorNode>();
6052
func->op = OP_CONSTRUCT;
6053
6054
if (precision != PRECISION_DEFAULT) {
6055
func->return_precision_cache = precision;
6056
}
6057
6058
VariableNode *funcname = alloc_node<VariableNode>();
6059
funcname->name = get_datatype_name(datatype);
6060
func->arguments.push_back(funcname);
6061
6062
int carg = -1;
6063
6064
bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg);
6065
6066
if (carg >= 0) {
6067
completion_type = COMPLETION_CALL_ARGUMENTS;
6068
completion_line = tk_line;
6069
completion_block = p_block;
6070
completion_function = funcname->name;
6071
completion_argument = carg;
6072
}
6073
6074
if (!ok) {
6075
return nullptr;
6076
}
6077
6078
if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) {
6079
_set_error(vformat(RTR("No matching constructor found for: '%s'."), String(funcname->name)));
6080
return nullptr;
6081
}
6082
6083
expr = _reduce_expression(p_block, func);
6084
}
6085
}
6086
} else if (tk.type == TK_IDENTIFIER) {
6087
_set_tkpos(prepos);
6088
6089
StringName identifier;
6090
6091
StructNode *pstruct = nullptr;
6092
bool struct_init = false;
6093
6094
_get_completable_identifier(p_block, COMPLETION_IDENTIFIER, identifier);
6095
6096
if (shader->structs.has(identifier)) {
6097
pstruct = shader->structs[identifier].shader_struct;
6098
struct_init = true;
6099
}
6100
6101
tk = _get_token();
6102
if (tk.type == TK_PARENTHESIS_OPEN) {
6103
if (struct_init) { //a struct constructor
6104
6105
const StringName &name = identifier;
6106
6107
OperatorNode *func = alloc_node<OperatorNode>();
6108
func->op = OP_STRUCT;
6109
func->struct_name = name;
6110
func->return_cache = TYPE_STRUCT;
6111
VariableNode *funcname = alloc_node<VariableNode>();
6112
funcname->name = name;
6113
func->arguments.push_back(funcname);
6114
6115
for (List<ShaderLanguage::MemberNode *>::Element *E = pstruct->members.front(); E; E = E->next()) {
6116
Node *nexpr;
6117
6118
if (E->get()->array_size != 0) {
6119
nexpr = _parse_array_constructor(p_block, p_function_info, E->get()->get_datatype(), E->get()->struct_name, E->get()->array_size);
6120
if (!nexpr) {
6121
return nullptr;
6122
}
6123
} else {
6124
nexpr = _parse_and_reduce_expression(p_block, p_function_info);
6125
if (!nexpr) {
6126
return nullptr;
6127
}
6128
if (!_compare_datatypes_in_nodes(E->get(), nexpr)) {
6129
return nullptr;
6130
}
6131
}
6132
6133
if (E->next()) {
6134
tk = _get_token();
6135
if (tk.type != TK_COMMA) {
6136
_set_expected_error(",");
6137
return nullptr;
6138
}
6139
}
6140
func->arguments.push_back(nexpr);
6141
}
6142
tk = _get_token();
6143
if (tk.type != TK_PARENTHESIS_CLOSE) {
6144
_set_expected_error(")");
6145
return nullptr;
6146
}
6147
6148
expr = func;
6149
6150
} else { //a function call
6151
6152
// Non-builtin function call is forbidden for constant declaration.
6153
if (is_const_decl) {
6154
if (shader->functions.has(identifier)) {
6155
_set_error(RTR("Expected constant expression."));
6156
return nullptr;
6157
}
6158
}
6159
6160
const StringName &rname = identifier;
6161
StringName name = identifier;
6162
6163
OperatorNode *func = alloc_node<OperatorNode>();
6164
func->op = OP_CALL;
6165
6166
VariableNode *funcname = alloc_node<VariableNode>();
6167
funcname->name = name;
6168
funcname->rname = name;
6169
6170
func->arguments.push_back(funcname);
6171
6172
int carg = -1;
6173
6174
bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg);
6175
6176
// Check if block has a variable with the same name as function to prevent shader crash.
6177
ShaderLanguage::BlockNode *bnode = p_block;
6178
while (bnode) {
6179
if (bnode->variables.has(name)) {
6180
_set_error(RTR("Expected a function name."));
6181
return nullptr;
6182
}
6183
bnode = bnode->parent_block;
6184
}
6185
6186
int64_t arg_count = func->arguments.size();
6187
int64_t arg_count2 = func->arguments.size() - 1;
6188
6189
// Test if function was parsed first.
6190
int function_index = -1;
6191
for (int i = 0, max_valid_args = 0; i < shader->vfunctions.size(); i++) {
6192
if (!shader->vfunctions[i].callable || shader->vfunctions[i].rname != rname || arg_count2 != shader->vfunctions[i].function->arguments.size()) {
6193
continue;
6194
}
6195
6196
bool found = true;
6197
int valid_args = 0;
6198
6199
// Search for correct overload.
6200
for (int j = 1; j < arg_count; j++) {
6201
const FunctionNode::Argument &a = shader->vfunctions[i].function->arguments[j - 1];
6202
Node *b = func->arguments[j];
6203
6204
if (a.type == b->get_datatype() && a.array_size == b->get_array_size()) {
6205
if (a.type == TYPE_STRUCT) {
6206
if (a.struct_name != b->get_datatype_name()) {
6207
found = false;
6208
break;
6209
} else {
6210
valid_args++;
6211
}
6212
} else {
6213
valid_args++;
6214
}
6215
} else {
6216
if (function_overload_count[rname] == 0 && get_scalar_type(a.type) == a.type && b->type == Node::NODE_TYPE_CONSTANT && a.array_size == 0 && convert_constant(static_cast<ConstantNode *>(b), a.type)) {
6217
// Implicit cast if no overloads.
6218
continue;
6219
}
6220
found = false;
6221
break;
6222
}
6223
}
6224
6225
// Using the best match index for completion hint if the function not found.
6226
if (valid_args > max_valid_args) {
6227
name = shader->vfunctions[i].name;
6228
funcname->name = name;
6229
max_valid_args = valid_args;
6230
}
6231
6232
if (!found) {
6233
continue;
6234
}
6235
6236
// Add to current function as dependency.
6237
for (int j = 0; j < shader->vfunctions.size(); j++) {
6238
if (shader->vfunctions[j].name == current_function) {
6239
shader->vfunctions.write[j].uses_function.insert(name);
6240
break;
6241
}
6242
}
6243
6244
name = shader->vfunctions[i].name;
6245
funcname->name = name;
6246
6247
// See if texture arguments must connect.
6248
function_index = i;
6249
break;
6250
}
6251
6252
if (carg >= 0) {
6253
completion_type = COMPLETION_CALL_ARGUMENTS;
6254
completion_line = tk_line;
6255
completion_block = p_block;
6256
completion_function = funcname->name;
6257
completion_argument = carg;
6258
}
6259
6260
if (!ok) {
6261
return nullptr;
6262
}
6263
6264
if (name != current_function) { // Recursion is not allowed.
6265
// Register call.
6266
if (calls_info.has(name)) {
6267
calls_info[current_function].calls.push_back(&calls_info[name]);
6268
}
6269
6270
bool is_builtin = false;
6271
6272
if (is_supported_frag_only_funcs && stages) {
6273
for (const KeyValue<StringName, FunctionInfo> &E : *stages) {
6274
if (E.value.stage_functions.has(name)) {
6275
// Register usage of the restricted stage function.
6276
calls_info[current_function].uses_restricted_items.push_back(Pair<StringName, CallInfo::Item>(name, CallInfo::Item(CallInfo::Item::ITEM_TYPE_BUILTIN, _get_tkpos())));
6277
is_builtin = true;
6278
break;
6279
}
6280
}
6281
}
6282
6283
if (!is_builtin) {
6284
int idx = 0;
6285
while (frag_only_func_defs[idx].name) {
6286
if (frag_only_func_defs[idx].name == name) {
6287
// If a built-in function not found for the current shader type, then it shouldn't be parsed further.
6288
if (!is_supported_frag_only_funcs) {
6289
_set_error(vformat(RTR("Built-in function '%s' is not supported for the '%s' shader type."), name, shader_type_identifier));
6290
return nullptr;
6291
}
6292
// Register usage of the restricted function.
6293
calls_info[current_function].uses_restricted_items.push_back(Pair<StringName, CallInfo::Item>(name, CallInfo::Item(CallInfo::Item::ITEM_TYPE_BUILTIN, _get_tkpos())));
6294
is_builtin = true;
6295
break;
6296
}
6297
idx++;
6298
}
6299
}
6300
6301
// Recursively checks for the restricted function call.
6302
if (is_supported_frag_only_funcs && current_function == "vertex" && stages->has(current_function) && !_validate_restricted_func(name, &calls_info[current_function], is_builtin)) {
6303
return nullptr;
6304
}
6305
}
6306
6307
bool is_custom_func = false;
6308
if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name, &is_custom_func)) {
6309
_set_error(vformat(RTR("No matching function found for: '%s'."), String(funcname->rname)));
6310
return nullptr;
6311
}
6312
completion_class = TAG_GLOBAL; // reset sub-class
6313
if (function_index >= 0) {
6314
//connect texture arguments, so we can cache in the
6315
//argument what type of filter and repeat to use
6316
6317
FunctionNode *call_function = shader->vfunctions[function_index].function;
6318
if (call_function) {
6319
func->return_cache = call_function->get_datatype();
6320
func->struct_name = call_function->get_datatype_name();
6321
func->return_array_size = call_function->get_array_size();
6322
6323
//get current base function
6324
FunctionNode *base_function = nullptr;
6325
{
6326
BlockNode *b = p_block;
6327
6328
while (b) {
6329
if (b->parent_function) {
6330
base_function = b->parent_function;
6331
break;
6332
} else {
6333
b = b->parent_block;
6334
}
6335
}
6336
}
6337
6338
ERR_FAIL_NULL_V(base_function, nullptr); // Bug, wtf.
6339
6340
for (int i = 0; i < call_function->arguments.size(); i++) {
6341
int argidx = i + 1;
6342
if (argidx < arg_count) {
6343
bool error = false;
6344
Node *n = func->arguments[argidx];
6345
ArgumentQualifier arg_qual = call_function->arguments[i].qualifier;
6346
bool is_out_arg = arg_qual != ArgumentQualifier::ARGUMENT_QUALIFIER_IN;
6347
6348
if (n->type == Node::NODE_TYPE_VARIABLE || n->type == Node::NODE_TYPE_ARRAY) {
6349
StringName varname;
6350
6351
if (n->type == Node::NODE_TYPE_VARIABLE) {
6352
VariableNode *vn = static_cast<VariableNode *>(n);
6353
varname = vn->name;
6354
} else { // TYPE_ARRAY
6355
ArrayNode *an = static_cast<ArrayNode *>(n);
6356
varname = an->name;
6357
}
6358
6359
if (shader->varyings.has(varname)) {
6360
switch (shader->varyings[varname].stage) {
6361
case ShaderNode::Varying::STAGE_UNKNOWN:
6362
if (is_out_arg) {
6363
error = true;
6364
}
6365
break;
6366
case ShaderNode::Varying::STAGE_VERTEX:
6367
if (is_out_arg && current_function != varying_function_names.vertex) { // inout/out
6368
error = true;
6369
}
6370
break;
6371
case ShaderNode::Varying::STAGE_FRAGMENT:
6372
if (!is_out_arg) {
6373
if (current_function != varying_function_names.fragment && current_function != varying_function_names.light) {
6374
error = true;
6375
}
6376
} else if (current_function != varying_function_names.fragment) { // inout/out
6377
error = true;
6378
}
6379
break;
6380
default:
6381
break;
6382
}
6383
6384
if (error) {
6385
_set_error(vformat(RTR("Varying '%s' cannot be passed for the '%s' parameter in that context."), varname, _get_qualifier_str(arg_qual)));
6386
return nullptr;
6387
}
6388
}
6389
}
6390
6391
bool is_const_arg = call_function->arguments[i].is_const;
6392
6393
if (is_const_arg || is_out_arg) {
6394
StringName varname;
6395
6396
if (n->type == Node::NODE_TYPE_CONSTANT || n->type == Node::NODE_TYPE_OPERATOR || n->type == Node::NODE_TYPE_ARRAY_CONSTRUCT) {
6397
if (!is_const_arg) {
6398
error = true;
6399
}
6400
} else if (n->type == Node::NODE_TYPE_ARRAY) {
6401
ArrayNode *an = static_cast<ArrayNode *>(n);
6402
if (!is_const_arg && (an->call_expression != nullptr || an->is_const)) {
6403
error = true;
6404
}
6405
varname = an->name;
6406
} else if (n->type == Node::NODE_TYPE_VARIABLE) {
6407
VariableNode *vn = static_cast<VariableNode *>(n);
6408
if (vn->is_const && !is_const_arg) {
6409
error = true;
6410
}
6411
varname = vn->name;
6412
} else if (n->type == Node::NODE_TYPE_MEMBER) {
6413
MemberNode *mn = static_cast<MemberNode *>(n);
6414
if (mn->basetype_const && is_out_arg) {
6415
error = true;
6416
}
6417
}
6418
if (!error && varname != StringName()) {
6419
if (shader->constants.has(varname)) {
6420
error = true;
6421
} else if (shader->uniforms.has(varname)) {
6422
error = true;
6423
} else if (p_function_info.built_ins.has(varname)) {
6424
BuiltInInfo info = p_function_info.built_ins[varname];
6425
if (info.constant) {
6426
error = true;
6427
}
6428
}
6429
}
6430
6431
if (error) {
6432
_set_error(vformat(RTR("A constant value cannot be passed for the '%s' parameter."), _get_qualifier_str(arg_qual)));
6433
return nullptr;
6434
}
6435
}
6436
if (is_sampler_type(call_function->arguments[i].type)) {
6437
// Let's see where our argument comes from.
6438
StringName varname;
6439
if (n->type == Node::NODE_TYPE_VARIABLE) {
6440
VariableNode *vn = static_cast<VariableNode *>(n);
6441
varname = vn->name;
6442
} else if (n->type == Node::NODE_TYPE_ARRAY) {
6443
ArrayNode *an = static_cast<ArrayNode *>(n);
6444
varname = an->name;
6445
}
6446
6447
if (shader->uniforms.has(varname)) {
6448
//being sampler, this either comes from a uniform
6449
ShaderNode::Uniform *u = &shader->uniforms[varname];
6450
ERR_CONTINUE(u->type != call_function->arguments[i].type); //this should have been validated previously
6451
6452
if (RendererCompositor::get_singleton()->is_xr_enabled() && is_custom_func) {
6453
ShaderNode::Uniform::Hint hint = u->hint;
6454
6455
if (hint == ShaderNode::Uniform::HINT_DEPTH_TEXTURE || hint == ShaderNode::Uniform::HINT_SCREEN_TEXTURE || hint == ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) {
6456
_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)));
6457
return nullptr;
6458
}
6459
}
6460
6461
//propagate
6462
if (!_propagate_function_call_sampler_uniform_settings(name, i, u->filter, u->repeat, u->hint)) {
6463
return nullptr;
6464
}
6465
} else if (p_function_info.built_ins.has(varname)) {
6466
//a built-in
6467
if (!_propagate_function_call_sampler_builtin_reference(name, i, varname)) {
6468
return nullptr;
6469
}
6470
} else {
6471
//or this comes from an argument, but nothing else can be a sampler
6472
bool found = false;
6473
for (int j = 0; j < base_function->arguments.size(); j++) {
6474
if (base_function->arguments[j].name == varname) {
6475
if (!base_function->arguments[j].tex_argument_connect.has(call_function->name)) {
6476
base_function->arguments.write[j].tex_argument_connect[call_function->name] = HashSet<int>();
6477
}
6478
base_function->arguments.write[j].tex_argument_connect[call_function->name].insert(i);
6479
found = true;
6480
break;
6481
}
6482
}
6483
ERR_CONTINUE(!found);
6484
}
6485
}
6486
} else {
6487
break;
6488
}
6489
}
6490
}
6491
}
6492
expr = func;
6493
#ifdef DEBUG_ENABLED
6494
if (check_warnings && is_custom_func) {
6495
StringName func_name;
6496
6497
if (p_block && p_block->parent_function) {
6498
func_name = p_block->parent_function->name;
6499
}
6500
6501
_parse_used_identifier(name, IdentifierType::IDENTIFIER_FUNCTION, func_name);
6502
}
6503
#endif // DEBUG_ENABLED
6504
}
6505
} else {
6506
//an identifier
6507
6508
last_name = identifier;
6509
last_type = IDENTIFIER_MAX;
6510
_set_tkpos(pos);
6511
6512
DataType data_type = TYPE_MAX;
6513
IdentifierType ident_type = IDENTIFIER_MAX;
6514
int array_size = 0;
6515
StringName struct_name;
6516
bool is_local = false;
6517
6518
if (p_block && p_block->block_tag != SubClassTag::TAG_GLOBAL) {
6519
int idx = 0;
6520
bool found = false;
6521
6522
while (builtin_func_defs[idx].name) {
6523
if (builtin_func_defs[idx].tag == p_block->block_tag && builtin_func_defs[idx].name == identifier) {
6524
found = true;
6525
break;
6526
}
6527
idx++;
6528
}
6529
if (!found) {
6530
_set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier)));
6531
return nullptr;
6532
}
6533
} else {
6534
if (!_find_identifier(p_block, false, p_function_info, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) {
6535
if (identifier == "SCREEN_TEXTURE" || identifier == "DEPTH_TEXTURE" || identifier == "NORMAL_ROUGHNESS_TEXTURE") {
6536
String name = String(identifier);
6537
String name_lower = name.to_lower();
6538
_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));
6539
return nullptr;
6540
}
6541
_set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier)));
6542
return nullptr;
6543
}
6544
if (is_const_decl && !is_const) {
6545
_set_error(RTR("Expected constant expression."));
6546
return nullptr;
6547
}
6548
if (ident_type == IDENTIFIER_FUNCTION) {
6549
_set_error(vformat(RTR("Can't use function as identifier: '%s'."), String(identifier)));
6550
return nullptr;
6551
}
6552
#ifdef DEBUG_ENABLED
6553
if (check_warnings) {
6554
StringName func_name;
6555
BlockNode *b = p_block;
6556
6557
while (b) {
6558
if (b->parent_function) {
6559
func_name = b->parent_function->name;
6560
break;
6561
} else {
6562
b = b->parent_block;
6563
}
6564
}
6565
6566
_parse_used_identifier(identifier, ident_type, func_name);
6567
}
6568
#endif // DEBUG_ENABLED
6569
if (ident_type == IDENTIFIER_VARYING) {
6570
TkPos prev_pos = _get_tkpos();
6571
Token next_token = _get_token();
6572
6573
// An array of varyings.
6574
if (next_token.type == TK_BRACKET_OPEN) {
6575
_get_token(); // Pass constant.
6576
_get_token(); // Pass TK_BRACKET_CLOSE.
6577
next_token = _get_token();
6578
}
6579
_set_tkpos(prev_pos);
6580
6581
ShaderNode::Varying &var = shader->varyings[identifier];
6582
calls_info[current_function].uses_restricted_items.push_back(Pair<StringName, CallInfo::Item>(identifier, CallInfo::Item(CallInfo::Item::ITEM_TYPE_VARYING, prev_pos)));
6583
6584
String error;
6585
if (is_token_operator_assign(next_token.type)) {
6586
if (!_validate_varying_assign(shader->varyings[identifier], &error)) {
6587
_set_error(error);
6588
return nullptr;
6589
}
6590
} else {
6591
if (var.stage == ShaderNode::Varying::STAGE_UNKNOWN && var.type < TYPE_INT) {
6592
if (current_function == varying_function_names.vertex) {
6593
_set_error(vformat(RTR("Varying with '%s' data type may only be used in the '%s' function."), get_datatype_name(var.type), "fragment"));
6594
} else {
6595
_set_error(vformat(RTR("Varying '%s' must be assigned in the '%s' function first."), identifier, "fragment"));
6596
}
6597
return nullptr;
6598
}
6599
}
6600
}
6601
#ifdef DEBUG_ENABLED
6602
if (check_position_write && ident_type == IDENTIFIER_BUILTIN_VAR) {
6603
if (String(identifier) == "POSITION") {
6604
// Check if the user wrote "POSITION = vec4(VERTEX," and warn if they did.
6605
TkPos prev_pos = _get_tkpos();
6606
if (_get_token().type == TK_OP_ASSIGN &&
6607
_get_token().type == TK_TYPE_VEC4 &&
6608
_get_token().type == TK_PARENTHESIS_OPEN &&
6609
_get_token().text == "VERTEX" &&
6610
_get_token().type == TK_COMMA) {
6611
_add_line_warning(ShaderWarning::MAGIC_POSITION_WRITE);
6612
}
6613
6614
// Reset the position so compiling can continue as normal.
6615
_set_tkpos(prev_pos);
6616
}
6617
}
6618
#endif // DEBUG_ENABLED
6619
if (is_const) {
6620
last_type = IDENTIFIER_CONSTANT;
6621
} else {
6622
last_type = ident_type;
6623
}
6624
6625
is_local = ident_type == IDENTIFIER_LOCAL_VAR || ident_type == IDENTIFIER_FUNCTION_ARGUMENT;
6626
}
6627
6628
Node *index_expression = nullptr;
6629
Node *call_expression = nullptr;
6630
Node *assign_expression = nullptr;
6631
6632
if (array_size > 0) {
6633
prepos = _get_tkpos();
6634
tk = _get_token();
6635
6636
if (tk.type == TK_OP_ASSIGN) {
6637
if (is_const) {
6638
_set_error(RTR("Constants cannot be modified."));
6639
return nullptr;
6640
}
6641
assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size);
6642
if (!assign_expression) {
6643
return nullptr;
6644
}
6645
} else if (tk.type == TK_PERIOD) {
6646
completion_class = TAG_ARRAY;
6647
if (p_block != nullptr) {
6648
p_block->block_tag = SubClassTag::TAG_ARRAY;
6649
}
6650
call_expression = _parse_and_reduce_expression(p_block, p_function_info);
6651
if (p_block != nullptr) {
6652
p_block->block_tag = SubClassTag::TAG_GLOBAL;
6653
}
6654
if (!call_expression) {
6655
return nullptr;
6656
}
6657
} else if (tk.type == TK_BRACKET_OPEN) { // indexing
6658
index_expression = _parse_and_reduce_expression(p_block, p_function_info);
6659
if (!index_expression) {
6660
return nullptr;
6661
}
6662
6663
if (index_expression->get_array_size() != 0 || (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT)) {
6664
_set_error(RTR("Only integer expressions are allowed for indexing."));
6665
return nullptr;
6666
}
6667
6668
if (index_expression->type == Node::NODE_TYPE_CONSTANT) {
6669
ConstantNode *cnode = static_cast<ConstantNode *>(index_expression);
6670
if (cnode) {
6671
if (!cnode->values.is_empty()) {
6672
int value = cnode->values[0].sint;
6673
if (value < 0 || value >= array_size) {
6674
_set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), value, 0, array_size - 1));
6675
return nullptr;
6676
}
6677
}
6678
}
6679
}
6680
6681
tk = _get_token();
6682
if (tk.type != TK_BRACKET_CLOSE) {
6683
_set_expected_error("]");
6684
return nullptr;
6685
}
6686
} else {
6687
_set_tkpos(prepos);
6688
}
6689
6690
ArrayNode *arrname = alloc_node<ArrayNode>();
6691
arrname->name = identifier;
6692
arrname->datatype_cache = data_type;
6693
arrname->struct_name = struct_name;
6694
arrname->index_expression = index_expression;
6695
arrname->call_expression = call_expression;
6696
arrname->assign_expression = assign_expression;
6697
arrname->is_const = is_const;
6698
arrname->array_size = array_size;
6699
arrname->is_local = is_local;
6700
expr = arrname;
6701
} else {
6702
VariableNode *varname = alloc_node<VariableNode>();
6703
varname->name = identifier;
6704
varname->datatype_cache = data_type;
6705
varname->is_const = is_const;
6706
varname->struct_name = struct_name;
6707
varname->is_local = is_local;
6708
expr = varname;
6709
}
6710
}
6711
} else if (tk.type == TK_OP_ADD) {
6712
continue; //this one does nothing
6713
} 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) {
6714
Expression e;
6715
e.is_op = true;
6716
6717
switch (tk.type) {
6718
case TK_OP_SUB:
6719
e.op = OP_NEGATE;
6720
break;
6721
case TK_OP_NOT:
6722
e.op = OP_NOT;
6723
break;
6724
case TK_OP_BIT_INVERT:
6725
e.op = OP_BIT_INVERT;
6726
break;
6727
case TK_OP_INCREMENT:
6728
e.op = OP_INCREMENT;
6729
break;
6730
case TK_OP_DECREMENT:
6731
e.op = OP_DECREMENT;
6732
break;
6733
default:
6734
ERR_FAIL_V(nullptr);
6735
}
6736
6737
expression.push_back(e);
6738
continue;
6739
} else {
6740
bool valid = false;
6741
if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_FOR_EXPRESSION && tk.type == TK_PARENTHESIS_CLOSE) {
6742
valid = true;
6743
_set_tkpos(prepos);
6744
6745
OperatorNode *func = alloc_node<OperatorNode>();
6746
func->op = OP_EMPTY;
6747
expr = func;
6748
}
6749
if (!valid) {
6750
if (tk.type != TK_SEMICOLON) {
6751
_set_error(vformat(RTR("Expected expression, found: '%s'."), get_token_text(tk)));
6752
return nullptr;
6753
} else {
6754
#ifdef DEBUG_ENABLED
6755
if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_FOR_INIT && p_block->block_type != BlockNode::BLOCK_TYPE_FOR_CONDITION)) {
6756
if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
6757
_add_line_warning(ShaderWarning::FORMATTING_ERROR, RTR("Empty statement. Remove ';' to fix this warning."));
6758
}
6759
}
6760
#endif // DEBUG_ENABLED
6761
_set_tkpos(prepos);
6762
6763
OperatorNode *func = alloc_node<OperatorNode>();
6764
func->op = OP_EMPTY;
6765
expr = func;
6766
}
6767
}
6768
}
6769
6770
ERR_FAIL_NULL_V(expr, nullptr);
6771
6772
/* OK now see what's NEXT to the operator.. */
6773
6774
while (true) {
6775
TkPos pos2 = _get_tkpos();
6776
tk = _get_token();
6777
6778
if (tk.type == TK_CURSOR) {
6779
//do nothing
6780
} else if (tk.type == TK_PERIOD) {
6781
#ifdef DEBUG_ENABLED
6782
uint32_t prev_keyword_completion_context = keyword_completion_context;
6783
keyword_completion_context = CF_UNSPECIFIED;
6784
#endif
6785
6786
DataType dt = expr->get_datatype();
6787
String st = expr->get_datatype_name();
6788
6789
if (!expr->is_indexed() && expr->get_array_size() > 0) {
6790
completion_class = TAG_ARRAY;
6791
if (p_block != nullptr) {
6792
p_block->block_tag = SubClassTag::TAG_ARRAY;
6793
}
6794
Node *call_expression = _parse_and_reduce_expression(p_block, p_function_info);
6795
if (p_block != nullptr) {
6796
p_block->block_tag = SubClassTag::TAG_GLOBAL;
6797
}
6798
if (!call_expression) {
6799
return nullptr;
6800
}
6801
expr = call_expression;
6802
break;
6803
}
6804
6805
StringName identifier;
6806
if (_get_completable_identifier(p_block, dt == TYPE_STRUCT ? COMPLETION_STRUCT : COMPLETION_INDEX, identifier)) {
6807
if (dt == TYPE_STRUCT) {
6808
completion_struct = st;
6809
} else {
6810
completion_base = dt;
6811
}
6812
}
6813
6814
if (identifier == StringName()) {
6815
_set_error(RTR("Expected an identifier as a member."));
6816
return nullptr;
6817
}
6818
String ident = identifier;
6819
6820
bool ok = true;
6821
bool repeated = false;
6822
DataType member_type = TYPE_VOID;
6823
StringName member_struct_name = "";
6824
int array_size = 0;
6825
6826
RBSet<char> position_symbols;
6827
RBSet<char> color_symbols;
6828
RBSet<char> texture_symbols;
6829
6830
bool mix_error = false;
6831
6832
switch (dt) {
6833
case TYPE_STRUCT: {
6834
ok = false;
6835
String member_name = String(ident.ptr());
6836
if (shader->structs.has(st)) {
6837
StructNode *n = shader->structs[st].shader_struct;
6838
for (const MemberNode *E : n->members) {
6839
if (String(E->name) == member_name) {
6840
member_type = E->datatype;
6841
array_size = E->array_size;
6842
if (member_type == TYPE_STRUCT) {
6843
member_struct_name = E->struct_name;
6844
}
6845
ok = true;
6846
break;
6847
}
6848
}
6849
}
6850
6851
} break;
6852
case TYPE_BVEC2:
6853
case TYPE_IVEC2:
6854
case TYPE_UVEC2:
6855
case TYPE_VEC2: {
6856
int l = ident.length();
6857
if (l == 1) {
6858
member_type = DataType(dt - 1);
6859
} else if (l == 2) {
6860
member_type = dt;
6861
} else if (l == 3) {
6862
member_type = DataType(dt + 1);
6863
} else if (l == 4) {
6864
member_type = DataType(dt + 2);
6865
} else {
6866
ok = false;
6867
break;
6868
}
6869
6870
const char32_t *c = ident.ptr();
6871
for (int i = 0; i < l; i++) {
6872
switch (c[i]) {
6873
case 'r':
6874
case 'g':
6875
if (position_symbols.size() > 0 || texture_symbols.size() > 0) {
6876
mix_error = true;
6877
break;
6878
}
6879
if (!color_symbols.has(c[i])) {
6880
color_symbols.insert(c[i]);
6881
} else {
6882
repeated = true;
6883
}
6884
break;
6885
case 'x':
6886
case 'y':
6887
if (color_symbols.size() > 0 || texture_symbols.size() > 0) {
6888
mix_error = true;
6889
break;
6890
}
6891
if (!position_symbols.has(c[i])) {
6892
position_symbols.insert(c[i]);
6893
} else {
6894
repeated = true;
6895
}
6896
break;
6897
case 's':
6898
case 't':
6899
if (color_symbols.size() > 0 || position_symbols.size() > 0) {
6900
mix_error = true;
6901
break;
6902
}
6903
if (!texture_symbols.has(c[i])) {
6904
texture_symbols.insert(c[i]);
6905
} else {
6906
repeated = true;
6907
}
6908
break;
6909
default:
6910
ok = false;
6911
break;
6912
}
6913
}
6914
6915
} break;
6916
case TYPE_BVEC3:
6917
case TYPE_IVEC3:
6918
case TYPE_UVEC3:
6919
case TYPE_VEC3: {
6920
int l = ident.length();
6921
if (l == 1) {
6922
member_type = DataType(dt - 2);
6923
} else if (l == 2) {
6924
member_type = DataType(dt - 1);
6925
} else if (l == 3) {
6926
member_type = dt;
6927
} else if (l == 4) {
6928
member_type = DataType(dt + 1);
6929
} else {
6930
ok = false;
6931
break;
6932
}
6933
6934
const char32_t *c = ident.ptr();
6935
for (int i = 0; i < l; i++) {
6936
switch (c[i]) {
6937
case 'r':
6938
case 'g':
6939
case 'b':
6940
if (position_symbols.size() > 0 || texture_symbols.size() > 0) {
6941
mix_error = true;
6942
break;
6943
}
6944
if (!color_symbols.has(c[i])) {
6945
color_symbols.insert(c[i]);
6946
} else {
6947
repeated = true;
6948
}
6949
break;
6950
case 'x':
6951
case 'y':
6952
case 'z':
6953
if (color_symbols.size() > 0 || texture_symbols.size() > 0) {
6954
mix_error = true;
6955
break;
6956
}
6957
if (!position_symbols.has(c[i])) {
6958
position_symbols.insert(c[i]);
6959
} else {
6960
repeated = true;
6961
}
6962
break;
6963
case 's':
6964
case 't':
6965
case 'p':
6966
if (color_symbols.size() > 0 || position_symbols.size() > 0) {
6967
mix_error = true;
6968
break;
6969
}
6970
if (!texture_symbols.has(c[i])) {
6971
texture_symbols.insert(c[i]);
6972
} else {
6973
repeated = true;
6974
}
6975
break;
6976
default:
6977
ok = false;
6978
break;
6979
}
6980
}
6981
6982
} break;
6983
case TYPE_BVEC4:
6984
case TYPE_IVEC4:
6985
case TYPE_UVEC4:
6986
case TYPE_VEC4: {
6987
int l = ident.length();
6988
if (l == 1) {
6989
member_type = DataType(dt - 3);
6990
} else if (l == 2) {
6991
member_type = DataType(dt - 2);
6992
} else if (l == 3) {
6993
member_type = DataType(dt - 1);
6994
} else if (l == 4) {
6995
member_type = dt;
6996
} else {
6997
ok = false;
6998
break;
6999
}
7000
7001
const char32_t *c = ident.ptr();
7002
for (int i = 0; i < l; i++) {
7003
switch (c[i]) {
7004
case 'r':
7005
case 'g':
7006
case 'b':
7007
case 'a':
7008
if (position_symbols.size() > 0 || texture_symbols.size() > 0) {
7009
mix_error = true;
7010
break;
7011
}
7012
if (!color_symbols.has(c[i])) {
7013
color_symbols.insert(c[i]);
7014
} else {
7015
repeated = true;
7016
}
7017
break;
7018
case 'x':
7019
case 'y':
7020
case 'z':
7021
case 'w':
7022
if (color_symbols.size() > 0 || texture_symbols.size() > 0) {
7023
mix_error = true;
7024
break;
7025
}
7026
if (!position_symbols.has(c[i])) {
7027
position_symbols.insert(c[i]);
7028
} else {
7029
repeated = true;
7030
}
7031
break;
7032
case 's':
7033
case 't':
7034
case 'p':
7035
case 'q':
7036
if (color_symbols.size() > 0 || position_symbols.size() > 0) {
7037
mix_error = true;
7038
break;
7039
}
7040
if (!texture_symbols.has(c[i])) {
7041
texture_symbols.insert(c[i]);
7042
} else {
7043
repeated = true;
7044
}
7045
break;
7046
default:
7047
ok = false;
7048
break;
7049
}
7050
}
7051
7052
} break;
7053
7054
default: {
7055
ok = false;
7056
}
7057
}
7058
7059
if (mix_error) {
7060
_set_error(vformat(RTR("Cannot combine symbols from different sets in expression '.%s'."), ident));
7061
return nullptr;
7062
}
7063
7064
if (!ok) {
7065
_set_error(vformat(RTR("Invalid member for '%s' expression: '.%s'."), (dt == TYPE_STRUCT ? st : get_datatype_name(dt)), ident));
7066
return nullptr;
7067
}
7068
7069
MemberNode *mn = alloc_node<MemberNode>();
7070
mn->basetype = dt;
7071
mn->basetype_const = is_const;
7072
mn->datatype = member_type;
7073
mn->base_struct_name = st;
7074
mn->struct_name = member_struct_name;
7075
mn->array_size = array_size;
7076
mn->name = ident;
7077
mn->owner = expr;
7078
mn->has_swizzling_duplicates = repeated;
7079
7080
if (array_size > 0) {
7081
TkPos prev_pos = _get_tkpos();
7082
tk = _get_token();
7083
if (tk.type == TK_OP_ASSIGN) {
7084
if (last_type == IDENTIFIER_CONSTANT) {
7085
_set_error(RTR("Constants cannot be modified."));
7086
return nullptr;
7087
}
7088
Node *assign_expression = _parse_array_constructor(p_block, p_function_info, member_type, member_struct_name, array_size);
7089
if (!assign_expression) {
7090
return nullptr;
7091
}
7092
mn->assign_expression = assign_expression;
7093
} else if (tk.type == TK_PERIOD) {
7094
completion_class = TAG_ARRAY;
7095
if (p_block != nullptr) {
7096
p_block->block_tag = SubClassTag::TAG_ARRAY;
7097
}
7098
mn->call_expression = _parse_and_reduce_expression(p_block, p_function_info);
7099
if (p_block != nullptr) {
7100
p_block->block_tag = SubClassTag::TAG_GLOBAL;
7101
}
7102
if (!mn->call_expression) {
7103
return nullptr;
7104
}
7105
} else if (tk.type == TK_BRACKET_OPEN) {
7106
Node *index_expression = _parse_and_reduce_expression(p_block, p_function_info);
7107
if (!index_expression) {
7108
return nullptr;
7109
}
7110
7111
if (index_expression->get_array_size() != 0 || (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT)) {
7112
_set_error(RTR("Only integer expressions are allowed for indexing."));
7113
return nullptr;
7114
}
7115
7116
if (index_expression->type == Node::NODE_TYPE_CONSTANT) {
7117
ConstantNode *cnode = static_cast<ConstantNode *>(index_expression);
7118
if (cnode) {
7119
if (!cnode->values.is_empty()) {
7120
int value = cnode->values[0].sint;
7121
if (value < 0 || value >= array_size) {
7122
_set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), value, 0, array_size - 1));
7123
return nullptr;
7124
}
7125
}
7126
}
7127
}
7128
7129
tk = _get_token();
7130
if (tk.type != TK_BRACKET_CLOSE) {
7131
_set_expected_error("]");
7132
return nullptr;
7133
}
7134
mn->index_expression = index_expression;
7135
} else {
7136
_set_tkpos(prev_pos);
7137
}
7138
}
7139
expr = mn;
7140
7141
#ifdef DEBUG_ENABLED
7142
keyword_completion_context = prev_keyword_completion_context;
7143
#endif
7144
7145
//todo
7146
//member (period) has priority over any operator
7147
//creates a subindexing expression in place
7148
7149
/*} else if (tk.type==TK_BRACKET_OPEN) {
7150
//todo
7151
//subindexing has priority over any operator
7152
//creates a subindexing expression in place
7153
7154
*/
7155
} else if (tk.type == TK_BRACKET_OPEN) {
7156
Node *index = _parse_and_reduce_expression(p_block, p_function_info);
7157
if (!index) {
7158
return nullptr;
7159
}
7160
7161
if (index->get_array_size() != 0 || (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT)) {
7162
_set_error(RTR("Only integer expressions are allowed for indexing."));
7163
return nullptr;
7164
}
7165
7166
DataType member_type = TYPE_VOID;
7167
String member_struct_name;
7168
7169
if (expr->get_array_size() > 0) {
7170
if (index->type == Node::NODE_TYPE_CONSTANT) {
7171
uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
7172
if (index_constant >= (uint32_t)expr->get_array_size()) {
7173
_set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, expr->get_array_size() - 1));
7174
return nullptr;
7175
}
7176
}
7177
member_type = expr->get_datatype();
7178
if (member_type == TYPE_STRUCT) {
7179
member_struct_name = expr->get_datatype_name();
7180
}
7181
} else {
7182
switch (expr->get_datatype()) {
7183
case TYPE_BVEC2:
7184
case TYPE_VEC2:
7185
case TYPE_IVEC2:
7186
case TYPE_UVEC2:
7187
case TYPE_MAT2:
7188
if (index->type == Node::NODE_TYPE_CONSTANT) {
7189
uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
7190
if (index_constant >= 2) {
7191
_set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, 1));
7192
return nullptr;
7193
}
7194
}
7195
7196
switch (expr->get_datatype()) {
7197
case TYPE_BVEC2:
7198
member_type = TYPE_BOOL;
7199
break;
7200
case TYPE_VEC2:
7201
member_type = TYPE_FLOAT;
7202
break;
7203
case TYPE_IVEC2:
7204
member_type = TYPE_INT;
7205
break;
7206
case TYPE_UVEC2:
7207
member_type = TYPE_UINT;
7208
break;
7209
case TYPE_MAT2:
7210
member_type = TYPE_VEC2;
7211
break;
7212
default:
7213
break;
7214
}
7215
7216
break;
7217
case TYPE_BVEC3:
7218
case TYPE_VEC3:
7219
case TYPE_IVEC3:
7220
case TYPE_UVEC3:
7221
case TYPE_MAT3:
7222
if (index->type == Node::NODE_TYPE_CONSTANT) {
7223
uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
7224
if (index_constant >= 3) {
7225
_set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, 2));
7226
return nullptr;
7227
}
7228
}
7229
7230
switch (expr->get_datatype()) {
7231
case TYPE_BVEC3:
7232
member_type = TYPE_BOOL;
7233
break;
7234
case TYPE_VEC3:
7235
member_type = TYPE_FLOAT;
7236
break;
7237
case TYPE_IVEC3:
7238
member_type = TYPE_INT;
7239
break;
7240
case TYPE_UVEC3:
7241
member_type = TYPE_UINT;
7242
break;
7243
case TYPE_MAT3:
7244
member_type = TYPE_VEC3;
7245
break;
7246
default:
7247
break;
7248
}
7249
break;
7250
case TYPE_BVEC4:
7251
case TYPE_VEC4:
7252
case TYPE_IVEC4:
7253
case TYPE_UVEC4:
7254
case TYPE_MAT4:
7255
if (index->type == Node::NODE_TYPE_CONSTANT) {
7256
uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
7257
if (index_constant >= 4) {
7258
_set_error(vformat(RTR("Index [%d] out of range [%d..%d]."), index_constant, 0, 3));
7259
return nullptr;
7260
}
7261
}
7262
7263
switch (expr->get_datatype()) {
7264
case TYPE_BVEC4:
7265
member_type = TYPE_BOOL;
7266
break;
7267
case TYPE_VEC4:
7268
member_type = TYPE_FLOAT;
7269
break;
7270
case TYPE_IVEC4:
7271
member_type = TYPE_INT;
7272
break;
7273
case TYPE_UVEC4:
7274
member_type = TYPE_UINT;
7275
break;
7276
case TYPE_MAT4:
7277
member_type = TYPE_VEC4;
7278
break;
7279
default:
7280
break;
7281
}
7282
break;
7283
default: {
7284
_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()))));
7285
return nullptr;
7286
}
7287
}
7288
}
7289
OperatorNode *op = alloc_node<OperatorNode>();
7290
op->op = OP_INDEX;
7291
op->return_cache = member_type;
7292
op->struct_name = member_struct_name;
7293
op->arguments.push_back(expr);
7294
op->arguments.push_back(index);
7295
expr = op;
7296
7297
tk = _get_token();
7298
if (tk.type != TK_BRACKET_CLOSE) {
7299
_set_expected_error("]");
7300
return nullptr;
7301
}
7302
7303
} else if (tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) {
7304
OperatorNode *op = alloc_node<OperatorNode>();
7305
op->op = tk.type == TK_OP_DECREMENT ? OP_POST_DECREMENT : OP_POST_INCREMENT;
7306
op->arguments.push_back(expr);
7307
7308
if (!_validate_operator(p_block, p_function_info, op, &op->return_cache, &op->return_array_size)) {
7309
_set_error(RTR("Invalid base type for increment/decrement operator."));
7310
return nullptr;
7311
}
7312
7313
String error;
7314
if (!_validate_assign(expr, p_function_info, &error)) {
7315
_set_error(error);
7316
return nullptr;
7317
}
7318
expr = op;
7319
} else {
7320
_set_tkpos(pos2);
7321
break;
7322
}
7323
}
7324
7325
Expression e;
7326
e.is_op = false;
7327
e.node = expr;
7328
expression.push_back(e);
7329
7330
pos = _get_tkpos();
7331
tk = _get_token();
7332
7333
if (p_previous_expression_info != nullptr && tk.type == p_previous_expression_info->tt_break && !p_previous_expression_info->is_last_expr) {
7334
break;
7335
}
7336
7337
if (is_token_operator(tk.type)) {
7338
Expression o;
7339
o.is_op = true;
7340
7341
switch (tk.type) {
7342
case TK_OP_EQUAL:
7343
o.op = OP_EQUAL;
7344
break;
7345
case TK_OP_NOT_EQUAL:
7346
o.op = OP_NOT_EQUAL;
7347
break;
7348
case TK_OP_LESS:
7349
o.op = OP_LESS;
7350
break;
7351
case TK_OP_LESS_EQUAL:
7352
o.op = OP_LESS_EQUAL;
7353
break;
7354
case TK_OP_GREATER:
7355
o.op = OP_GREATER;
7356
break;
7357
case TK_OP_GREATER_EQUAL:
7358
o.op = OP_GREATER_EQUAL;
7359
break;
7360
case TK_OP_AND:
7361
o.op = OP_AND;
7362
break;
7363
case TK_OP_OR:
7364
o.op = OP_OR;
7365
break;
7366
case TK_OP_ADD:
7367
o.op = OP_ADD;
7368
break;
7369
case TK_OP_SUB:
7370
o.op = OP_SUB;
7371
break;
7372
case TK_OP_MUL:
7373
o.op = OP_MUL;
7374
break;
7375
case TK_OP_DIV:
7376
o.op = OP_DIV;
7377
break;
7378
case TK_OP_MOD:
7379
o.op = OP_MOD;
7380
break;
7381
case TK_OP_SHIFT_LEFT:
7382
o.op = OP_SHIFT_LEFT;
7383
break;
7384
case TK_OP_SHIFT_RIGHT:
7385
o.op = OP_SHIFT_RIGHT;
7386
break;
7387
case TK_OP_ASSIGN:
7388
o.op = OP_ASSIGN;
7389
break;
7390
case TK_OP_ASSIGN_ADD:
7391
o.op = OP_ASSIGN_ADD;
7392
break;
7393
case TK_OP_ASSIGN_SUB:
7394
o.op = OP_ASSIGN_SUB;
7395
break;
7396
case TK_OP_ASSIGN_MUL:
7397
o.op = OP_ASSIGN_MUL;
7398
break;
7399
case TK_OP_ASSIGN_DIV:
7400
o.op = OP_ASSIGN_DIV;
7401
break;
7402
case TK_OP_ASSIGN_MOD:
7403
o.op = OP_ASSIGN_MOD;
7404
break;
7405
case TK_OP_ASSIGN_SHIFT_LEFT:
7406
o.op = OP_ASSIGN_SHIFT_LEFT;
7407
break;
7408
case TK_OP_ASSIGN_SHIFT_RIGHT:
7409
o.op = OP_ASSIGN_SHIFT_RIGHT;
7410
break;
7411
case TK_OP_ASSIGN_BIT_AND:
7412
o.op = OP_ASSIGN_BIT_AND;
7413
break;
7414
case TK_OP_ASSIGN_BIT_OR:
7415
o.op = OP_ASSIGN_BIT_OR;
7416
break;
7417
case TK_OP_ASSIGN_BIT_XOR:
7418
o.op = OP_ASSIGN_BIT_XOR;
7419
break;
7420
case TK_OP_BIT_AND:
7421
o.op = OP_BIT_AND;
7422
break;
7423
case TK_OP_BIT_OR:
7424
o.op = OP_BIT_OR;
7425
break;
7426
case TK_OP_BIT_XOR:
7427
o.op = OP_BIT_XOR;
7428
break;
7429
case TK_QUESTION:
7430
o.op = OP_SELECT_IF;
7431
break;
7432
case TK_COLON:
7433
o.op = OP_SELECT_ELSE;
7434
break;
7435
default: {
7436
_set_error(vformat(RTR("Invalid token for the operator: '%s'."), get_token_text(tk)));
7437
return nullptr;
7438
}
7439
}
7440
7441
expression.push_back(o);
7442
7443
if (o.op == OP_SELECT_IF) {
7444
ExpressionInfo info;
7445
info.expression = &expression;
7446
info.tt_break = TK_COLON;
7447
7448
expr = _parse_and_reduce_expression(p_block, p_function_info, &info);
7449
if (!expr) {
7450
return nullptr;
7451
}
7452
7453
expression.push_back({ true, { OP_SELECT_ELSE } });
7454
7455
if (p_previous_expression_info != nullptr) {
7456
info.is_last_expr = p_previous_expression_info->is_last_expr;
7457
} else {
7458
info.is_last_expr = true;
7459
}
7460
7461
expr = _parse_and_reduce_expression(p_block, p_function_info, &info);
7462
if (!expr) {
7463
return nullptr;
7464
}
7465
7466
break;
7467
}
7468
} else {
7469
_set_tkpos(pos); //something else, so rollback and end
7470
break;
7471
}
7472
}
7473
7474
/* Reduce the set set of expressions and place them in an operator tree, respecting precedence */
7475
7476
while (expression.size() > 1) {
7477
int next_op = -1;
7478
int min_priority = 0xFFFFF;
7479
bool is_unary = false;
7480
bool is_ternary = false;
7481
7482
for (int i = 0; i < expression.size(); i++) {
7483
if (!expression[i].is_op) {
7484
continue;
7485
}
7486
7487
bool unary = false;
7488
bool ternary = false;
7489
Operator op = expression[i].op;
7490
7491
int priority;
7492
switch (op) {
7493
case OP_EQUAL:
7494
priority = 8;
7495
break;
7496
case OP_NOT_EQUAL:
7497
priority = 8;
7498
break;
7499
case OP_LESS:
7500
priority = 7;
7501
break;
7502
case OP_LESS_EQUAL:
7503
priority = 7;
7504
break;
7505
case OP_GREATER:
7506
priority = 7;
7507
break;
7508
case OP_GREATER_EQUAL:
7509
priority = 7;
7510
break;
7511
case OP_AND:
7512
priority = 12;
7513
break;
7514
case OP_OR:
7515
priority = 14;
7516
break;
7517
case OP_NOT:
7518
priority = 3;
7519
unary = true;
7520
break;
7521
case OP_NEGATE:
7522
priority = 3;
7523
unary = true;
7524
break;
7525
case OP_ADD:
7526
priority = 5;
7527
break;
7528
case OP_SUB:
7529
priority = 5;
7530
break;
7531
case OP_MUL:
7532
priority = 4;
7533
break;
7534
case OP_DIV:
7535
priority = 4;
7536
break;
7537
case OP_MOD:
7538
priority = 4;
7539
break;
7540
case OP_SHIFT_LEFT:
7541
priority = 6;
7542
break;
7543
case OP_SHIFT_RIGHT:
7544
priority = 6;
7545
break;
7546
case OP_ASSIGN:
7547
priority = 16;
7548
break;
7549
case OP_ASSIGN_ADD:
7550
priority = 16;
7551
break;
7552
case OP_ASSIGN_SUB:
7553
priority = 16;
7554
break;
7555
case OP_ASSIGN_MUL:
7556
priority = 16;
7557
break;
7558
case OP_ASSIGN_DIV:
7559
priority = 16;
7560
break;
7561
case OP_ASSIGN_MOD:
7562
priority = 16;
7563
break;
7564
case OP_ASSIGN_SHIFT_LEFT:
7565
priority = 16;
7566
break;
7567
case OP_ASSIGN_SHIFT_RIGHT:
7568
priority = 16;
7569
break;
7570
case OP_ASSIGN_BIT_AND:
7571
priority = 16;
7572
break;
7573
case OP_ASSIGN_BIT_OR:
7574
priority = 16;
7575
break;
7576
case OP_ASSIGN_BIT_XOR:
7577
priority = 16;
7578
break;
7579
case OP_BIT_AND:
7580
priority = 9;
7581
break;
7582
case OP_BIT_OR:
7583
priority = 11;
7584
break;
7585
case OP_BIT_XOR:
7586
priority = 10;
7587
break;
7588
case OP_BIT_INVERT:
7589
priority = 3;
7590
unary = true;
7591
break;
7592
case OP_INCREMENT:
7593
priority = 3;
7594
unary = true;
7595
break;
7596
case OP_DECREMENT:
7597
priority = 3;
7598
unary = true;
7599
break;
7600
case OP_SELECT_IF:
7601
priority = 15;
7602
ternary = true;
7603
break;
7604
case OP_SELECT_ELSE:
7605
priority = 15;
7606
ternary = true;
7607
break;
7608
7609
default:
7610
ERR_FAIL_V(nullptr); //unexpected operator
7611
}
7612
7613
#ifdef DEBUG_ENABLED
7614
if (check_warnings && HAS_WARNING(ShaderWarning::FLOAT_COMPARISON_FLAG) && (op == OP_EQUAL || op == OP_NOT_EQUAL) &&
7615
(!expression[i - 1].is_op && !expression[i + 1].is_op) &&
7616
(expression[i - 1].node->get_datatype() == TYPE_FLOAT && expression[i + 1].node->get_datatype() == TYPE_FLOAT)) {
7617
_add_line_warning(ShaderWarning::FLOAT_COMPARISON);
7618
}
7619
#endif // DEBUG_ENABLED
7620
7621
if (priority < min_priority) {
7622
// < is used for left to right (default)
7623
// <= is used for right to left
7624
next_op = i;
7625
min_priority = priority;
7626
is_unary = unary;
7627
is_ternary = ternary;
7628
}
7629
}
7630
7631
ERR_FAIL_COND_V(next_op == -1, nullptr);
7632
7633
// OK! create operator..
7634
if (is_unary) {
7635
int expr_pos = next_op;
7636
while (expression[expr_pos].is_op) {
7637
expr_pos++;
7638
if (expr_pos == expression.size()) {
7639
//can happen..
7640
_set_error(RTR("Unexpected end of expression."));
7641
return nullptr;
7642
}
7643
}
7644
7645
//consecutively do unary operators
7646
for (int i = expr_pos - 1; i >= next_op; i--) {
7647
OperatorNode *op = alloc_node<OperatorNode>();
7648
op->op = expression[i].op;
7649
7650
String error;
7651
if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_function_info, &error)) {
7652
_set_error(error);
7653
return nullptr;
7654
}
7655
op->arguments.push_back(expression[i + 1].node);
7656
7657
expression.write[i].is_op = false;
7658
expression.write[i].node = op;
7659
7660
if (!_validate_operator(p_block, p_function_info, op, &op->return_cache, &op->return_array_size)) {
7661
if (error_set) {
7662
return nullptr;
7663
}
7664
7665
String at;
7666
for (int j = 0; j < op->arguments.size(); j++) {
7667
if (j > 0) {
7668
at += ", ";
7669
}
7670
at += get_datatype_name(op->arguments[j]->get_datatype());
7671
if (!op->arguments[j]->is_indexed() && op->arguments[j]->get_array_size() > 0) {
7672
at += "[";
7673
at += itos(op->arguments[j]->get_array_size());
7674
at += "]";
7675
}
7676
}
7677
_set_error(vformat(RTR("Invalid arguments to unary operator '%s': %s."), get_operator_text(op->op), at));
7678
return nullptr;
7679
}
7680
expression.remove_at(i + 1);
7681
}
7682
7683
} else if (is_ternary) {
7684
if (next_op < 1 || next_op >= (expression.size() - 1)) {
7685
_set_parsing_error();
7686
ERR_FAIL_V(nullptr);
7687
}
7688
7689
if (next_op + 2 >= expression.size() || !expression[next_op + 2].is_op || expression[next_op + 2].op != OP_SELECT_ELSE) {
7690
_set_error(RTR("Missing matching ':' for select operator."));
7691
return nullptr;
7692
}
7693
7694
OperatorNode *op = alloc_node<OperatorNode>();
7695
op->op = expression[next_op].op;
7696
op->arguments.push_back(expression[next_op - 1].node);
7697
op->arguments.push_back(expression[next_op + 1].node);
7698
op->arguments.push_back(expression[next_op + 3].node);
7699
7700
expression.write[next_op - 1].is_op = false;
7701
expression.write[next_op - 1].node = op;
7702
if (!_validate_operator(p_block, p_function_info, op, &op->return_cache, &op->return_array_size)) {
7703
if (error_set) {
7704
return nullptr;
7705
}
7706
7707
String at;
7708
for (int i = 0; i < op->arguments.size(); i++) {
7709
if (i > 0) {
7710
at += ", ";
7711
}
7712
at += get_datatype_name(op->arguments[i]->get_datatype());
7713
if (!op->arguments[i]->is_indexed() && op->arguments[i]->get_array_size() > 0) {
7714
at += "[";
7715
at += itos(op->arguments[i]->get_array_size());
7716
at += "]";
7717
}
7718
}
7719
_set_error(vformat(RTR("Invalid argument to ternary operator: '%s'."), at));
7720
return nullptr;
7721
}
7722
7723
for (int i = 0; i < 4; i++) {
7724
expression.remove_at(next_op);
7725
}
7726
7727
} else {
7728
if (next_op < 1 || next_op >= (expression.size() - 1)) {
7729
_set_parsing_error();
7730
ERR_FAIL_V(nullptr);
7731
}
7732
7733
OperatorNode *op = alloc_node<OperatorNode>();
7734
op->op = expression[next_op].op;
7735
7736
if (expression[next_op - 1].is_op) {
7737
_set_parsing_error();
7738
ERR_FAIL_V(nullptr);
7739
}
7740
7741
if (_is_operator_assign(op->op)) {
7742
if (p_block && expression[next_op - 1].node->type == Node::NODE_TYPE_VARIABLE) {
7743
VariableNode *vn = static_cast<VariableNode *>(expression[next_op - 1].node);
7744
p_block->use_op_eval = vn->is_const;
7745
}
7746
7747
String assign_message;
7748
if (!_validate_assign(expression[next_op - 1].node, p_function_info, &assign_message)) {
7749
_set_error(assign_message);
7750
return nullptr;
7751
}
7752
}
7753
7754
if (expression[next_op + 1].is_op) {
7755
// this is not invalid and can really appear
7756
// but it becomes invalid anyway because no binary op
7757
// can be followed by a unary op in a valid combination,
7758
// due to how precedence works, unaries will always disappear first
7759
7760
_set_parsing_error();
7761
}
7762
7763
op->arguments.push_back(expression[next_op - 1].node); //expression goes as left
7764
op->arguments.push_back(expression[next_op + 1].node); //next expression goes as right
7765
expression.write[next_op - 1].node = op;
7766
7767
//replace all 3 nodes by this operator and make it an expression
7768
7769
if (!_validate_operator(p_block, p_function_info, op, &op->return_cache, &op->return_array_size)) {
7770
if (error_set) {
7771
return nullptr;
7772
}
7773
7774
String at;
7775
for (int i = 0; i < op->arguments.size(); i++) {
7776
if (i > 0) {
7777
at += ", ";
7778
}
7779
if (op->arguments[i]->get_datatype() == TYPE_STRUCT) {
7780
at += op->arguments[i]->get_datatype_name();
7781
} else {
7782
at += get_datatype_name(op->arguments[i]->get_datatype());
7783
}
7784
if (!op->arguments[i]->is_indexed() && op->arguments[i]->get_array_size() > 0) {
7785
at += "[";
7786
at += itos(op->arguments[i]->get_array_size());
7787
at += "]";
7788
}
7789
}
7790
_set_error(vformat(RTR("Invalid arguments to operator '%s': '%s'."), get_operator_text(op->op), at));
7791
return nullptr;
7792
}
7793
7794
expression.remove_at(next_op);
7795
expression.remove_at(next_op);
7796
}
7797
}
7798
7799
if (p_block) {
7800
p_block->use_op_eval = true;
7801
}
7802
7803
if (p_previous_expression_info != nullptr) {
7804
p_previous_expression_info->expression->push_back(expression[0]);
7805
}
7806
7807
return expression[0].node;
7808
}
7809
7810
ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node) {
7811
if (p_node->type != Node::NODE_TYPE_OPERATOR) {
7812
return p_node;
7813
}
7814
7815
//for now only reduce simple constructors
7816
OperatorNode *op = static_cast<OperatorNode *>(p_node);
7817
7818
if (op->op == OP_CONSTRUCT) {
7819
ERR_FAIL_COND_V(op->arguments[0]->type != Node::NODE_TYPE_VARIABLE, p_node);
7820
7821
DataType type = op->get_datatype();
7822
DataType base = get_scalar_type(type);
7823
int cardinality = get_cardinality(type);
7824
7825
Vector<Scalar> values;
7826
7827
for (int i = 1; i < op->arguments.size(); i++) {
7828
op->arguments.write[i] = _reduce_expression(p_block, op->arguments[i]);
7829
if (op->arguments[i]->type == Node::NODE_TYPE_CONSTANT) {
7830
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i]);
7831
7832
if (get_scalar_type(cn->datatype) == base) {
7833
for (int j = 0; j < cn->values.size(); j++) {
7834
values.push_back(cn->values[j]);
7835
}
7836
} else if (get_scalar_type(cn->datatype) == cn->datatype) {
7837
Scalar v;
7838
if (!convert_constant(cn, base, &v)) {
7839
return p_node;
7840
}
7841
values.push_back(v);
7842
} else {
7843
return p_node;
7844
}
7845
7846
} else {
7847
return p_node;
7848
}
7849
}
7850
7851
if (values.size() == 1) {
7852
if (type >= TYPE_MAT2 && type <= TYPE_MAT4) {
7853
Scalar value = values[0];
7854
Scalar zero;
7855
zero.real = 0.0f;
7856
int size = 2 + (type - TYPE_MAT2);
7857
7858
values.clear();
7859
for (int i = 0; i < size; i++) {
7860
for (int j = 0; j < size; j++) {
7861
values.push_back(i == j ? value : zero);
7862
}
7863
}
7864
} else {
7865
Scalar value = values[0];
7866
for (int i = 1; i < cardinality; i++) {
7867
values.push_back(value);
7868
}
7869
}
7870
} else if (values.size() != cardinality) {
7871
ERR_PRINT("Failed to reduce expression, values and cardinality mismatch.");
7872
return p_node;
7873
}
7874
7875
ConstantNode *cn = alloc_node<ConstantNode>();
7876
cn->datatype = op->get_datatype();
7877
cn->values = values;
7878
return cn;
7879
} else if (op->op == OP_NEGATE) {
7880
op->arguments.write[0] = _reduce_expression(p_block, op->arguments[0]);
7881
if (op->arguments[0]->type == Node::NODE_TYPE_CONSTANT) {
7882
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[0]);
7883
7884
DataType base = get_scalar_type(cn->datatype);
7885
7886
Vector<Scalar> values;
7887
7888
for (int i = 0; i < cn->values.size(); i++) {
7889
Scalar nv;
7890
switch (base) {
7891
case TYPE_BOOL: {
7892
nv.boolean = !cn->values[i].boolean;
7893
} break;
7894
case TYPE_INT: {
7895
nv.sint = -cn->values[i].sint;
7896
} break;
7897
case TYPE_UINT: {
7898
// Intentionally wrap the unsigned int value, because GLSL does.
7899
nv.uint = 0 - cn->values[i].uint;
7900
} break;
7901
case TYPE_FLOAT: {
7902
nv.real = -cn->values[i].real;
7903
} break;
7904
default: {
7905
}
7906
}
7907
7908
values.push_back(nv);
7909
}
7910
7911
cn->values = values;
7912
return cn;
7913
}
7914
}
7915
7916
return p_node;
7917
}
7918
7919
ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const FunctionInfo &p_function_info, const ExpressionInfo *p_previous_expression_info) {
7920
ShaderLanguage::Node *expr = _parse_expression(p_block, p_function_info, p_previous_expression_info);
7921
if (!expr) { //errored
7922
return nullptr;
7923
}
7924
7925
expr = _reduce_expression(p_block, expr);
7926
7927
return expr;
7928
}
7929
7930
Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_just_one, bool p_can_break, bool p_can_continue) {
7931
while (true) {
7932
TkPos pos = _get_tkpos();
7933
Token tk = _get_token();
7934
#ifdef DEBUG_ENABLED
7935
Token next;
7936
#endif // DEBUG_ENABLED
7937
7938
if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_SWITCH) {
7939
if (tk.type != TK_CF_CASE && tk.type != TK_CF_DEFAULT && tk.type != TK_CURLY_BRACKET_CLOSE) {
7940
_set_error(vformat(RTR("A switch may only contain '%s' and '%s' blocks."), "case", "default"));
7941
return ERR_PARSE_ERROR;
7942
}
7943
}
7944
7945
bool is_struct = shader->structs.has(tk.text);
7946
bool is_var_init = false;
7947
bool is_condition = false;
7948
7949
if (tk.type == TK_CURLY_BRACKET_CLOSE) { //end of block
7950
if (p_just_one) {
7951
_set_expected_error("}");
7952
return ERR_PARSE_ERROR;
7953
}
7954
7955
return OK;
7956
7957
} else if (tk.type == TK_CONST || is_token_precision(tk.type) || is_token_nonvoid_datatype(tk.type) || is_struct) {
7958
is_var_init = true;
7959
7960
String struct_name = "";
7961
if (is_struct) {
7962
struct_name = tk.text;
7963
#ifdef DEBUG_ENABLED
7964
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(struct_name)) {
7965
used_structs[struct_name].used = true;
7966
}
7967
#endif // DEBUG_ENABLED
7968
}
7969
#ifdef DEBUG_ENABLED
7970
uint32_t precision_flag = CF_PRECISION_MODIFIER;
7971
7972
keyword_completion_context = CF_DATATYPE;
7973
if (!is_token_precision(tk.type)) {
7974
if (!is_struct) {
7975
keyword_completion_context |= precision_flag;
7976
}
7977
}
7978
#endif // DEBUG_ENABLED
7979
7980
bool is_const = false;
7981
7982
if (tk.type == TK_CONST) {
7983
is_const = true;
7984
tk = _get_token();
7985
7986
if (!is_struct) {
7987
is_struct = shader->structs.has(tk.text); // check again.
7988
struct_name = tk.text;
7989
}
7990
}
7991
7992
DataPrecision precision = PRECISION_DEFAULT;
7993
if (is_token_precision(tk.type)) {
7994
precision = get_token_precision(tk.type);
7995
tk = _get_token();
7996
7997
if (!is_struct) {
7998
is_struct = shader->structs.has(tk.text); // check again.
7999
}
8000
8001
#ifdef DEBUG_ENABLED
8002
if (keyword_completion_context & precision_flag) {
8003
keyword_completion_context ^= precision_flag;
8004
}
8005
#endif // DEBUG_ENABLED
8006
}
8007
8008
#ifdef DEBUG_ENABLED
8009
if (is_const && _lookup_next(next)) {
8010
if (is_token_precision(next.type)) {
8011
keyword_completion_context = CF_UNSPECIFIED;
8012
}
8013
if (is_token_datatype(next.type)) {
8014
keyword_completion_context ^= CF_DATATYPE;
8015
}
8016
}
8017
#endif // DEBUG_ENABLED
8018
8019
if (precision != PRECISION_DEFAULT) {
8020
if (!is_token_nonvoid_datatype(tk.type)) {
8021
_set_error(RTR("Expected variable type after precision modifier."));
8022
return ERR_PARSE_ERROR;
8023
}
8024
}
8025
8026
if (!is_struct) {
8027
if (!is_token_variable_datatype(tk.type)) {
8028
_set_error(RTR("Invalid variable type (samplers are not allowed)."));
8029
return ERR_PARSE_ERROR;
8030
}
8031
}
8032
8033
DataType type = is_struct ? TYPE_STRUCT : get_token_datatype(tk.type);
8034
8035
if (precision != PRECISION_DEFAULT && _validate_precision(type, precision) != OK) {
8036
return ERR_PARSE_ERROR;
8037
}
8038
8039
#ifdef DEBUG_ENABLED
8040
keyword_completion_context = CF_UNSPECIFIED;
8041
#endif // DEBUG_ENABLED
8042
8043
int array_size = 0;
8044
bool fixed_array_size = false;
8045
bool first = true;
8046
8047
VariableDeclarationNode *vdnode = alloc_node<VariableDeclarationNode>();
8048
vdnode->precision = precision;
8049
if (is_struct) {
8050
vdnode->struct_name = struct_name;
8051
vdnode->datatype = TYPE_STRUCT;
8052
} else {
8053
vdnode->datatype = type;
8054
};
8055
vdnode->is_const = is_const;
8056
8057
do {
8058
bool unknown_size = false;
8059
VariableDeclarationNode::Declaration decl;
8060
8061
tk = _get_token();
8062
8063
if (first) {
8064
first = false;
8065
8066
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
8067
_set_error(RTR("Expected an identifier or '[' after type."));
8068
return ERR_PARSE_ERROR;
8069
}
8070
8071
if (tk.type == TK_BRACKET_OPEN) {
8072
Error error = _parse_array_size(p_block, p_function_info, false, &decl.size_expression, &array_size, &unknown_size);
8073
if (error != OK) {
8074
return error;
8075
}
8076
decl.size = array_size;
8077
8078
fixed_array_size = true;
8079
tk = _get_token();
8080
}
8081
}
8082
8083
if (tk.type != TK_IDENTIFIER) {
8084
_set_error(RTR("Expected an identifier."));
8085
return ERR_PARSE_ERROR;
8086
}
8087
8088
StringName name = tk.text;
8089
ShaderLanguage::IdentifierType itype;
8090
if (_find_identifier(p_block, true, p_function_info, name, (ShaderLanguage::DataType *)nullptr, &itype)) {
8091
if (itype != IDENTIFIER_FUNCTION) {
8092
_set_redefinition_error(String(name));
8093
return ERR_PARSE_ERROR;
8094
}
8095
}
8096
decl.name = name;
8097
8098
#ifdef DEBUG_ENABLED
8099
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG) && p_block) {
8100
FunctionNode *parent_function = nullptr;
8101
{
8102
BlockNode *block = p_block;
8103
while (block && !block->parent_function) {
8104
block = block->parent_block;
8105
}
8106
parent_function = block->parent_function;
8107
}
8108
if (parent_function) {
8109
StringName func_name = parent_function->name;
8110
8111
if (!used_local_vars.has(func_name)) {
8112
used_local_vars.insert(func_name, HashMap<StringName, Usage>());
8113
}
8114
8115
used_local_vars[func_name].insert(name, Usage(tk_line));
8116
}
8117
}
8118
#endif // DEBUG_ENABLED
8119
is_const_decl = is_const;
8120
8121
BlockNode::Variable var;
8122
var.type = type;
8123
var.precision = precision;
8124
var.line = tk_line;
8125
var.array_size = array_size;
8126
var.is_const = is_const;
8127
var.struct_name = struct_name;
8128
8129
tk = _get_token();
8130
8131
if (tk.type == TK_BRACKET_OPEN) {
8132
Error error = _parse_array_size(p_block, p_function_info, false, &decl.size_expression, &var.array_size, &unknown_size);
8133
if (error != OK) {
8134
return error;
8135
}
8136
8137
decl.size = var.array_size;
8138
array_size = var.array_size;
8139
8140
tk = _get_token();
8141
}
8142
#ifdef DEBUG_ENABLED
8143
if (var.type == DataType::TYPE_BOOL) {
8144
keyword_completion_context = CF_BOOLEAN;
8145
}
8146
#endif // DEBUG_ENABLED
8147
if (var.array_size > 0 || unknown_size) {
8148
bool full_def = false;
8149
8150
if (tk.type == TK_OP_ASSIGN) {
8151
TkPos prev_pos = _get_tkpos();
8152
tk = _get_token();
8153
8154
if (tk.type == TK_IDENTIFIER) { // a function call array initialization
8155
_set_tkpos(prev_pos);
8156
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
8157
8158
if (!n) {
8159
_set_error(RTR("Expected array initializer."));
8160
return ERR_PARSE_ERROR;
8161
} else {
8162
if (unknown_size) {
8163
decl.size = n->get_array_size();
8164
var.array_size = n->get_array_size();
8165
}
8166
8167
if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) {
8168
return ERR_PARSE_ERROR;
8169
}
8170
8171
decl.single_expression = true;
8172
decl.initializer.push_back(n);
8173
}
8174
8175
tk = _get_token();
8176
} else {
8177
if (tk.type != TK_CURLY_BRACKET_OPEN) {
8178
if (unknown_size) {
8179
_set_expected_error("{");
8180
return ERR_PARSE_ERROR;
8181
}
8182
8183
full_def = true;
8184
8185
DataPrecision precision2 = PRECISION_DEFAULT;
8186
if (is_token_precision(tk.type)) {
8187
precision2 = get_token_precision(tk.type);
8188
tk = _get_token();
8189
if (!is_token_nonvoid_datatype(tk.type)) {
8190
_set_error(RTR("Expected data type after precision modifier."));
8191
return ERR_PARSE_ERROR;
8192
}
8193
}
8194
8195
DataType type2;
8196
StringName struct_name2 = "";
8197
8198
if (shader->structs.has(tk.text)) {
8199
type2 = TYPE_STRUCT;
8200
struct_name2 = tk.text;
8201
} else {
8202
if (!is_token_variable_datatype(tk.type)) {
8203
_set_error(RTR("Invalid data type for the array."));
8204
return ERR_PARSE_ERROR;
8205
}
8206
type2 = get_token_datatype(tk.type);
8207
}
8208
8209
if (precision2 != PRECISION_DEFAULT && _validate_precision(type2, precision2) != OK) {
8210
return ERR_PARSE_ERROR;
8211
}
8212
8213
int array_size2 = 0;
8214
8215
tk = _get_token();
8216
if (tk.type == TK_BRACKET_OPEN) {
8217
bool is_unknown_size = false;
8218
Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size2, &is_unknown_size);
8219
if (error != OK) {
8220
return error;
8221
}
8222
if (is_unknown_size) {
8223
array_size2 = var.array_size;
8224
}
8225
tk = _get_token();
8226
} else {
8227
_set_expected_error("[");
8228
return ERR_PARSE_ERROR;
8229
}
8230
8231
if (precision != precision2 || type != type2 || struct_name != struct_name2 || var.array_size != array_size2) {
8232
String from;
8233
if (precision2 != PRECISION_DEFAULT) {
8234
from += get_precision_name(precision2);
8235
from += " ";
8236
}
8237
if (type2 == TYPE_STRUCT) {
8238
from += struct_name2;
8239
} else {
8240
from += get_datatype_name(type2);
8241
}
8242
from += "[";
8243
from += itos(array_size2);
8244
from += "]'";
8245
8246
String to;
8247
if (precision != PRECISION_DEFAULT) {
8248
to += get_precision_name(precision);
8249
to += " ";
8250
}
8251
if (type == TYPE_STRUCT) {
8252
to += struct_name;
8253
} else {
8254
to += get_datatype_name(type);
8255
}
8256
to += "[";
8257
to += itos(var.array_size);
8258
to += "]'";
8259
8260
_set_error(vformat(RTR("Cannot convert from '%s' to '%s'."), from, to));
8261
return ERR_PARSE_ERROR;
8262
}
8263
}
8264
8265
bool curly = tk.type == TK_CURLY_BRACKET_OPEN;
8266
8267
if (unknown_size) {
8268
if (!curly) {
8269
_set_expected_error("{");
8270
return ERR_PARSE_ERROR;
8271
}
8272
} else {
8273
if (full_def) {
8274
if (curly) {
8275
_set_expected_error("(");
8276
return ERR_PARSE_ERROR;
8277
}
8278
}
8279
}
8280
8281
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
8282
while (true) {
8283
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
8284
if (!n) {
8285
return ERR_PARSE_ERROR;
8286
}
8287
8288
if (is_const && n->type == Node::NODE_TYPE_OPERATOR && static_cast<OperatorNode *>(n)->op == OP_CALL) {
8289
_set_error(RTR("Expected a constant expression."));
8290
return ERR_PARSE_ERROR;
8291
}
8292
8293
if (!_compare_datatypes(var.type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) {
8294
return ERR_PARSE_ERROR;
8295
}
8296
8297
tk = _get_token();
8298
if (tk.type == TK_COMMA) {
8299
decl.initializer.push_back(n);
8300
continue;
8301
} else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) {
8302
decl.initializer.push_back(n);
8303
break;
8304
} else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) {
8305
decl.initializer.push_back(n);
8306
break;
8307
} else {
8308
if (curly) {
8309
_set_expected_error("}", ",");
8310
} else {
8311
_set_expected_error(")", ",");
8312
}
8313
return ERR_PARSE_ERROR;
8314
}
8315
}
8316
if (unknown_size) {
8317
decl.size = decl.initializer.size();
8318
var.array_size = decl.initializer.size();
8319
} else if (decl.initializer.size() != var.array_size) {
8320
_set_error(vformat(RTR("Array size mismatch. Expected %d elements (found %d)."), var.array_size, decl.initializer.size()));
8321
return ERR_PARSE_ERROR;
8322
}
8323
tk = _get_token();
8324
} else {
8325
_set_expected_error("(");
8326
return ERR_PARSE_ERROR;
8327
}
8328
}
8329
} else {
8330
if (unknown_size) {
8331
_set_error(RTR("Expected array initialization."));
8332
return ERR_PARSE_ERROR;
8333
}
8334
if (is_const) {
8335
_set_error(RTR("Expected initialization of constant."));
8336
return ERR_PARSE_ERROR;
8337
}
8338
}
8339
8340
array_size = var.array_size;
8341
} else if (tk.type == TK_OP_ASSIGN) {
8342
p_block->use_op_eval = is_const;
8343
8344
// Variable created with assignment! Must parse an expression.
8345
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
8346
if (!n) {
8347
return ERR_PARSE_ERROR;
8348
}
8349
if (is_const && n->type == Node::NODE_TYPE_OPERATOR && static_cast<OperatorNode *>(n)->op == OP_CALL) {
8350
OperatorNode *op = static_cast<OperatorNode *>(n);
8351
for (int i = 1; i < op->arguments.size(); i++) {
8352
if (!_check_node_constness(op->arguments[i])) {
8353
_set_error(vformat(RTR("Expected constant expression for argument %d of function call after '='."), i - 1));
8354
return ERR_PARSE_ERROR;
8355
}
8356
}
8357
}
8358
8359
if (is_const) {
8360
var.values = n->get_values();
8361
}
8362
8363
if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) {
8364
return ERR_PARSE_ERROR;
8365
}
8366
8367
decl.initializer.push_back(n);
8368
tk = _get_token();
8369
} else {
8370
if (is_const) {
8371
_set_error(RTR("Expected initialization of constant."));
8372
return ERR_PARSE_ERROR;
8373
}
8374
}
8375
8376
vdnode->declarations.push_back(decl);
8377
p_block->variables[name] = var;
8378
is_const_decl = false;
8379
8380
if (!fixed_array_size) {
8381
array_size = 0;
8382
}
8383
8384
if (tk.type == TK_SEMICOLON) {
8385
break;
8386
} else if (tk.type != TK_COMMA) {
8387
_set_expected_error(",", ";");
8388
return ERR_PARSE_ERROR;
8389
}
8390
} while (tk.type == TK_COMMA); //another variable
8391
#ifdef DEBUG_ENABLED
8392
keyword_completion_context = CF_BLOCK;
8393
#endif // DEBUG_ENABLED
8394
p_block->statements.push_back(static_cast<Node *>(vdnode));
8395
} else if (tk.type == TK_CURLY_BRACKET_OPEN) {
8396
//a sub block, just because..
8397
BlockNode *block = alloc_node<BlockNode>();
8398
block->parent_block = p_block;
8399
if (_parse_block(block, p_function_info, false, p_can_break, p_can_continue) != OK) {
8400
return ERR_PARSE_ERROR;
8401
}
8402
p_block->statements.push_back(block);
8403
} else if (tk.type == TK_CF_IF) {
8404
//if () {}
8405
tk = _get_token();
8406
if (tk.type != TK_PARENTHESIS_OPEN) {
8407
_set_expected_after_error("(", "if");
8408
return ERR_PARSE_ERROR;
8409
}
8410
8411
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
8412
cf->flow_op = FLOW_OP_IF;
8413
#ifdef DEBUG_ENABLED
8414
keyword_completion_context = CF_IF_DECL;
8415
#endif // DEBUG_ENABLED
8416
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
8417
if (!n) {
8418
return ERR_PARSE_ERROR;
8419
}
8420
#ifdef DEBUG_ENABLED
8421
keyword_completion_context = CF_BLOCK;
8422
#endif // DEBUG_ENABLED
8423
8424
if (n->get_datatype() != TYPE_BOOL) {
8425
_set_error(RTR("Expected a boolean expression."));
8426
return ERR_PARSE_ERROR;
8427
}
8428
8429
tk = _get_token();
8430
if (tk.type != TK_PARENTHESIS_CLOSE) {
8431
_set_expected_error(")");
8432
return ERR_PARSE_ERROR;
8433
}
8434
8435
BlockNode *block = alloc_node<BlockNode>();
8436
block->parent_block = p_block;
8437
cf->expressions.push_back(n);
8438
cf->blocks.push_back(block);
8439
p_block->statements.push_back(cf);
8440
8441
Error err = _parse_block(block, p_function_info, true, p_can_break, p_can_continue);
8442
if (err) {
8443
return err;
8444
}
8445
8446
pos = _get_tkpos();
8447
tk = _get_token();
8448
if (tk.type == TK_CF_ELSE) {
8449
block = alloc_node<BlockNode>();
8450
block->parent_block = p_block;
8451
cf->blocks.push_back(block);
8452
err = _parse_block(block, p_function_info, true, p_can_break, p_can_continue);
8453
if (err) {
8454
return err;
8455
}
8456
} else {
8457
_set_tkpos(pos); //rollback
8458
}
8459
} else if (tk.type == TK_CF_SWITCH) {
8460
// switch() {}
8461
tk = _get_token();
8462
if (tk.type != TK_PARENTHESIS_OPEN) {
8463
_set_expected_after_error("(", "switch");
8464
return ERR_PARSE_ERROR;
8465
}
8466
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
8467
cf->flow_op = FLOW_OP_SWITCH;
8468
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
8469
if (!n) {
8470
return ERR_PARSE_ERROR;
8471
}
8472
const ShaderLanguage::DataType data_type = n->get_datatype();
8473
if (data_type != TYPE_INT && data_type != TYPE_UINT) {
8474
_set_error(RTR("Expected an integer or unsigned integer expression."));
8475
return ERR_PARSE_ERROR;
8476
}
8477
tk = _get_token();
8478
if (tk.type != TK_PARENTHESIS_CLOSE) {
8479
_set_expected_error(")");
8480
return ERR_PARSE_ERROR;
8481
}
8482
tk = _get_token();
8483
if (tk.type != TK_CURLY_BRACKET_OPEN) {
8484
_set_expected_after_error("{", "switch");
8485
return ERR_PARSE_ERROR;
8486
}
8487
BlockNode *switch_block = alloc_node<BlockNode>();
8488
switch_block->block_type = BlockNode::BLOCK_TYPE_SWITCH;
8489
switch_block->parent_block = p_block;
8490
switch_block->expected_type = data_type;
8491
cf->expressions.push_back(n);
8492
cf->blocks.push_back(switch_block);
8493
p_block->statements.push_back(cf);
8494
8495
pos = _get_tkpos();
8496
tk = _get_token();
8497
bool has_default = false;
8498
if (tk.type == TK_CF_CASE || tk.type == TK_CF_DEFAULT) {
8499
if (tk.type == TK_CF_DEFAULT) {
8500
has_default = true;
8501
}
8502
_set_tkpos(pos);
8503
} else {
8504
_set_expected_error("case", "default");
8505
return ERR_PARSE_ERROR;
8506
}
8507
8508
while (true) { // Go-through multiple cases.
8509
8510
if (_parse_block(switch_block, p_function_info, true, true, false) != OK) {
8511
return ERR_PARSE_ERROR;
8512
}
8513
pos = _get_tkpos();
8514
tk = _get_token();
8515
if (tk.type == TK_CF_CASE) {
8516
_set_tkpos(pos);
8517
continue;
8518
} else if (tk.type == TK_CF_DEFAULT) {
8519
if (has_default) {
8520
_set_error(RTR("Default case must be defined only once."));
8521
return ERR_PARSE_ERROR;
8522
}
8523
has_default = true;
8524
_set_tkpos(pos);
8525
continue;
8526
} else {
8527
break;
8528
}
8529
}
8530
8531
} else if (tk.type == TK_CF_CASE) {
8532
// case x : break; | return;
8533
8534
if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_CASE) {
8535
_set_tkpos(pos);
8536
return OK;
8537
}
8538
8539
if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_SWITCH)) {
8540
_set_error(vformat(RTR("'%s' must be placed within a '%s' block."), "case", "switch"));
8541
return ERR_PARSE_ERROR;
8542
}
8543
8544
tk = _get_token();
8545
8546
int sign = 1;
8547
8548
if (tk.type == TK_OP_SUB) {
8549
sign = -1;
8550
tk = _get_token();
8551
}
8552
8553
Node *n = nullptr;
8554
8555
if (!tk.is_integer_constant()) {
8556
bool correct_constant_expression = false;
8557
8558
if (tk.type == TK_IDENTIFIER) {
8559
DataType data_type;
8560
bool is_const;
8561
8562
bool found = _find_identifier(p_block, false, p_function_info, tk.text, &data_type, nullptr, &is_const);
8563
if (!found) {
8564
_set_error(vformat(RTR("Undefined identifier '%s' in a case label."), String(tk.text)));
8565
return ERR_PARSE_ERROR;
8566
}
8567
if (is_const && data_type == p_block->expected_type) {
8568
correct_constant_expression = true;
8569
}
8570
}
8571
8572
if (!correct_constant_expression) {
8573
if (p_block->expected_type == TYPE_UINT) {
8574
_set_error(RTR("Expected an unsigned integer constant."));
8575
} else {
8576
_set_error(RTR("Expected an integer constant."));
8577
}
8578
return ERR_PARSE_ERROR;
8579
}
8580
8581
VariableNode *vn = alloc_node<VariableNode>();
8582
vn->name = tk.text;
8583
{
8584
Vector<Scalar> v;
8585
DataType data_type;
8586
8587
_find_identifier(p_block, false, p_function_info, vn->name, &data_type, nullptr, nullptr, nullptr, nullptr, &v);
8588
if (data_type == TYPE_INT) {
8589
if (p_block->constants.has(v[0].sint)) {
8590
_set_error(vformat(RTR("Duplicated case label: %d."), v[0].sint));
8591
return ERR_PARSE_ERROR;
8592
}
8593
p_block->constants.insert(v[0].sint);
8594
} else {
8595
if (p_block->constants.has(v[0].uint)) {
8596
_set_error(vformat(RTR("Duplicated case label: %d."), v[0].uint));
8597
return ERR_PARSE_ERROR;
8598
}
8599
p_block->constants.insert(v[0].uint);
8600
}
8601
}
8602
n = vn;
8603
} else {
8604
ConstantNode *cn = alloc_node<ConstantNode>();
8605
Scalar v;
8606
if (p_block->expected_type == TYPE_UINT) {
8607
if (tk.type != TK_UINT_CONSTANT) {
8608
_set_error(RTR("Expected an unsigned integer constant."));
8609
return ERR_PARSE_ERROR;
8610
}
8611
v.uint = (uint32_t)tk.constant;
8612
if (p_block->constants.has(v.uint)) {
8613
_set_error(vformat(RTR("Duplicated case label: %d."), v.uint));
8614
return ERR_PARSE_ERROR;
8615
}
8616
p_block->constants.insert(v.uint);
8617
cn->datatype = TYPE_UINT;
8618
} else {
8619
if (tk.type != TK_INT_CONSTANT) {
8620
_set_error(RTR("Expected an integer constant."));
8621
return ERR_PARSE_ERROR;
8622
}
8623
v.sint = (int32_t)tk.constant * sign;
8624
if (p_block->constants.has(v.sint)) {
8625
_set_error(vformat(RTR("Duplicated case label: %d."), v.sint));
8626
return ERR_PARSE_ERROR;
8627
}
8628
p_block->constants.insert(v.sint);
8629
cn->datatype = TYPE_INT;
8630
}
8631
cn->values.push_back(v);
8632
n = cn;
8633
}
8634
8635
tk = _get_token();
8636
8637
if (tk.type != TK_COLON) {
8638
_set_expected_error(":");
8639
return ERR_PARSE_ERROR;
8640
}
8641
8642
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
8643
cf->flow_op = FLOW_OP_CASE;
8644
8645
BlockNode *case_block = alloc_node<BlockNode>();
8646
case_block->block_type = BlockNode::BLOCK_TYPE_CASE;
8647
case_block->parent_block = p_block;
8648
cf->expressions.push_back(n);
8649
cf->blocks.push_back(case_block);
8650
p_block->statements.push_back(cf);
8651
8652
Error err = _parse_block(case_block, p_function_info, false, true, false);
8653
if (err) {
8654
return err;
8655
}
8656
8657
return OK;
8658
8659
} else if (tk.type == TK_CF_DEFAULT) {
8660
if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_CASE) {
8661
_set_tkpos(pos);
8662
return OK;
8663
}
8664
8665
if (!p_block || (p_block->block_type != BlockNode::BLOCK_TYPE_SWITCH)) {
8666
_set_error(vformat(RTR("'%s' must be placed within a '%s' block."), "default", "switch"));
8667
return ERR_PARSE_ERROR;
8668
}
8669
8670
tk = _get_token();
8671
8672
if (tk.type != TK_COLON) {
8673
_set_expected_error(":");
8674
return ERR_PARSE_ERROR;
8675
}
8676
8677
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
8678
cf->flow_op = FLOW_OP_DEFAULT;
8679
8680
BlockNode *default_block = alloc_node<BlockNode>();
8681
default_block->block_type = BlockNode::BLOCK_TYPE_DEFAULT;
8682
default_block->parent_block = p_block;
8683
cf->blocks.push_back(default_block);
8684
p_block->statements.push_back(cf);
8685
8686
Error err = _parse_block(default_block, p_function_info, false, true, false);
8687
if (err) {
8688
return err;
8689
}
8690
8691
return OK;
8692
8693
} else if (tk.type == TK_CF_DO || tk.type == TK_CF_WHILE) {
8694
// do {} while()
8695
// while() {}
8696
bool is_do = tk.type == TK_CF_DO;
8697
8698
BlockNode *do_block = nullptr;
8699
if (is_do) {
8700
do_block = alloc_node<BlockNode>();
8701
do_block->parent_block = p_block;
8702
8703
Error err = _parse_block(do_block, p_function_info, true, true, true);
8704
if (err) {
8705
return err;
8706
}
8707
8708
tk = _get_token();
8709
if (tk.type != TK_CF_WHILE) {
8710
_set_expected_after_error("while", "do");
8711
return ERR_PARSE_ERROR;
8712
}
8713
}
8714
tk = _get_token();
8715
8716
if (tk.type != TK_PARENTHESIS_OPEN) {
8717
_set_expected_after_error("(", "while");
8718
return ERR_PARSE_ERROR;
8719
}
8720
8721
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
8722
if (is_do) {
8723
cf->flow_op = FLOW_OP_DO;
8724
} else {
8725
cf->flow_op = FLOW_OP_WHILE;
8726
}
8727
Node *n = _parse_and_reduce_expression(p_block, p_function_info);
8728
if (!n) {
8729
return ERR_PARSE_ERROR;
8730
}
8731
8732
tk = _get_token();
8733
if (tk.type != TK_PARENTHESIS_CLOSE) {
8734
_set_expected_error(")");
8735
return ERR_PARSE_ERROR;
8736
}
8737
if (!is_do) {
8738
BlockNode *block = alloc_node<BlockNode>();
8739
block->parent_block = p_block;
8740
cf->expressions.push_back(n);
8741
cf->blocks.push_back(block);
8742
p_block->statements.push_back(cf);
8743
8744
Error err = _parse_block(block, p_function_info, true, true, true);
8745
if (err) {
8746
return err;
8747
}
8748
} else {
8749
cf->expressions.push_back(n);
8750
cf->blocks.push_back(do_block);
8751
p_block->statements.push_back(cf);
8752
8753
tk = _get_token();
8754
if (tk.type != TK_SEMICOLON) {
8755
_set_expected_error(";");
8756
return ERR_PARSE_ERROR;
8757
}
8758
}
8759
} else if (tk.type == TK_CF_FOR) {
8760
// for() {}
8761
tk = _get_token();
8762
if (tk.type != TK_PARENTHESIS_OPEN) {
8763
_set_expected_after_error("(", "for");
8764
return ERR_PARSE_ERROR;
8765
}
8766
8767
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
8768
cf->flow_op = FLOW_OP_FOR;
8769
8770
BlockNode *init_block = alloc_node<BlockNode>();
8771
init_block->block_type = BlockNode::BLOCK_TYPE_FOR_INIT;
8772
init_block->parent_block = p_block;
8773
init_block->single_statement = true;
8774
cf->blocks.push_back(init_block);
8775
8776
#ifdef DEBUG_ENABLED
8777
keyword_completion_context = CF_DATATYPE;
8778
#endif // DEBUG_ENABLED
8779
Error err = _parse_block(init_block, p_function_info, true, false, false);
8780
if (err != OK) {
8781
return err;
8782
}
8783
#ifdef DEBUG_ENABLED
8784
keyword_completion_context = CF_UNSPECIFIED;
8785
#endif // DEBUG_ENABLED
8786
8787
BlockNode *condition_block = alloc_node<BlockNode>();
8788
condition_block->block_type = BlockNode::BLOCK_TYPE_FOR_CONDITION;
8789
condition_block->parent_block = init_block;
8790
condition_block->single_statement = true;
8791
condition_block->use_comma_between_statements = true;
8792
cf->blocks.push_back(condition_block);
8793
err = _parse_block(condition_block, p_function_info, true, false, false);
8794
if (err != OK) {
8795
return err;
8796
}
8797
8798
BlockNode *expression_block = alloc_node<BlockNode>();
8799
expression_block->block_type = BlockNode::BLOCK_TYPE_FOR_EXPRESSION;
8800
expression_block->parent_block = init_block;
8801
expression_block->single_statement = true;
8802
expression_block->use_comma_between_statements = true;
8803
cf->blocks.push_back(expression_block);
8804
err = _parse_block(expression_block, p_function_info, true, false, false);
8805
if (err != OK) {
8806
return err;
8807
}
8808
8809
BlockNode *block = alloc_node<BlockNode>();
8810
block->parent_block = init_block;
8811
cf->blocks.push_back(block);
8812
p_block->statements.push_back(cf);
8813
8814
#ifdef DEBUG_ENABLED
8815
keyword_completion_context = CF_BLOCK;
8816
#endif // DEBUG_ENABLED
8817
err = _parse_block(block, p_function_info, true, true, true);
8818
if (err != OK) {
8819
return err;
8820
}
8821
8822
} else if (tk.type == TK_CF_RETURN) {
8823
//check return type
8824
BlockNode *b = p_block;
8825
8826
while (b && !b->parent_function) {
8827
b = b->parent_block;
8828
}
8829
8830
if (!b) {
8831
_set_parsing_error();
8832
return ERR_BUG;
8833
}
8834
8835
if (b->parent_function && p_function_info.main_function) {
8836
_set_error(vformat(RTR("Using '%s' in the '%s' processor function is incorrect."), "return", b->parent_function->name));
8837
return ERR_PARSE_ERROR;
8838
}
8839
8840
String return_struct_name = String(b->parent_function->return_struct_name);
8841
String array_size_string;
8842
8843
if (b->parent_function->return_array_size > 0) {
8844
array_size_string = "[" + itos(b->parent_function->return_array_size) + "]";
8845
}
8846
8847
ControlFlowNode *flow = alloc_node<ControlFlowNode>();
8848
flow->flow_op = FLOW_OP_RETURN;
8849
8850
pos = _get_tkpos();
8851
tk = _get_token();
8852
if (tk.type == TK_SEMICOLON) {
8853
//all is good
8854
if (b->parent_function->return_type != TYPE_VOID) {
8855
_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));
8856
return ERR_PARSE_ERROR;
8857
}
8858
} else {
8859
if (b->parent_function->return_type == TYPE_VOID) {
8860
_set_error(vformat(RTR("'%s' function cannot return a value."), "void"));
8861
return ERR_PARSE_ERROR;
8862
}
8863
8864
_set_tkpos(pos); //rollback, wants expression
8865
8866
#ifdef DEBUG_ENABLED
8867
if (b->parent_function->return_type == DataType::TYPE_BOOL) {
8868
keyword_completion_context = CF_BOOLEAN;
8869
}
8870
#endif // DEBUG_ENABLED
8871
8872
Node *expr = _parse_and_reduce_expression(p_block, p_function_info);
8873
if (!expr) {
8874
return ERR_PARSE_ERROR;
8875
}
8876
8877
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()) {
8878
_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));
8879
return ERR_PARSE_ERROR;
8880
}
8881
8882
tk = _get_token();
8883
if (tk.type != TK_SEMICOLON) {
8884
_set_expected_after_error(";", "return");
8885
return ERR_PARSE_ERROR;
8886
}
8887
8888
#ifdef DEBUG_ENABLED
8889
if (b->parent_function->return_type == DataType::TYPE_BOOL) {
8890
keyword_completion_context = CF_BLOCK;
8891
}
8892
#endif // DEBUG_ENABLED
8893
8894
flow->expressions.push_back(expr);
8895
}
8896
8897
p_block->statements.push_back(flow);
8898
8899
BlockNode *block = p_block;
8900
while (block) {
8901
if (block->block_type == BlockNode::BLOCK_TYPE_CASE || block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
8902
return OK;
8903
}
8904
block = block->parent_block;
8905
}
8906
} else if (tk.type == TK_CF_DISCARD) {
8907
if (!is_discard_supported) {
8908
_set_error(vformat(RTR("Use of '%s' is not supported for the '%s' shader type."), "discard", shader_type_identifier));
8909
return ERR_PARSE_ERROR;
8910
}
8911
8912
//check return type
8913
BlockNode *b = p_block;
8914
while (b && !b->parent_function) {
8915
b = b->parent_block;
8916
}
8917
if (!b) {
8918
_set_parsing_error();
8919
return ERR_BUG;
8920
}
8921
8922
if (!b->parent_function->can_discard) {
8923
_set_error(vformat(RTR("'%s' cannot be used within the '%s' processor function."), "discard", b->parent_function->name));
8924
return ERR_PARSE_ERROR;
8925
}
8926
8927
ControlFlowNode *flow = alloc_node<ControlFlowNode>();
8928
flow->flow_op = FLOW_OP_DISCARD;
8929
8930
pos = _get_tkpos();
8931
tk = _get_token();
8932
8933
calls_info[b->parent_function->name].uses_restricted_items.push_back(Pair<StringName, CallInfo::Item>("discard", CallInfo::Item(CallInfo::Item::ITEM_TYPE_BUILTIN, pos)));
8934
8935
if (tk.type != TK_SEMICOLON) {
8936
_set_expected_after_error(";", "discard");
8937
return ERR_PARSE_ERROR;
8938
}
8939
8940
p_block->statements.push_back(flow);
8941
} else if (tk.type == TK_CF_BREAK) {
8942
if (!p_can_break) {
8943
_set_error(vformat(RTR("'%s' is not allowed outside of a loop or '%s' statement."), "break", "switch"));
8944
return ERR_PARSE_ERROR;
8945
}
8946
8947
ControlFlowNode *flow = alloc_node<ControlFlowNode>();
8948
flow->flow_op = FLOW_OP_BREAK;
8949
8950
pos = _get_tkpos();
8951
tk = _get_token();
8952
if (tk.type != TK_SEMICOLON) {
8953
_set_expected_after_error(";", "break");
8954
return ERR_PARSE_ERROR;
8955
}
8956
8957
p_block->statements.push_back(flow);
8958
8959
BlockNode *block = p_block;
8960
while (block) {
8961
if (block->block_type == BlockNode::BLOCK_TYPE_CASE || block->block_type == BlockNode::BLOCK_TYPE_DEFAULT) {
8962
return OK;
8963
}
8964
block = block->parent_block;
8965
}
8966
8967
} else if (tk.type == TK_CF_CONTINUE) {
8968
if (!p_can_continue) {
8969
_set_error(vformat(RTR("'%s' is not allowed outside of a loop."), "continue"));
8970
return ERR_PARSE_ERROR;
8971
}
8972
8973
ControlFlowNode *flow = alloc_node<ControlFlowNode>();
8974
flow->flow_op = FLOW_OP_CONTINUE;
8975
8976
pos = _get_tkpos();
8977
tk = _get_token();
8978
if (tk.type != TK_SEMICOLON) {
8979
//all is good
8980
_set_expected_after_error(";", "continue");
8981
return ERR_PARSE_ERROR;
8982
}
8983
8984
p_block->statements.push_back(flow);
8985
8986
} else {
8987
//nothing else, so expression
8988
_set_tkpos(pos); //rollback
8989
Node *expr = _parse_and_reduce_expression(p_block, p_function_info);
8990
if (!expr) {
8991
return ERR_PARSE_ERROR;
8992
}
8993
is_condition = expr->get_datatype() == TYPE_BOOL;
8994
8995
if (expr->type == Node::NODE_TYPE_OPERATOR) {
8996
OperatorNode *op = static_cast<OperatorNode *>(expr);
8997
if (op->op == OP_EMPTY) {
8998
is_var_init = true;
8999
is_condition = true;
9000
}
9001
}
9002
9003
p_block->statements.push_back(expr);
9004
tk = _get_token();
9005
9006
if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_CONDITION) {
9007
if (tk.type == TK_COMMA) {
9008
if (!is_condition) {
9009
_set_error(RTR("The middle expression is expected to have a boolean data type."));
9010
return ERR_PARSE_ERROR;
9011
}
9012
tk = _peek();
9013
if (tk.type == TK_SEMICOLON) {
9014
_set_error(vformat(RTR("Expected expression, found: '%s'."), get_token_text(tk)));
9015
return ERR_PARSE_ERROR;
9016
}
9017
continue;
9018
}
9019
if (tk.type != TK_SEMICOLON) {
9020
_set_expected_error(",", ";");
9021
return ERR_PARSE_ERROR;
9022
}
9023
} else if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_EXPRESSION) {
9024
if (tk.type == TK_COMMA) {
9025
tk = _peek();
9026
if (tk.type == TK_PARENTHESIS_CLOSE) {
9027
_set_error(vformat(RTR("Expected expression, found: '%s'."), get_token_text(tk)));
9028
return ERR_PARSE_ERROR;
9029
}
9030
continue;
9031
}
9032
if (tk.type != TK_PARENTHESIS_CLOSE) {
9033
_set_expected_error(",", ")");
9034
return ERR_PARSE_ERROR;
9035
}
9036
} else if (tk.type != TK_SEMICOLON) {
9037
_set_expected_error(";");
9038
return ERR_PARSE_ERROR;
9039
}
9040
}
9041
9042
if (p_block) {
9043
if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_INIT && !is_var_init) {
9044
_set_error(RTR("The left expression is expected to be a variable declaration."));
9045
return ERR_PARSE_ERROR;
9046
}
9047
if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_CONDITION && !is_condition) {
9048
_set_error(RTR("The middle expression is expected to have a boolean data type."));
9049
return ERR_PARSE_ERROR;
9050
}
9051
}
9052
9053
if (p_just_one) {
9054
break;
9055
}
9056
}
9057
9058
return OK;
9059
}
9060
9061
String ShaderLanguage::_get_shader_type_list(const HashSet<String> &p_shader_types) const {
9062
// Return a list of shader types as an human-readable string
9063
String valid_types;
9064
for (const String &E : p_shader_types) {
9065
if (!valid_types.is_empty()) {
9066
valid_types += ", ";
9067
}
9068
9069
valid_types += "'" + E + "'";
9070
}
9071
9072
return valid_types;
9073
}
9074
9075
String ShaderLanguage::_get_qualifier_str(ArgumentQualifier p_qualifier) const {
9076
switch (p_qualifier) {
9077
case ArgumentQualifier::ARGUMENT_QUALIFIER_IN:
9078
return "in";
9079
case ArgumentQualifier::ARGUMENT_QUALIFIER_OUT:
9080
return "out";
9081
case ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT:
9082
return "inout";
9083
}
9084
return "";
9085
}
9086
9087
Error ShaderLanguage::_validate_precision(DataType p_type, DataPrecision p_precision) {
9088
switch (p_type) {
9089
case TYPE_STRUCT: {
9090
_set_error(RTR("The precision modifier cannot be used on structs."));
9091
return FAILED;
9092
} break;
9093
case TYPE_BOOL:
9094
case TYPE_BVEC2:
9095
case TYPE_BVEC3:
9096
case TYPE_BVEC4: {
9097
_set_error(RTR("The precision modifier cannot be used on boolean types."));
9098
return FAILED;
9099
} break;
9100
default:
9101
break;
9102
}
9103
return OK;
9104
}
9105
9106
bool ShaderLanguage::_parse_numeric_constant_expression(const FunctionInfo &p_function_info, float &r_constant) {
9107
ShaderLanguage::Node *expr = _parse_and_reduce_expression(nullptr, p_function_info);
9108
if (expr == nullptr) {
9109
return false;
9110
}
9111
9112
Vector<Scalar> values;
9113
if (expr->type == Node::NODE_TYPE_VARIABLE) {
9114
_find_identifier(nullptr, false, p_function_info, static_cast<VariableNode *>(expr)->name, nullptr, nullptr, nullptr, nullptr, nullptr, &values);
9115
} else {
9116
values = expr->get_values();
9117
}
9118
9119
if (values.is_empty()) {
9120
return false; // To prevent possible crash.
9121
}
9122
9123
switch (expr->get_datatype()) {
9124
case TYPE_FLOAT:
9125
r_constant = values[0].real;
9126
break;
9127
case TYPE_INT:
9128
r_constant = static_cast<float>(values[0].sint);
9129
break;
9130
case TYPE_UINT:
9131
r_constant = static_cast<float>(values[0].uint);
9132
break;
9133
default:
9134
return false;
9135
}
9136
9137
return true;
9138
}
9139
9140
Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const Vector<ModeInfo> &p_stencil_modes, const HashSet<String> &p_shader_types) {
9141
Token tk;
9142
TkPos prev_pos;
9143
Token next;
9144
9145
if (!is_shader_inc) {
9146
#ifdef DEBUG_ENABLED
9147
keyword_completion_context = CF_SHADER_TYPE;
9148
#endif // DEBUG_ENABLED
9149
tk = _get_token();
9150
9151
if (tk.type != TK_SHADER_TYPE) {
9152
_set_error(vformat(RTR("Expected '%s' at the beginning of shader. Valid types are: %s."), "shader_type", _get_shader_type_list(p_shader_types)));
9153
return ERR_PARSE_ERROR;
9154
}
9155
#ifdef DEBUG_ENABLED
9156
keyword_completion_context = CF_UNSPECIFIED;
9157
#endif // DEBUG_ENABLED
9158
9159
_get_completable_identifier(nullptr, COMPLETION_SHADER_TYPE, shader_type_identifier);
9160
if (shader_type_identifier == StringName()) {
9161
_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)));
9162
return ERR_PARSE_ERROR;
9163
}
9164
if (!p_shader_types.has(shader_type_identifier)) {
9165
_set_error(vformat(RTR("Invalid shader type. Valid types are: %s"), _get_shader_type_list(p_shader_types)));
9166
return ERR_PARSE_ERROR;
9167
}
9168
prev_pos = _get_tkpos();
9169
tk = _get_token();
9170
9171
if (tk.type != TK_SEMICOLON) {
9172
_set_tkpos(prev_pos);
9173
_set_expected_after_error(";", "shader_type " + String(shader_type_identifier));
9174
return ERR_PARSE_ERROR;
9175
}
9176
}
9177
9178
#ifdef DEBUG_ENABLED
9179
keyword_completion_context = CF_GLOBAL_SPACE;
9180
#endif // DEBUG_ENABLED
9181
tk = _get_token();
9182
9183
int texture_uniforms = 0;
9184
int texture_binding = 0;
9185
int uniforms = 0;
9186
int instance_index = 0;
9187
int prop_index = 0;
9188
#ifdef DEBUG_ENABLED
9189
uint64_t uniform_buffer_size = 0;
9190
uint64_t max_uniform_buffer_size = 65536;
9191
int uniform_buffer_exceeded_line = -1;
9192
bool check_device_limit_warnings = check_warnings && HAS_WARNING(ShaderWarning::DEVICE_LIMIT_EXCEEDED_FLAG);
9193
#endif // DEBUG_ENABLED
9194
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
9195
9196
stages = &p_functions;
9197
9198
is_discard_supported = shader_type_identifier == "canvas_item" || shader_type_identifier == "spatial";
9199
is_supported_frag_only_funcs = is_discard_supported || shader_type_identifier == "sky";
9200
9201
const FunctionInfo &constants = p_functions.has("constants") ? p_functions["constants"] : FunctionInfo();
9202
9203
HashMap<String, String> defined_render_modes;
9204
HashMap<String, String> defined_stencil_modes;
9205
9206
while (tk.type != TK_EOF) {
9207
switch (tk.type) {
9208
case TK_RENDER_MODE: {
9209
#ifdef DEBUG_ENABLED
9210
keyword_completion_context = CF_UNSPECIFIED;
9211
#endif // DEBUG_ENABLED
9212
while (true) {
9213
Error error = _parse_shader_mode(false, p_render_modes, defined_render_modes);
9214
if (error != OK) {
9215
return error;
9216
}
9217
9218
tk = _get_token();
9219
9220
if (tk.type == TK_COMMA) {
9221
// All good, do nothing.
9222
} else if (tk.type == TK_SEMICOLON) {
9223
break; // Done.
9224
} else {
9225
_set_error(vformat(RTR("Unexpected token: '%s'."), get_token_text(tk)));
9226
return ERR_PARSE_ERROR;
9227
}
9228
}
9229
#ifdef DEBUG_ENABLED
9230
keyword_completion_context = CF_GLOBAL_SPACE;
9231
#endif // DEBUG_ENABLED
9232
} break;
9233
case TK_STENCIL_MODE: {
9234
#ifdef DEBUG_ENABLED
9235
keyword_completion_context = CF_UNSPECIFIED;
9236
#endif // DEBUG_ENABLED
9237
while (true) {
9238
TkPos pos = _get_tkpos();
9239
tk = _get_token();
9240
9241
if (tk.is_integer_constant()) {
9242
const int reference_value = tk.constant;
9243
9244
if (shader->stencil_reference != -1) {
9245
_set_error(vformat(RTR("Duplicated stencil mode reference value: '%s'."), reference_value));
9246
return ERR_PARSE_ERROR;
9247
}
9248
9249
if (reference_value < 0) {
9250
_set_error(vformat(RTR("Stencil mode reference value cannot be negative: '%s'."), reference_value));
9251
return ERR_PARSE_ERROR;
9252
}
9253
9254
if (reference_value > 255) {
9255
_set_error(vformat(RTR("Stencil mode reference value cannot be greater than 255: '%s'."), reference_value));
9256
return ERR_PARSE_ERROR;
9257
}
9258
9259
shader->stencil_reference = reference_value;
9260
} else {
9261
_set_tkpos(pos);
9262
9263
Error error = _parse_shader_mode(true, p_stencil_modes, defined_stencil_modes);
9264
if (error != OK) {
9265
return error;
9266
}
9267
}
9268
9269
tk = _get_token();
9270
9271
if (tk.type == TK_COMMA) {
9272
//all good, do nothing
9273
} else if (tk.type == TK_SEMICOLON) {
9274
break; //done
9275
} else {
9276
_set_error(vformat(RTR("Unexpected token: '%s'."), get_token_text(tk)));
9277
return ERR_PARSE_ERROR;
9278
}
9279
}
9280
#ifdef DEBUG_ENABLED
9281
keyword_completion_context = CF_GLOBAL_SPACE;
9282
#endif // DEBUG_ENABLED
9283
} break;
9284
case TK_STRUCT: {
9285
ShaderNode::Struct st;
9286
DataType type;
9287
#ifdef DEBUG_ENABLED
9288
keyword_completion_context = CF_UNSPECIFIED;
9289
#endif // DEBUG_ENABLED
9290
tk = _get_token();
9291
if (tk.type == TK_IDENTIFIER) {
9292
st.name = tk.text;
9293
if (shader->constants.has(st.name) || shader->structs.has(st.name)) {
9294
_set_redefinition_error(String(st.name));
9295
return ERR_PARSE_ERROR;
9296
}
9297
tk = _get_token();
9298
if (tk.type != TK_CURLY_BRACKET_OPEN) {
9299
_set_expected_error("{");
9300
return ERR_PARSE_ERROR;
9301
}
9302
} else {
9303
_set_error(RTR("Expected a struct identifier."));
9304
return ERR_PARSE_ERROR;
9305
}
9306
9307
StructNode *st_node = alloc_node<StructNode>();
9308
st.shader_struct = st_node;
9309
9310
int member_count = 0;
9311
HashSet<String> member_names;
9312
9313
while (true) { // variables list
9314
#ifdef DEBUG_ENABLED
9315
keyword_completion_context = CF_DATATYPE | CF_PRECISION_MODIFIER;
9316
#endif // DEBUG_ENABLED
9317
9318
tk = _get_token();
9319
if (tk.type == TK_CURLY_BRACKET_CLOSE) {
9320
break;
9321
}
9322
StringName struct_name = "";
9323
bool struct_dt = false;
9324
DataPrecision precision = PRECISION_DEFAULT;
9325
9326
if (tk.type == TK_STRUCT) {
9327
_set_error(RTR("Nested structs are not allowed."));
9328
return ERR_PARSE_ERROR;
9329
}
9330
9331
if (is_token_precision(tk.type)) {
9332
precision = get_token_precision(tk.type);
9333
tk = _get_token();
9334
#ifdef DEBUG_ENABLED
9335
keyword_completion_context ^= CF_PRECISION_MODIFIER;
9336
#endif // DEBUG_ENABLED
9337
}
9338
9339
if (shader->structs.has(tk.text)) {
9340
struct_name = tk.text;
9341
#ifdef DEBUG_ENABLED
9342
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(struct_name)) {
9343
used_structs[struct_name].used = true;
9344
}
9345
#endif // DEBUG_ENABLED
9346
struct_dt = true;
9347
}
9348
9349
if (!is_token_datatype(tk.type) && !struct_dt) {
9350
_set_error(RTR("Expected data type."));
9351
return ERR_PARSE_ERROR;
9352
} else {
9353
type = struct_dt ? TYPE_STRUCT : get_token_datatype(tk.type);
9354
9355
if (precision != PRECISION_DEFAULT && _validate_precision(type, precision) != OK) {
9356
return ERR_PARSE_ERROR;
9357
}
9358
9359
if (type == TYPE_VOID || is_sampler_type(type)) {
9360
_set_error(vformat(RTR("A '%s' data type is not allowed here."), get_datatype_name(type)));
9361
return ERR_PARSE_ERROR;
9362
}
9363
#ifdef DEBUG_ENABLED
9364
keyword_completion_context = CF_UNSPECIFIED;
9365
#endif // DEBUG_ENABLED
9366
9367
bool first = true;
9368
bool fixed_array_size = false;
9369
int array_size = 0;
9370
9371
do {
9372
tk = _get_token();
9373
9374
if (first) {
9375
first = false;
9376
9377
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
9378
_set_error(RTR("Expected an identifier or '['."));
9379
return ERR_PARSE_ERROR;
9380
}
9381
9382
if (tk.type == TK_BRACKET_OPEN) {
9383
Error error = _parse_array_size(nullptr, constants, true, nullptr, &array_size, nullptr);
9384
if (error != OK) {
9385
return error;
9386
}
9387
fixed_array_size = true;
9388
tk = _get_token();
9389
}
9390
}
9391
9392
if (tk.type != TK_IDENTIFIER) {
9393
_set_error(RTR("Expected an identifier."));
9394
return ERR_PARSE_ERROR;
9395
}
9396
9397
MemberNode *member = alloc_node<MemberNode>();
9398
member->precision = precision;
9399
member->datatype = type;
9400
member->struct_name = struct_name;
9401
member->name = tk.text;
9402
member->array_size = array_size;
9403
9404
if (member_names.has(member->name)) {
9405
_set_redefinition_error(String(member->name));
9406
return ERR_PARSE_ERROR;
9407
}
9408
member_names.insert(member->name);
9409
tk = _get_token();
9410
9411
if (tk.type == TK_BRACKET_OPEN) {
9412
Error error = _parse_array_size(nullptr, constants, true, nullptr, &member->array_size, nullptr);
9413
if (error != OK) {
9414
return error;
9415
}
9416
tk = _get_token();
9417
}
9418
9419
if (!fixed_array_size) {
9420
array_size = 0;
9421
}
9422
9423
if (tk.type != TK_SEMICOLON && tk.type != TK_COMMA) {
9424
_set_expected_error(",", ";");
9425
return ERR_PARSE_ERROR;
9426
}
9427
9428
st_node->members.push_back(member);
9429
member_count++;
9430
} while (tk.type == TK_COMMA); // another member
9431
}
9432
}
9433
if (member_count == 0) {
9434
_set_error(RTR("Empty structs are not allowed."));
9435
return ERR_PARSE_ERROR;
9436
}
9437
#ifdef DEBUG_ENABLED
9438
keyword_completion_context = CF_UNSPECIFIED;
9439
#endif // DEBUG_ENABLED
9440
9441
tk = _get_token();
9442
if (tk.type != TK_SEMICOLON) {
9443
_set_expected_error(";");
9444
return ERR_PARSE_ERROR;
9445
}
9446
#ifdef DEBUG_ENABLED
9447
keyword_completion_context = CF_GLOBAL_SPACE;
9448
#endif // DEBUG_ENABLED
9449
9450
shader->structs[st.name] = st;
9451
shader->vstructs.push_back(st); // struct's order is important!
9452
#ifdef DEBUG_ENABLED
9453
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG)) {
9454
used_structs.insert(st.name, Usage(tk_line));
9455
}
9456
#endif // DEBUG_ENABLED
9457
} break;
9458
case TK_GLOBAL: {
9459
#ifdef DEBUG_ENABLED
9460
keyword_completion_context = CF_UNIFORM_KEYWORD;
9461
if (_lookup_next(next)) {
9462
if (next.type == TK_UNIFORM) {
9463
keyword_completion_context ^= CF_UNIFORM_KEYWORD;
9464
}
9465
}
9466
#endif // DEBUG_ENABLED
9467
tk = _get_token();
9468
if (tk.type != TK_UNIFORM) {
9469
_set_expected_after_error("uniform", "global");
9470
return ERR_PARSE_ERROR;
9471
}
9472
uniform_scope = ShaderNode::Uniform::SCOPE_GLOBAL;
9473
};
9474
[[fallthrough]];
9475
case TK_INSTANCE: {
9476
if (tk.type == TK_INSTANCE) {
9477
#ifdef DEBUG_ENABLED
9478
keyword_completion_context = CF_UNIFORM_KEYWORD;
9479
if (_lookup_next(next)) {
9480
if (next.type == TK_UNIFORM) {
9481
keyword_completion_context ^= CF_UNIFORM_KEYWORD;
9482
}
9483
}
9484
#endif // DEBUG_ENABLED
9485
if (shader_type_identifier != StringName() && String(shader_type_identifier) != "spatial" && String(shader_type_identifier) != "canvas_item") {
9486
_set_error(vformat(RTR("Uniform instances are not yet implemented for '%s' shaders."), shader_type_identifier));
9487
return ERR_PARSE_ERROR;
9488
}
9489
if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) {
9490
tk = _get_token();
9491
if (tk.type != TK_UNIFORM) {
9492
_set_expected_after_error("uniform", "instance");
9493
return ERR_PARSE_ERROR;
9494
}
9495
uniform_scope = ShaderNode::Uniform::SCOPE_INSTANCE;
9496
}
9497
}
9498
};
9499
[[fallthrough]];
9500
case TK_UNIFORM:
9501
case TK_VARYING: {
9502
bool is_uniform = tk.type == TK_UNIFORM;
9503
#ifdef DEBUG_ENABLED
9504
keyword_completion_context = CF_UNSPECIFIED;
9505
#endif // DEBUG_ENABLED
9506
if (!is_uniform) {
9507
if (shader_type_identifier == "particles" || shader_type_identifier == "sky" || shader_type_identifier == "fog") {
9508
_set_error(vformat(RTR("Varyings cannot be used in '%s' shaders."), shader_type_identifier));
9509
return ERR_PARSE_ERROR;
9510
}
9511
}
9512
DataPrecision precision = PRECISION_DEFAULT;
9513
DataInterpolation interpolation = INTERPOLATION_DEFAULT;
9514
DataType type;
9515
StringName name;
9516
int array_size = 0;
9517
9518
tk = _get_token();
9519
#ifdef DEBUG_ENABLED
9520
bool temp_error = false;
9521
uint32_t datatype_flag;
9522
9523
if (!is_uniform) {
9524
datatype_flag = CF_VARYING_TYPE;
9525
keyword_completion_context = CF_INTERPOLATION_QUALIFIER | CF_PRECISION_MODIFIER | datatype_flag;
9526
9527
if (_lookup_next(next)) {
9528
if (is_token_interpolation(next.type)) {
9529
keyword_completion_context ^= (CF_INTERPOLATION_QUALIFIER | datatype_flag);
9530
} else if (is_token_precision(next.type)) {
9531
keyword_completion_context ^= (CF_PRECISION_MODIFIER | datatype_flag);
9532
} else if (is_token_datatype(next.type)) {
9533
keyword_completion_context ^= datatype_flag;
9534
}
9535
}
9536
} else {
9537
datatype_flag = CF_UNIFORM_TYPE;
9538
keyword_completion_context = CF_PRECISION_MODIFIER | datatype_flag;
9539
9540
if (_lookup_next(next)) {
9541
if (is_token_precision(next.type)) {
9542
keyword_completion_context ^= (CF_PRECISION_MODIFIER | datatype_flag);
9543
} else if (is_token_datatype(next.type)) {
9544
keyword_completion_context ^= datatype_flag;
9545
}
9546
}
9547
}
9548
#endif // DEBUG_ENABLED
9549
9550
if (is_token_interpolation(tk.type)) {
9551
if (is_uniform) {
9552
_set_error(RTR("Interpolation qualifiers are not supported for uniforms."));
9553
#ifdef DEBUG_ENABLED
9554
temp_error = true;
9555
#else
9556
return ERR_PARSE_ERROR;
9557
#endif // DEBUG_ENABLED
9558
}
9559
interpolation = get_token_interpolation(tk.type);
9560
tk = _get_token();
9561
#ifdef DEBUG_ENABLED
9562
if (keyword_completion_context & CF_INTERPOLATION_QUALIFIER) {
9563
keyword_completion_context ^= CF_INTERPOLATION_QUALIFIER;
9564
}
9565
if (_lookup_next(next)) {
9566
if (is_token_precision(next.type)) {
9567
keyword_completion_context ^= CF_PRECISION_MODIFIER;
9568
} else if (is_token_datatype(next.type)) {
9569
keyword_completion_context ^= datatype_flag;
9570
}
9571
}
9572
if (temp_error) {
9573
return ERR_PARSE_ERROR;
9574
}
9575
#endif // DEBUG_ENABLED
9576
}
9577
9578
if (is_token_precision(tk.type)) {
9579
precision = get_token_precision(tk.type);
9580
tk = _get_token();
9581
#ifdef DEBUG_ENABLED
9582
if (keyword_completion_context & CF_INTERPOLATION_QUALIFIER) {
9583
keyword_completion_context ^= CF_INTERPOLATION_QUALIFIER;
9584
}
9585
if (keyword_completion_context & CF_PRECISION_MODIFIER) {
9586
keyword_completion_context ^= CF_PRECISION_MODIFIER;
9587
}
9588
if (_lookup_next(next)) {
9589
if (is_token_datatype(next.type)) {
9590
keyword_completion_context = CF_UNSPECIFIED;
9591
}
9592
}
9593
#endif // DEBUG_ENABLED
9594
}
9595
9596
if (shader->structs.has(tk.text)) {
9597
if (is_uniform) {
9598
_set_error(vformat(RTR("The '%s' data type is not supported for uniforms."), "struct"));
9599
return ERR_PARSE_ERROR;
9600
} else {
9601
_set_error(vformat(RTR("The '%s' data type is not allowed here."), "struct"));
9602
return ERR_PARSE_ERROR;
9603
}
9604
}
9605
9606
if (!is_token_datatype(tk.type)) {
9607
_set_error(RTR("Expected data type."));
9608
return ERR_PARSE_ERROR;
9609
}
9610
9611
type = get_token_datatype(tk.type);
9612
9613
if (precision != PRECISION_DEFAULT && _validate_precision(type, precision) != OK) {
9614
return ERR_PARSE_ERROR;
9615
}
9616
9617
if (type == TYPE_VOID) {
9618
_set_error(vformat(RTR("The '%s' data type is not allowed here."), "void"));
9619
return ERR_PARSE_ERROR;
9620
}
9621
9622
if (!is_uniform && interpolation != INTERPOLATION_DEFAULT && type < TYPE_INT) {
9623
_set_error(vformat(RTR("Interpolation modifier '%s' cannot be used with boolean types."), get_interpolation_name(interpolation)));
9624
return ERR_PARSE_ERROR;
9625
}
9626
9627
if (!is_uniform && type > TYPE_MAT4) {
9628
_set_error(RTR("Invalid data type for varying."));
9629
return ERR_PARSE_ERROR;
9630
}
9631
9632
#ifdef DEBUG_ENABLED
9633
keyword_completion_context = CF_UNSPECIFIED;
9634
#endif // DEBUG_ENABLED
9635
tk = _get_token();
9636
9637
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
9638
_set_error(RTR("Expected an identifier or '['."));
9639
return ERR_PARSE_ERROR;
9640
}
9641
9642
if (tk.type == TK_BRACKET_OPEN) {
9643
Error error = _parse_array_size(nullptr, constants, true, nullptr, &array_size, nullptr);
9644
if (error != OK) {
9645
return error;
9646
}
9647
tk = _get_token();
9648
}
9649
9650
if (tk.type != TK_IDENTIFIER) {
9651
_set_error(RTR("Expected an identifier."));
9652
return ERR_PARSE_ERROR;
9653
}
9654
9655
prev_pos = _get_tkpos();
9656
name = tk.text;
9657
9658
if (_find_identifier(nullptr, false, constants, name)) {
9659
_set_redefinition_error(String(name));
9660
return ERR_PARSE_ERROR;
9661
}
9662
9663
if (has_builtin(p_functions, name)) {
9664
_set_redefinition_error(String(name));
9665
return ERR_PARSE_ERROR;
9666
}
9667
9668
if (is_uniform) {
9669
if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL && Engine::get_singleton()->is_editor_hint()) { // Type checking for global uniforms is not allowed outside the editor.
9670
//validate global uniform
9671
DataType gvtype = global_shader_uniform_get_type_func(name);
9672
if (gvtype == TYPE_MAX) {
9673
_set_error(vformat(RTR("Global uniform '%s' does not exist. Create it in Project Settings."), String(name)));
9674
return ERR_PARSE_ERROR;
9675
}
9676
9677
if (type != gvtype) {
9678
_set_error(vformat(RTR("Global uniform '%s' must be of type '%s'."), String(name), get_datatype_name(gvtype)));
9679
return ERR_PARSE_ERROR;
9680
}
9681
}
9682
ShaderNode::Uniform uniform;
9683
9684
uniform.type = type;
9685
uniform.scope = uniform_scope;
9686
uniform.precision = precision;
9687
uniform.array_size = array_size;
9688
uniform.group = current_uniform_group_name;
9689
uniform.subgroup = current_uniform_subgroup_name;
9690
9691
tk = _get_token();
9692
if (tk.type == TK_BRACKET_OPEN) {
9693
Error error = _parse_array_size(nullptr, constants, true, nullptr, &uniform.array_size, nullptr);
9694
if (error != OK) {
9695
return error;
9696
}
9697
tk = _get_token();
9698
}
9699
9700
if (is_sampler_type(type)) {
9701
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
9702
_set_error(vformat(RTR("The '%s' qualifier is not supported for sampler types."), "SCOPE_INSTANCE"));
9703
return ERR_PARSE_ERROR;
9704
}
9705
uniform.texture_order = texture_uniforms++;
9706
uniform.texture_binding = texture_binding;
9707
if (uniform.array_size > 0) {
9708
texture_binding += uniform.array_size;
9709
} else {
9710
++texture_binding;
9711
}
9712
uniform.order = -1;
9713
uniform.prop_order = prop_index++;
9714
} else {
9715
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) {
9716
_set_error(vformat(RTR("The '%s' qualifier is not supported for matrix types."), "SCOPE_INSTANCE"));
9717
return ERR_PARSE_ERROR;
9718
}
9719
uniform.texture_order = -1;
9720
if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
9721
uniform.order = uniforms++;
9722
uniform.prop_order = prop_index++;
9723
#ifdef DEBUG_ENABLED
9724
if (check_device_limit_warnings) {
9725
if (uniform.array_size > 0) {
9726
int size = get_datatype_size(uniform.type) * uniform.array_size;
9727
int m = (16 * uniform.array_size);
9728
if ((size % m) != 0U) {
9729
size += m - (size % m);
9730
}
9731
uniform_buffer_size += size;
9732
} else {
9733
uniform_buffer_size += get_datatype_size(uniform.type);
9734
}
9735
9736
if (uniform_buffer_exceeded_line == -1 && uniform_buffer_size > max_uniform_buffer_size) {
9737
uniform_buffer_exceeded_line = tk_line;
9738
}
9739
}
9740
#endif // DEBUG_ENABLED
9741
}
9742
}
9743
9744
if (uniform.array_size > 0) {
9745
if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) {
9746
_set_error(vformat(RTR("The '%s' qualifier is not supported for uniform arrays."), "SCOPE_GLOBAL"));
9747
return ERR_PARSE_ERROR;
9748
}
9749
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
9750
_set_error(vformat(RTR("The '%s' qualifier is not supported for uniform arrays."), "SCOPE_INSTANCE"));
9751
return ERR_PARSE_ERROR;
9752
}
9753
}
9754
9755
int custom_instance_index = -1;
9756
9757
if (tk.type == TK_COLON) {
9758
completion_type = COMPLETION_HINT;
9759
completion_base = type;
9760
completion_base_array = uniform.array_size > 0;
9761
9762
//hint
9763
do {
9764
tk = _get_token();
9765
completion_line = tk.line;
9766
9767
if (!is_token_hint(tk.type)) {
9768
_set_error(RTR("Expected valid type hint after ':'."));
9769
return ERR_PARSE_ERROR;
9770
}
9771
9772
if (uniform.array_size > 0) {
9773
static Vector<int> supported_hints = {
9774
TK_HINT_SOURCE_COLOR, TK_HINT_COLOR_CONVERSION_DISABLED, TK_REPEAT_DISABLE, TK_REPEAT_ENABLE,
9775
TK_FILTER_LINEAR, TK_FILTER_LINEAR_MIPMAP, TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC,
9776
TK_FILTER_NEAREST, TK_FILTER_NEAREST_MIPMAP, TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC
9777
};
9778
if (!supported_hints.has(tk.type)) {
9779
_set_error(RTR("This hint is not supported for uniform arrays."));
9780
return ERR_PARSE_ERROR;
9781
}
9782
}
9783
9784
ShaderNode::Uniform::Hint new_hint = ShaderNode::Uniform::HINT_NONE;
9785
TextureFilter new_filter = FILTER_DEFAULT;
9786
TextureRepeat new_repeat = REPEAT_DEFAULT;
9787
9788
switch (tk.type) {
9789
case TK_HINT_SOURCE_COLOR: {
9790
if (type != TYPE_VEC3 && type != TYPE_VEC4 && !is_sampler_type(type)) {
9791
_set_error(vformat(RTR("Source color hint is for '%s', '%s' or sampler types only."), "vec3", "vec4"));
9792
return ERR_PARSE_ERROR;
9793
}
9794
9795
if (is_sampler_type(type)) {
9796
if (uniform.use_color) {
9797
_set_error(vformat(RTR("Duplicated hint: '%s'."), "source_color"));
9798
return ERR_PARSE_ERROR;
9799
}
9800
uniform.use_color = true;
9801
} else {
9802
new_hint = ShaderNode::Uniform::HINT_SOURCE_COLOR;
9803
}
9804
} break;
9805
case TK_HINT_COLOR_CONVERSION_DISABLED: {
9806
if (type != TYPE_VEC3 && type != TYPE_VEC4) {
9807
_set_error(vformat(RTR("Source color conversion disabled hint is for '%s', '%s'."), "vec3", "vec4"));
9808
return ERR_PARSE_ERROR;
9809
}
9810
if (uniform.hint != ShaderNode::Uniform::HINT_SOURCE_COLOR) {
9811
_set_error(vformat(RTR("Hint '%s' should be preceded by '%s'."), "color_conversion_disabled", "source_color"));
9812
return ERR_PARSE_ERROR;
9813
}
9814
uniform.hint = ShaderNode::Uniform::HINT_NONE;
9815
new_hint = ShaderNode::Uniform::HINT_COLOR_CONVERSION_DISABLED;
9816
} break;
9817
case TK_HINT_DEFAULT_BLACK_TEXTURE: {
9818
new_hint = ShaderNode::Uniform::HINT_DEFAULT_BLACK;
9819
} break;
9820
case TK_HINT_DEFAULT_WHITE_TEXTURE: {
9821
new_hint = ShaderNode::Uniform::HINT_DEFAULT_WHITE;
9822
} break;
9823
case TK_HINT_DEFAULT_TRANSPARENT_TEXTURE: {
9824
new_hint = ShaderNode::Uniform::HINT_DEFAULT_TRANSPARENT;
9825
} break;
9826
case TK_HINT_NORMAL_TEXTURE: {
9827
new_hint = ShaderNode::Uniform::HINT_NORMAL;
9828
} break;
9829
case TK_HINT_ROUGHNESS_NORMAL_TEXTURE: {
9830
new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL;
9831
} break;
9832
case TK_HINT_ROUGHNESS_R: {
9833
new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_R;
9834
} break;
9835
case TK_HINT_ROUGHNESS_G: {
9836
new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_G;
9837
} break;
9838
case TK_HINT_ROUGHNESS_B: {
9839
new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_B;
9840
} break;
9841
case TK_HINT_ROUGHNESS_A: {
9842
new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_A;
9843
} break;
9844
case TK_HINT_ROUGHNESS_GRAY: {
9845
new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_GRAY;
9846
} break;
9847
case TK_HINT_ANISOTROPY_TEXTURE: {
9848
new_hint = ShaderNode::Uniform::HINT_ANISOTROPY;
9849
} break;
9850
case TK_HINT_RANGE: {
9851
if (type != TYPE_FLOAT && type != TYPE_INT) {
9852
_set_error(vformat(RTR("Range hint is for '%s' and '%s' only."), "float", "int"));
9853
return ERR_PARSE_ERROR;
9854
}
9855
9856
tk = _get_token();
9857
if (tk.type != TK_PARENTHESIS_OPEN) {
9858
_set_expected_after_error("(", "hint_range");
9859
return ERR_PARSE_ERROR;
9860
}
9861
9862
if (!_parse_numeric_constant_expression(constants, uniform.hint_range[0])) {
9863
_set_error(RTR("Expected a valid numeric expression."));
9864
return ERR_PARSE_ERROR;
9865
}
9866
9867
tk = _get_token();
9868
9869
if (tk.type != TK_COMMA) {
9870
_set_expected_error(",");
9871
return ERR_PARSE_ERROR;
9872
}
9873
9874
if (!_parse_numeric_constant_expression(constants, uniform.hint_range[1])) {
9875
_set_error(RTR("Expected a valid numeric expression after ','."));
9876
return ERR_PARSE_ERROR;
9877
}
9878
9879
tk = _get_token();
9880
9881
if (tk.type == TK_COMMA) {
9882
if (!_parse_numeric_constant_expression(constants, uniform.hint_range[2])) {
9883
_set_error(RTR("Expected a valid numeric expression after ','."));
9884
return ERR_PARSE_ERROR;
9885
}
9886
tk = _get_token();
9887
} else {
9888
if (type == TYPE_INT) {
9889
uniform.hint_range[2] = 1;
9890
} else {
9891
uniform.hint_range[2] = 0.001;
9892
}
9893
}
9894
9895
if (tk.type != TK_PARENTHESIS_CLOSE) {
9896
_set_expected_error(")");
9897
return ERR_PARSE_ERROR;
9898
}
9899
9900
new_hint = ShaderNode::Uniform::HINT_RANGE;
9901
} break;
9902
case TK_HINT_ENUM: {
9903
if (type != TYPE_INT) {
9904
_set_error(vformat(RTR("Enum hint is for '%s' only."), "int"));
9905
return ERR_PARSE_ERROR;
9906
}
9907
9908
tk = _get_token();
9909
if (tk.type != TK_PARENTHESIS_OPEN) {
9910
_set_expected_after_error("(", "hint_enum");
9911
return ERR_PARSE_ERROR;
9912
}
9913
9914
while (true) {
9915
tk = _get_token();
9916
9917
if (tk.type != TK_STRING_CONSTANT) {
9918
_set_error(RTR("Expected a string constant."));
9919
return ERR_PARSE_ERROR;
9920
}
9921
9922
uniform.hint_enum_names.push_back(tk.text);
9923
9924
tk = _get_token();
9925
9926
if (tk.type == TK_PARENTHESIS_CLOSE) {
9927
break;
9928
} else if (tk.type != TK_COMMA) {
9929
_set_error(RTR("Expected ',' or ')' after string constant."));
9930
return ERR_PARSE_ERROR;
9931
}
9932
}
9933
9934
new_hint = ShaderNode::Uniform::HINT_ENUM;
9935
} break;
9936
case TK_HINT_INSTANCE_INDEX: {
9937
if (custom_instance_index != -1) {
9938
_set_error(vformat(RTR("Can only specify '%s' once."), "instance_index"));
9939
return ERR_PARSE_ERROR;
9940
}
9941
9942
tk = _get_token();
9943
if (tk.type != TK_PARENTHESIS_OPEN) {
9944
_set_expected_after_error("(", "instance_index");
9945
return ERR_PARSE_ERROR;
9946
}
9947
9948
tk = _get_token();
9949
9950
if (tk.type == TK_OP_SUB) {
9951
_set_error(RTR("The instance index can't be negative."));
9952
return ERR_PARSE_ERROR;
9953
}
9954
9955
if (!tk.is_integer_constant()) {
9956
_set_error(RTR("Expected an integer constant."));
9957
return ERR_PARSE_ERROR;
9958
}
9959
9960
custom_instance_index = tk.constant;
9961
current_uniform_instance_index_defined = true;
9962
9963
if (custom_instance_index >= MAX_INSTANCE_UNIFORM_INDICES) {
9964
_set_error(vformat(RTR("Allowed instance uniform indices must be within [0..%d] range."), MAX_INSTANCE_UNIFORM_INDICES - 1));
9965
return ERR_PARSE_ERROR;
9966
}
9967
9968
tk = _get_token();
9969
9970
if (tk.type != TK_PARENTHESIS_CLOSE) {
9971
_set_expected_error(")");
9972
return ERR_PARSE_ERROR;
9973
}
9974
} break;
9975
case TK_HINT_SCREEN_TEXTURE: {
9976
new_hint = ShaderNode::Uniform::HINT_SCREEN_TEXTURE;
9977
--texture_uniforms;
9978
--texture_binding;
9979
} break;
9980
case TK_HINT_NORMAL_ROUGHNESS_TEXTURE: {
9981
new_hint = ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE;
9982
--texture_uniforms;
9983
--texture_binding;
9984
if (OS::get_singleton()->get_current_rendering_method() != "forward_plus") {
9985
_set_error(RTR("'hint_normal_roughness_texture' is only available when using the Forward+ renderer."));
9986
return ERR_PARSE_ERROR;
9987
}
9988
if (shader_type_identifier != StringName() && String(shader_type_identifier) != "spatial") {
9989
_set_error(vformat(RTR("'hint_normal_roughness_texture' is not supported in '%s' shaders."), shader_type_identifier));
9990
return ERR_PARSE_ERROR;
9991
}
9992
} break;
9993
case TK_HINT_DEPTH_TEXTURE: {
9994
new_hint = ShaderNode::Uniform::HINT_DEPTH_TEXTURE;
9995
--texture_uniforms;
9996
--texture_binding;
9997
if (shader_type_identifier != StringName() && String(shader_type_identifier) != "spatial") {
9998
_set_error(vformat(RTR("'hint_depth_texture' is not supported in '%s' shaders."), shader_type_identifier));
9999
return ERR_PARSE_ERROR;
10000
}
10001
} break;
10002
case TK_FILTER_NEAREST: {
10003
new_filter = FILTER_NEAREST;
10004
} break;
10005
case TK_FILTER_LINEAR: {
10006
new_filter = FILTER_LINEAR;
10007
} break;
10008
case TK_FILTER_NEAREST_MIPMAP: {
10009
new_filter = FILTER_NEAREST_MIPMAP;
10010
} break;
10011
case TK_FILTER_LINEAR_MIPMAP: {
10012
new_filter = FILTER_LINEAR_MIPMAP;
10013
} break;
10014
case TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC: {
10015
new_filter = FILTER_NEAREST_MIPMAP_ANISOTROPIC;
10016
} break;
10017
case TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC: {
10018
new_filter = FILTER_LINEAR_MIPMAP_ANISOTROPIC;
10019
} break;
10020
case TK_REPEAT_DISABLE: {
10021
new_repeat = REPEAT_DISABLE;
10022
} break;
10023
case TK_REPEAT_ENABLE: {
10024
new_repeat = REPEAT_ENABLE;
10025
} break;
10026
10027
default:
10028
break;
10029
}
10030
10031
bool is_sampler_hint = new_hint != ShaderNode::Uniform::HINT_NONE && new_hint != ShaderNode::Uniform::HINT_SOURCE_COLOR && new_hint != ShaderNode::Uniform::HINT_COLOR_CONVERSION_DISABLED && new_hint != ShaderNode::Uniform::HINT_RANGE && new_hint != ShaderNode::Uniform::HINT_ENUM;
10032
if (((new_filter != FILTER_DEFAULT || new_repeat != REPEAT_DEFAULT) || is_sampler_hint) && !is_sampler_type(type)) {
10033
_set_error(RTR("This hint is only for sampler types."));
10034
return ERR_PARSE_ERROR;
10035
}
10036
10037
if (new_hint != ShaderNode::Uniform::HINT_NONE) {
10038
if (uniform.hint != ShaderNode::Uniform::HINT_NONE) {
10039
if (uniform.hint == new_hint) {
10040
_set_error(vformat(RTR("Duplicated hint: '%s'."), get_uniform_hint_name(new_hint)));
10041
} else {
10042
_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)));
10043
}
10044
return ERR_PARSE_ERROR;
10045
} else {
10046
uniform.hint = new_hint;
10047
current_uniform_hint = new_hint;
10048
}
10049
}
10050
10051
if (new_filter != FILTER_DEFAULT) {
10052
if (uniform.filter != FILTER_DEFAULT) {
10053
if (uniform.filter == new_filter) {
10054
_set_error(vformat(RTR("Duplicated filter mode: '%s'."), get_texture_filter_name(new_filter)));
10055
} else {
10056
_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)));
10057
}
10058
return ERR_PARSE_ERROR;
10059
} else {
10060
uniform.filter = new_filter;
10061
current_uniform_filter = new_filter;
10062
}
10063
}
10064
10065
if (new_repeat != REPEAT_DEFAULT) {
10066
if (uniform.repeat != REPEAT_DEFAULT) {
10067
if (uniform.repeat == new_repeat) {
10068
_set_error(vformat(RTR("Duplicated repeat mode: '%s'."), get_texture_repeat_name(new_repeat)));
10069
} else {
10070
_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)));
10071
}
10072
return ERR_PARSE_ERROR;
10073
} else {
10074
uniform.repeat = new_repeat;
10075
current_uniform_repeat = new_repeat;
10076
}
10077
}
10078
10079
tk = _get_token();
10080
10081
} while (tk.type == TK_COMMA);
10082
}
10083
10084
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
10085
if (custom_instance_index >= 0) {
10086
uniform.instance_index = custom_instance_index;
10087
} else {
10088
uniform.instance_index = instance_index++;
10089
if (instance_index > MAX_INSTANCE_UNIFORM_INDICES) {
10090
_set_error(vformat(RTR("Too many '%s' uniforms in shader, maximum supported is %d."), "instance", MAX_INSTANCE_UNIFORM_INDICES));
10091
return ERR_PARSE_ERROR;
10092
}
10093
}
10094
}
10095
10096
//reset scope for next uniform
10097
10098
if (tk.type == TK_OP_ASSIGN) {
10099
if (uniform.array_size > 0) {
10100
_set_error(RTR("Setting default values to uniform arrays is not supported."));
10101
return ERR_PARSE_ERROR;
10102
}
10103
10104
Node *expr = _parse_and_reduce_expression(nullptr, constants);
10105
if (!expr) {
10106
return ERR_PARSE_ERROR;
10107
}
10108
if (expr->type != Node::NODE_TYPE_CONSTANT) {
10109
_set_error(RTR("Expected constant expression after '='."));
10110
return ERR_PARSE_ERROR;
10111
}
10112
10113
ConstantNode *cn = static_cast<ConstantNode *>(expr);
10114
10115
uniform.default_value.resize(cn->values.size());
10116
10117
if (!convert_constant(cn, uniform.type, uniform.default_value.ptrw())) {
10118
_set_error(vformat(RTR("Can't convert constant to '%s'."), get_datatype_name(uniform.type)));
10119
return ERR_PARSE_ERROR;
10120
}
10121
tk = _get_token();
10122
}
10123
10124
shader->uniforms[name] = uniform;
10125
#ifdef DEBUG_ENABLED
10126
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_UNIFORM_FLAG)) {
10127
used_uniforms.insert(name, Usage(tk_line));
10128
}
10129
#endif // DEBUG_ENABLED
10130
10131
//reset scope for next uniform
10132
uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
10133
10134
if (tk.type != TK_SEMICOLON) {
10135
_set_expected_error(";");
10136
return ERR_PARSE_ERROR;
10137
}
10138
10139
#ifdef DEBUG_ENABLED
10140
keyword_completion_context = CF_GLOBAL_SPACE;
10141
#endif // DEBUG_ENABLED
10142
completion_type = COMPLETION_NONE;
10143
10144
current_uniform_hint = ShaderNode::Uniform::HINT_NONE;
10145
current_uniform_filter = FILTER_DEFAULT;
10146
current_uniform_repeat = REPEAT_DEFAULT;
10147
current_uniform_instance_index_defined = false;
10148
} else { // varying
10149
ShaderNode::Varying varying;
10150
varying.type = type;
10151
varying.precision = precision;
10152
varying.interpolation = interpolation;
10153
varying.tkpos = prev_pos;
10154
varying.array_size = array_size;
10155
10156
tk = _get_token();
10157
if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) {
10158
if (array_size == 0) {
10159
_set_expected_error(";", "[");
10160
} else {
10161
_set_expected_error(";");
10162
}
10163
return ERR_PARSE_ERROR;
10164
}
10165
10166
if (tk.type == TK_BRACKET_OPEN) {
10167
Error error = _parse_array_size(nullptr, constants, true, nullptr, &varying.array_size, nullptr);
10168
if (error != OK) {
10169
return error;
10170
}
10171
tk = _get_token();
10172
}
10173
10174
shader->varyings[name] = varying;
10175
#ifdef DEBUG_ENABLED
10176
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_VARYING_FLAG)) {
10177
used_varyings.insert(name, Usage(tk_line));
10178
}
10179
#endif // DEBUG_ENABLED
10180
}
10181
10182
} break;
10183
case TK_UNIFORM_GROUP: {
10184
tk = _get_token();
10185
if (tk.type == TK_IDENTIFIER) {
10186
current_uniform_group_name = tk.text;
10187
current_uniform_subgroup_name = "";
10188
tk = _get_token();
10189
if (tk.type == TK_PERIOD) {
10190
tk = _get_token();
10191
if (tk.type == TK_IDENTIFIER) {
10192
current_uniform_subgroup_name = tk.text;
10193
tk = _get_token();
10194
if (tk.type != TK_SEMICOLON) {
10195
_set_expected_error(";");
10196
return ERR_PARSE_ERROR;
10197
}
10198
} else {
10199
_set_error(RTR("Expected an uniform subgroup identifier."));
10200
return ERR_PARSE_ERROR;
10201
}
10202
} else if (tk.type != TK_SEMICOLON) {
10203
_set_expected_error(";", ".");
10204
return ERR_PARSE_ERROR;
10205
}
10206
} else {
10207
if (tk.type != TK_SEMICOLON) {
10208
if (current_uniform_group_name.is_empty()) {
10209
_set_error(RTR("Expected an uniform group identifier."));
10210
} else {
10211
_set_error(RTR("Expected an uniform group identifier or `;`."));
10212
}
10213
return ERR_PARSE_ERROR;
10214
} else if (current_uniform_group_name.is_empty()) {
10215
_set_error(RTR("Group needs to be opened before."));
10216
return ERR_PARSE_ERROR;
10217
} else {
10218
current_uniform_group_name = "";
10219
current_uniform_subgroup_name = "";
10220
}
10221
}
10222
} break;
10223
case TK_SHADER_TYPE: {
10224
_set_error(RTR("Shader type is already defined."));
10225
return ERR_PARSE_ERROR;
10226
} break;
10227
default: {
10228
//function or constant variable
10229
10230
bool is_constant = false;
10231
bool is_struct = false;
10232
StringName struct_name;
10233
DataPrecision precision = PRECISION_DEFAULT;
10234
DataType type;
10235
StringName name;
10236
int array_size = 0;
10237
10238
if (tk.type == TK_CONST) {
10239
is_constant = true;
10240
tk = _get_token();
10241
}
10242
10243
if (is_token_precision(tk.type)) {
10244
precision = get_token_precision(tk.type);
10245
tk = _get_token();
10246
}
10247
10248
if (shader->structs.has(tk.text)) {
10249
is_struct = true;
10250
struct_name = tk.text;
10251
} else {
10252
#ifdef DEBUG_ENABLED
10253
if (_lookup_next(next)) {
10254
if (next.type == TK_UNIFORM) {
10255
keyword_completion_context = CF_UNIFORM_QUALIFIER;
10256
}
10257
}
10258
#endif // DEBUG_ENABLED
10259
if (!is_token_datatype(tk.type)) {
10260
_set_error(RTR("Expected constant, function, uniform or varying."));
10261
return ERR_PARSE_ERROR;
10262
}
10263
10264
if (!is_token_variable_datatype(tk.type)) {
10265
if (is_constant) {
10266
_set_error(RTR("Invalid constant type (samplers are not allowed)."));
10267
} else {
10268
_set_error(RTR("Invalid function type (samplers are not allowed)."));
10269
}
10270
return ERR_PARSE_ERROR;
10271
}
10272
}
10273
10274
if (is_struct) {
10275
type = TYPE_STRUCT;
10276
} else {
10277
type = get_token_datatype(tk.type);
10278
}
10279
10280
if (precision != PRECISION_DEFAULT && _validate_precision(type, precision) != OK) {
10281
return ERR_PARSE_ERROR;
10282
}
10283
10284
prev_pos = _get_tkpos();
10285
tk = _get_token();
10286
10287
#ifdef DEBUG_ENABLED
10288
keyword_completion_context = CF_UNSPECIFIED;
10289
#endif // DEBUG_ENABLED
10290
10291
bool unknown_size = false;
10292
bool fixed_array_size = false;
10293
10294
if (tk.type == TK_BRACKET_OPEN) {
10295
Error error = _parse_array_size(nullptr, constants, !is_constant, nullptr, &array_size, &unknown_size);
10296
if (error != OK) {
10297
return error;
10298
}
10299
fixed_array_size = true;
10300
prev_pos = _get_tkpos();
10301
}
10302
10303
_set_tkpos(prev_pos);
10304
10305
_get_completable_identifier(nullptr, COMPLETION_MAIN_FUNCTION, name);
10306
10307
if (name == StringName()) {
10308
if (is_constant) {
10309
_set_error(RTR("Expected an identifier or '[' after type."));
10310
} else {
10311
_set_error(RTR("Expected a function name after type."));
10312
}
10313
return ERR_PARSE_ERROR;
10314
}
10315
10316
IdentifierType itype;
10317
if (shader->structs.has(name) || (_find_identifier(nullptr, false, constants, name, nullptr, &itype) && itype != IDENTIFIER_FUNCTION) || has_builtin(p_functions, name, !is_constant)) {
10318
_set_redefinition_error(String(name));
10319
return ERR_PARSE_ERROR;
10320
}
10321
10322
tk = _get_token();
10323
if (tk.type != TK_PARENTHESIS_OPEN) {
10324
if (type == TYPE_VOID) {
10325
_set_error(RTR("Expected '(' after function identifier."));
10326
return ERR_PARSE_ERROR;
10327
}
10328
10329
//variable
10330
while (true) {
10331
ShaderNode::Constant constant;
10332
constant.name = name;
10333
constant.type = is_struct ? TYPE_STRUCT : type;
10334
constant.struct_name = struct_name;
10335
constant.precision = precision;
10336
constant.initializer = nullptr;
10337
constant.array_size = array_size;
10338
is_const_decl = true;
10339
10340
if (tk.type == TK_BRACKET_OPEN) {
10341
Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size);
10342
if (error != OK) {
10343
return error;
10344
}
10345
tk = _get_token();
10346
}
10347
10348
if (tk.type == TK_OP_ASSIGN) {
10349
if (!is_constant) {
10350
_set_error(vformat(RTR("Global non-constant variables are not supported. Expected '%s' keyword before constant definition."), "const"));
10351
return ERR_PARSE_ERROR;
10352
}
10353
10354
if (constant.array_size > 0 || unknown_size) {
10355
bool full_def = false;
10356
10357
VariableDeclarationNode::Declaration decl;
10358
decl.name = name;
10359
decl.size = constant.array_size;
10360
10361
tk = _get_token();
10362
10363
if (tk.type != TK_CURLY_BRACKET_OPEN) {
10364
if (unknown_size) {
10365
_set_expected_error("{");
10366
return ERR_PARSE_ERROR;
10367
}
10368
10369
full_def = true;
10370
10371
DataPrecision precision2 = PRECISION_DEFAULT;
10372
if (is_token_precision(tk.type)) {
10373
precision2 = get_token_precision(tk.type);
10374
tk = _get_token();
10375
if (!is_token_nonvoid_datatype(tk.type)) {
10376
_set_error(RTR("Expected data type after precision modifier."));
10377
return ERR_PARSE_ERROR;
10378
}
10379
}
10380
10381
StringName struct_name2;
10382
DataType type2;
10383
10384
if (shader->structs.has(tk.text)) {
10385
type2 = TYPE_STRUCT;
10386
struct_name2 = tk.text;
10387
} else {
10388
if (!is_token_variable_datatype(tk.type)) {
10389
_set_error(RTR("Invalid data type for the array."));
10390
return ERR_PARSE_ERROR;
10391
}
10392
type2 = get_token_datatype(tk.type);
10393
}
10394
10395
int array_size2 = 0;
10396
tk = _get_token();
10397
10398
if (tk.type == TK_BRACKET_OPEN) {
10399
bool is_unknown_size = false;
10400
Error error = _parse_array_size(nullptr, constants, false, nullptr, &array_size2, &is_unknown_size);
10401
if (error != OK) {
10402
return error;
10403
}
10404
if (is_unknown_size) {
10405
array_size2 = constant.array_size;
10406
}
10407
tk = _get_token();
10408
} else {
10409
_set_expected_error("[");
10410
return ERR_PARSE_ERROR;
10411
}
10412
10413
if (constant.precision != precision2 || constant.type != type2 || struct_name != struct_name2 || constant.array_size != array_size2) {
10414
String from;
10415
if (type2 == TYPE_STRUCT) {
10416
from += struct_name2;
10417
} else {
10418
if (precision2 != PRECISION_DEFAULT) {
10419
from += get_precision_name(precision2);
10420
from += " ";
10421
}
10422
from += get_datatype_name(type2);
10423
}
10424
from += "[";
10425
from += itos(array_size2);
10426
from += "]'";
10427
10428
String to;
10429
if (type == TYPE_STRUCT) {
10430
to += struct_name;
10431
} else {
10432
if (precision != PRECISION_DEFAULT) {
10433
to += get_precision_name(precision);
10434
to += " ";
10435
}
10436
to += get_datatype_name(type);
10437
}
10438
to += "[";
10439
to += itos(constant.array_size);
10440
to += "]'";
10441
10442
_set_error(vformat(RTR("Cannot convert from '%s' to '%s'."), from, to));
10443
return ERR_PARSE_ERROR;
10444
}
10445
}
10446
10447
bool curly = tk.type == TK_CURLY_BRACKET_OPEN;
10448
10449
if (unknown_size) {
10450
if (!curly) {
10451
_set_expected_error("{");
10452
return ERR_PARSE_ERROR;
10453
}
10454
} else {
10455
if (full_def) {
10456
if (curly) {
10457
_set_expected_error("(");
10458
return ERR_PARSE_ERROR;
10459
}
10460
}
10461
}
10462
10463
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
10464
while (true) {
10465
Node *n = _parse_and_reduce_expression(nullptr, constants);
10466
if (!n) {
10467
return ERR_PARSE_ERROR;
10468
}
10469
10470
if (n->type == Node::NODE_TYPE_OPERATOR && static_cast<OperatorNode *>(n)->op == OP_CALL) {
10471
_set_error(RTR("Expected constant expression."));
10472
return ERR_PARSE_ERROR;
10473
}
10474
10475
if (!_compare_datatypes(constant.type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) {
10476
return ERR_PARSE_ERROR;
10477
}
10478
10479
tk = _get_token();
10480
if (tk.type == TK_COMMA) {
10481
decl.initializer.push_back(n);
10482
continue;
10483
} else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) {
10484
decl.initializer.push_back(n);
10485
break;
10486
} else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) {
10487
decl.initializer.push_back(n);
10488
break;
10489
} else {
10490
if (curly) {
10491
_set_expected_error("}", ",");
10492
} else {
10493
_set_expected_error(")", ",");
10494
}
10495
return ERR_PARSE_ERROR;
10496
}
10497
}
10498
if (unknown_size) {
10499
decl.size = decl.initializer.size();
10500
constant.array_size = decl.initializer.size();
10501
} else if (decl.initializer.size() != constant.array_size) {
10502
_set_error(vformat(RTR("Array size mismatch. Expected %d elements (found %d)."), constant.array_size, decl.initializer.size()));
10503
return ERR_PARSE_ERROR;
10504
}
10505
} else {
10506
_set_expected_error("(");
10507
return ERR_PARSE_ERROR;
10508
}
10509
10510
array_size = constant.array_size;
10511
10512
ConstantNode *expr = memnew(ConstantNode);
10513
10514
expr->datatype = constant.type;
10515
10516
expr->struct_name = constant.struct_name;
10517
10518
expr->array_size = constant.array_size;
10519
10520
expr->array_declarations.push_back(decl);
10521
10522
constant.initializer = static_cast<ConstantNode *>(expr);
10523
} else {
10524
#ifdef DEBUG_ENABLED
10525
if (constant.type == DataType::TYPE_BOOL) {
10526
keyword_completion_context = CF_BOOLEAN;
10527
}
10528
#endif // DEBUG_ENABLED
10529
10530
//variable created with assignment! must parse an expression
10531
Node *expr = _parse_and_reduce_expression(nullptr, constants);
10532
if (!expr) {
10533
return ERR_PARSE_ERROR;
10534
}
10535
#ifdef DEBUG_ENABLED
10536
if (constant.type == DataType::TYPE_BOOL) {
10537
keyword_completion_context = CF_GLOBAL_SPACE;
10538
}
10539
#endif // DEBUG_ENABLED
10540
if (expr->type == Node::NODE_TYPE_OPERATOR && static_cast<OperatorNode *>(expr)->op == OP_CALL) {
10541
OperatorNode *op = static_cast<OperatorNode *>(expr);
10542
for (int i = 1; i < op->arguments.size(); i++) {
10543
if (!_check_node_constness(op->arguments[i])) {
10544
_set_error(vformat(RTR("Expected constant expression for argument %d of function call after '='."), i - 1));
10545
return ERR_PARSE_ERROR;
10546
}
10547
}
10548
}
10549
10550
constant.initializer = expr;
10551
10552
if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), expr->get_array_size())) {
10553
return ERR_PARSE_ERROR;
10554
}
10555
}
10556
tk = _get_token();
10557
} else {
10558
if (constant.array_size > 0 || unknown_size) {
10559
_set_error(RTR("Expected array initialization."));
10560
return ERR_PARSE_ERROR;
10561
} else {
10562
_set_error(RTR("Expected initialization of constant."));
10563
return ERR_PARSE_ERROR;
10564
}
10565
}
10566
10567
shader->constants[name] = constant;
10568
shader->vconstants.push_back(constant);
10569
#ifdef DEBUG_ENABLED
10570
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_CONSTANT_FLAG)) {
10571
used_constants.insert(name, Usage(tk_line));
10572
}
10573
#endif // DEBUG_ENABLED
10574
10575
if (tk.type == TK_COMMA) {
10576
tk = _get_token();
10577
if (tk.type != TK_IDENTIFIER) {
10578
_set_error(RTR("Expected an identifier after type."));
10579
return ERR_PARSE_ERROR;
10580
}
10581
10582
name = tk.text;
10583
if (_find_identifier(nullptr, false, constants, name)) {
10584
_set_redefinition_error(String(name));
10585
return ERR_PARSE_ERROR;
10586
}
10587
10588
if (has_builtin(p_functions, name)) {
10589
_set_redefinition_error(String(name));
10590
return ERR_PARSE_ERROR;
10591
}
10592
10593
tk = _get_token();
10594
10595
if (!fixed_array_size) {
10596
array_size = 0;
10597
}
10598
unknown_size = false;
10599
10600
} else if (tk.type == TK_SEMICOLON) {
10601
is_const_decl = false;
10602
break;
10603
} else {
10604
_set_expected_error(",", ";");
10605
return ERR_PARSE_ERROR;
10606
}
10607
}
10608
10609
break;
10610
}
10611
10612
if (is_constant) {
10613
_set_error(vformat(RTR("'%s' qualifier cannot be used with a function return type."), "const"));
10614
return ERR_PARSE_ERROR;
10615
}
10616
10617
FunctionInfo builtins;
10618
if (p_functions.has(name)) {
10619
builtins = p_functions[name];
10620
}
10621
10622
if (p_functions.has("global")) { // Adds global variables: 'TIME'
10623
for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["global"].built_ins) {
10624
builtins.built_ins.insert(E.key, E.value);
10625
}
10626
}
10627
10628
if (p_functions.has("constants")) { // Adds global constants: 'PI', 'TAU', 'E'
10629
for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["constants"].built_ins) {
10630
builtins.built_ins.insert(E.key, E.value);
10631
}
10632
}
10633
10634
for (int i = 0; i < shader->vfunctions.size(); i++) {
10635
if (!shader->vfunctions[i].callable && shader->vfunctions[i].name == name) {
10636
_set_redefinition_error(String(name));
10637
return ERR_PARSE_ERROR;
10638
}
10639
}
10640
10641
ShaderNode::Function function;
10642
10643
function.callable = !p_functions.has(name);
10644
function.name = name;
10645
function.rname = name;
10646
10647
FunctionNode *func_node = alloc_node<FunctionNode>();
10648
function.function = func_node;
10649
10650
func_node->name = name;
10651
func_node->rname = name;
10652
func_node->return_type = type;
10653
func_node->return_struct_name = struct_name;
10654
func_node->return_precision = precision;
10655
func_node->return_array_size = array_size;
10656
10657
if (p_functions.has(name)) {
10658
func_node->can_discard = p_functions[name].can_discard;
10659
} else {
10660
func_node->can_discard = is_discard_supported; // Allow use it for custom functions (in supported shader types).
10661
}
10662
10663
if (!function_overload_count.has(name)) {
10664
function_overload_count.insert(name, 0);
10665
} else {
10666
function_overload_count[name]++;
10667
}
10668
10669
func_node->body = alloc_node<BlockNode>();
10670
func_node->body->parent_function = func_node;
10671
10672
tk = _get_token();
10673
10674
while (true) {
10675
if (tk.type == TK_PARENTHESIS_CLOSE) {
10676
break;
10677
}
10678
#ifdef DEBUG_ENABLED
10679
keyword_completion_context = CF_CONST_KEYWORD | CF_FUNC_DECL_PARAM_SPEC | CF_PRECISION_MODIFIER | CF_FUNC_DECL_PARAM_TYPE; // eg. const in mediump float
10680
10681
if (_lookup_next(next)) {
10682
if (next.type == TK_CONST) {
10683
keyword_completion_context = CF_UNSPECIFIED;
10684
} else if (is_token_arg_qual(next.type)) {
10685
keyword_completion_context = CF_CONST_KEYWORD;
10686
} else if (is_token_precision(next.type)) {
10687
keyword_completion_context = (CF_CONST_KEYWORD | CF_FUNC_DECL_PARAM_SPEC | CF_FUNC_DECL_PARAM_TYPE);
10688
} else if (is_token_datatype(next.type)) {
10689
keyword_completion_context = (CF_CONST_KEYWORD | CF_FUNC_DECL_PARAM_SPEC | CF_PRECISION_MODIFIER);
10690
}
10691
}
10692
#endif // DEBUG_ENABLED
10693
10694
bool param_is_const = false;
10695
if (tk.type == TK_CONST) {
10696
param_is_const = true;
10697
tk = _get_token();
10698
#ifdef DEBUG_ENABLED
10699
if (keyword_completion_context & CF_CONST_KEYWORD) {
10700
keyword_completion_context ^= CF_CONST_KEYWORD;
10701
}
10702
10703
if (_lookup_next(next)) {
10704
if (is_token_arg_qual(next.type)) {
10705
keyword_completion_context = CF_UNSPECIFIED;
10706
} else if (is_token_precision(next.type)) {
10707
keyword_completion_context = (CF_FUNC_DECL_PARAM_SPEC | CF_FUNC_DECL_PARAM_TYPE);
10708
} else if (is_token_datatype(next.type)) {
10709
keyword_completion_context = (CF_FUNC_DECL_PARAM_SPEC | CF_PRECISION_MODIFIER);
10710
}
10711
}
10712
#endif // DEBUG_ENABLED
10713
}
10714
10715
ArgumentQualifier param_qualifier = ARGUMENT_QUALIFIER_IN;
10716
if (is_token_arg_qual(tk.type)) {
10717
bool error = false;
10718
switch (tk.type) {
10719
case TK_ARG_IN: {
10720
param_qualifier = ARGUMENT_QUALIFIER_IN;
10721
} break;
10722
case TK_ARG_OUT: {
10723
if (param_is_const) {
10724
_set_error(vformat(RTR("The '%s' qualifier cannot be used within a function parameter declared with '%s'."), "out", "const"));
10725
error = true;
10726
}
10727
param_qualifier = ARGUMENT_QUALIFIER_OUT;
10728
} break;
10729
case TK_ARG_INOUT: {
10730
if (param_is_const) {
10731
_set_error(vformat(RTR("The '%s' qualifier cannot be used within a function parameter declared with '%s'."), "inout", "const"));
10732
error = true;
10733
}
10734
param_qualifier = ARGUMENT_QUALIFIER_INOUT;
10735
} break;
10736
default:
10737
error = true;
10738
break;
10739
}
10740
tk = _get_token();
10741
#ifdef DEBUG_ENABLED
10742
if (keyword_completion_context & CF_CONST_KEYWORD) {
10743
keyword_completion_context ^= CF_CONST_KEYWORD;
10744
}
10745
if (keyword_completion_context & CF_FUNC_DECL_PARAM_SPEC) {
10746
keyword_completion_context ^= CF_FUNC_DECL_PARAM_SPEC;
10747
}
10748
10749
if (_lookup_next(next)) {
10750
if (is_token_precision(next.type)) {
10751
keyword_completion_context = CF_FUNC_DECL_PARAM_TYPE;
10752
} else if (is_token_datatype(next.type)) {
10753
keyword_completion_context = CF_PRECISION_MODIFIER;
10754
}
10755
}
10756
#endif // DEBUG_ENABLED
10757
if (error) {
10758
return ERR_PARSE_ERROR;
10759
}
10760
}
10761
10762
DataType param_type;
10763
StringName param_name;
10764
StringName param_struct_name;
10765
DataPrecision param_precision = PRECISION_DEFAULT;
10766
int arg_array_size = 0;
10767
10768
if (is_token_precision(tk.type)) {
10769
param_precision = get_token_precision(tk.type);
10770
tk = _get_token();
10771
#ifdef DEBUG_ENABLED
10772
if (keyword_completion_context & CF_CONST_KEYWORD) {
10773
keyword_completion_context ^= CF_CONST_KEYWORD;
10774
}
10775
if (keyword_completion_context & CF_FUNC_DECL_PARAM_SPEC) {
10776
keyword_completion_context ^= CF_FUNC_DECL_PARAM_SPEC;
10777
}
10778
if (keyword_completion_context & CF_PRECISION_MODIFIER) {
10779
keyword_completion_context ^= CF_PRECISION_MODIFIER;
10780
}
10781
10782
if (_lookup_next(next)) {
10783
if (is_token_datatype(next.type)) {
10784
keyword_completion_context = CF_UNSPECIFIED;
10785
}
10786
}
10787
#endif // DEBUG_ENABLED
10788
}
10789
10790
is_struct = false;
10791
10792
if (shader->structs.has(tk.text)) {
10793
is_struct = true;
10794
param_struct_name = tk.text;
10795
#ifdef DEBUG_ENABLED
10796
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(param_struct_name)) {
10797
used_structs[param_struct_name].used = true;
10798
}
10799
#endif // DEBUG_ENABLED
10800
}
10801
10802
if (!is_struct && !is_token_datatype(tk.type)) {
10803
_set_error(RTR("Expected a valid data type for argument."));
10804
return ERR_PARSE_ERROR;
10805
}
10806
10807
if (param_qualifier == ARGUMENT_QUALIFIER_OUT || param_qualifier == ARGUMENT_QUALIFIER_INOUT) {
10808
if (is_sampler_type(get_token_datatype(tk.type))) {
10809
_set_error(RTR("Opaque types cannot be output parameters."));
10810
return ERR_PARSE_ERROR;
10811
}
10812
}
10813
10814
if (is_struct) {
10815
param_type = TYPE_STRUCT;
10816
} else {
10817
param_type = get_token_datatype(tk.type);
10818
if (param_type == TYPE_VOID) {
10819
_set_error(RTR("Void type not allowed as argument."));
10820
return ERR_PARSE_ERROR;
10821
}
10822
}
10823
10824
if (param_precision != PRECISION_DEFAULT && _validate_precision(param_type, param_precision) != OK) {
10825
return ERR_PARSE_ERROR;
10826
}
10827
#ifdef DEBUG_ENABLED
10828
keyword_completion_context = CF_UNSPECIFIED;
10829
#endif // DEBUG_ENABLED
10830
tk = _get_token();
10831
10832
if (tk.type == TK_BRACKET_OPEN) {
10833
Error error = _parse_array_size(nullptr, constants, true, nullptr, &arg_array_size, nullptr);
10834
if (error != OK) {
10835
return error;
10836
}
10837
tk = _get_token();
10838
}
10839
if (tk.type != TK_IDENTIFIER) {
10840
_set_error(RTR("Expected an identifier for argument name."));
10841
return ERR_PARSE_ERROR;
10842
}
10843
10844
param_name = tk.text;
10845
10846
if (_find_identifier(func_node->body, false, builtins, param_name, (ShaderLanguage::DataType *)nullptr, &itype)) {
10847
if (itype != IDENTIFIER_FUNCTION) {
10848
_set_redefinition_error(String(param_name));
10849
return ERR_PARSE_ERROR;
10850
}
10851
}
10852
10853
if (has_builtin(p_functions, param_name)) {
10854
_set_redefinition_error(String(param_name));
10855
return ERR_PARSE_ERROR;
10856
}
10857
10858
FunctionNode::Argument arg;
10859
arg.type = param_type;
10860
arg.name = param_name;
10861
arg.struct_name = param_struct_name;
10862
arg.precision = param_precision;
10863
arg.qualifier = param_qualifier;
10864
arg.tex_argument_check = false;
10865
arg.tex_builtin_check = false;
10866
arg.tex_argument_filter = FILTER_DEFAULT;
10867
arg.tex_argument_repeat = REPEAT_DEFAULT;
10868
arg.is_const = param_is_const;
10869
10870
tk = _get_token();
10871
if (tk.type == TK_BRACKET_OPEN) {
10872
Error error = _parse_array_size(nullptr, constants, true, nullptr, &arg_array_size, nullptr);
10873
if (error != OK) {
10874
return error;
10875
}
10876
tk = _get_token();
10877
}
10878
10879
arg.array_size = arg_array_size;
10880
func_node->arguments.push_back(arg);
10881
10882
if (tk.type == TK_COMMA) {
10883
tk = _get_token();
10884
//do none and go on
10885
} else if (tk.type != TK_PARENTHESIS_CLOSE) {
10886
_set_expected_error(",", ")");
10887
return ERR_PARSE_ERROR;
10888
}
10889
}
10890
10891
// Searches for function index and check for the exact duplicate in overloads.
10892
int function_index = 0;
10893
for (int i = 0; i < shader->vfunctions.size(); i++) {
10894
if (!shader->vfunctions[i].callable || shader->vfunctions[i].rname != name) {
10895
continue;
10896
}
10897
10898
function_index++;
10899
10900
if (shader->vfunctions[i].function->arguments.size() != func_node->arguments.size()) {
10901
continue;
10902
}
10903
10904
bool is_same = true;
10905
10906
for (int j = 0; j < shader->vfunctions[i].function->arguments.size(); j++) {
10907
FunctionNode::Argument a = func_node->arguments[j];
10908
FunctionNode::Argument b = shader->vfunctions[i].function->arguments[j];
10909
10910
if (a.type == b.type && a.array_size == b.array_size) {
10911
if (a.type == TYPE_STRUCT) {
10912
is_same = a.struct_name == b.struct_name;
10913
}
10914
} else {
10915
is_same = false;
10916
}
10917
10918
if (!is_same) {
10919
break;
10920
}
10921
}
10922
10923
if (is_same) {
10924
_set_redefinition_error(String(name));
10925
return ERR_PARSE_ERROR;
10926
}
10927
}
10928
10929
// Creates a fake name for function overload, which will be replaced by the real name by the compiler.
10930
String name2 = name;
10931
if (function_index > 0) {
10932
name2 = vformat("%s@%s", name, itos(function_index + 1));
10933
10934
function.name = name2;
10935
func_node->name = name2;
10936
}
10937
10938
shader->functions.insert(name2, function);
10939
shader->vfunctions.push_back(function);
10940
10941
CallInfo call_info;
10942
call_info.name = name2;
10943
calls_info.insert(name2, call_info);
10944
10945
#ifdef DEBUG_ENABLED
10946
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_FUNCTION_FLAG) && !p_functions.has(name)) {
10947
used_functions.insert(name2, Usage(tk_line));
10948
}
10949
#endif // DEBUG_ENABLED
10950
10951
if (p_functions.has(name)) {
10952
//if one of the core functions, make sure they are of the correct form
10953
if (func_node->arguments.size() > 0) {
10954
_set_error(vformat(RTR("Function '%s' expects no arguments."), String(name)));
10955
return ERR_PARSE_ERROR;
10956
}
10957
if (func_node->return_type != TYPE_VOID) {
10958
_set_error(vformat(RTR("Function '%s' must be of '%s' return type."), String(name), "void"));
10959
return ERR_PARSE_ERROR;
10960
}
10961
}
10962
10963
//all good let's parse inside the function!
10964
tk = _get_token();
10965
if (tk.type != TK_CURLY_BRACKET_OPEN) {
10966
_set_error(RTR("Expected a '{' to begin function."));
10967
return ERR_PARSE_ERROR;
10968
}
10969
10970
current_function = name2;
10971
10972
#ifdef DEBUG_ENABLED
10973
keyword_completion_context = CF_BLOCK;
10974
#endif // DEBUG_ENABLED
10975
Error err = _parse_block(func_node->body, builtins);
10976
if (err) {
10977
return err;
10978
}
10979
#ifdef DEBUG_ENABLED
10980
keyword_completion_context = CF_GLOBAL_SPACE;
10981
#endif // DEBUG_ENABLED
10982
if (func_node->return_type != DataType::TYPE_VOID) {
10983
BlockNode *block = func_node->body;
10984
if (_find_last_flow_op_in_block(block, FlowOperation::FLOW_OP_RETURN) != OK) {
10985
_set_error(vformat(RTR("Expected at least one '%s' statement in a non-void function."), "return"));
10986
return ERR_PARSE_ERROR;
10987
}
10988
}
10989
current_function = StringName();
10990
}
10991
}
10992
10993
tk = _get_token();
10994
}
10995
uint32_t varying_index = base_varying_index;
10996
uint32_t max_varyings = 31;
10997
// Can be false for internal shaders created in the process of initializing the engine.
10998
if (RSG::utilities) {
10999
max_varyings = RSG::utilities->get_maximum_shader_varyings();
11000
}
11001
11002
for (const KeyValue<StringName, ShaderNode::Varying> &kv : shader->varyings) {
11003
if (kv.value.stage != ShaderNode::Varying::STAGE_FRAGMENT && (kv.value.type > TYPE_BVEC4 && kv.value.type < TYPE_FLOAT) && kv.value.interpolation != INTERPOLATION_FLAT) {
11004
_set_tkpos(kv.value.tkpos);
11005
_set_error(vformat(RTR("Varying with integer data type must be declared with `%s` interpolation qualifier."), "flat"));
11006
return ERR_PARSE_ERROR;
11007
}
11008
11009
if (varying_index + kv.value.get_size() > max_varyings) {
11010
_set_tkpos(kv.value.tkpos);
11011
_set_error(vformat(RTR("Too many varyings used in shader (%d used, maximum supported is %d)."), varying_index + kv.value.get_size(), max_varyings));
11012
return ERR_PARSE_ERROR;
11013
}
11014
11015
varying_index += kv.value.get_size();
11016
}
11017
11018
#ifdef DEBUG_ENABLED
11019
if (check_device_limit_warnings && uniform_buffer_exceeded_line != -1) {
11020
_add_warning(ShaderWarning::DEVICE_LIMIT_EXCEEDED, uniform_buffer_exceeded_line, RTR("uniform buffer"), { uniform_buffer_size, max_uniform_buffer_size });
11021
}
11022
#endif // DEBUG_ENABLED
11023
return OK;
11024
}
11025
11026
bool ShaderLanguage::has_builtin(const HashMap<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name, bool p_check_global_funcs) {
11027
if (p_check_global_funcs && global_func_set.has(p_name)) {
11028
return true;
11029
}
11030
11031
for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : p_functions) {
11032
if (E.value.built_ins.has(p_name)) {
11033
return true;
11034
}
11035
}
11036
11037
return false;
11038
}
11039
11040
Error ShaderLanguage::_find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op) {
11041
bool found = false;
11042
11043
for (int i = p_flow->blocks.size() - 1; i >= 0; i--) {
11044
if (p_flow->blocks[i]->type == Node::NODE_TYPE_BLOCK) {
11045
BlockNode *last_block = static_cast<BlockNode *>(p_flow->blocks[i]);
11046
if (_find_last_flow_op_in_block(last_block, p_op) == OK) {
11047
found = true;
11048
break;
11049
}
11050
}
11051
}
11052
if (found) {
11053
return OK;
11054
}
11055
return FAILED;
11056
}
11057
11058
Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op) {
11059
bool found = false;
11060
11061
for (List<ShaderLanguage::Node *>::Element *E = p_block->statements.back(); E; E = E->prev()) {
11062
if (E->get()->type == Node::NODE_TYPE_CONTROL_FLOW) {
11063
ControlFlowNode *flow = static_cast<ControlFlowNode *>(E->get());
11064
if (flow->flow_op == p_op) {
11065
found = true;
11066
break;
11067
} else {
11068
if (_find_last_flow_op_in_op(flow, p_op) == OK) {
11069
found = true;
11070
break;
11071
}
11072
}
11073
} else if (E->get()->type == Node::NODE_TYPE_BLOCK) {
11074
BlockNode *block = static_cast<BlockNode *>(E->get());
11075
if (_find_last_flow_op_in_block(block, p_op) == OK) {
11076
found = true;
11077
break;
11078
}
11079
}
11080
}
11081
11082
if (found) {
11083
return OK;
11084
}
11085
return FAILED;
11086
}
11087
11088
Error ShaderLanguage::_parse_shader_mode(bool p_is_stencil, const Vector<ModeInfo> &p_modes, HashMap<String, String> &r_defined_modes) {
11089
StringName mode;
11090
_get_completable_identifier(nullptr, p_is_stencil ? COMPLETION_STENCIL_MODE : COMPLETION_RENDER_MODE, mode);
11091
11092
if (mode == StringName()) {
11093
if (p_is_stencil) {
11094
_set_error(RTR("Expected an identifier for stencil mode."));
11095
} else {
11096
_set_error(RTR("Expected an identifier for render mode."));
11097
}
11098
return ERR_PARSE_ERROR;
11099
}
11100
11101
const String smode = String(mode);
11102
11103
Vector<StringName> &current_modes = p_is_stencil ? shader->stencil_modes : shader->render_modes;
11104
11105
if (current_modes.has(mode)) {
11106
if (p_is_stencil) {
11107
_set_error(vformat(RTR("Duplicated stencil mode: '%s'."), smode));
11108
} else {
11109
_set_error(vformat(RTR("Duplicated render mode: '%s'."), smode));
11110
}
11111
return ERR_PARSE_ERROR;
11112
}
11113
11114
bool found = false;
11115
11116
if (is_shader_inc) {
11117
for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
11118
const Vector<ModeInfo> modes = p_is_stencil ? ShaderTypes::get_singleton()->get_stencil_modes(RenderingServer::ShaderMode(i)) : ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(i));
11119
11120
for (const ModeInfo &info : modes) {
11121
const String name = String(info.name);
11122
11123
if (smode.begins_with(name)) {
11124
if (!info.options.is_empty()) {
11125
if (info.options.has(smode.substr(name.length() + 1))) {
11126
found = true;
11127
11128
if (r_defined_modes.has(name)) {
11129
if (p_is_stencil) {
11130
_set_error(vformat(RTR("Redefinition of stencil mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, r_defined_modes[name]));
11131
} else {
11132
_set_error(vformat(RTR("Redefinition of render mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, r_defined_modes[name]));
11133
}
11134
return ERR_PARSE_ERROR;
11135
}
11136
r_defined_modes.insert(name, smode);
11137
break;
11138
}
11139
} else {
11140
found = true;
11141
break;
11142
}
11143
}
11144
}
11145
}
11146
} else {
11147
for (const ModeInfo &info : p_modes) {
11148
const String name = String(info.name);
11149
11150
if (smode.begins_with(name)) {
11151
if (!info.options.is_empty()) {
11152
if (info.options.has(smode.substr(name.length() + 1))) {
11153
found = true;
11154
11155
if (r_defined_modes.has(name)) {
11156
if (p_is_stencil) {
11157
_set_error(vformat(RTR("Redefinition of stencil mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, r_defined_modes[name]));
11158
} else {
11159
_set_error(vformat(RTR("Redefinition of render mode: '%s'. The '%s' mode has already been set to '%s'."), smode, name, r_defined_modes[name]));
11160
}
11161
return ERR_PARSE_ERROR;
11162
}
11163
r_defined_modes.insert(name, smode);
11164
break;
11165
}
11166
} else {
11167
found = true;
11168
break;
11169
}
11170
}
11171
}
11172
}
11173
11174
if (!found) {
11175
if (p_is_stencil) {
11176
_set_error(vformat(RTR("Invalid stencil mode: '%s'."), smode));
11177
} else {
11178
_set_error(vformat(RTR("Invalid render mode: '%s'."), smode));
11179
}
11180
return ERR_PARSE_ERROR;
11181
}
11182
11183
if (p_is_stencil) {
11184
shader->stencil_modes.push_back(mode);
11185
} else {
11186
shader->render_modes.push_back(mode);
11187
}
11188
11189
return OK;
11190
}
11191
11192
// skips over whitespace and /* */ and // comments
11193
static int _get_first_ident_pos(const String &p_code) {
11194
int idx = 0;
11195
11196
#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : char32_t(0))
11197
11198
while (true) {
11199
if (GETCHAR(0) == '/' && GETCHAR(1) == '/') {
11200
idx += 2;
11201
while (true) {
11202
if (GETCHAR(0) == 0) {
11203
return 0;
11204
}
11205
if (GETCHAR(0) == '\n') {
11206
idx++;
11207
break; // loop
11208
}
11209
idx++;
11210
}
11211
} else if (GETCHAR(0) == '/' && GETCHAR(1) == '*') {
11212
idx += 2;
11213
while (true) {
11214
if (GETCHAR(0) == 0) {
11215
return 0;
11216
}
11217
if (GETCHAR(0) == '*' && GETCHAR(1) == '/') {
11218
idx += 2;
11219
break; // loop
11220
}
11221
idx++;
11222
}
11223
} else {
11224
switch (GETCHAR(0)) {
11225
case ' ':
11226
case '\t':
11227
case '\r':
11228
case '\n': {
11229
idx++;
11230
} break; // switch
11231
default:
11232
return idx;
11233
}
11234
}
11235
}
11236
11237
#undef GETCHAR
11238
}
11239
11240
String ShaderLanguage::get_shader_type(const String &p_code) {
11241
bool reading_type = false;
11242
11243
String cur_identifier;
11244
11245
for (int i = _get_first_ident_pos(p_code); i < p_code.length(); i++) {
11246
if (p_code[i] == ';') {
11247
break;
11248
11249
} else if (p_code[i] <= 32) {
11250
if (!cur_identifier.is_empty()) {
11251
if (!reading_type) {
11252
if (cur_identifier != "shader_type") {
11253
return String();
11254
}
11255
11256
reading_type = true;
11257
cur_identifier = String();
11258
} else {
11259
return cur_identifier;
11260
}
11261
}
11262
} else {
11263
cur_identifier += String::chr(p_code[i]);
11264
}
11265
}
11266
11267
if (reading_type) {
11268
return cur_identifier;
11269
}
11270
11271
return String();
11272
}
11273
11274
bool ShaderLanguage::is_builtin_func_out_parameter(const String &p_name, int p_param) {
11275
int i = 0;
11276
while (builtin_func_out_args[i].name) {
11277
if (p_name == builtin_func_out_args[i].name) {
11278
for (int j = 0; j < BuiltinFuncOutArgs::MAX_ARGS; j++) {
11279
int arg = builtin_func_out_args[i].arguments[j];
11280
if (arg == p_param) {
11281
return true;
11282
}
11283
if (arg < 0) {
11284
return false;
11285
}
11286
}
11287
}
11288
i++;
11289
}
11290
return false;
11291
}
11292
11293
#ifdef DEBUG_ENABLED
11294
void ShaderLanguage::_check_warning_accums() {
11295
for (const KeyValue<ShaderWarning::Code, HashMap<StringName, HashMap<StringName, Usage>> *> &E : warnings_check_map2) {
11296
for (const KeyValue<StringName, HashMap<StringName, Usage>> &T : *E.value) {
11297
for (const KeyValue<StringName, Usage> &U : T.value) {
11298
if (!U.value.used) {
11299
_add_warning(E.key, U.value.decl_line, U.key);
11300
}
11301
}
11302
}
11303
}
11304
for (const KeyValue<ShaderWarning::Code, HashMap<StringName, Usage> *> &E : warnings_check_map) {
11305
for (const KeyValue<StringName, Usage> &U : (*E.value)) {
11306
if (!U.value.used) {
11307
_add_warning(E.key, U.value.decl_line, U.key);
11308
}
11309
}
11310
}
11311
}
11312
List<ShaderWarning>::Element *ShaderLanguage::get_warnings_ptr() {
11313
return warnings.front();
11314
}
11315
void ShaderLanguage::enable_warning_checking(bool p_enabled) {
11316
check_warnings = p_enabled;
11317
}
11318
bool ShaderLanguage::is_warning_checking_enabled() const {
11319
return check_warnings;
11320
}
11321
void ShaderLanguage::set_warning_flags(uint32_t p_flags) {
11322
warning_flags = p_flags;
11323
}
11324
uint32_t ShaderLanguage::get_warning_flags() const {
11325
return warning_flags;
11326
}
11327
#endif // DEBUG_ENABLED
11328
11329
Error ShaderLanguage::compile(const String &p_code, const ShaderCompileInfo &p_info) {
11330
clear();
11331
is_shader_inc = p_info.is_include;
11332
11333
code = p_code;
11334
global_shader_uniform_get_type_func = p_info.global_shader_uniform_type_func;
11335
11336
varying_function_names = p_info.varying_function_names;
11337
base_varying_index = p_info.base_varying_index;
11338
11339
nodes = nullptr;
11340
11341
shader = alloc_node<ShaderNode>();
11342
Error err = _parse_shader(p_info.functions, p_info.render_modes, p_info.stencil_modes, p_info.shader_types);
11343
11344
#ifdef DEBUG_ENABLED
11345
if (check_warnings) {
11346
_check_warning_accums();
11347
}
11348
#endif // DEBUG_ENABLED
11349
11350
if (err != OK) {
11351
return err;
11352
}
11353
return OK;
11354
}
11355
11356
Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_info, List<ScriptLanguage::CodeCompletionOption> *r_options, String &r_call_hint) {
11357
clear();
11358
is_shader_inc = p_info.is_include;
11359
11360
code = p_code;
11361
varying_function_names = p_info.varying_function_names;
11362
11363
nodes = nullptr;
11364
global_shader_uniform_get_type_func = p_info.global_shader_uniform_type_func;
11365
11366
shader = alloc_node<ShaderNode>();
11367
_parse_shader(p_info.functions, p_info.render_modes, p_info.stencil_modes, p_info.shader_types);
11368
11369
#ifdef DEBUG_ENABLED
11370
// Adds context keywords.
11371
if (keyword_completion_context != CF_UNSPECIFIED) {
11372
constexpr int sz = std::size(keyword_list);
11373
for (int i = 0; i < sz; i++) {
11374
if (keyword_list[i].flags == CF_UNSPECIFIED) {
11375
break; // Ignore hint keywords (parsed below).
11376
}
11377
if (keyword_list[i].flags & keyword_completion_context) {
11378
if (keyword_list[i].excluded_shader_types.has(shader_type_identifier) || keyword_list[i].excluded_functions.has(current_function)) {
11379
continue;
11380
}
11381
ScriptLanguage::CodeCompletionOption option(keyword_list[i].text, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11382
r_options->push_back(option);
11383
}
11384
}
11385
}
11386
#endif // DEBUG_ENABLED
11387
11388
switch (completion_type) {
11389
case COMPLETION_NONE: {
11390
//do nothing
11391
return OK;
11392
} break;
11393
case COMPLETION_SHADER_TYPE: {
11394
for (const String &shader_type : p_info.shader_types) {
11395
ScriptLanguage::CodeCompletionOption option(shader_type, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11396
r_options->push_back(option);
11397
}
11398
return OK;
11399
} break;
11400
case COMPLETION_RENDER_MODE: {
11401
if (is_shader_inc) {
11402
for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
11403
const Vector<ModeInfo> modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(i));
11404
11405
for (int j = 0; j < modes.size(); j++) {
11406
const ModeInfo &info = modes[j];
11407
11408
if (!info.options.is_empty()) {
11409
bool found = false;
11410
11411
for (int k = 0; k < info.options.size(); k++) {
11412
if (shader->render_modes.has(String(info.name) + "_" + String(info.options[k]))) {
11413
found = true;
11414
}
11415
}
11416
11417
if (!found) {
11418
for (int k = 0; k < info.options.size(); k++) {
11419
ScriptLanguage::CodeCompletionOption option(String(info.name) + "_" + String(info.options[k]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11420
r_options->push_back(option);
11421
}
11422
}
11423
} else {
11424
const String name = String(info.name);
11425
11426
if (!shader->render_modes.has(name)) {
11427
ScriptLanguage::CodeCompletionOption option(name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11428
r_options->push_back(option);
11429
}
11430
}
11431
}
11432
}
11433
} else {
11434
for (int i = 0; i < p_info.render_modes.size(); i++) {
11435
const ModeInfo &info = p_info.render_modes[i];
11436
11437
if (!info.options.is_empty()) {
11438
bool found = false;
11439
11440
for (int j = 0; j < info.options.size(); j++) {
11441
if (shader->render_modes.has(String(info.name) + "_" + String(info.options[j]))) {
11442
found = true;
11443
}
11444
}
11445
11446
if (!found) {
11447
for (int j = 0; j < info.options.size(); j++) {
11448
ScriptLanguage::CodeCompletionOption option(String(info.name) + "_" + String(info.options[j]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11449
r_options->push_back(option);
11450
}
11451
}
11452
} else {
11453
const String name = String(info.name);
11454
11455
if (!shader->render_modes.has(name)) {
11456
ScriptLanguage::CodeCompletionOption option(name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11457
r_options->push_back(option);
11458
}
11459
}
11460
}
11461
}
11462
11463
return OK;
11464
} break;
11465
case COMPLETION_STENCIL_MODE: {
11466
if (is_shader_inc) {
11467
for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
11468
const Vector<ModeInfo> modes = ShaderTypes::get_singleton()->get_stencil_modes(RenderingServer::ShaderMode(i));
11469
11470
for (const ModeInfo &info : modes) {
11471
if (!info.options.is_empty()) {
11472
bool found = false;
11473
11474
for (const StringName &option : info.options) {
11475
if (shader->stencil_modes.has(String(info.name) + "_" + String(option))) {
11476
found = true;
11477
}
11478
}
11479
11480
if (!found) {
11481
for (const StringName &option : info.options) {
11482
ScriptLanguage::CodeCompletionOption completion_option(String(info.name) + "_" + String(option), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11483
r_options->push_back(completion_option);
11484
}
11485
}
11486
} else {
11487
const String name = String(info.name);
11488
11489
if (!shader->stencil_modes.has(name)) {
11490
ScriptLanguage::CodeCompletionOption option(name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11491
r_options->push_back(option);
11492
}
11493
}
11494
}
11495
}
11496
} else {
11497
for (const ModeInfo &info : p_info.stencil_modes) {
11498
if (!info.options.is_empty()) {
11499
bool found = false;
11500
11501
for (const StringName &option : info.options) {
11502
if (shader->stencil_modes.has(String(info.name) + "_" + String(option))) {
11503
found = true;
11504
}
11505
}
11506
11507
if (!found) {
11508
for (const StringName &option : info.options) {
11509
ScriptLanguage::CodeCompletionOption completion_option(String(info.name) + "_" + String(option), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11510
r_options->push_back(completion_option);
11511
}
11512
}
11513
} else {
11514
const String name = String(info.name);
11515
11516
if (!shader->stencil_modes.has(name)) {
11517
ScriptLanguage::CodeCompletionOption option(name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11518
r_options->push_back(option);
11519
}
11520
}
11521
}
11522
}
11523
11524
return OK;
11525
} break;
11526
case COMPLETION_STRUCT: {
11527
if (shader->structs.has(completion_struct)) {
11528
StructNode *node = shader->structs[completion_struct].shader_struct;
11529
for (ShaderLanguage::MemberNode *member : node->members) {
11530
ScriptLanguage::CodeCompletionOption option(member->name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER);
11531
r_options->push_back(option);
11532
}
11533
}
11534
11535
return OK;
11536
} break;
11537
case COMPLETION_MAIN_FUNCTION: {
11538
for (const KeyValue<StringName, FunctionInfo> &E : p_info.functions) {
11539
if (!E.value.main_function) {
11540
continue;
11541
}
11542
bool found = false;
11543
for (int i = 0; i < shader->vfunctions.size(); i++) {
11544
if (shader->vfunctions[i].name == E.key) {
11545
found = true;
11546
break;
11547
}
11548
}
11549
if (found) {
11550
continue;
11551
}
11552
ScriptLanguage::CodeCompletionOption option(E.key, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
11553
r_options->push_back(option);
11554
}
11555
11556
return OK;
11557
} break;
11558
case COMPLETION_IDENTIFIER:
11559
case COMPLETION_FUNCTION_CALL: {
11560
bool comp_ident = completion_type == COMPLETION_IDENTIFIER;
11561
HashMap<String, ScriptLanguage::CodeCompletionKind> matches;
11562
StringName skip_function;
11563
BlockNode *block = completion_block;
11564
11565
if (completion_class == TAG_GLOBAL) {
11566
while (block) {
11567
if (comp_ident) {
11568
for (const KeyValue<StringName, BlockNode::Variable> &E : block->variables) {
11569
if (E.value.line < completion_line) {
11570
matches.insert(E.key, ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE);
11571
}
11572
}
11573
}
11574
11575
if (block->parent_function) {
11576
if (comp_ident) {
11577
for (int i = 0; i < block->parent_function->arguments.size(); i++) {
11578
matches.insert(block->parent_function->arguments[i].name, ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE);
11579
}
11580
}
11581
skip_function = block->parent_function->name;
11582
}
11583
block = block->parent_block;
11584
}
11585
11586
if (comp_ident) {
11587
if (is_shader_inc) {
11588
for (int i = 0; i < RenderingServer::SHADER_MAX; i++) {
11589
const HashMap<StringName, ShaderLanguage::FunctionInfo> info = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(i));
11590
11591
if (info.has("global")) {
11592
for (const KeyValue<StringName, BuiltInInfo> &E : info["global"].built_ins) {
11593
ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
11594
if (E.value.constant) {
11595
kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
11596
}
11597
matches.insert(E.key, kind);
11598
}
11599
}
11600
11601
if (info.has("constants")) {
11602
for (const KeyValue<StringName, BuiltInInfo> &E : info["constants"].built_ins) {
11603
ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
11604
if (E.value.constant) {
11605
kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
11606
}
11607
matches.insert(E.key, kind);
11608
}
11609
}
11610
11611
if (skip_function != StringName() && info.has(skip_function)) {
11612
for (const KeyValue<StringName, BuiltInInfo> &E : info[skip_function].built_ins) {
11613
ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
11614
if (E.value.constant) {
11615
kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
11616
}
11617
matches.insert(E.key, kind);
11618
}
11619
}
11620
}
11621
} else {
11622
if (p_info.functions.has("global")) {
11623
for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["global"].built_ins) {
11624
ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
11625
if (E.value.constant) {
11626
kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
11627
}
11628
matches.insert(E.key, kind);
11629
}
11630
}
11631
11632
if (p_info.functions.has("constants")) {
11633
for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["constants"].built_ins) {
11634
ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
11635
if (E.value.constant) {
11636
kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
11637
}
11638
matches.insert(E.key, kind);
11639
}
11640
}
11641
11642
if (skip_function != StringName() && p_info.functions.has(skip_function)) {
11643
for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions[skip_function].built_ins) {
11644
ScriptLanguage::CodeCompletionKind kind = ScriptLanguage::CODE_COMPLETION_KIND_MEMBER;
11645
if (E.value.constant) {
11646
kind = ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT;
11647
}
11648
matches.insert(E.key, kind);
11649
}
11650
}
11651
}
11652
11653
for (const KeyValue<StringName, ShaderNode::Constant> &E : shader->constants) {
11654
matches.insert(E.key, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT);
11655
}
11656
for (const KeyValue<StringName, ShaderNode::Varying> &E : shader->varyings) {
11657
matches.insert(E.key, ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE);
11658
}
11659
for (const KeyValue<StringName, ShaderNode::Uniform> &E : shader->uniforms) {
11660
matches.insert(E.key, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER);
11661
}
11662
}
11663
11664
for (int i = 0; i < shader->vfunctions.size(); i++) {
11665
if (!shader->vfunctions[i].callable || shader->vfunctions[i].name == skip_function) {
11666
continue;
11667
}
11668
matches.insert(String(shader->vfunctions[i].rname), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
11669
}
11670
11671
int idx = 0;
11672
bool low_end = RenderingServer::get_singleton()->is_low_end();
11673
11674
if (stages) {
11675
// Stage functions can be used in custom functions as well, that why need to check them all.
11676
for (const KeyValue<StringName, FunctionInfo> &E : *stages) {
11677
for (const KeyValue<StringName, StageFunctionInfo> &F : E.value.stage_functions) {
11678
if (F.value.skip_function == skip_function && stages->has(skip_function)) {
11679
continue;
11680
}
11681
matches.insert(String(F.key), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
11682
}
11683
}
11684
}
11685
11686
while (builtin_func_defs[idx].name) {
11687
if ((low_end && builtin_func_defs[idx].high_end) || _check_restricted_func(builtin_func_defs[idx].name, skip_function)) {
11688
idx++;
11689
continue;
11690
}
11691
11692
matches.insert(String(builtin_func_defs[idx].name), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
11693
idx++;
11694
}
11695
11696
} else { // sub-class
11697
int idx = 0;
11698
bool low_end = RenderingServer::get_singleton()->is_low_end();
11699
11700
while (builtin_func_defs[idx].name) {
11701
if (low_end && builtin_func_defs[idx].high_end) {
11702
idx++;
11703
continue;
11704
}
11705
if (builtin_func_defs[idx].tag == completion_class) {
11706
matches.insert(String(builtin_func_defs[idx].name), ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
11707
}
11708
idx++;
11709
}
11710
}
11711
11712
for (const KeyValue<String, ScriptLanguage::CodeCompletionKind> &E : matches) {
11713
ScriptLanguage::CodeCompletionOption option(E.key, E.value);
11714
if (E.value == ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION) {
11715
option.insert_text += "(";
11716
}
11717
r_options->push_back(option);
11718
}
11719
11720
return OK;
11721
} break;
11722
case COMPLETION_CALL_ARGUMENTS: {
11723
StringName block_function;
11724
BlockNode *block = completion_block;
11725
String calltip;
11726
11727
while (block) {
11728
if (block->parent_function) {
11729
block_function = block->parent_function->name;
11730
}
11731
block = block->parent_block;
11732
}
11733
11734
for (int i = 0, overload_index = 0; i < shader->vfunctions.size(); i++) {
11735
if (!shader->vfunctions[i].callable || shader->vfunctions[i].rname != completion_function) {
11736
continue;
11737
}
11738
11739
if (shader->vfunctions[i].function->return_type == TYPE_STRUCT) {
11740
calltip += String(shader->vfunctions[i].function->return_struct_name);
11741
} else {
11742
calltip += get_datatype_name(shader->vfunctions[i].function->return_type);
11743
}
11744
11745
if (shader->vfunctions[i].function->return_array_size > 0) {
11746
calltip += "[";
11747
calltip += itos(shader->vfunctions[i].function->return_array_size);
11748
calltip += "]";
11749
}
11750
11751
calltip += " ";
11752
calltip += shader->vfunctions[i].rname;
11753
calltip += "(";
11754
11755
for (int j = 0; j < shader->vfunctions[i].function->arguments.size(); j++) {
11756
if (j > 0) {
11757
calltip += ", ";
11758
} else {
11759
calltip += " ";
11760
}
11761
11762
if (j == completion_argument) {
11763
calltip += char32_t(0xFFFF);
11764
}
11765
11766
if (shader->vfunctions[i].function->arguments[j].is_const) {
11767
calltip += "const ";
11768
}
11769
11770
if (shader->vfunctions[i].function->arguments[j].qualifier != ArgumentQualifier::ARGUMENT_QUALIFIER_IN) {
11771
if (shader->vfunctions[i].function->arguments[j].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT) {
11772
calltip += "out ";
11773
} else { // ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT
11774
calltip += "inout ";
11775
}
11776
}
11777
11778
if (shader->vfunctions[i].function->arguments[j].type == TYPE_STRUCT) {
11779
calltip += String(shader->vfunctions[i].function->arguments[j].struct_name);
11780
} else {
11781
calltip += get_datatype_name(shader->vfunctions[i].function->arguments[j].type);
11782
}
11783
calltip += " ";
11784
calltip += shader->vfunctions[i].function->arguments[j].name;
11785
11786
if (shader->vfunctions[i].function->arguments[j].array_size > 0) {
11787
calltip += "[";
11788
calltip += itos(shader->vfunctions[i].function->arguments[j].array_size);
11789
calltip += "]";
11790
}
11791
11792
if (j == completion_argument) {
11793
calltip += char32_t(0xFFFF);
11794
}
11795
}
11796
11797
if (shader->vfunctions[i].function->arguments.size()) {
11798
calltip += " ";
11799
}
11800
calltip += ")";
11801
11802
if (overload_index < function_overload_count[shader->vfunctions[i].rname]) {
11803
overload_index++;
11804
calltip += "\n";
11805
continue;
11806
}
11807
11808
r_call_hint = calltip;
11809
return OK;
11810
}
11811
11812
if (stages) {
11813
// Stage functions can be used in custom functions as well, that why need to check them all.
11814
for (const KeyValue<StringName, FunctionInfo> &S : *stages) {
11815
for (const KeyValue<StringName, StageFunctionInfo> &E : S.value.stage_functions) {
11816
// No need to check for the skip function here.
11817
if (completion_function != E.key) {
11818
continue;
11819
}
11820
11821
calltip += get_datatype_name(E.value.return_type);
11822
calltip += " ";
11823
calltip += E.key;
11824
calltip += "(";
11825
11826
for (int i = 0; i < E.value.arguments.size(); i++) {
11827
if (i > 0) {
11828
calltip += ", ";
11829
} else {
11830
calltip += " ";
11831
}
11832
11833
if (i == completion_argument) {
11834
calltip += char32_t(0xFFFF);
11835
}
11836
11837
calltip += get_datatype_name(E.value.arguments[i].type);
11838
calltip += " ";
11839
calltip += E.value.arguments[i].name;
11840
11841
if (i == completion_argument) {
11842
calltip += char32_t(0xFFFF);
11843
}
11844
}
11845
11846
if (E.value.arguments.size()) {
11847
calltip += " ";
11848
}
11849
calltip += ")";
11850
11851
r_call_hint = calltip;
11852
return OK;
11853
}
11854
}
11855
}
11856
11857
int idx = 0;
11858
bool low_end = RenderingServer::get_singleton()->is_low_end();
11859
11860
while (builtin_func_defs[idx].name) {
11861
if ((low_end && builtin_func_defs[idx].high_end) || _check_restricted_func(builtin_func_defs[idx].name, block_function)) {
11862
idx++;
11863
continue;
11864
}
11865
11866
int idx2 = 0;
11867
HashSet<int> out_args;
11868
while (builtin_func_out_args[idx2].name != nullptr) {
11869
if (builtin_func_out_args[idx2].name == builtin_func_defs[idx].name) {
11870
for (int i = 0; i < BuiltinFuncOutArgs::MAX_ARGS; i++) {
11871
int arg = builtin_func_out_args[idx2].arguments[i];
11872
if (arg == -1) {
11873
break;
11874
}
11875
out_args.insert(arg);
11876
}
11877
break;
11878
}
11879
idx2++;
11880
}
11881
11882
if (completion_function == builtin_func_defs[idx].name) {
11883
if (builtin_func_defs[idx].tag != completion_class) {
11884
idx++;
11885
continue;
11886
}
11887
11888
if (calltip.length()) {
11889
calltip += "\n";
11890
}
11891
11892
calltip += get_datatype_name(builtin_func_defs[idx].rettype);
11893
calltip += " ";
11894
calltip += builtin_func_defs[idx].name;
11895
calltip += "(";
11896
11897
bool found_arg = false;
11898
for (int i = 0; i < BuiltinFuncDef::MAX_ARGS - 1; i++) {
11899
if (builtin_func_defs[idx].args[i] == TYPE_VOID) {
11900
break;
11901
}
11902
11903
if (i > 0) {
11904
calltip += ", ";
11905
} else {
11906
calltip += " ";
11907
}
11908
11909
if (i == completion_argument) {
11910
calltip += char32_t(0xFFFF);
11911
}
11912
11913
if (out_args.has(i)) {
11914
calltip += "out ";
11915
}
11916
11917
calltip += get_datatype_name(builtin_func_defs[idx].args[i]);
11918
11919
String arg_name = (String)builtin_func_defs[idx].args_names[i];
11920
if (!arg_name.is_empty()) {
11921
calltip += " ";
11922
calltip += arg_name;
11923
}
11924
11925
if (i == completion_argument) {
11926
calltip += char32_t(0xFFFF);
11927
}
11928
11929
found_arg = true;
11930
}
11931
11932
if (found_arg) {
11933
calltip += " ";
11934
}
11935
calltip += ")";
11936
}
11937
idx++;
11938
}
11939
11940
r_call_hint = calltip;
11941
11942
return OK;
11943
11944
} break;
11945
case COMPLETION_INDEX: {
11946
const char colv[4] = { 'r', 'g', 'b', 'a' };
11947
const char coordv[4] = { 'x', 'y', 'z', 'w' };
11948
const char coordt[4] = { 's', 't', 'p', 'q' };
11949
const String theme_color_names[4] = { "axis_x_color", "axis_y_color", "axis_z_color", "axis_w_color" };
11950
11951
int limit = 0;
11952
11953
switch (completion_base) {
11954
case TYPE_BVEC2:
11955
case TYPE_IVEC2:
11956
case TYPE_UVEC2:
11957
case TYPE_VEC2: {
11958
limit = 2;
11959
11960
} break;
11961
case TYPE_BVEC3:
11962
case TYPE_IVEC3:
11963
case TYPE_UVEC3:
11964
case TYPE_VEC3: {
11965
limit = 3;
11966
11967
} break;
11968
case TYPE_BVEC4:
11969
case TYPE_IVEC4:
11970
case TYPE_UVEC4:
11971
case TYPE_VEC4: {
11972
limit = 4;
11973
11974
} break;
11975
default: {
11976
}
11977
}
11978
11979
for (int i = 0; i < limit; i++) {
11980
r_options->push_back(ScriptLanguage::CodeCompletionOption(String::chr(colv[i]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT, ScriptLanguage::LOCATION_OTHER, theme_color_names[i]));
11981
r_options->push_back(ScriptLanguage::CodeCompletionOption(String::chr(coordv[i]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT, ScriptLanguage::LOCATION_OTHER, theme_color_names[i]));
11982
r_options->push_back(ScriptLanguage::CodeCompletionOption(String::chr(coordt[i]), ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT, ScriptLanguage::LOCATION_OTHER, theme_color_names[i]));
11983
}
11984
11985
} break;
11986
case COMPLETION_HINT: {
11987
if (completion_base == DataType::TYPE_VEC3 || completion_base == DataType::TYPE_VEC4) {
11988
if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
11989
ScriptLanguage::CodeCompletionOption option("source_color", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
11990
r_options->push_back(option);
11991
r_options->push_back({ "color_conversion_disabled", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT });
11992
}
11993
} else if ((completion_base == DataType::TYPE_INT || completion_base == DataType::TYPE_FLOAT) && !completion_base_array) {
11994
if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
11995
Vector<String> options;
11996
11997
if (completion_base == DataType::TYPE_INT) {
11998
options.push_back("hint_range(0, 100, 1)");
11999
options.push_back("hint_enum(\"Zero\", \"One\", \"Two\")");
12000
} else {
12001
options.push_back("hint_range(0.0, 1.0, 0.1)");
12002
}
12003
12004
for (const String &option_text : options) {
12005
String hint_name = option_text.substr(0, option_text.find_char(char32_t('(')));
12006
ScriptLanguage::CodeCompletionOption option(hint_name, ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
12007
option.insert_text = option_text;
12008
r_options->push_back(option);
12009
}
12010
}
12011
} else if ((int(completion_base) > int(TYPE_MAT4) && int(completion_base) < int(TYPE_STRUCT))) {
12012
Vector<String> options;
12013
if (current_uniform_filter == FILTER_DEFAULT) {
12014
options.push_back("filter_linear");
12015
options.push_back("filter_linear_mipmap");
12016
options.push_back("filter_linear_mipmap_anisotropic");
12017
options.push_back("filter_nearest");
12018
options.push_back("filter_nearest_mipmap");
12019
options.push_back("filter_nearest_mipmap_anisotropic");
12020
}
12021
if (current_uniform_repeat == REPEAT_DEFAULT) {
12022
options.push_back("repeat_enable");
12023
options.push_back("repeat_disable");
12024
}
12025
if (completion_base_array) {
12026
if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
12027
options.push_back("source_color");
12028
}
12029
} else {
12030
if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
12031
options.push_back("hint_anisotropy");
12032
options.push_back("hint_default_black");
12033
options.push_back("hint_default_white");
12034
options.push_back("hint_default_transparent");
12035
options.push_back("hint_normal");
12036
options.push_back("hint_roughness_a");
12037
options.push_back("hint_roughness_b");
12038
options.push_back("hint_roughness_g");
12039
options.push_back("hint_roughness_gray");
12040
options.push_back("hint_roughness_normal");
12041
options.push_back("hint_roughness_r");
12042
options.push_back("hint_screen_texture");
12043
options.push_back("hint_normal_roughness_texture");
12044
options.push_back("hint_depth_texture");
12045
options.push_back("source_color");
12046
}
12047
}
12048
12049
for (int i = 0; i < options.size(); i++) {
12050
ScriptLanguage::CodeCompletionOption option(options[i], ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
12051
r_options->push_back(option);
12052
}
12053
}
12054
if (!completion_base_array && !current_uniform_instance_index_defined) {
12055
ScriptLanguage::CodeCompletionOption option("instance_index", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
12056
option.insert_text = "instance_index(0)";
12057
r_options->push_back(option);
12058
}
12059
} break;
12060
}
12061
12062
return ERR_PARSE_ERROR;
12063
}
12064
12065
String ShaderLanguage::get_error_text() {
12066
return error_str;
12067
}
12068
12069
Vector<ShaderLanguage::FilePosition> ShaderLanguage::get_include_positions() {
12070
return include_positions;
12071
}
12072
12073
int ShaderLanguage::get_error_line() {
12074
return error_line;
12075
}
12076
12077
ShaderLanguage::ShaderNode *ShaderLanguage::get_shader() {
12078
return shader;
12079
}
12080
12081
ShaderLanguage::ShaderLanguage() {
12082
nodes = nullptr;
12083
completion_class = TAG_GLOBAL;
12084
12085
if (instance_counter.get() == 0) {
12086
int idx = 0;
12087
while (builtin_func_defs[idx].name) {
12088
if (builtin_func_defs[idx].tag == SubClassTag::TAG_GLOBAL) {
12089
global_func_set.insert(builtin_func_defs[idx].name);
12090
}
12091
idx++;
12092
}
12093
}
12094
instance_counter.increment();
12095
12096
#ifdef DEBUG_ENABLED
12097
warnings_check_map.insert(ShaderWarning::UNUSED_CONSTANT, &used_constants);
12098
warnings_check_map.insert(ShaderWarning::UNUSED_FUNCTION, &used_functions);
12099
warnings_check_map.insert(ShaderWarning::UNUSED_STRUCT, &used_structs);
12100
warnings_check_map.insert(ShaderWarning::UNUSED_UNIFORM, &used_uniforms);
12101
warnings_check_map.insert(ShaderWarning::UNUSED_VARYING, &used_varyings);
12102
12103
warnings_check_map2.insert(ShaderWarning::UNUSED_LOCAL_VARIABLE, &used_local_vars);
12104
#endif // DEBUG_ENABLED
12105
}
12106
12107
ShaderLanguage::~ShaderLanguage() {
12108
clear();
12109
instance_counter.decrement();
12110
if (instance_counter.get() == 0) {
12111
global_func_set.clear();
12112
}
12113
}
12114
12115