@galacean/engine-shader-compiler 2.0.0-alpha.52 → 2.0.0-alpha.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -4
- package/bundler/cli.js +199 -104
- package/bundler/precompile.cjs.js +117 -47
- package/bundler/precompile.js +117 -47
- package/bundler/rollup.cjs.js +115 -45
- package/bundler/rollup.js +115 -45
- package/dist/browser.js +13421 -6555
- package/dist/browser.js.map +1 -1
- package/dist/browser.min.js +1 -1
- package/dist/browser.min.js.map +1 -1
- package/dist/main.js +1758 -8450
- package/dist/main.js.map +1 -1
- package/dist/module.js +1730 -8427
- package/dist/module.js.map +1 -1
- package/dist/precompile.main.js +2280 -0
- package/dist/precompile.main.js.map +1 -0
- package/dist/precompile.module.js +2276 -0
- package/dist/precompile.module.js.map +1 -0
- package/package.json +24 -13
- package/types/GLESBackend.d.ts +22 -0
- package/types/ShaderBackend.d.ts +15 -0
- package/types/ShaderCompilation.d.ts +40 -0
- package/types/ShaderCompiler.d.ts +42 -14
- package/types/ShaderInstructionEncoder.d.ts +46 -14
- package/types/ShaderPrecompiler.d.ts +31 -0
- package/types/bundler/precompile.d.ts +26 -3
- package/types/bundler/rollup.d.ts +23 -2
- package/types/codeGen/CodeGenVisitor.d.ts +11 -6
- package/types/codeGen/GLES100.d.ts +3 -5
- package/types/codeGen/GLES300.d.ts +14 -7
- package/types/codeGen/GLESVisitor.d.ts +55 -9
- package/types/codeGen/VisitorContext.d.ts +88 -29
- package/types/codeGen/types.d.ts +1 -1
- package/types/index.d.ts +4 -1
- package/types/precompile.d.ts +1 -0
- package/dist/browser.verbose.js +0 -9601
- package/dist/browser.verbose.js.map +0 -1
- package/dist/browser.verbose.min.js +0 -2
- package/dist/browser.verbose.min.js.map +0 -1
- package/dist/main.verbose.js +0 -9598
- package/dist/main.verbose.js.map +0 -1
- package/dist/module.verbose.js +0 -9591
- package/dist/module.verbose.js.map +0 -1
- package/types/GSError.d.ts +0 -16
- package/types/ParserUtils.d.ts +0 -43
- package/types/Preprocessor.d.ts +0 -30
- package/types/ShaderCompilerUtils.d.ts +0 -10
- package/types/common/BaseLexer.d.ts +0 -51
- package/types/common/BaseToken.d.ts +0 -35
- package/types/common/IBaseSymbol.d.ts +0 -5
- package/types/common/ShaderPosition.d.ts +0 -8
- package/types/common/ShaderRange.d.ts +0 -8
- package/types/common/SymbolTable.d.ts +0 -13
- package/types/common/SymbolTableStack.d.ts +0 -17
- package/types/common/enums/Keyword.d.ts +0 -124
- package/types/common/enums/ShaderStage.d.ts +0 -5
- package/types/common/index.d.ts +0 -5
- package/types/common/types.d.ts +0 -101
- package/types/lalr/CFG.d.ts +0 -5
- package/types/lalr/LALR1.d.ts +0 -27
- package/types/lalr/Production.d.ts +0 -9
- package/types/lalr/State.d.ts +0 -20
- package/types/lalr/StateItem.d.ts +0 -20
- package/types/lalr/Utils.d.ts +0 -22
- package/types/lalr/index.d.ts +0 -2
- package/types/lalr/types.d.ts +0 -14
- package/types/lexer/Lexer.d.ts +0 -143
- package/types/lexer/index.d.ts +0 -1
- package/types/parser/AST.d.ts +0 -502
- package/types/parser/Grammar.d.ts +0 -11
- package/types/parser/GrammarSymbol.d.ts +0 -128
- package/types/parser/SemanticAnalyzer.d.ts +0 -42
- package/types/parser/ShaderInfo.d.ts +0 -10
- package/types/parser/ShaderTargetParser.d.ts +0 -26
- package/types/parser/builtin/functions.d.ts +0 -34
- package/types/parser/builtin/index.d.ts +0 -2
- package/types/parser/builtin/variables.d.ts +0 -11
- package/types/parser/index.d.ts +0 -2
- package/types/parser/symbolTable/FnSymbol.d.ts +0 -6
- package/types/parser/symbolTable/StructSymbol.d.ts +0 -6
- package/types/parser/symbolTable/SymbolDataType.d.ts +0 -8
- package/types/parser/symbolTable/SymbolInfo.d.ts +0 -22
- package/types/parser/symbolTable/VarSymbol.d.ts +0 -8
- package/types/parser/symbolTable/index.d.ts +0 -6
- package/types/parser/types.d.ts +0 -24
- package/types/sourceParser/ShaderSourceFactory.d.ts +0 -8
- package/types/sourceParser/ShaderSourceParser.d.ts +0 -30
- package/types/sourceParser/ShaderSourceSymbol.d.ts +0 -10
- package/types/sourceParser/SourceLexer.d.ts +0 -19
- package/types/sourceParser/index.d.ts +0 -1
- package/verbose/package.json +0 -10
|
@@ -0,0 +1,2276 @@
|
|
|
1
|
+
import { normalizeShaderIncludeMap, ShaderSourceParser, parseValidatedShaderPass, ShaderCoreInfo as ShaderCoreInfo$1, branchAnalysis, ParserObjectPool, createValidatedShaderTargetParser } from '@galacean/engine-shader-parser/internal/analyzer';
|
|
2
|
+
import { ReturnableObjectPool, ShaderPreprocessorDirective, Logger, ShaderLanguage } from '@galacean/engine-core';
|
|
3
|
+
import { Color } from '@galacean/engine-math';
|
|
4
|
+
import { SymbolInfo, EShaderStage, VarSymbol, BaseToken, ParserUtils, ShaderStructRole, ESymbolType, FnSymbol, ASTNode, Keyword, NoneTerminal, parsePreprocessorExpression, toPreprocessorCondition, mapExpandedShaderError, GSError, GSErrorName, TreeNode, canInheritanceBranchesCover, getLexicalDeclarationCoexistence, ShaderBuiltinSemantic, GLESShaderInfo, ShaderCoreInfo } from '@galacean/engine-shader-parser/internal';
|
|
5
|
+
|
|
6
|
+
function _set_prototype_of(o, p) {
|
|
7
|
+
_set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
|
|
8
|
+
o.__proto__ = p;
|
|
9
|
+
|
|
10
|
+
return o;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
return _set_prototype_of(o, p);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function _inherits(subClass, superClass) {
|
|
17
|
+
if (typeof superClass !== "function" && superClass !== null) {
|
|
18
|
+
throw new TypeError("Super expression must either be null or a function");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } });
|
|
22
|
+
|
|
23
|
+
if (superClass) _set_prototype_of(subClass, superClass);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function _instanceof(left, right) {
|
|
27
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
28
|
+
return !!right[Symbol.hasInstance](left);
|
|
29
|
+
} else return left instanceof right;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function _is_native_reflect_construct() {
|
|
33
|
+
// Since Reflect.construct can't be properly polyfilled, some
|
|
34
|
+
// implementations (e.g. core-js@2) don't set the correct internal slots.
|
|
35
|
+
// Those polyfills don't allow us to subclass built-ins, so we need to
|
|
36
|
+
// use our fallback implementation.
|
|
37
|
+
try {
|
|
38
|
+
// If the internal slots aren't set, this throws an error similar to
|
|
39
|
+
// TypeError: this is not a Boolean object.
|
|
40
|
+
var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
|
|
41
|
+
} catch (_) {}
|
|
42
|
+
return (_is_native_reflect_construct = function() {
|
|
43
|
+
return !!result;
|
|
44
|
+
})();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function _construct(Parent, args, Class) {
|
|
48
|
+
if (_is_native_reflect_construct()) _construct = Reflect.construct;
|
|
49
|
+
else {
|
|
50
|
+
_construct = function construct(Parent, args, Class) {
|
|
51
|
+
var a = [null];
|
|
52
|
+
a.push.apply(a, args);
|
|
53
|
+
var Constructor = Function.bind.apply(Parent, a);
|
|
54
|
+
var instance = new Constructor();
|
|
55
|
+
|
|
56
|
+
if (Class) _set_prototype_of(instance, Class.prototype);
|
|
57
|
+
|
|
58
|
+
return instance;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return _construct.apply(null, arguments);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function _get_prototype_of(o) {
|
|
66
|
+
_get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
|
|
67
|
+
return o.__proto__ || Object.getPrototypeOf(o);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return _get_prototype_of(o);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function _is_native_function(fn) {
|
|
74
|
+
return Function.toString.call(fn).indexOf("[native code]") !== -1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function _wrap_native_super(Class) {
|
|
78
|
+
var _cache = typeof Map === "function" ? new Map() : undefined;
|
|
79
|
+
_wrap_native_super = function(Class) {
|
|
80
|
+
if (Class === null || !_is_native_function(Class)) return Class;
|
|
81
|
+
if (typeof Class !== "function") throw new TypeError("Super expression must either be null or a function");
|
|
82
|
+
if (typeof _cache !== "undefined") {
|
|
83
|
+
if (_cache.has(Class)) return _cache.get(Class);
|
|
84
|
+
_cache.set(Class, Wrapper);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function Wrapper() {
|
|
88
|
+
return _construct(Class, arguments, _get_prototype_of(this).constructor);
|
|
89
|
+
}
|
|
90
|
+
Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } });
|
|
91
|
+
|
|
92
|
+
return _set_prototype_of(Wrapper, Class);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
return _wrap_native_super(Class);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function _array_like_to_array(arr, len) {
|
|
99
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
100
|
+
|
|
101
|
+
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
102
|
+
|
|
103
|
+
return arr2;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
107
|
+
if (!o) return;
|
|
108
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
109
|
+
|
|
110
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
111
|
+
|
|
112
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
113
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
114
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function _create_for_of_iterator_helper_loose(o, allowArrayLike) {
|
|
118
|
+
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
|
119
|
+
|
|
120
|
+
if (it) return (it = it.call(o)).next.bind(it);
|
|
121
|
+
// Fallback for engines without symbol support
|
|
122
|
+
if (Array.isArray(o) || (it = _unsupported_iterable_to_array(o)) || allowArrayLike && o && typeof o.length === "number") {
|
|
123
|
+
if (it) o = it;
|
|
124
|
+
|
|
125
|
+
var i = 0;
|
|
126
|
+
|
|
127
|
+
return function() {
|
|
128
|
+
if (i >= o.length) return { done: true };
|
|
129
|
+
|
|
130
|
+
return { done: false, value: o[i++] };
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function _defineProperties(target, props) {
|
|
138
|
+
for (var i = 0; i < props.length; i++) {
|
|
139
|
+
var descriptor = props[i];
|
|
140
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
141
|
+
descriptor.configurable = true;
|
|
142
|
+
|
|
143
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
144
|
+
|
|
145
|
+
Object.defineProperty(target, descriptor.key, descriptor);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function _create_class(Constructor, protoProps, staticProps) {
|
|
149
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
150
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
151
|
+
|
|
152
|
+
return Constructor;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** @internal */ var VisitorContext = /*#__PURE__*/ function() {
|
|
156
|
+
function VisitorContext() {
|
|
157
|
+
this._lookupSymbol = new SymbolInfo("", null);
|
|
158
|
+
this._structRoles = new Map();
|
|
159
|
+
this._vertexUnresolvedVariableRoles = new Map();
|
|
160
|
+
this._fragmentUnresolvedVariableRoles = new Map();
|
|
161
|
+
this._vertexAmbiguousVariableNames = new Set();
|
|
162
|
+
this._fragmentAmbiguousVariableNames = new Set();
|
|
163
|
+
this.attributeStructs = [];
|
|
164
|
+
this.attributeList = [];
|
|
165
|
+
this.varyingStructs = [];
|
|
166
|
+
this.varyingList = [];
|
|
167
|
+
this.mrtStructs = [];
|
|
168
|
+
this.mrtList = [];
|
|
169
|
+
this._referencedGlobalSymbols = new Set();
|
|
170
|
+
this._referencedGlobalMacroASTs = [];
|
|
171
|
+
this._structVariableRoles = new Map();
|
|
172
|
+
this.codeCache = new Map();
|
|
173
|
+
this.fragmentReturnModes = new Map();
|
|
174
|
+
this.terminalInterfaceReturns = new Set();
|
|
175
|
+
this.reset();
|
|
176
|
+
}
|
|
177
|
+
var _proto = VisitorContext.prototype;
|
|
178
|
+
_proto.reset = function reset(resetAll) {
|
|
179
|
+
if (resetAll === void 0) resetAll = true;
|
|
180
|
+
this.codeCache.clear();
|
|
181
|
+
this.fragmentReturnModes.clear();
|
|
182
|
+
this.terminalInterfaceReturns.clear();
|
|
183
|
+
if (resetAll) {
|
|
184
|
+
this.attributeStructs.length = 0;
|
|
185
|
+
this.attributeList.length = 0;
|
|
186
|
+
this.varyingStructs.length = 0;
|
|
187
|
+
this.varyingList.length = 0;
|
|
188
|
+
this.mrtStructs.length = 0;
|
|
189
|
+
this.mrtList.length = 0;
|
|
190
|
+
this._structRoles.clear();
|
|
191
|
+
this._vertexUnresolvedVariableRoles.clear();
|
|
192
|
+
this._fragmentUnresolvedVariableRoles.clear();
|
|
193
|
+
this._vertexAmbiguousVariableNames.clear();
|
|
194
|
+
this._fragmentAmbiguousVariableNames.clear();
|
|
195
|
+
}
|
|
196
|
+
this._referencedAttributeList = Object.create(null);
|
|
197
|
+
this._referencedVaryingList = Object.create(null);
|
|
198
|
+
this._referencedMRTList = Object.create(null);
|
|
199
|
+
this._referencedGlobals = Object.create(null);
|
|
200
|
+
this._referencedGlobalSymbols.clear();
|
|
201
|
+
this._globalSymbolQueries = Object.create(null);
|
|
202
|
+
this._referencedGlobalMacroASTs.length = 0;
|
|
203
|
+
if (resetAll) {
|
|
204
|
+
this._structVariableRoles.clear();
|
|
205
|
+
this._passSymbolTable = undefined;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* Finds the shared interface role of custom-struct declaration candidates.
|
|
210
|
+
* @param declarations - Exact parser struct identities resolved at one type occurrence.
|
|
211
|
+
* @returns Interface role, or `undefined` when the type is not an unambiguous interface struct.
|
|
212
|
+
*/ _proto.getStructRole = function getStructRole(declarations) {
|
|
213
|
+
var resolvedRole;
|
|
214
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(declarations), _step; !(_step = _iterator()).done;){
|
|
215
|
+
var declaration = _step.value;
|
|
216
|
+
var role = this._structRoles.get(declaration);
|
|
217
|
+
if (!role || resolvedRole && resolvedRole !== role) return;
|
|
218
|
+
resolvedRole = role;
|
|
219
|
+
}
|
|
220
|
+
return resolvedRole;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Tests the exact interface role of one struct declaration.
|
|
224
|
+
* @param declaration - Parser struct identity.
|
|
225
|
+
* @param role - Expected interface role.
|
|
226
|
+
* @returns Whether the declaration owns that role.
|
|
227
|
+
*/ _proto.hasStructRole = function hasStructRole(declaration, role) {
|
|
228
|
+
return this._structRoles.get(declaration) === role;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Registers stage-interface struct types for constant-time role lookup.
|
|
232
|
+
* @param role - Interface role shared by the supplied structs.
|
|
233
|
+
* @param structs - Struct declarations derived from parser IR.
|
|
234
|
+
* @internal
|
|
235
|
+
*/ _proto.registerStructTypes = function registerStructTypes(role, structs) {
|
|
236
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(structs), _step; !(_step = _iterator()).done;){
|
|
237
|
+
var struct = _step.value;
|
|
238
|
+
this._structRoles.set(struct, role);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Registers a resolved variable that holds an interface struct.
|
|
243
|
+
* @param variable - Parser symbol identity for the declaration.
|
|
244
|
+
* @param role - Struct interface role.
|
|
245
|
+
* @param stage - Optional stage from whose entry the variable is reachable. Omit when only exact
|
|
246
|
+
* symbol lookup is required.
|
|
247
|
+
*/ _proto.registerStructVar = function registerStructVar(variable, role, stage) {
|
|
248
|
+
this._structVariableRoles.set(variable, role);
|
|
249
|
+
if (stage === undefined) return;
|
|
250
|
+
var roles = stage === EShaderStage.VERTEX ? this._vertexUnresolvedVariableRoles : this._fragmentUnresolvedVariableRoles;
|
|
251
|
+
var ambiguous = stage === EShaderStage.VERTEX ? this._vertexAmbiguousVariableNames : this._fragmentAmbiguousVariableNames;
|
|
252
|
+
var name = variable.ident;
|
|
253
|
+
if (ambiguous.has(name)) return;
|
|
254
|
+
var existing = roles.get(name);
|
|
255
|
+
if (existing && existing !== role) {
|
|
256
|
+
roles.delete(name);
|
|
257
|
+
ambiguous.add(name);
|
|
258
|
+
} else {
|
|
259
|
+
roles.set(name, role);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* Finds an interface role for a global macro value that has no lexical symbol identity.
|
|
264
|
+
* @param variableName - Bare variable name in the macro replacement AST.
|
|
265
|
+
* @returns A role only when every stage-reachable declaration with that name agrees.
|
|
266
|
+
*/ _proto.getUnresolvedStructVarRole = function getUnresolvedStructVarRole(variableName) {
|
|
267
|
+
var roles = this.stage === EShaderStage.VERTEX ? this._vertexUnresolvedVariableRoles : this._fragmentUnresolvedVariableRoles;
|
|
268
|
+
var ambiguous = this.stage === EShaderStage.VERTEX ? this._vertexAmbiguousVariableNames : this._fragmentAmbiguousVariableNames;
|
|
269
|
+
return ambiguous.has(variableName) ? undefined : roles.get(variableName);
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* Finds the shared interface role of branch-visible variable candidates.
|
|
273
|
+
* @param symbols - Exact parser symbols resolved at one reference.
|
|
274
|
+
* @returns Interface role, or `undefined` when the reference is not an unambiguous interface value.
|
|
275
|
+
*/ _proto.getStructVarRole = function getStructVarRole(symbols) {
|
|
276
|
+
var resolvedRole;
|
|
277
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(symbols), _step; !(_step = _iterator()).done;){
|
|
278
|
+
var symbol = _step.value;
|
|
279
|
+
if (!_instanceof(symbol, VarSymbol)) return;
|
|
280
|
+
var role = this._structVariableRoles.get(symbol);
|
|
281
|
+
if (!role || resolvedRole && resolvedRole !== role) return;
|
|
282
|
+
resolvedRole = role;
|
|
283
|
+
}
|
|
284
|
+
return resolvedRole;
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Marks a value-return belonging to a fragment entry for backend lowering.
|
|
288
|
+
* @param statement - Exact return statement identity.
|
|
289
|
+
* @param mode - Fragment output contract of the containing entry declaration.
|
|
290
|
+
*/ _proto.registerFragmentReturn = function registerFragmentReturn(statement, mode) {
|
|
291
|
+
this.fragmentReturnModes.set(statement, mode);
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* Finds the output contract for a fragment-entry return statement.
|
|
295
|
+
* @param statement - Return statement identity.
|
|
296
|
+
* @returns Output mode, or `undefined` for ordinary helper/vertex returns.
|
|
297
|
+
*/ _proto.getFragmentReturnMode = function getFragmentReturnMode(statement) {
|
|
298
|
+
return this.fragmentReturnModes.get(statement);
|
|
299
|
+
};
|
|
300
|
+
/** Marks a syntactically final interface return whose control-flow exit can be omitted. */ _proto.registerTerminalInterfaceReturn = function registerTerminalInterfaceReturn(statement) {
|
|
301
|
+
this.terminalInterfaceReturns.add(statement);
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* Tests whether an interface return is the final syntactic statement in its function.
|
|
305
|
+
* @param statement - Return statement identity.
|
|
306
|
+
* @returns Whether backend lowering may omit a trailing `return;`.
|
|
307
|
+
*/ _proto.isTerminalInterfaceReturn = function isTerminalInterfaceReturn(statement) {
|
|
308
|
+
return this.terminalInterfaceReturns.has(statement);
|
|
309
|
+
};
|
|
310
|
+
_proto.referenceAttribute = function referenceAttribute(ident) {
|
|
311
|
+
this._referenceProp(ident.lexeme, this.attributeList, this._referencedAttributeList);
|
|
312
|
+
};
|
|
313
|
+
_proto.referenceVarying = function referenceVarying(ident) {
|
|
314
|
+
this._referenceProp(ident.lexeme, this.varyingList, this._referencedVaryingList);
|
|
315
|
+
};
|
|
316
|
+
_proto.referenceMRTProp = function referenceMRTProp(ident) {
|
|
317
|
+
this._referenceProp(ident.lexeme, this.mrtList, this._referencedMRTList);
|
|
318
|
+
};
|
|
319
|
+
_proto.referenceGlobal = function referenceGlobal(ident, type) {
|
|
320
|
+
var _this__globalSymbolQueries, _ident;
|
|
321
|
+
var _;
|
|
322
|
+
var queries = (_ = (_this__globalSymbolQueries = this._globalSymbolQueries)[_ident = ident]) != null ? _ : _this__globalSymbolQueries[_ident] = Object.create(null);
|
|
323
|
+
var symbols = queries[type];
|
|
324
|
+
if (!symbols) {
|
|
325
|
+
var _this__referencedGlobals, _ident1;
|
|
326
|
+
this._lookupSymbol.set(ident, type);
|
|
327
|
+
symbols = queries[type] = this._passSymbolTable.getSymbols(this._lookupSymbol, true, []);
|
|
328
|
+
var _1;
|
|
329
|
+
var namedSymbols = (_1 = (_this__referencedGlobals = this._referencedGlobals)[_ident1 = ident]) != null ? _1 : _this__referencedGlobals[_ident1] = [];
|
|
330
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(symbols), _step; !(_step = _iterator()).done;){
|
|
331
|
+
var symbol = _step.value;
|
|
332
|
+
if (!this._referencedGlobalSymbols.has(symbol)) {
|
|
333
|
+
this._referencedGlobalSymbols.add(symbol);
|
|
334
|
+
namedSymbols.push(symbol);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Repeated uses still establish edges from each declaration's owner.
|
|
339
|
+
this.onReferenceGlobal == null ? void 0 : this.onReferenceGlobal.call(this, symbols);
|
|
340
|
+
};
|
|
341
|
+
// Track which IO props are actually referenced (drives in/out emission). A missing member is no
|
|
342
|
+
// longer flagged here — that's the parser's struct-field check (UndeclaredStructMember).
|
|
343
|
+
_proto._referenceProp = function _referenceProp(name, list, refList) {
|
|
344
|
+
if (!refList[name]) refList[name] = list.filter(function(item) {
|
|
345
|
+
return item.ident.lexeme === name;
|
|
346
|
+
});
|
|
347
|
+
this.onReferenceStructProps == null ? void 0 : this.onReferenceStructProps.call(this, refList[name]);
|
|
348
|
+
};
|
|
349
|
+
return VisitorContext;
|
|
350
|
+
}();
|
|
351
|
+
|
|
352
|
+
var TempArray = /*#__PURE__*/ function() {
|
|
353
|
+
function TempArray() {
|
|
354
|
+
this.array = new Array();
|
|
355
|
+
}
|
|
356
|
+
var _proto = TempArray.prototype;
|
|
357
|
+
_proto.dispose = function dispose() {
|
|
358
|
+
this.array.length = 0;
|
|
359
|
+
};
|
|
360
|
+
return TempArray;
|
|
361
|
+
}();
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* @internal
|
|
365
|
+
* The code generator
|
|
366
|
+
*/ var CodeGenVisitor = /*#__PURE__*/ function() {
|
|
367
|
+
function CodeGenVisitor() {
|
|
368
|
+
this.context = new VisitorContext();
|
|
369
|
+
}
|
|
370
|
+
var _proto = CodeGenVisitor.prototype;
|
|
371
|
+
_proto.cache = function cache(node, code) {
|
|
372
|
+
this.context.codeCache.set(node, code);
|
|
373
|
+
return code;
|
|
374
|
+
};
|
|
375
|
+
_proto.getCachedCode = function getCachedCode(node) {
|
|
376
|
+
return this.context.codeCache.get(node);
|
|
377
|
+
};
|
|
378
|
+
_proto.defaultCodeGen = function defaultCodeGen(children) {
|
|
379
|
+
var pool = CodeGenVisitor._tmpArrayPool;
|
|
380
|
+
var ret = pool.get();
|
|
381
|
+
ret.dispose();
|
|
382
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(children), _step; !(_step = _iterator()).done;){
|
|
383
|
+
var child = _step.value;
|
|
384
|
+
if (_instanceof(child, BaseToken)) {
|
|
385
|
+
// Legacy opaque `#define` lexemes carry the directive verbatim; expression-style defines use the AST path
|
|
386
|
+
ret.array.push(child.lexeme);
|
|
387
|
+
} else {
|
|
388
|
+
ret.array.push(child.codeGen(this));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
var result = ret.array.join(" ");
|
|
392
|
+
ret.dispose();
|
|
393
|
+
pool.return(ret);
|
|
394
|
+
return result;
|
|
395
|
+
};
|
|
396
|
+
_proto.visitPostfixExpression = function visitPostfixExpression(node) {
|
|
397
|
+
var children = node.children;
|
|
398
|
+
var derivationLength = children.length;
|
|
399
|
+
var context = this.context;
|
|
400
|
+
if (derivationLength === 3) {
|
|
401
|
+
var postExpr = children[0];
|
|
402
|
+
var prop = children[2];
|
|
403
|
+
if (_instanceof(prop, BaseToken)) {
|
|
404
|
+
// Direct variables use parser symbol identity so lexical shadowing cannot inherit an IO role
|
|
405
|
+
// from a same-named declaration. Macro-expanded identifiers can lack a resolved symbol, so
|
|
406
|
+
// only that zero-symbol path consults the current stage's unambiguous name-to-role map.
|
|
407
|
+
var role;
|
|
408
|
+
var directRoot = ParserUtils.unwrapBareIdentifier(postExpr, {
|
|
409
|
+
allowParens: true
|
|
410
|
+
});
|
|
411
|
+
if (directRoot) {
|
|
412
|
+
var symbols = directRoot.resolvedValueSymbols();
|
|
413
|
+
var unresolvedName = ParserUtils.extractDirectIdentLexeme(postExpr);
|
|
414
|
+
role = symbols.length ? context.getStructVarRole(symbols) : unresolvedName ? context.getUnresolvedStructVarRole(unresolvedName) : undefined;
|
|
415
|
+
}
|
|
416
|
+
if (role) {
|
|
417
|
+
if (role === ShaderStructRole.Attribute) context.referenceAttribute(prop);
|
|
418
|
+
else if (role === ShaderStructRole.Varying) context.referenceVarying(prop);
|
|
419
|
+
else context.referenceMRTProp(prop);
|
|
420
|
+
return prop.lexeme;
|
|
421
|
+
}
|
|
422
|
+
return postExpr.codeGen(this) + "." + prop.lexeme;
|
|
423
|
+
} else {
|
|
424
|
+
return postExpr.codeGen(this) + "." + prop.codeGen(this);
|
|
425
|
+
}
|
|
426
|
+
} else if (derivationLength === 4) {
|
|
427
|
+
var identNode = children[0];
|
|
428
|
+
var indexNode = children[2];
|
|
429
|
+
return identNode.codeGen(this) + "[" + indexNode.codeGen(this) + "]";
|
|
430
|
+
}
|
|
431
|
+
return this.defaultCodeGen(node.children);
|
|
432
|
+
};
|
|
433
|
+
_proto.visitVariableIdentifier = function visitVariableIdentifier(node) {
|
|
434
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(node.referenceGlobalSymbolNames), _step; !(_step = _iterator()).done;){
|
|
435
|
+
var name = _step.value;
|
|
436
|
+
this.context.referenceGlobal(name, ESymbolType.Any);
|
|
437
|
+
}
|
|
438
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(node.resolvedSymbols()), _step1; !(_step1 = _iterator1()).done;){
|
|
439
|
+
var symbol = _step1.value;
|
|
440
|
+
if (_instanceof(symbol, FnSymbol)) this.referenceFunction(symbol, node.location.start.index, node._branch);
|
|
441
|
+
}
|
|
442
|
+
return node.getLexeme(this);
|
|
443
|
+
};
|
|
444
|
+
_proto.referenceFunction = function referenceFunction(symbol, referenceIndex, branch) {
|
|
445
|
+
this.context.referenceGlobal(symbol.ident, ESymbolType.FN);
|
|
446
|
+
};
|
|
447
|
+
_proto.visitFunctionCall = function visitFunctionCall(node) {
|
|
448
|
+
var call = node.children[0];
|
|
449
|
+
if (_instanceof(call.fnSymbol, FnSymbol)) {
|
|
450
|
+
var _call_fnSymbols;
|
|
451
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(((_call_fnSymbols = call.fnSymbols) == null ? void 0 : _call_fnSymbols.length) ? call.fnSymbols : [
|
|
452
|
+
call.fnSymbol
|
|
453
|
+
]), _step; !(_step = _iterator()).done;){
|
|
454
|
+
var symbol = _step.value;
|
|
455
|
+
this.referenceFunction(symbol, node.location.start.index, node._branch);
|
|
456
|
+
}
|
|
457
|
+
var paramList = call.children[2];
|
|
458
|
+
if (_instanceof(paramList, ASTNode.FunctionCallParameterList)) {
|
|
459
|
+
var astNodes = paramList.paramNodes;
|
|
460
|
+
var finalSymbol = this.context._referencedGlobals[call.fnSymbol.ident].find(function(candidate) {
|
|
461
|
+
return _instanceof(candidate, FnSymbol) && candidate.equal(call.fnSymbol);
|
|
462
|
+
});
|
|
463
|
+
var paramInfoList = (finalSymbol != null ? finalSymbol : call.fnSymbol).astNode.protoType.parameterList;
|
|
464
|
+
var context = this.context;
|
|
465
|
+
var params = astNodes.filter(function(_, i) {
|
|
466
|
+
var _paramInfoList_i;
|
|
467
|
+
var parameter = paramInfoList == null ? void 0 : (_paramInfoList_i = paramInfoList[i]) == null ? void 0 : _paramInfoList_i.astNode;
|
|
468
|
+
// Drop struct-IO parameters (attribute/varying/mrt) — they're flattened
|
|
469
|
+
// into top-level declarations and no longer exist as function-call args.
|
|
470
|
+
return !_instanceof(parameter, ASTNode.ParameterDeclaration) || !parameter.symbol || !context.getStructVarRole([
|
|
471
|
+
parameter.symbol
|
|
472
|
+
]);
|
|
473
|
+
});
|
|
474
|
+
var paramsCode = "";
|
|
475
|
+
for(var i = 0, length = params.length; i < length; i++){
|
|
476
|
+
var astNode = params[i];
|
|
477
|
+
var code = astNode.codeGen(this);
|
|
478
|
+
if (_instanceof(astNode, ASTNode.MacroCallArgBlock) || i === 0) {
|
|
479
|
+
paramsCode += code;
|
|
480
|
+
} else {
|
|
481
|
+
paramsCode += ", " + code;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return call.fnSymbol.ident + "(" + paramsCode + ")";
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return this.defaultCodeGen(node.children);
|
|
488
|
+
};
|
|
489
|
+
_proto.visitMacroCallFunction = function visitMacroCallFunction(node) {
|
|
490
|
+
var children = node.children;
|
|
491
|
+
var paramList = children[2];
|
|
492
|
+
if (_instanceof(paramList, ASTNode.FunctionCallParameterList)) {
|
|
493
|
+
var astNodes = paramList.paramNodes;
|
|
494
|
+
var context = this.context;
|
|
495
|
+
// Drop bare IO-struct args only when the macro aliases a user fn (whose
|
|
496
|
+
// formal was flattened). All other shapes preserve args verbatim.
|
|
497
|
+
var params;
|
|
498
|
+
if (node.isFunctionLikeMacro || !node.aliasesNonBuiltinIdent) {
|
|
499
|
+
params = astNodes;
|
|
500
|
+
} else {
|
|
501
|
+
params = astNodes.filter(function(arg) {
|
|
502
|
+
if (_instanceof(arg, ASTNode.AssignmentExpression)) {
|
|
503
|
+
var variableParam = ParserUtils.unwrapBareIdentifier(arg, {
|
|
504
|
+
allowParens: false
|
|
505
|
+
});
|
|
506
|
+
if (variableParam && context.getStructVarRole(variableParam.resolvedValueSymbols())) {
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return true;
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
var paramsCode = "";
|
|
514
|
+
for(var i = 0, length = params.length; i < length; i++){
|
|
515
|
+
var argNode = params[i];
|
|
516
|
+
var code = argNode.codeGen(this);
|
|
517
|
+
if (_instanceof(argNode, ASTNode.MacroCallArgBlock) || i === 0) {
|
|
518
|
+
paramsCode += code;
|
|
519
|
+
} else {
|
|
520
|
+
paramsCode += ", " + code;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return node.macroName + "(" + paramsCode + ")";
|
|
524
|
+
} else {
|
|
525
|
+
return this.defaultCodeGen(node.children);
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
_proto.visitStatementList = function visitStatementList(node) {
|
|
529
|
+
var children = node.children;
|
|
530
|
+
if (children.length === 1) {
|
|
531
|
+
return children[0].codeGen(this);
|
|
532
|
+
} else {
|
|
533
|
+
return children[0].codeGen(this) + "\n" + children[1].codeGen(this);
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
/**
|
|
537
|
+
* Code-generate a `#define` macro parsed as expression AST. Produces a `#define`
|
|
538
|
+
* directive whose value is the AST-rewritten string — so varying flattening
|
|
539
|
+
* happens naturally via `visitPostfixExpression` inside the AST walk.
|
|
540
|
+
*/ _proto.visitMacroDefine = function visitMacroDefine(node) {
|
|
541
|
+
// For function-like macros, preserve the original `(params)` lexeme verbatim —
|
|
542
|
+
// the parameter list is user-authored text that shouldn't be canonicalized.
|
|
543
|
+
var paramsLexeme = "";
|
|
544
|
+
if (node.isFunction) {
|
|
545
|
+
var paramsToken = node.children[2];
|
|
546
|
+
if (_instanceof(paramsToken, BaseToken)) paramsLexeme = paramsToken.lexeme;
|
|
547
|
+
}
|
|
548
|
+
var valueCode = node.valueExpression ? node.valueExpression.codeGen(this) : "";
|
|
549
|
+
// Newlines around the directive keep `#` at the start of its physical line per
|
|
550
|
+
// GLSL ES 3.0 §3.4, regardless of how surrounding tokens are joined.
|
|
551
|
+
return "\n#define " + node.macroName + paramsLexeme + (valueCode ? " " + valueCode : "") + "\n";
|
|
552
|
+
};
|
|
553
|
+
_proto.visitSingleDeclaration = function visitSingleDeclaration(node) {
|
|
554
|
+
return this.defaultCodeGen(node.children);
|
|
555
|
+
};
|
|
556
|
+
_proto.visitGlobalVariableDeclaration = function visitGlobalVariableDeclaration(node) {
|
|
557
|
+
var children = node.children;
|
|
558
|
+
var fullType = children[0];
|
|
559
|
+
if (_instanceof(fullType, ASTNode.FullySpecifiedType) && fullType.typeSpecifier.isCustom) {
|
|
560
|
+
var context = this.context;
|
|
561
|
+
// Global interface variables are flattened and therefore are not emitted as uniforms.
|
|
562
|
+
if (context.getStructVarRole([
|
|
563
|
+
node.declarator.symbol
|
|
564
|
+
])) {
|
|
565
|
+
return "";
|
|
566
|
+
}
|
|
567
|
+
context.referenceGlobal(fullType.type, ESymbolType.STRUCT);
|
|
568
|
+
}
|
|
569
|
+
return "uniform " + this.defaultCodeGen(children);
|
|
570
|
+
};
|
|
571
|
+
_proto.visitDeclaration = function visitDeclaration(node) {
|
|
572
|
+
var context = this.context;
|
|
573
|
+
var children = node.children;
|
|
574
|
+
var child = children[0];
|
|
575
|
+
if (_instanceof(child, ASTNode.InitDeclaratorList)) {
|
|
576
|
+
var first = child.children[0];
|
|
577
|
+
var _child_declarator;
|
|
578
|
+
var declarator = (_child_declarator = child.declarator) != null ? _child_declarator : _instanceof(first, ASTNode.SingleDeclaration) ? first.declarator : undefined;
|
|
579
|
+
var role = declarator && context.getStructVarRole([
|
|
580
|
+
declarator.symbol
|
|
581
|
+
]);
|
|
582
|
+
if (role === ShaderStructRole.Varying || role === ShaderStructRole.Mrt) return "";
|
|
583
|
+
}
|
|
584
|
+
return this.defaultCodeGen(children);
|
|
585
|
+
};
|
|
586
|
+
_proto.visitFunctionParameterList = function visitFunctionParameterList(node) {
|
|
587
|
+
var context = this.context;
|
|
588
|
+
var params = node.parameterInfoList.filter(function(item) {
|
|
589
|
+
var parameter = item.astNode;
|
|
590
|
+
return !_instanceof(parameter, ASTNode.ParameterDeclaration) || !parameter.symbol || !context.getStructVarRole([
|
|
591
|
+
parameter.symbol
|
|
592
|
+
]);
|
|
593
|
+
});
|
|
594
|
+
var out = "";
|
|
595
|
+
for(var i = 0, length = params.length; i < length; i++){
|
|
596
|
+
var item = params[i];
|
|
597
|
+
var astNode = item.astNode;
|
|
598
|
+
var code = astNode.codeGen(this);
|
|
599
|
+
if (_instanceof(astNode, ASTNode.MacroParamBlock) || i === 0) {
|
|
600
|
+
out += code;
|
|
601
|
+
} else {
|
|
602
|
+
out += ", " + code;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return out;
|
|
606
|
+
};
|
|
607
|
+
_proto.visitFunctionHeader = function visitFunctionHeader(node) {
|
|
608
|
+
var returnType = node.returnType.typeSpecifier;
|
|
609
|
+
if (this.context.getStructRole(returnType.structDeclarations) === ShaderStructRole.Varying) {
|
|
610
|
+
return "void " + node.ident.lexeme + "(";
|
|
611
|
+
}
|
|
612
|
+
return this.defaultCodeGen(node.children);
|
|
613
|
+
};
|
|
614
|
+
_proto.visitJumpStatement = function visitJumpStatement(node) {
|
|
615
|
+
var children = node.children;
|
|
616
|
+
var cmd = children[0];
|
|
617
|
+
if (cmd.type === Keyword.RETURN) {
|
|
618
|
+
var expr = children[1];
|
|
619
|
+
if (_instanceof(expr, ASTNode.Expression)) {
|
|
620
|
+
var returnVar = ParserUtils.unwrapNodeByType(expr, NoneTerminal.variable_identifier);
|
|
621
|
+
if (returnVar && this.context.getStructVarRole(returnVar.resolvedValueSymbols()) === ShaderStructRole.Varying) {
|
|
622
|
+
return this.context.isTerminalInterfaceReturn(node) ? "" : "return;";
|
|
623
|
+
}
|
|
624
|
+
var returnFnCall = ParserUtils.unwrapNodeByType(expr, NoneTerminal.function_call);
|
|
625
|
+
var calledFunction = returnFnCall == null ? void 0 : returnFnCall.children[0];
|
|
626
|
+
var returnDeclarations = _instanceof(calledFunction == null ? void 0 : calledFunction.fnSymbol, FnSymbol) ? calledFunction.fnSymbol.astNode.protoType.returnType.typeSpecifier.structDeclarations : [];
|
|
627
|
+
if (this.context.getStructRole(returnDeclarations) === ShaderStructRole.Varying) {
|
|
628
|
+
var call = "" + expr.codeGen(this) + ";";
|
|
629
|
+
return this.context.isTerminalInterfaceReturn(node) ? call : "{ " + call + " return; }";
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
return this.defaultCodeGen(children);
|
|
634
|
+
};
|
|
635
|
+
_proto.visitFunctionIdentifier = function visitFunctionIdentifier(node) {
|
|
636
|
+
return this.defaultCodeGen(node.children);
|
|
637
|
+
};
|
|
638
|
+
_proto.visitTypeSpecifier = function visitTypeSpecifier(node) {
|
|
639
|
+
return this.defaultCodeGen(node.children);
|
|
640
|
+
};
|
|
641
|
+
_proto.visitStructSpecifier = function visitStructSpecifier(node) {
|
|
642
|
+
var _this = this;
|
|
643
|
+
var context = this.context;
|
|
644
|
+
var varyingStructs = context.varyingStructs, attributeStructs = context.attributeStructs, mrtStructs = context.mrtStructs;
|
|
645
|
+
var isVaryingStruct = varyingStructs.indexOf(node) !== -1;
|
|
646
|
+
var isAttributeStruct = attributeStructs.indexOf(node) !== -1;
|
|
647
|
+
var isMRTStruct = mrtStructs.indexOf(node) !== -1;
|
|
648
|
+
if (isVaryingStruct || isAttributeStruct || isMRTStruct) {
|
|
649
|
+
var _result;
|
|
650
|
+
var result = [];
|
|
651
|
+
(_result = result).push.apply(_result, [].concat(node.macroExpressions.map(function(item) {
|
|
652
|
+
return {
|
|
653
|
+
text: _instanceof(item, BaseToken) ? item.lexeme : item.codeGen(_this),
|
|
654
|
+
index: item.location.start.index
|
|
655
|
+
};
|
|
656
|
+
})));
|
|
657
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(node.propList), _step; !(_step = _iterator()).done;){
|
|
658
|
+
var prop = _step.value;
|
|
659
|
+
var _context__referencedVaryingList_name, _context__referencedAttributeList_name, _context__referencedMRTList_name;
|
|
660
|
+
var name = prop.ident.lexeme;
|
|
661
|
+
if (isVaryingStruct && ((_context__referencedVaryingList_name = context._referencedVaryingList[name]) == null ? void 0 : _context__referencedVaryingList_name.indexOf(prop)) >= 0) {
|
|
662
|
+
result.push({
|
|
663
|
+
text: "" + this.getVaryingProp(prop) + "\n",
|
|
664
|
+
index: prop.ident.location.start.index
|
|
665
|
+
});
|
|
666
|
+
} else if (isAttributeStruct && ((_context__referencedAttributeList_name = context._referencedAttributeList[name]) == null ? void 0 : _context__referencedAttributeList_name.indexOf(prop)) >= 0) {
|
|
667
|
+
result.push({
|
|
668
|
+
text: "" + this.getAttributeProp(prop) + "\n",
|
|
669
|
+
index: prop.ident.location.start.index
|
|
670
|
+
});
|
|
671
|
+
} else if (isMRTStruct && ((_context__referencedMRTList_name = context._referencedMRTList[name]) == null ? void 0 : _context__referencedMRTList_name.indexOf(prop)) >= 0) {
|
|
672
|
+
result.push({
|
|
673
|
+
text: "" + this.getMRTProp(prop) + "\n",
|
|
674
|
+
index: prop.ident.location.start.index
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
var text = result.sort(function(a, b) {
|
|
679
|
+
return a.index - b.index;
|
|
680
|
+
}).map(function(item) {
|
|
681
|
+
return item.text;
|
|
682
|
+
}).join("");
|
|
683
|
+
return text;
|
|
684
|
+
} else {
|
|
685
|
+
return this.defaultCodeGen(node.children);
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
_proto.visitFunctionDefinition = function visitFunctionDefinition(fnNode) {
|
|
689
|
+
var fnName = fnNode.protoType.ident.lexeme;
|
|
690
|
+
var context = this.context;
|
|
691
|
+
var terminal = ParserUtils.lastStatement(fnNode.statements);
|
|
692
|
+
if (_instanceof(terminal, ASTNode.JumpStatement)) context.registerTerminalInterfaceReturn(terminal);
|
|
693
|
+
if (fnName == context.stageEntry) {
|
|
694
|
+
var statements = fnNode.statements.codeGen(this);
|
|
695
|
+
return "void main() " + statements;
|
|
696
|
+
} else {
|
|
697
|
+
return this.defaultCodeGen(fnNode.children);
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
return CodeGenVisitor;
|
|
701
|
+
}();
|
|
702
|
+
CodeGenVisitor._tmpArrayPool = new ReturnableObjectPool(TempArray, 10);
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* @internal
|
|
706
|
+
*/ var ShaderInstructionEncoder = /*#__PURE__*/ function() {
|
|
707
|
+
function ShaderInstructionEncoder() {}
|
|
708
|
+
/**
|
|
709
|
+
* Marks compiler-owned text without placing parser objects in the instruction stream.
|
|
710
|
+
* @param text - Declaration or derived declaration text.
|
|
711
|
+
* @param owner - Neutral declaration identity, if runtime selection is required.
|
|
712
|
+
* @param activate - Whether this is the declaration's original source position.
|
|
713
|
+
* @returns Intermediate source consumed by the instruction encoder.
|
|
714
|
+
* @internal
|
|
715
|
+
*/ ShaderInstructionEncoder.declaration = function declaration(text, owner, activate) {
|
|
716
|
+
if (activate === void 0) activate = true;
|
|
717
|
+
if (!owner) return text;
|
|
718
|
+
var activation = activate ? "\0D" + owner.id + "," + owner.group + "," + owner.sourceScope + "\0\n" : "";
|
|
719
|
+
return text ? activation + "\0T" + owner.id + "\0\n" + text + "\n\0E\0\n" : activation;
|
|
720
|
+
};
|
|
721
|
+
/**
|
|
722
|
+
* Marks derived text shared by any selected, reachable declaration without activating an owner.
|
|
723
|
+
* @param text - Shared derived declaration text.
|
|
724
|
+
* @param owners - Declarations that require the text; an empty list never retains it.
|
|
725
|
+
* @returns Intermediate source consumed by the instruction encoder.
|
|
726
|
+
* @internal
|
|
727
|
+
*/ ShaderInstructionEncoder.sharedDeclaration = function sharedDeclaration(text, owners) {
|
|
728
|
+
return text ? "\0T" + owners.map(function(owner) {
|
|
729
|
+
return owner.id;
|
|
730
|
+
}).join(",") + "\0\n" + text + "\n\0E\0\n" : "";
|
|
731
|
+
};
|
|
732
|
+
/**
|
|
733
|
+
* Records a declaration dependency for variant-time reachability after ownership selection.
|
|
734
|
+
* @param from - Referencing declaration identity, or zero for a stage root.
|
|
735
|
+
* @param to - Referenced declaration identity.
|
|
736
|
+
* @returns Intermediate source consumed by the instruction encoder.
|
|
737
|
+
* @internal
|
|
738
|
+
*/ ShaderInstructionEncoder.reference = function reference(from, to) {
|
|
739
|
+
return "\0R" + from + "," + to + "\0\n";
|
|
740
|
+
};
|
|
741
|
+
/**
|
|
742
|
+
* Removes private emission markers from the public source view after instruction encoding.
|
|
743
|
+
* @param source - Encoded intermediate stage source.
|
|
744
|
+
* @returns GLSL source without compiler metadata.
|
|
745
|
+
* @internal
|
|
746
|
+
*/ ShaderInstructionEncoder.source = function source(source) {
|
|
747
|
+
return source.indexOf("\0") < 0 ? source : source.replace(/\0[^\0]*\0\n?/g, "");
|
|
748
|
+
};
|
|
749
|
+
/**
|
|
750
|
+
* Encodes generated GLSL directives into runtime-selectable instructions.
|
|
751
|
+
* @param glsl - Generated stage source.
|
|
752
|
+
* @param preprocessorExpressions - Parser-owned expression trees keyed by logical directive text.
|
|
753
|
+
* @returns Runtime shader instruction stream.
|
|
754
|
+
* @throws Error when a conditional directive is malformed or has a deterministic evaluation failure.
|
|
755
|
+
* @internal
|
|
756
|
+
*/ ShaderInstructionEncoder.parse = function parse(glsl, preprocessorExpressions) {
|
|
757
|
+
var instructions = [];
|
|
758
|
+
var length = glsl.length;
|
|
759
|
+
var pos = 0;
|
|
760
|
+
var owners;
|
|
761
|
+
var backfillStack = [];
|
|
762
|
+
while(pos < length){
|
|
763
|
+
var directiveStart = ShaderInstructionEncoder._findDirectiveStart(glsl, pos, length);
|
|
764
|
+
if (directiveStart === -1) {
|
|
765
|
+
ShaderInstructionEncoder._pushText(instructions, glsl, pos, length, owners);
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
if (directiveStart > pos) {
|
|
769
|
+
ShaderInstructionEncoder._pushText(instructions, glsl, pos, directiveStart, owners);
|
|
770
|
+
}
|
|
771
|
+
var lineEnd = ShaderInstructionEncoder._findLogicalLineEnd(glsl, directiveStart, length);
|
|
772
|
+
var line = glsl.substring(directiveStart, lineEnd).replace(/\\(?:\r\n|\n|\r)/g, "");
|
|
773
|
+
pos = lineEnd < length ? lineEnd + 1 : length;
|
|
774
|
+
if (line.charCodeAt(0) === 0) {
|
|
775
|
+
var kind = line.charAt(1);
|
|
776
|
+
if (kind === "D") {
|
|
777
|
+
var fields = line.slice(2, -1).split(",").map(Number);
|
|
778
|
+
instructions.push([
|
|
779
|
+
ShaderPreprocessorDirective.Declaration,
|
|
780
|
+
fields[0],
|
|
781
|
+
fields[1],
|
|
782
|
+
fields[2]
|
|
783
|
+
]);
|
|
784
|
+
} else if (kind === "R") {
|
|
785
|
+
var fields1 = line.slice(2, -1).split(",").map(Number);
|
|
786
|
+
instructions.push([
|
|
787
|
+
ShaderPreprocessorDirective.Reference,
|
|
788
|
+
fields1[0],
|
|
789
|
+
fields1[1]
|
|
790
|
+
]);
|
|
791
|
+
} else {
|
|
792
|
+
var ids = line.slice(2, -1);
|
|
793
|
+
owners = kind === "T" ? ids ? ids.split(",").map(Number) : [] : undefined;
|
|
794
|
+
}
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
var match = ShaderInstructionEncoder._DIRECTIVE_RE.exec(line);
|
|
798
|
+
if (!match) {
|
|
799
|
+
var text = lineEnd < length ? line + "\n" : line;
|
|
800
|
+
ShaderInstructionEncoder._pushText(instructions, text, 0, text.length, owners);
|
|
801
|
+
continue;
|
|
802
|
+
}
|
|
803
|
+
var keyword = match[1];
|
|
804
|
+
var rest = match[2].trim();
|
|
805
|
+
switch(keyword){
|
|
806
|
+
case "ifdef":
|
|
807
|
+
{
|
|
808
|
+
var idx = instructions.length;
|
|
809
|
+
instructions.push([
|
|
810
|
+
ShaderPreprocessorDirective.IfDef,
|
|
811
|
+
rest,
|
|
812
|
+
-1
|
|
813
|
+
]);
|
|
814
|
+
backfillStack.push([
|
|
815
|
+
idx
|
|
816
|
+
]);
|
|
817
|
+
break;
|
|
818
|
+
}
|
|
819
|
+
case "ifndef":
|
|
820
|
+
{
|
|
821
|
+
var idx1 = instructions.length;
|
|
822
|
+
instructions.push([
|
|
823
|
+
ShaderPreprocessorDirective.IfNdef,
|
|
824
|
+
rest,
|
|
825
|
+
-1
|
|
826
|
+
]);
|
|
827
|
+
backfillStack.push([
|
|
828
|
+
idx1
|
|
829
|
+
]);
|
|
830
|
+
break;
|
|
831
|
+
}
|
|
832
|
+
case "if":
|
|
833
|
+
{
|
|
834
|
+
var cond = ShaderInstructionEncoder._parseCondition(rest, preprocessorExpressions);
|
|
835
|
+
var idx2 = instructions.length;
|
|
836
|
+
ShaderInstructionEncoder._pushConditionInstruction(instructions, cond);
|
|
837
|
+
backfillStack.push([
|
|
838
|
+
idx2
|
|
839
|
+
]);
|
|
840
|
+
break;
|
|
841
|
+
}
|
|
842
|
+
case "elif":
|
|
843
|
+
{
|
|
844
|
+
var stack = backfillStack[backfillStack.length - 1];
|
|
845
|
+
var prevIdx = stack[stack.length - 1];
|
|
846
|
+
var elseIdx = instructions.length;
|
|
847
|
+
instructions.push([
|
|
848
|
+
ShaderPreprocessorDirective.Else,
|
|
849
|
+
-1
|
|
850
|
+
]);
|
|
851
|
+
stack.push(elseIdx);
|
|
852
|
+
ShaderInstructionEncoder._backfillJump(instructions[prevIdx], instructions.length);
|
|
853
|
+
var cond1 = ShaderInstructionEncoder._parseCondition(rest, preprocessorExpressions);
|
|
854
|
+
var idx3 = instructions.length;
|
|
855
|
+
ShaderInstructionEncoder._pushConditionInstruction(instructions, cond1);
|
|
856
|
+
stack.push(idx3);
|
|
857
|
+
break;
|
|
858
|
+
}
|
|
859
|
+
case "else":
|
|
860
|
+
{
|
|
861
|
+
var stack1 = backfillStack[backfillStack.length - 1];
|
|
862
|
+
var prevIdx1 = stack1[stack1.length - 1];
|
|
863
|
+
var elseIdx1 = instructions.length;
|
|
864
|
+
instructions.push([
|
|
865
|
+
ShaderPreprocessorDirective.Else,
|
|
866
|
+
-1
|
|
867
|
+
]);
|
|
868
|
+
stack1.push(elseIdx1);
|
|
869
|
+
ShaderInstructionEncoder._backfillJump(instructions[prevIdx1], instructions.length);
|
|
870
|
+
break;
|
|
871
|
+
}
|
|
872
|
+
case "endif":
|
|
873
|
+
{
|
|
874
|
+
var endifIdx = instructions.length;
|
|
875
|
+
instructions.push([
|
|
876
|
+
ShaderPreprocessorDirective.Endif
|
|
877
|
+
]);
|
|
878
|
+
var stack2 = backfillStack.pop();
|
|
879
|
+
if (stack2) {
|
|
880
|
+
var afterEndif = endifIdx + 1;
|
|
881
|
+
for(var j = 0; j < stack2.length; j++){
|
|
882
|
+
var inst = instructions[stack2[j]];
|
|
883
|
+
if (inst[0] === ShaderPreprocessorDirective.Else) {
|
|
884
|
+
inst[1] = afterEndif;
|
|
885
|
+
} else {
|
|
886
|
+
ShaderInstructionEncoder._backfillJump(inst, afterEndif, true);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
break;
|
|
891
|
+
}
|
|
892
|
+
case "define":
|
|
893
|
+
{
|
|
894
|
+
var funcMatch = ShaderInstructionEncoder._FUNC_MACRO_RE.exec(rest);
|
|
895
|
+
if (funcMatch) {
|
|
896
|
+
var params = funcMatch[2].split(",").map(function(p) {
|
|
897
|
+
return p.trim();
|
|
898
|
+
}).filter(function(p) {
|
|
899
|
+
return p.length > 0;
|
|
900
|
+
});
|
|
901
|
+
instructions.push([
|
|
902
|
+
ShaderPreprocessorDirective.DefineFunc,
|
|
903
|
+
funcMatch[1],
|
|
904
|
+
params,
|
|
905
|
+
ShaderInstructionEncoder._stripLineComment(funcMatch[3].trim())
|
|
906
|
+
]);
|
|
907
|
+
} else {
|
|
908
|
+
var separator = ShaderInstructionEncoder._findInlineWhitespace(rest);
|
|
909
|
+
if (separator === rest.length) {
|
|
910
|
+
instructions.push([
|
|
911
|
+
ShaderPreprocessorDirective.Define,
|
|
912
|
+
rest
|
|
913
|
+
]);
|
|
914
|
+
} else {
|
|
915
|
+
instructions.push([
|
|
916
|
+
ShaderPreprocessorDirective.DefineVal,
|
|
917
|
+
rest.substring(0, separator),
|
|
918
|
+
ShaderInstructionEncoder._stripLineComment(rest.substring(separator + 1).trim())
|
|
919
|
+
]);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
break;
|
|
923
|
+
}
|
|
924
|
+
case "undef":
|
|
925
|
+
{
|
|
926
|
+
instructions.push([
|
|
927
|
+
ShaderPreprocessorDirective.Undef,
|
|
928
|
+
rest
|
|
929
|
+
]);
|
|
930
|
+
break;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
return instructions;
|
|
935
|
+
};
|
|
936
|
+
ShaderInstructionEncoder._pushConditionInstruction = function _pushConditionInstruction(instructions, cond) {
|
|
937
|
+
if (cond.t === "def") {
|
|
938
|
+
instructions.push([
|
|
939
|
+
ShaderPreprocessorDirective.IfDef,
|
|
940
|
+
cond.m,
|
|
941
|
+
-1
|
|
942
|
+
]);
|
|
943
|
+
} else if (cond.t === "ndef") {
|
|
944
|
+
instructions.push([
|
|
945
|
+
ShaderPreprocessorDirective.IfNdef,
|
|
946
|
+
cond.m,
|
|
947
|
+
-1
|
|
948
|
+
]);
|
|
949
|
+
} else if (cond.t === "cmp") {
|
|
950
|
+
instructions.push([
|
|
951
|
+
ShaderPreprocessorDirective.IfCmp,
|
|
952
|
+
cond.m,
|
|
953
|
+
cond.op,
|
|
954
|
+
cond.v,
|
|
955
|
+
-1
|
|
956
|
+
]);
|
|
957
|
+
} else {
|
|
958
|
+
instructions.push([
|
|
959
|
+
ShaderPreprocessorDirective.IfExpr,
|
|
960
|
+
cond,
|
|
961
|
+
-1
|
|
962
|
+
]);
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
ShaderInstructionEncoder._parseCondition = function _parseCondition(expression, preprocessorExpressions) {
|
|
966
|
+
var _preprocessorExpressions_get;
|
|
967
|
+
var result = (_preprocessorExpressions_get = preprocessorExpressions == null ? void 0 : preprocessorExpressions.get(expression)) != null ? _preprocessorExpressions_get : parsePreprocessorExpression(expression);
|
|
968
|
+
if ("error" in result) {
|
|
969
|
+
if (!result.error.certain && result.hasExpandableIdentifier) return {
|
|
970
|
+
t: "deferred",
|
|
971
|
+
e: expression
|
|
972
|
+
};
|
|
973
|
+
throw new Error(result.error.message);
|
|
974
|
+
}
|
|
975
|
+
if (result.evaluationError) throw new Error(result.evaluationError);
|
|
976
|
+
var compact = toPreprocessorCondition(result.condition);
|
|
977
|
+
if (compact && !result.hasExpandableIdentifier) return compact;
|
|
978
|
+
return result.hasExpandableIdentifier ? {
|
|
979
|
+
t: "deferred",
|
|
980
|
+
e: expression
|
|
981
|
+
} : result.condition;
|
|
982
|
+
};
|
|
983
|
+
ShaderInstructionEncoder._findDirectiveStart = function _findDirectiveStart(source, from, length) {
|
|
984
|
+
var i = from;
|
|
985
|
+
while(i < length){
|
|
986
|
+
var j = i;
|
|
987
|
+
while(j < length){
|
|
988
|
+
var c = source.charCodeAt(j);
|
|
989
|
+
if (c === 32 /* space */ || c === 9 /* tab */ ) {
|
|
990
|
+
j++;
|
|
991
|
+
} else {
|
|
992
|
+
break;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
if (j < length && (source.charCodeAt(j) === 35 /* '#' */ || source.charCodeAt(j) === 0)) return i;
|
|
996
|
+
var nl = source.indexOf("\n", i);
|
|
997
|
+
if (nl === -1) break;
|
|
998
|
+
i = nl + 1;
|
|
999
|
+
}
|
|
1000
|
+
return -1;
|
|
1001
|
+
};
|
|
1002
|
+
ShaderInstructionEncoder._findLogicalLineEnd = function _findLogicalLineEnd(source, start, length) {
|
|
1003
|
+
var lineEnd = source.indexOf("\n", start);
|
|
1004
|
+
while(lineEnd !== -1){
|
|
1005
|
+
var beforeBreak = source.charCodeAt(lineEnd - 1) === 13 ? lineEnd - 2 : lineEnd - 1;
|
|
1006
|
+
if (beforeBreak < start || source.charCodeAt(beforeBreak) !== 92) return lineEnd;
|
|
1007
|
+
lineEnd = source.indexOf("\n", lineEnd + 1);
|
|
1008
|
+
}
|
|
1009
|
+
return length;
|
|
1010
|
+
};
|
|
1011
|
+
ShaderInstructionEncoder._findInlineWhitespace = function _findInlineWhitespace(source) {
|
|
1012
|
+
var index = 0;
|
|
1013
|
+
while(index < source.length){
|
|
1014
|
+
var charCode = source.charCodeAt(index);
|
|
1015
|
+
if (charCode === 32 /* space */ || charCode === 9 /* tab */ ) break;
|
|
1016
|
+
index++;
|
|
1017
|
+
}
|
|
1018
|
+
return index;
|
|
1019
|
+
};
|
|
1020
|
+
ShaderInstructionEncoder._pushText = function _pushText(instructions, source, from, to, owners) {
|
|
1021
|
+
if (from >= to) return;
|
|
1022
|
+
var last = instructions.length > 0 ? instructions[instructions.length - 1] : null;
|
|
1023
|
+
var directive = owners === undefined ? ShaderPreprocessorDirective.Text : ShaderPreprocessorDirective.OwnedText;
|
|
1024
|
+
if (last && last[0] === directive && (owners === undefined || last.length === owners.length + 2 && owners.every(function(owner, index) {
|
|
1025
|
+
return last[index + 2] === owner;
|
|
1026
|
+
}))) {
|
|
1027
|
+
last[1] += source.substring(from, to);
|
|
1028
|
+
} else {
|
|
1029
|
+
instructions.push(owners === undefined ? [
|
|
1030
|
+
directive,
|
|
1031
|
+
source.substring(from, to)
|
|
1032
|
+
] : [].concat([
|
|
1033
|
+
directive,
|
|
1034
|
+
source.substring(from, to)
|
|
1035
|
+
], owners));
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
/**
|
|
1039
|
+
* Backfill jump offset of an IF/ELIF instruction.
|
|
1040
|
+
* When onlyPlaceholder is true, only backfill if the current value is still -1
|
|
1041
|
+
*/ ShaderInstructionEncoder._backfillJump = function _backfillJump(inst, target, onlyPlaceholder) {
|
|
1042
|
+
if (onlyPlaceholder === void 0) onlyPlaceholder = false;
|
|
1043
|
+
var directive = inst[0];
|
|
1044
|
+
if (directive === ShaderPreprocessorDirective.IfDef || directive === ShaderPreprocessorDirective.IfNdef) {
|
|
1045
|
+
if (!onlyPlaceholder || inst[2] === -1) inst[2] = target;
|
|
1046
|
+
} else if (directive === ShaderPreprocessorDirective.IfCmp) {
|
|
1047
|
+
if (!onlyPlaceholder || inst[4] === -1) inst[4] = target;
|
|
1048
|
+
} else if (directive === ShaderPreprocessorDirective.IfExpr) {
|
|
1049
|
+
if (!onlyPlaceholder || inst[2] === -1) inst[2] = target;
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1052
|
+
ShaderInstructionEncoder._stripLineComment = function _stripLineComment(s) {
|
|
1053
|
+
var idx = s.indexOf("//");
|
|
1054
|
+
return idx >= 0 ? s.substring(0, idx).trimEnd() : s;
|
|
1055
|
+
};
|
|
1056
|
+
return ShaderInstructionEncoder;
|
|
1057
|
+
}();
|
|
1058
|
+
ShaderInstructionEncoder._DIRECTIVE_RE = /^[ \t]*#[ \t]*(if|ifdef|ifndef|elif|else|endif|define|undef)\b(.*)/;
|
|
1059
|
+
ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* @internal
|
|
1063
|
+
*/ var GLESVisitor = /*#__PURE__*/ function(CodeGenVisitor) {
|
|
1064
|
+
_inherits(GLESVisitor, CodeGenVisitor);
|
|
1065
|
+
function GLESVisitor() {
|
|
1066
|
+
var _this;
|
|
1067
|
+
_this = CodeGenVisitor.apply(this, arguments) || this, _this._globalCodeArray = [], _this._forwardFunctionDeclarations = new Map(), _this._forwardStructIndices = new Map(), _this._structCodeSegments = new Map(), _this._forwardVariableIndices = new Map(), _this._variableCodeSegments = new Map(), _this._declarationOwners = new Map(), _this._deferredPrototypes = new Map(), _this._declarationReferences = new Map(), _this._outerMacroDeclarations = [];
|
|
1068
|
+
return _this;
|
|
1069
|
+
}
|
|
1070
|
+
var _proto = GLESVisitor.prototype;
|
|
1071
|
+
/**
|
|
1072
|
+
* Clears pass-local output retained by the pooled visitor.
|
|
1073
|
+
*/ _proto.reset = function reset() {
|
|
1074
|
+
var _this = this, globalCodeArray = _this._globalCodeArray;
|
|
1075
|
+
globalCodeArray.length = 0;
|
|
1076
|
+
this._forwardFunctionDeclarations.clear();
|
|
1077
|
+
this._forwardStructIndices.clear();
|
|
1078
|
+
this._structCodeSegments.clear();
|
|
1079
|
+
this._forwardVariableIndices.clear();
|
|
1080
|
+
this._variableCodeSegments.clear();
|
|
1081
|
+
this._deferredPrototypes.clear();
|
|
1082
|
+
this._declarationReferences.clear();
|
|
1083
|
+
this._currentDeclaration = undefined;
|
|
1084
|
+
};
|
|
1085
|
+
/**
|
|
1086
|
+
* Releases references retained by an idle visitor when its pool is collected.
|
|
1087
|
+
* @internal
|
|
1088
|
+
*/ _proto.dispose = function dispose() {
|
|
1089
|
+
this.context.reset();
|
|
1090
|
+
this.reset();
|
|
1091
|
+
};
|
|
1092
|
+
/**
|
|
1093
|
+
* Emits target-specific declarations that precede generated global code.
|
|
1094
|
+
* @param data - Parser-owned shader facts.
|
|
1095
|
+
* @param out - Destination code segments.
|
|
1096
|
+
*/ _proto.getOtherGlobal = function getOtherGlobal(data, out) {
|
|
1097
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(data.globalPrecisions), _step; !(_step = _iterator()).done;){
|
|
1098
|
+
var precision = _step.value;
|
|
1099
|
+
out.push({
|
|
1100
|
+
text: precision.codeGen(this),
|
|
1101
|
+
index: precision.location.start.index
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
};
|
|
1105
|
+
/**
|
|
1106
|
+
* Generates vertex and fragment source from neutral parser facts.
|
|
1107
|
+
* @param ir - Request-owned neutral shader IR.
|
|
1108
|
+
* @param coreInfo - Entry and stage-interface facts derived from the same IR.
|
|
1109
|
+
* @returns Generated vertex and fragment source.
|
|
1110
|
+
*/ _proto.generate = function generate(ir, coreInfo) {
|
|
1111
|
+
var _this = this;
|
|
1112
|
+
var _context_attributeStructs, _context_attributeList, _context_varyingStructs, _context_varyingList, _context_mrtStructs, _context_mrtList;
|
|
1113
|
+
this.context.reset();
|
|
1114
|
+
this.reset();
|
|
1115
|
+
var node = ir.program;
|
|
1116
|
+
var shaderData = node.shaderData;
|
|
1117
|
+
var context = this.context;
|
|
1118
|
+
context._passSymbolTable = shaderData.symbolTable;
|
|
1119
|
+
var outerGlobalMacroDeclarations = coreInfo.outerGlobalMacroDeclarations;
|
|
1120
|
+
var io = coreInfo.io;
|
|
1121
|
+
(_context_attributeStructs = context.attributeStructs).push.apply(_context_attributeStructs, [].concat(io.attributeStructs));
|
|
1122
|
+
(_context_attributeList = context.attributeList).push.apply(_context_attributeList, [].concat(io.attributeList));
|
|
1123
|
+
(_context_varyingStructs = context.varyingStructs).push.apply(_context_varyingStructs, [].concat(io.varyingStructs));
|
|
1124
|
+
(_context_varyingList = context.varyingList).push.apply(_context_varyingList, [].concat(io.varyingList));
|
|
1125
|
+
(_context_mrtStructs = context.mrtStructs).push.apply(_context_mrtStructs, [].concat(io.mrtStructs));
|
|
1126
|
+
(_context_mrtList = context.mrtList).push.apply(_context_mrtList, [].concat(io.mrtList));
|
|
1127
|
+
context.registerStructTypes(ShaderStructRole.Attribute, io.attributeStructs);
|
|
1128
|
+
context.registerStructTypes(ShaderStructRole.Varying, io.varyingStructs);
|
|
1129
|
+
context.registerStructTypes(ShaderStructRole.Mrt, io.mrtStructs);
|
|
1130
|
+
io.structVariableRoles.forEach(function(role, variable) {
|
|
1131
|
+
return context.registerStructVar(variable, role);
|
|
1132
|
+
});
|
|
1133
|
+
io.vertexStructVariableRoles.forEach(function(role, variable) {
|
|
1134
|
+
context.registerStructVar(variable, role, EShaderStage.VERTEX);
|
|
1135
|
+
});
|
|
1136
|
+
io.fragmentStructVariableRoles.forEach(function(role, variable) {
|
|
1137
|
+
context.registerStructVar(variable, role, EShaderStage.FRAGMENT);
|
|
1138
|
+
});
|
|
1139
|
+
this._sourceIR = ir;
|
|
1140
|
+
this._outerMacroDeclarations = outerGlobalMacroDeclarations;
|
|
1141
|
+
try {
|
|
1142
|
+
coreInfo.deferredDeclarationOwnership.forEach(function(owner, symbol) {
|
|
1143
|
+
return _this._declarationOwners.set(symbol.astNode, owner);
|
|
1144
|
+
});
|
|
1145
|
+
if (this._declarationOwners.size) {
|
|
1146
|
+
var nextId = 0;
|
|
1147
|
+
var nextGroup = 0;
|
|
1148
|
+
this._declarationOwners.forEach(function(owner) {
|
|
1149
|
+
nextId = Math.max(nextId, owner.id);
|
|
1150
|
+
nextGroup = Math.max(nextGroup, owner.group);
|
|
1151
|
+
});
|
|
1152
|
+
// Reachability follows the selected declaration, including dependencies without an override.
|
|
1153
|
+
shaderData.symbolTable.forEach(function(symbol) {
|
|
1154
|
+
if (symbol.astNode && !_this._declarationOwners.has(symbol.astNode)) {
|
|
1155
|
+
_this._declarationOwners.set(symbol.astNode, {
|
|
1156
|
+
id: ++nextId,
|
|
1157
|
+
group: ++nextGroup,
|
|
1158
|
+
sourceScope: symbol.sourceScope
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
});
|
|
1162
|
+
context.onReferenceGlobal = function(symbols) {
|
|
1163
|
+
var _this_currentDeclarationOwner;
|
|
1164
|
+
var _this_currentDeclarationOwner_id;
|
|
1165
|
+
var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner = _this.currentDeclarationOwner) == null ? void 0 : _this_currentDeclarationOwner.id) != null ? _this_currentDeclarationOwner_id : 0;
|
|
1166
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(symbols), _step; !(_step = _iterator()).done;){
|
|
1167
|
+
var symbol = _step.value;
|
|
1168
|
+
_this._referenceDeclaration(from, symbol.astNode);
|
|
1169
|
+
}
|
|
1170
|
+
};
|
|
1171
|
+
var propDeclarations = new Map();
|
|
1172
|
+
for(var _iterator = _create_for_of_iterator_helper_loose([].concat(io.attributeStructs, io.varyingStructs, io.mrtStructs)), _step; !(_step = _iterator()).done;){
|
|
1173
|
+
var struct = _step.value;
|
|
1174
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(struct.propList), _step1; !(_step1 = _iterator1()).done;){
|
|
1175
|
+
var prop = _step1.value;
|
|
1176
|
+
propDeclarations.set(prop, struct);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
context.onReferenceStructProps = function(props) {
|
|
1180
|
+
var _this_currentDeclarationOwner;
|
|
1181
|
+
var _this_currentDeclarationOwner_id;
|
|
1182
|
+
var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner = _this.currentDeclarationOwner) == null ? void 0 : _this_currentDeclarationOwner.id) != null ? _this_currentDeclarationOwner_id : 0;
|
|
1183
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(props), _step; !(_step = _iterator()).done;){
|
|
1184
|
+
var prop = _step.value;
|
|
1185
|
+
_this._referenceDeclaration(from, propDeclarations.get(prop));
|
|
1186
|
+
}
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
if (coreInfo.unsupportedDeferredDeclarations.length) {
|
|
1190
|
+
throw mapExpandedShaderError(new GSError(GSErrorName.CompilationError, "Deferred inheritance requires exact signatures and cannot resolve a known partial-coverage conflict.", coreInfo.unsupportedDeferredDeclarations[0].astNode.location, ir.source, undefined, "UnsupportedDeferredDeclaration"), ir.source, ir.sourceMap);
|
|
1191
|
+
}
|
|
1192
|
+
return {
|
|
1193
|
+
vertex: this._vertexMain(coreInfo.vertexEntry, shaderData, outerGlobalMacroDeclarations),
|
|
1194
|
+
fragment: this._fragmentMain(coreInfo.fragmentEntry, shaderData, outerGlobalMacroDeclarations)
|
|
1195
|
+
};
|
|
1196
|
+
} finally{
|
|
1197
|
+
this._sourceIR = undefined;
|
|
1198
|
+
this._outerMacroDeclarations = [];
|
|
1199
|
+
this._declarationOwners.clear();
|
|
1200
|
+
context.onReferenceGlobal = undefined;
|
|
1201
|
+
context.onReferenceStructProps = undefined;
|
|
1202
|
+
}
|
|
1203
|
+
};
|
|
1204
|
+
_proto._vertexMain = function _vertexMain(entryInfo, data, outerGlobalMacroDeclarations) {
|
|
1205
|
+
var context = this.context;
|
|
1206
|
+
context.stage = EShaderStage.VERTEX;
|
|
1207
|
+
context.stageEntry = entryInfo.name;
|
|
1208
|
+
// Attribute/varying structs were collected in ShaderCoreInfo
|
|
1209
|
+
// Pre-walk global `#define` values so referenced struct properties emit `attribute`/`varying` declarations.
|
|
1210
|
+
this._preRegisterGlobalMacroRefs(outerGlobalMacroDeclarations);
|
|
1211
|
+
var globalCodeArray = this._globalCodeArray;
|
|
1212
|
+
context.referenceGlobal(entryInfo.name, ESymbolType.FN);
|
|
1213
|
+
this._getGlobalSymbol(globalCodeArray);
|
|
1214
|
+
this._getCustomStruct(context.attributeStructs, globalCodeArray);
|
|
1215
|
+
this._getCustomStruct(context.varyingStructs, globalCodeArray);
|
|
1216
|
+
this._getGlobalMacroDeclarations(outerGlobalMacroDeclarations, globalCodeArray);
|
|
1217
|
+
this.getOtherGlobal(data, globalCodeArray);
|
|
1218
|
+
this._emitDeclarationReferences(globalCodeArray);
|
|
1219
|
+
var globalCode = globalCodeArray.sort(function(a, b) {
|
|
1220
|
+
return a.index - b.index;
|
|
1221
|
+
}).map(function(item) {
|
|
1222
|
+
return item.text;
|
|
1223
|
+
}).join("\n");
|
|
1224
|
+
context.reset(false);
|
|
1225
|
+
this.reset();
|
|
1226
|
+
return globalCode;
|
|
1227
|
+
};
|
|
1228
|
+
_proto._fragmentMain = function _fragmentMain(entryInfo, data, outerGlobalMacroStatements) {
|
|
1229
|
+
var _this = this;
|
|
1230
|
+
var context = this.context;
|
|
1231
|
+
context.stage = EShaderStage.FRAGMENT;
|
|
1232
|
+
context.stageEntry = entryInfo.name;
|
|
1233
|
+
this.prepareFragment(entryInfo, outerGlobalMacroStatements);
|
|
1234
|
+
// Every value-return must preserve early-exit control flow after entry return values are
|
|
1235
|
+
// lowered into fragment outputs.
|
|
1236
|
+
entryInfo.functions.forEach(function(fnSymbol) {
|
|
1237
|
+
var returnType = fnSymbol.astNode.protoType.returnType;
|
|
1238
|
+
var mode = returnType.type === Keyword.VEC4 ? "color" : returnType.typeSpecifier.structDeclarations.some(function(struct) {
|
|
1239
|
+
return context.hasStructRole(struct, ShaderStructRole.Mrt);
|
|
1240
|
+
}) ? "mrt" : undefined;
|
|
1241
|
+
if (mode) {
|
|
1242
|
+
var statements = fnSymbol.astNode.statements;
|
|
1243
|
+
_this._registerFragmentReturns(statements, mode, ParserUtils.lastStatement(statements));
|
|
1244
|
+
}
|
|
1245
|
+
});
|
|
1246
|
+
// Struct-variable identities are already populated from ShaderCoreInfo; just pre-walk macro
|
|
1247
|
+
// refs so struct codegen sees the references.
|
|
1248
|
+
this._preRegisterGlobalMacroRefs(outerGlobalMacroStatements);
|
|
1249
|
+
var globalCodeArray = this._globalCodeArray;
|
|
1250
|
+
context.referenceGlobal(entryInfo.name, ESymbolType.FN);
|
|
1251
|
+
this._getGlobalSymbol(globalCodeArray);
|
|
1252
|
+
this._getCustomStruct(context.varyingStructs, globalCodeArray);
|
|
1253
|
+
this._getCustomStruct(context.mrtStructs, globalCodeArray);
|
|
1254
|
+
this._getGlobalMacroDeclarations(outerGlobalMacroStatements, globalCodeArray);
|
|
1255
|
+
this.getOtherGlobal(data, globalCodeArray);
|
|
1256
|
+
this._emitDeclarationReferences(globalCodeArray);
|
|
1257
|
+
var globalCode = globalCodeArray.sort(function(a, b) {
|
|
1258
|
+
return a.index - b.index;
|
|
1259
|
+
}).map(function(item) {
|
|
1260
|
+
return item.text;
|
|
1261
|
+
}).join("\n");
|
|
1262
|
+
context.reset();
|
|
1263
|
+
this.reset();
|
|
1264
|
+
return globalCode;
|
|
1265
|
+
};
|
|
1266
|
+
_proto.prepareFragment = function prepareFragment(entryInfo, outerGlobalMacroStatements) {
|
|
1267
|
+
};
|
|
1268
|
+
/**
|
|
1269
|
+
* Pre-walk `#define` values in global macro declarations and register any
|
|
1270
|
+
* `structVar.prop` member accesses as referenced struct props. This must run before
|
|
1271
|
+
* struct codegen emits the declaration lists (`attribute …`, `varying …`, `MRT …`),
|
|
1272
|
+
* otherwise properties used only from macros would be missing from the output.
|
|
1273
|
+
*/ _proto._preRegisterGlobalMacroRefs = function _preRegisterGlobalMacroRefs(macros) {
|
|
1274
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(macros), _step; !(_step = _iterator()).done;){
|
|
1275
|
+
var macro = _step.value;
|
|
1276
|
+
this._walkMacroDefineTokens(macro.children);
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
_proto._walkMacroDefineTokens = function _walkMacroDefineTokens(children) {
|
|
1280
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(children), _step; !(_step = _iterator()).done;){
|
|
1281
|
+
var child = _step.value;
|
|
1282
|
+
if (_instanceof(child, ASTNode.MacroDefine)) {
|
|
1283
|
+
// Codegen the value once so the enclosed `visitPostfixExpression` calls
|
|
1284
|
+
// register their struct-prop references. The returned string is discarded
|
|
1285
|
+
// — the real emit happens later in `_getGlobalMacroDeclarations`.
|
|
1286
|
+
if (child.valueExpression) child.valueExpression.codeGen(this);
|
|
1287
|
+
} else if (_instanceof(child, TreeNode)) {
|
|
1288
|
+
var previous = this._currentDeclaration;
|
|
1289
|
+
if (_instanceof(child, ASTNode.FunctionDefinition)) this._currentDeclaration = child;
|
|
1290
|
+
this._walkMacroDefineTokens(child.children);
|
|
1291
|
+
this._currentDeclaration = previous;
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
_proto._registerFragmentReturns = function _registerFragmentReturns(node, mode, terminal) {
|
|
1296
|
+
if (_instanceof(node, ASTNode.JumpStatement) && node.children.length === 3) {
|
|
1297
|
+
this.context.registerFragmentReturn(node, mode);
|
|
1298
|
+
if (node === terminal) this.context.registerTerminalInterfaceReturn(node);
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1301
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(node.children), _step; !(_step = _iterator()).done;){
|
|
1302
|
+
var child = _step.value;
|
|
1303
|
+
if (_instanceof(child, TreeNode)) this._registerFragmentReturns(child, mode, terminal);
|
|
1304
|
+
}
|
|
1305
|
+
};
|
|
1306
|
+
_proto._getGlobalSymbol = function _getGlobalSymbol(out) {
|
|
1307
|
+
var context = this.context;
|
|
1308
|
+
// Set iteration includes dependencies discovered while generating earlier declarations.
|
|
1309
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(context._referencedGlobalSymbols), _step; !(_step = _iterator()).done;){
|
|
1310
|
+
var sm = _step.value;
|
|
1311
|
+
this._currentDeclaration = sm.astNode;
|
|
1312
|
+
var codeGenResult = sm.astNode.codeGen(this);
|
|
1313
|
+
this._currentDeclaration = undefined;
|
|
1314
|
+
if (!codeGenResult) continue;
|
|
1315
|
+
var text = codeGenResult + (sm.type === ESymbolType.VAR ? ";" : "");
|
|
1316
|
+
if (!sm.isInMacroBranch) {
|
|
1317
|
+
var segment = {
|
|
1318
|
+
text: this._declaration(text, sm.astNode),
|
|
1319
|
+
index: sm.astNode.location.start.index
|
|
1320
|
+
};
|
|
1321
|
+
out.push(segment);
|
|
1322
|
+
if (_instanceof(sm.astNode, ASTNode.StructSpecifier)) this._structCodeSegments.set(sm.astNode, segment);
|
|
1323
|
+
if (_instanceof(sm.astNode, ASTNode.VariableDeclaration)) this._variableCodeSegments.set(sm.astNode, segment);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
this._getForwardDeclarations(out);
|
|
1327
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(this._deferredPrototypes.values()), _step1; !(_step1 = _iterator1()).done;){
|
|
1328
|
+
var segment1 = _step1.value;
|
|
1329
|
+
out.push(segment1);
|
|
1330
|
+
}
|
|
1331
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(this._forwardFunctionDeclarations), _step2; !(_step2 = _iterator2()).done;){
|
|
1332
|
+
var _step_value = _step2.value, definition = _step_value[0], text1 = _step_value[1];
|
|
1333
|
+
if (!definition.isInMacroBranch) out.push({
|
|
1334
|
+
text: text1,
|
|
1335
|
+
index: definition.location.start.index
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
_proto.referenceFunction = function referenceFunction(symbol, referenceIndex, branch) {
|
|
1340
|
+
var _this = this;
|
|
1341
|
+
CodeGenVisitor.prototype.referenceFunction.call(this, symbol, referenceIndex, branch);
|
|
1342
|
+
var definition = symbol.astNode;
|
|
1343
|
+
var declarations = this._forwardFunctionDeclarations;
|
|
1344
|
+
if (symbol.ident === this.context.stageEntry) return;
|
|
1345
|
+
var candidates = this.context._referencedGlobals[symbol.ident].filter(function(candidate) {
|
|
1346
|
+
return _instanceof(candidate, FnSymbol) && candidate.equal(symbol);
|
|
1347
|
+
});
|
|
1348
|
+
var owner = this._declarationOwners.get(definition);
|
|
1349
|
+
if (owner) {
|
|
1350
|
+
var _this1, _loop = function() {
|
|
1351
|
+
var candidate = _step.value;
|
|
1352
|
+
var replacement = candidate.astNode;
|
|
1353
|
+
var nextOwner = _this1._declarationOwners.get(replacement);
|
|
1354
|
+
if (!nextOwner || nextOwner.group !== owner.group || nextOwner.sourceScope <= owner.sourceScope || replacement.location.start.index <= referenceIndex) return "continue";
|
|
1355
|
+
var prototype = replacement.protoType;
|
|
1356
|
+
var anchor = definition.location.start.index;
|
|
1357
|
+
var previous = _this1._deferredPrototypes.get(replacement);
|
|
1358
|
+
if (previous && previous.index <= anchor) return "continue";
|
|
1359
|
+
if (!_this1._isContextIndependent(prototype) || _this1._hasDeclarationContextBarrier(anchor, prototype.location.start.index, false)) {
|
|
1360
|
+
_this1._unsupportedForwardDeclaration(prototype);
|
|
1361
|
+
}
|
|
1362
|
+
var outer = _this1._outerMacroDeclarations.find(function(macro) {
|
|
1363
|
+
return macro.location.start.index <= anchor && macro.location.end.index >= definition.location.end.index;
|
|
1364
|
+
});
|
|
1365
|
+
var _outer_location_start_index;
|
|
1366
|
+
var typeAnchor = (_outer_location_start_index = outer == null ? void 0 : outer.location.start.index) != null ? _outer_location_start_index : anchor;
|
|
1367
|
+
_this1._prepareForwardTypes(prototype.returnType.typeSpecifier.structDeclarations, anchor, typeAnchor);
|
|
1368
|
+
var _prototype_parameterList;
|
|
1369
|
+
for(var _iterator = _create_for_of_iterator_helper_loose((_prototype_parameterList = prototype.parameterList) != null ? _prototype_parameterList : []), _step1; !(_step1 = _iterator()).done;){
|
|
1370
|
+
var parameter = _step1.value;
|
|
1371
|
+
var _parameter_typeInfo;
|
|
1372
|
+
var _parameter_typeInfo_structDeclarations;
|
|
1373
|
+
_this1._prepareForwardTypes((_parameter_typeInfo_structDeclarations = (_parameter_typeInfo = parameter.typeInfo) == null ? void 0 : _parameter_typeInfo.structDeclarations) != null ? _parameter_typeInfo_structDeclarations : [], anchor, typeAnchor);
|
|
1374
|
+
}
|
|
1375
|
+
// Selection is determined at the later definition, so the prototype must not replay its guard here.
|
|
1376
|
+
_this1._deferredPrototypes.set(replacement, {
|
|
1377
|
+
text: _this1._declaration("" + prototype.codeGen(_this1) + ";", replacement, false),
|
|
1378
|
+
index: typeAnchor
|
|
1379
|
+
});
|
|
1380
|
+
};
|
|
1381
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(candidates), _step; !(_step = _iterator()).done;)_this1 = this, _loop();
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1384
|
+
if (candidates.some(function(candidate) {
|
|
1385
|
+
return candidate.astNode === definition;
|
|
1386
|
+
})) return;
|
|
1387
|
+
var compatible = candidates.filter(function(candidate) {
|
|
1388
|
+
return _this._canBranchesOverlap(candidate.branchSignature, branch);
|
|
1389
|
+
});
|
|
1390
|
+
var preceding = compatible.filter(function(candidate) {
|
|
1391
|
+
return candidate.astNode.location.start.index < referenceIndex;
|
|
1392
|
+
});
|
|
1393
|
+
if (canInheritanceBranchesCover(preceding.map(function(candidate) {
|
|
1394
|
+
return candidate.branchSignature;
|
|
1395
|
+
}), branch)) return;
|
|
1396
|
+
var replacement = compatible.find(function(candidate) {
|
|
1397
|
+
return candidate.astNode.location.start.index > referenceIndex;
|
|
1398
|
+
});
|
|
1399
|
+
if (replacement) {
|
|
1400
|
+
// An inherited helper can call a declaration whose overriding body occurs later. Keep the
|
|
1401
|
+
// original declaration's macro/type context and emit only the final backend signature there.
|
|
1402
|
+
var prototype = replacement.astNode.protoType;
|
|
1403
|
+
var anchor = definition.location.start.index;
|
|
1404
|
+
var text = "" + prototype.codeGen(this) + ";";
|
|
1405
|
+
var signature = this._getForwardSignature(prototype);
|
|
1406
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(candidates), _step1; !(_step1 = _iterator1()).done;){
|
|
1407
|
+
var candidate = _step1.value;
|
|
1408
|
+
if (this._canBranchesOverlap(candidate.branchSignature, symbol.branchSignature) && this._getForwardSignature(candidate.astNode.protoType) !== signature) {
|
|
1409
|
+
this._unsupportedForwardDeclaration(candidate.astNode.protoType);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
if (declarations.has(definition)) return;
|
|
1413
|
+
if (!this._isContextIndependent(prototype) || this._hasDeclarationContextBarrier(anchor, prototype.location.start.index, false)) {
|
|
1414
|
+
this._unsupportedForwardDeclaration(prototype);
|
|
1415
|
+
}
|
|
1416
|
+
var outerMacro = this._outerMacroDeclarations.find(function(macro) {
|
|
1417
|
+
return macro.location.start.index <= anchor && macro.location.end.index >= definition.location.end.index;
|
|
1418
|
+
});
|
|
1419
|
+
var _outerMacro_location_start_index;
|
|
1420
|
+
var typeAnchor = (_outerMacro_location_start_index = outerMacro == null ? void 0 : outerMacro.location.start.index) != null ? _outerMacro_location_start_index : anchor;
|
|
1421
|
+
this._prepareForwardTypes(prototype.returnType.typeSpecifier.structDeclarations, anchor, typeAnchor);
|
|
1422
|
+
var _prototype_parameterList;
|
|
1423
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose((_prototype_parameterList = prototype.parameterList) != null ? _prototype_parameterList : []), _step2; !(_step2 = _iterator2()).done;){
|
|
1424
|
+
var parameter = _step2.value;
|
|
1425
|
+
var _parameter_typeInfo;
|
|
1426
|
+
if (_instanceof(parameter.astNode, ASTNode.ParameterDeclaration) && parameter.astNode.symbol && this.context.getStructVarRole([
|
|
1427
|
+
parameter.astNode.symbol
|
|
1428
|
+
])) {
|
|
1429
|
+
continue;
|
|
1430
|
+
}
|
|
1431
|
+
var _parameter_typeInfo_structDeclarations;
|
|
1432
|
+
this._prepareForwardTypes((_parameter_typeInfo_structDeclarations = (_parameter_typeInfo = parameter.typeInfo) == null ? void 0 : _parameter_typeInfo.structDeclarations) != null ? _parameter_typeInfo_structDeclarations : [], anchor, typeAnchor);
|
|
1433
|
+
}
|
|
1434
|
+
declarations.set(definition, text);
|
|
1435
|
+
}
|
|
1436
|
+
};
|
|
1437
|
+
_proto._getForwardSignature = function _getForwardSignature(prototype) {
|
|
1438
|
+
var _this, _loop = function() {
|
|
1439
|
+
var parameter = _step.value;
|
|
1440
|
+
var declaration = parameter.astNode;
|
|
1441
|
+
if (_instanceof(declaration, ASTNode.ParameterDeclaration) && declaration.symbol && _this.context.getStructVarRole([
|
|
1442
|
+
declaration.symbol
|
|
1443
|
+
])) return "continue";
|
|
1444
|
+
var tokens = [];
|
|
1445
|
+
var visit = function(node) {
|
|
1446
|
+
if (_instanceof(node, BaseToken)) {
|
|
1447
|
+
if (node !== parameter.ident && node.type !== Keyword.IN) tokens.push(node.lexeme);
|
|
1448
|
+
} else {
|
|
1449
|
+
node.children.forEach(visit);
|
|
1450
|
+
}
|
|
1451
|
+
};
|
|
1452
|
+
visit(declaration);
|
|
1453
|
+
var text = tokens.join(" ");
|
|
1454
|
+
if (text !== "void") parameters.push(text);
|
|
1455
|
+
};
|
|
1456
|
+
var parameters = [];
|
|
1457
|
+
var _prototype_parameterList;
|
|
1458
|
+
for(var _iterator = _create_for_of_iterator_helper_loose((_prototype_parameterList = prototype.parameterList) != null ? _prototype_parameterList : []), _step; !(_step = _iterator()).done;)_this = this, _loop();
|
|
1459
|
+
return prototype.returnType.codeGen(this) + "(" + parameters.join(",") + ")";
|
|
1460
|
+
};
|
|
1461
|
+
_proto._canBranchesOverlap = function _canBranchesOverlap(left, right) {
|
|
1462
|
+
return getLexicalDeclarationCoexistence(left, right) !== "exclusive" && !canInheritanceBranchesCover([], [].concat(left, right));
|
|
1463
|
+
};
|
|
1464
|
+
_proto.visitVariableIdentifier = function visitVariableIdentifier(node) {
|
|
1465
|
+
var _this, _loop = function() {
|
|
1466
|
+
var _this1, _loop = function() {
|
|
1467
|
+
var candidate = _step1.value;
|
|
1468
|
+
if (candidate.astNode.location.start.index <= node.location.start.index) return "continue";
|
|
1469
|
+
if (owner) {
|
|
1470
|
+
var nextOwner = _this1._declarationOwners.get(candidate.astNode);
|
|
1471
|
+
if (!nextOwner || nextOwner.group !== owner.group || nextOwner.sourceScope <= owner.sourceScope) return "continue";
|
|
1472
|
+
}
|
|
1473
|
+
var declaration = candidate.astNode;
|
|
1474
|
+
if (!_instanceof(candidate, VarSymbol) || !candidate.isUniform || !_instanceof(declaration, ASTNode.VariableDeclaration)) {
|
|
1475
|
+
_this1._unsupportedForwardDeclaration(declaration);
|
|
1476
|
+
}
|
|
1477
|
+
var macro = _this1._outerMacroDeclarations.find(function(item) {
|
|
1478
|
+
return item.location.start.index <= declaration.location.start.index && item.location.end.index >= declaration.location.end.index;
|
|
1479
|
+
});
|
|
1480
|
+
var _macro_location_end_index;
|
|
1481
|
+
if (!_this1._isContextIndependent(declaration) || _this1._hasDeclarationContextBarrier(anchor, (_macro_location_end_index = macro == null ? void 0 : macro.location.end.index) != null ? _macro_location_end_index : declaration.location.end.index, true)) {
|
|
1482
|
+
_this1._unsupportedForwardDeclaration(declaration);
|
|
1483
|
+
}
|
|
1484
|
+
_this1._prepareForwardTypes(candidate.dataType.structDeclarations, anchor);
|
|
1485
|
+
var _this__forwardVariableIndices_get;
|
|
1486
|
+
_this1._forwardVariableIndices.set(declaration, Math.min((_this__forwardVariableIndices_get = _this1._forwardVariableIndices.get(declaration)) != null ? _this__forwardVariableIndices_get : Infinity, anchor));
|
|
1487
|
+
};
|
|
1488
|
+
var symbol = _step.value;
|
|
1489
|
+
var _this_context__referencedGlobals_symbol_ident;
|
|
1490
|
+
if (!_instanceof(symbol, VarSymbol) || !symbol.isUniform) return "continue";
|
|
1491
|
+
var candidates = (_this_context__referencedGlobals_symbol_ident = _this.context._referencedGlobals[symbol.ident]) == null ? void 0 : _this_context__referencedGlobals_symbol_ident.filter(function(candidate) {
|
|
1492
|
+
return _instanceof(candidate, VarSymbol);
|
|
1493
|
+
});
|
|
1494
|
+
var owner = _this._declarationOwners.get(symbol.astNode);
|
|
1495
|
+
if (!candidates || !owner && candidates.includes(symbol)) return "continue";
|
|
1496
|
+
var preceding = candidates.filter(function(candidate) {
|
|
1497
|
+
return candidate.astNode.location.start.index < node.location.start.index;
|
|
1498
|
+
});
|
|
1499
|
+
if (!owner && canInheritanceBranchesCover(preceding.map(function(candidate) {
|
|
1500
|
+
return candidate.branchSignature;
|
|
1501
|
+
}), node._branch)) return "continue";
|
|
1502
|
+
var oldMacro = _this._outerMacroDeclarations.find(function(macro) {
|
|
1503
|
+
return macro.location.start.index <= symbol.astNode.location.start.index && macro.location.end.index >= symbol.astNode.location.end.index;
|
|
1504
|
+
});
|
|
1505
|
+
var _oldMacro_location_start_index;
|
|
1506
|
+
var anchor = (_oldMacro_location_start_index = oldMacro == null ? void 0 : oldMacro.location.start.index) != null ? _oldMacro_location_start_index : symbol.astNode.location.start.index;
|
|
1507
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(candidates), _step1; !(_step1 = _iterator()).done;)_this1 = _this, _loop();
|
|
1508
|
+
};
|
|
1509
|
+
var code = CodeGenVisitor.prototype.visitVariableIdentifier.call(this, node);
|
|
1510
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(node.resolvedSymbols()), _step; !(_step = _iterator()).done;)_this = this, _loop();
|
|
1511
|
+
return code;
|
|
1512
|
+
};
|
|
1513
|
+
_proto._getForwardDeclarations = function _getForwardDeclarations(out) {
|
|
1514
|
+
var _this, _loop = function() {
|
|
1515
|
+
var _step_value = _step1.value, declaration = _step_value[0], index = _step_value[1];
|
|
1516
|
+
var owner = _this._declarationOwners.get(declaration);
|
|
1517
|
+
var macro = _this._outerMacroDeclarations.find(function(item) {
|
|
1518
|
+
return item.location.start.index <= declaration.location.start.index && item.location.end.index >= declaration.location.end.index;
|
|
1519
|
+
});
|
|
1520
|
+
if (!macro) {
|
|
1521
|
+
var previous = _instanceof(declaration, ASTNode.StructSpecifier) ? _this._structCodeSegments.get(declaration) : _this._variableCodeSegments.get(declaration);
|
|
1522
|
+
if (previous) {
|
|
1523
|
+
if (owner) previous.text = _this._declaration("", declaration);
|
|
1524
|
+
else out.splice(out.indexOf(previous), 1);
|
|
1525
|
+
}
|
|
1526
|
+
out.push({
|
|
1527
|
+
text: code(declaration),
|
|
1528
|
+
index: index
|
|
1529
|
+
});
|
|
1530
|
+
} else if (owner) {
|
|
1531
|
+
out.push({
|
|
1532
|
+
text: code(declaration),
|
|
1533
|
+
index: index
|
|
1534
|
+
});
|
|
1535
|
+
} else {
|
|
1536
|
+
var group = guarded.get(macro);
|
|
1537
|
+
if (!group) guarded.set(macro, group = {
|
|
1538
|
+
index: index,
|
|
1539
|
+
declarations: []
|
|
1540
|
+
});
|
|
1541
|
+
group.index = Math.min(group.index, index);
|
|
1542
|
+
group.declarations.push(declaration);
|
|
1543
|
+
}
|
|
1544
|
+
};
|
|
1545
|
+
var _this1 = this;
|
|
1546
|
+
var guarded = new Map();
|
|
1547
|
+
var declarations = Array.from(this._forwardStructIndices);
|
|
1548
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(this._forwardVariableIndices), _step; !(_step = _iterator()).done;){
|
|
1549
|
+
var entry = _step.value;
|
|
1550
|
+
declarations.push(entry);
|
|
1551
|
+
}
|
|
1552
|
+
var code = function(declaration) {
|
|
1553
|
+
return _this1._declaration(declaration.codeGen(_this1) + (_instanceof(declaration, ASTNode.VariableDeclaration) ? ";" : ""), declaration, false);
|
|
1554
|
+
};
|
|
1555
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(declarations), _step1; !(_step1 = _iterator1()).done;)_this = this, _loop();
|
|
1556
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(guarded), _step2; !(_step2 = _iterator2()).done;){
|
|
1557
|
+
var _step_value = _step2.value, macro = _step_value[0], group = _step_value[1];
|
|
1558
|
+
var segments = macro.macroExpressions.map(function(item) {
|
|
1559
|
+
return {
|
|
1560
|
+
text: _instanceof(item, BaseToken) ? item.lexeme : item.codeGen(_this1),
|
|
1561
|
+
index: item.location.start.index
|
|
1562
|
+
};
|
|
1563
|
+
});
|
|
1564
|
+
for(var _iterator3 = _create_for_of_iterator_helper_loose(group.declarations), _step3; !(_step3 = _iterator3()).done;){
|
|
1565
|
+
var declaration = _step3.value;
|
|
1566
|
+
segments.push({
|
|
1567
|
+
text: code(declaration),
|
|
1568
|
+
index: declaration.location.start.index
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
out.push({
|
|
1572
|
+
text: segments.sort(function(a, b) {
|
|
1573
|
+
return a.index - b.index;
|
|
1574
|
+
}).map(function(item) {
|
|
1575
|
+
return item.text;
|
|
1576
|
+
}).join("\n"),
|
|
1577
|
+
index: group.index
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
};
|
|
1581
|
+
_proto.visitTypeSpecifier = function visitTypeSpecifier(node) {
|
|
1582
|
+
var _this, _loop = function() {
|
|
1583
|
+
var type = _step.value;
|
|
1584
|
+
if (!type.ident || _this.context.getStructRole([
|
|
1585
|
+
type
|
|
1586
|
+
])) return "continue";
|
|
1587
|
+
// A function-local struct can shadow a global name without participating in inheritance.
|
|
1588
|
+
var parent = type.parent;
|
|
1589
|
+
while(parent && !_instanceof(parent, ASTNode.GlobalDeclaration) && !_instanceof(parent, ASTNode.FunctionDefinition)){
|
|
1590
|
+
parent = parent.parent;
|
|
1591
|
+
}
|
|
1592
|
+
if (_instanceof(parent, ASTNode.FunctionDefinition)) return "continue";
|
|
1593
|
+
_this.context.referenceGlobal(type.ident.lexeme, ESymbolType.STRUCT);
|
|
1594
|
+
var final = _this.context._referencedGlobals[type.ident.lexeme];
|
|
1595
|
+
var owner = _this._declarationOwners.get(type);
|
|
1596
|
+
if (!owner && final.some(function(symbol) {
|
|
1597
|
+
return symbol.astNode === type;
|
|
1598
|
+
})) return "continue";
|
|
1599
|
+
var oldMacro = _this._outerMacroDeclarations.find(function(item) {
|
|
1600
|
+
return item.location.start.index <= type.location.start.index && item.location.end.index >= type.location.end.index;
|
|
1601
|
+
});
|
|
1602
|
+
var _oldMacro_location_start_index;
|
|
1603
|
+
_this._prepareForwardTypes(final.filter(function(symbol) {
|
|
1604
|
+
if (!owner) return true;
|
|
1605
|
+
var nextOwner = _this1._declarationOwners.get(symbol.astNode);
|
|
1606
|
+
return (nextOwner == null ? void 0 : nextOwner.group) === owner.group && nextOwner.sourceScope > owner.sourceScope;
|
|
1607
|
+
}).map(function(symbol) {
|
|
1608
|
+
return symbol.astNode;
|
|
1609
|
+
}).filter(function(item) {
|
|
1610
|
+
return _instanceof(item, ASTNode.StructSpecifier);
|
|
1611
|
+
}), (_oldMacro_location_start_index = oldMacro == null ? void 0 : oldMacro.location.start.index) != null ? _oldMacro_location_start_index : type.location.start.index);
|
|
1612
|
+
};
|
|
1613
|
+
var _this1 = this;
|
|
1614
|
+
var call = _instanceof(node.parent, ASTNode.FunctionIdentifier) ? node.parent.parent : undefined;
|
|
1615
|
+
if (_instanceof(call, ASTNode.FunctionCallGeneric) && _instanceof(call.fnSymbol, FnSymbol)) {
|
|
1616
|
+
return CodeGenVisitor.prototype.visitTypeSpecifier.call(this, node);
|
|
1617
|
+
}
|
|
1618
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(node.structDependencies), _step; !(_step = _iterator()).done;)_this = this, _loop();
|
|
1619
|
+
return CodeGenVisitor.prototype.visitTypeSpecifier.call(this, node);
|
|
1620
|
+
};
|
|
1621
|
+
_proto._prepareForwardTypes = function _prepareForwardTypes(types, anchor, hoistAnchor) {
|
|
1622
|
+
var _this, _loop = function() {
|
|
1623
|
+
var type = _step.value;
|
|
1624
|
+
var _this__forwardStructIndices_get;
|
|
1625
|
+
if (((_this__forwardStructIndices_get = _this._forwardStructIndices.get(type)) != null ? _this__forwardStructIndices_get : Infinity) <= anchor) return "continue";
|
|
1626
|
+
if (type.ident) {
|
|
1627
|
+
_this.context.referenceGlobal(type.ident.lexeme, ESymbolType.STRUCT);
|
|
1628
|
+
var final = _this.context._referencedGlobals[type.ident.lexeme];
|
|
1629
|
+
if (!final.some(function(symbol) {
|
|
1630
|
+
return symbol.astNode === type;
|
|
1631
|
+
})) {
|
|
1632
|
+
_this._prepareForwardTypes(final.map(function(symbol) {
|
|
1633
|
+
return symbol.astNode;
|
|
1634
|
+
}).filter(function(item) {
|
|
1635
|
+
return _instanceof(item, ASTNode.StructSpecifier);
|
|
1636
|
+
}), anchor, hoistAnchor);
|
|
1637
|
+
return "continue";
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
var needsHoist = type.location.start.index > anchor;
|
|
1641
|
+
var macro = _this._outerMacroDeclarations.find(function(item) {
|
|
1642
|
+
return item.location.start.index <= type.location.start.index && item.location.end.index >= type.location.end.index;
|
|
1643
|
+
});
|
|
1644
|
+
var _macro_location_end_index;
|
|
1645
|
+
if (needsHoist && (!_this._isContextIndependent(type) || _this._hasDeclarationContextBarrier(hoistAnchor, (_macro_location_end_index = macro == null ? void 0 : macro.location.end.index) != null ? _macro_location_end_index : type.location.end.index, true))) {
|
|
1646
|
+
_this._unsupportedForwardDeclaration(type);
|
|
1647
|
+
}
|
|
1648
|
+
var dependencyAnchor = needsHoist ? hoistAnchor : type.location.start.index;
|
|
1649
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(type.propList), _step1; !(_step1 = _iterator()).done;){
|
|
1650
|
+
var property = _step1.value;
|
|
1651
|
+
_this._prepareForwardTypes(property.typeInfo.structDeclarations, dependencyAnchor);
|
|
1652
|
+
}
|
|
1653
|
+
if (needsHoist) _this._forwardStructIndices.set(type, hoistAnchor);
|
|
1654
|
+
};
|
|
1655
|
+
if (hoistAnchor === void 0) hoistAnchor = anchor;
|
|
1656
|
+
if (this.context.getStructRole(types)) return;
|
|
1657
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(types), _step; !(_step = _iterator()).done;)_this = this, _loop();
|
|
1658
|
+
};
|
|
1659
|
+
_proto._isContextIndependent = function _isContextIndependent(node) {
|
|
1660
|
+
var _this = this;
|
|
1661
|
+
if (_instanceof(node, ASTNode.VariableIdentifier) || _instanceof(node, ASTNode.MacroCallSymbol) || _instanceof(node, ASTNode.MacroCallFunction)) return false;
|
|
1662
|
+
if (_instanceof(node, ASTNode.TypeSpecifier) && node.isCustom && !node.structDeclarations.length) return false;
|
|
1663
|
+
return node.children.every(function(child) {
|
|
1664
|
+
return _instanceof(child, TreeNode) ? _this._isContextIndependent(child) : child.type < Keyword.MACRO_IF || child.type > Keyword.MACRO_DEFINE_PARAMS;
|
|
1665
|
+
});
|
|
1666
|
+
};
|
|
1667
|
+
_proto._hasDeclarationContextBarrier = function _hasDeclarationContextBarrier(start, end, includeMacros) {
|
|
1668
|
+
var visit = function(node, inFunction) {
|
|
1669
|
+
if (inFunction === void 0) inFunction = false;
|
|
1670
|
+
if (node.location.end.index <= start || node.location.start.index >= end) return false;
|
|
1671
|
+
if (_instanceof(node, ASTNode.PrecisionSpecifier) && !inFunction) return true;
|
|
1672
|
+
if (includeMacros && _instanceof(node, ASTNode.MacroDefine)) return true;
|
|
1673
|
+
inFunction || (inFunction = _instanceof(node, ASTNode.FunctionDefinition));
|
|
1674
|
+
return node.children.some(function(child) {
|
|
1675
|
+
return _instanceof(child, TreeNode) ? visit(child, inFunction) : includeMacros && child.location.start.index > start && child.location.start.index < end && (child.type === Keyword.MACRO_UNDEF || child.type === Keyword.MACRO_DEFINE_EXPRESSION);
|
|
1676
|
+
});
|
|
1677
|
+
};
|
|
1678
|
+
return visit(this._sourceIR.program);
|
|
1679
|
+
};
|
|
1680
|
+
_proto._unsupportedForwardDeclaration = function _unsupportedForwardDeclaration(node) {
|
|
1681
|
+
var ir = this._sourceIR;
|
|
1682
|
+
throw mapExpandedShaderError(new GSError(GSErrorName.CompilationError, "Inherited declarations require incompatible forward signatures or depend on a later macro or precision context.", node.location, ir.source, undefined, "UnsupportedForwardDeclaration"), ir.source, ir.sourceMap);
|
|
1683
|
+
};
|
|
1684
|
+
_proto._getCustomStruct = function _getCustomStruct(structNodes, out) {
|
|
1685
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(structNodes), _step; !(_step = _iterator()).done;){
|
|
1686
|
+
var node = _step.value;
|
|
1687
|
+
var text = node.codeGen(this);
|
|
1688
|
+
if (!node.isInMacroBranch) {
|
|
1689
|
+
out.push({
|
|
1690
|
+
text: this._declaration(text, node),
|
|
1691
|
+
index: node.location.start.index
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
};
|
|
1696
|
+
_proto._getGlobalMacroDeclarations = function _getGlobalMacroDeclarations(macros, out) {
|
|
1697
|
+
var _this = this;
|
|
1698
|
+
var context = this.context;
|
|
1699
|
+
var referencedGlobalMacroASTs = context._referencedGlobalMacroASTs;
|
|
1700
|
+
referencedGlobalMacroASTs.length = 0;
|
|
1701
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(context._referencedGlobalSymbols), _step; !(_step = _iterator()).done;){
|
|
1702
|
+
var symbol = _step.value;
|
|
1703
|
+
if (symbol.isInMacroBranch) referencedGlobalMacroASTs.push(symbol.astNode);
|
|
1704
|
+
}
|
|
1705
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(macros), _step1; !(_step1 = _iterator1()).done;){
|
|
1706
|
+
var macro = _step1.value;
|
|
1707
|
+
var text = void 0;
|
|
1708
|
+
var child = macro.children[0];
|
|
1709
|
+
if (_instanceof(child, ASTNode.GlobalMacroIfStatement)) {
|
|
1710
|
+
var _result;
|
|
1711
|
+
var result = [];
|
|
1712
|
+
(_result = result).push.apply(_result, [].concat(macro.macroExpressions.map(function(item) {
|
|
1713
|
+
return {
|
|
1714
|
+
text: _instanceof(item, BaseToken) ? item.lexeme : item.codeGen(_this),
|
|
1715
|
+
index: item.location.start.index
|
|
1716
|
+
};
|
|
1717
|
+
})));
|
|
1718
|
+
this._visitGlobalMacroIfStatement(child, result);
|
|
1719
|
+
text = result.sort(function(a, b) {
|
|
1720
|
+
return a.index - b.index;
|
|
1721
|
+
}).map(function(item) {
|
|
1722
|
+
return item.text;
|
|
1723
|
+
}).join("\n");
|
|
1724
|
+
} else if (_instanceof(child, BaseToken) && child.type === Keyword.MACRO_DEFINE_EXPRESSION) {
|
|
1725
|
+
// Legacy opaque `#define` — its lexeme is the complete directive text,
|
|
1726
|
+
// newlines included; emit verbatim.
|
|
1727
|
+
text = child.lexeme;
|
|
1728
|
+
} else {
|
|
1729
|
+
text = macro.codeGen(this);
|
|
1730
|
+
}
|
|
1731
|
+
out.push({
|
|
1732
|
+
text: text,
|
|
1733
|
+
index: macro.location.start.index
|
|
1734
|
+
});
|
|
1735
|
+
}
|
|
1736
|
+
};
|
|
1737
|
+
_proto._visitGlobalMacroIfStatement = function _visitGlobalMacroIfStatement(node, out) {
|
|
1738
|
+
var children = node.children;
|
|
1739
|
+
for(var i = 0; i < children.length; i++){
|
|
1740
|
+
var child = children[i];
|
|
1741
|
+
if (_instanceof(child, ASTNode.PrecisionSpecifier)) {
|
|
1742
|
+
out.push({
|
|
1743
|
+
text: child.codeGen(this),
|
|
1744
|
+
index: child.location.start.index
|
|
1745
|
+
});
|
|
1746
|
+
} else if (_instanceof(child, ASTNode.FunctionDefinition)) {
|
|
1747
|
+
var text = this.context._referencedGlobalMacroASTs.indexOf(child) !== -1 ? this.getCachedCode(child) : this._forwardFunctionDeclarations.get(child);
|
|
1748
|
+
if (text !== undefined) {
|
|
1749
|
+
out.push({
|
|
1750
|
+
text: this._declaration(text, child),
|
|
1751
|
+
index: child.location.start.index
|
|
1752
|
+
});
|
|
1753
|
+
}
|
|
1754
|
+
} else if (_instanceof(child, ASTNode.StructSpecifier)) {
|
|
1755
|
+
if (this._forwardStructIndices.has(child)) {
|
|
1756
|
+
var text1 = this._declaration("", child);
|
|
1757
|
+
if (text1) out.push({
|
|
1758
|
+
text: text1,
|
|
1759
|
+
index: child.location.start.index
|
|
1760
|
+
});
|
|
1761
|
+
continue;
|
|
1762
|
+
}
|
|
1763
|
+
var context = this.context;
|
|
1764
|
+
var stage = context.stage;
|
|
1765
|
+
if (context._referencedGlobalMacroASTs.indexOf(child) !== -1 || (stage === EShaderStage.VERTEX ? context.hasStructRole(child, ShaderStructRole.Attribute) || context.hasStructRole(child, ShaderStructRole.Varying) : context.hasStructRole(child, ShaderStructRole.Varying) || context.hasStructRole(child, ShaderStructRole.Mrt))) {
|
|
1766
|
+
var _this_getCachedCode;
|
|
1767
|
+
out.push({
|
|
1768
|
+
text: this._declaration((_this_getCachedCode = this.getCachedCode(child)) != null ? _this_getCachedCode : "", child),
|
|
1769
|
+
index: child.location.start.index
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
} else if (_instanceof(child, ASTNode.VariableDeclarationList)) {
|
|
1773
|
+
var variableDeclarations = child.variableDeclarations;
|
|
1774
|
+
for(var i1 = 0; i1 < variableDeclarations.length; i1++){
|
|
1775
|
+
var variableDeclaration = variableDeclarations[i1];
|
|
1776
|
+
if (this.context._referencedGlobalMacroASTs.indexOf(variableDeclaration) !== -1) {
|
|
1777
|
+
var _this_getCachedCode1;
|
|
1778
|
+
out.push({
|
|
1779
|
+
text: this._declaration(this._forwardVariableIndices.has(variableDeclaration) ? "" : "" + ((_this_getCachedCode1 = this.getCachedCode(variableDeclaration)) != null ? _this_getCachedCode1 : "") + ";", variableDeclaration),
|
|
1780
|
+
index: variableDeclaration.location.start.index
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
if (_instanceof(child, TreeNode)) {
|
|
1786
|
+
this._visitGlobalMacroIfStatement(child, out);
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
};
|
|
1790
|
+
_proto._referenceDeclaration = function _referenceDeclaration(from, node) {
|
|
1791
|
+
var owner = this._declarationOwners.get(node);
|
|
1792
|
+
if (!owner) return;
|
|
1793
|
+
var targets = this._declarationReferences.get(from);
|
|
1794
|
+
if (!targets) this._declarationReferences.set(from, targets = new Set());
|
|
1795
|
+
targets.add(owner.id);
|
|
1796
|
+
};
|
|
1797
|
+
_proto._emitDeclarationReferences = function _emitDeclarationReferences(out) {
|
|
1798
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(this._declarationReferences), _step; !(_step = _iterator()).done;){
|
|
1799
|
+
var _step_value = _step.value, from = _step_value[0], targets = _step_value[1];
|
|
1800
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(targets), _step1; !(_step1 = _iterator1()).done;){
|
|
1801
|
+
var to = _step1.value;
|
|
1802
|
+
out.push({
|
|
1803
|
+
text: ShaderInstructionEncoder.reference(from, to),
|
|
1804
|
+
index: -1
|
|
1805
|
+
});
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
};
|
|
1809
|
+
_proto._declaration = function _declaration(text, node, activate) {
|
|
1810
|
+
if (activate === void 0) activate = true;
|
|
1811
|
+
return ShaderInstructionEncoder.declaration(text, this._declarationOwners.get(node), activate);
|
|
1812
|
+
};
|
|
1813
|
+
_create_class(GLESVisitor, [
|
|
1814
|
+
{
|
|
1815
|
+
key: "currentDeclarationOwner",
|
|
1816
|
+
get: /** Ownership of the declaration currently generating dependencies. @internal */ function get() {
|
|
1817
|
+
return this._currentDeclaration && this._declarationOwners.get(this._currentDeclaration);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
]);
|
|
1821
|
+
return GLESVisitor;
|
|
1822
|
+
}(CodeGenVisitor);
|
|
1823
|
+
|
|
1824
|
+
var GLES100Visitor = /*#__PURE__*/ function(GLESVisitor) {
|
|
1825
|
+
_inherits(GLES100Visitor, GLESVisitor);
|
|
1826
|
+
function GLES100Visitor() {
|
|
1827
|
+
return GLESVisitor.apply(this, arguments) || this;
|
|
1828
|
+
}
|
|
1829
|
+
var _proto = GLES100Visitor.prototype;
|
|
1830
|
+
_proto.getAttributeProp = function getAttributeProp(prop) {
|
|
1831
|
+
return "attribute " + prop.typeInfo.typeLexeme + " " + prop.ident.lexeme + ";";
|
|
1832
|
+
};
|
|
1833
|
+
_proto.getVaryingProp = function getVaryingProp(prop) {
|
|
1834
|
+
return "varying " + prop.typeInfo.typeLexeme + " " + prop.ident.lexeme + ";";
|
|
1835
|
+
};
|
|
1836
|
+
_proto.getMRTProp = function getMRTProp() {
|
|
1837
|
+
return "";
|
|
1838
|
+
};
|
|
1839
|
+
_proto.visitPostfixExpression = function visitPostfixExpression(node) {
|
|
1840
|
+
var children = node.children;
|
|
1841
|
+
var postExpr = children[0];
|
|
1842
|
+
var context = this.context;
|
|
1843
|
+
var directRoot = _instanceof(postExpr, ASTNode.PostfixExpression) ? ParserUtils.unwrapBareIdentifier(postExpr, {
|
|
1844
|
+
allowParens: true
|
|
1845
|
+
}) : undefined;
|
|
1846
|
+
var _directRoot_resolvedValueSymbols;
|
|
1847
|
+
var directSymbols = (_directRoot_resolvedValueSymbols = directRoot == null ? void 0 : directRoot.resolvedValueSymbols()) != null ? _directRoot_resolvedValueSymbols : [];
|
|
1848
|
+
var unresolvedName = _instanceof(postExpr, ASTNode.PostfixExpression) ? ParserUtils.extractDirectIdentLexeme(postExpr) : null;
|
|
1849
|
+
var directRole = directRoot ? directSymbols.length ? context.getStructVarRole(directSymbols) : unresolvedName ? context.getUnresolvedStructVarRole(unresolvedName) : undefined : undefined;
|
|
1850
|
+
if (directRole === ShaderStructRole.Mrt) {
|
|
1851
|
+
var propReferenced = children[2];
|
|
1852
|
+
var prop = context.mrtList.find(function(item) {
|
|
1853
|
+
return item.ident.lexeme === propReferenced.lexeme;
|
|
1854
|
+
});
|
|
1855
|
+
// The parser already validated struct fields (UndeclaredStructMember); a miss here is an
|
|
1856
|
+
// already-errored shader, so emit nothing rather than re-report.
|
|
1857
|
+
if (!prop) return "";
|
|
1858
|
+
return "gl_FragData[" + prop.mrtIndex + "]";
|
|
1859
|
+
}
|
|
1860
|
+
return GLESVisitor.prototype.visitPostfixExpression.call(this, node);
|
|
1861
|
+
};
|
|
1862
|
+
_proto.visitJumpStatement = function visitJumpStatement(node) {
|
|
1863
|
+
var mode = this.context.getFragmentReturnMode(node);
|
|
1864
|
+
var terminal = this.context.isTerminalInterfaceReturn(node);
|
|
1865
|
+
if (mode === "mrt") return terminal ? "" : "return;";
|
|
1866
|
+
if (mode === "color") {
|
|
1867
|
+
var expression = node.children[1];
|
|
1868
|
+
var assignment = "gl_FragColor = " + expression.codeGen(this) + ";";
|
|
1869
|
+
return terminal ? assignment : "{ " + assignment + " return; }";
|
|
1870
|
+
}
|
|
1871
|
+
return GLESVisitor.prototype.visitJumpStatement.call(this, node);
|
|
1872
|
+
};
|
|
1873
|
+
return GLES100Visitor;
|
|
1874
|
+
}(GLESVisitor);
|
|
1875
|
+
|
|
1876
|
+
var V3_GL_FragColor = "GS_glFragColor";
|
|
1877
|
+
var V3_GL_FragData = "GS_glFragData";
|
|
1878
|
+
var GLES300Visitor = /*#__PURE__*/ function(GLESVisitor) {
|
|
1879
|
+
_inherits(GLES300Visitor, GLESVisitor);
|
|
1880
|
+
function GLES300Visitor() {
|
|
1881
|
+
var _this;
|
|
1882
|
+
_this = GLESVisitor.apply(this, arguments) || this, _this._outputDeclarations = new Map(), _this._fragDataArrayRequired = false, _this._fragDataIndices = new Map(), _this._scannedFragmentFunctions = new Set();
|
|
1883
|
+
return _this;
|
|
1884
|
+
}
|
|
1885
|
+
var _proto = GLES300Visitor.prototype;
|
|
1886
|
+
_proto.reset = function reset() {
|
|
1887
|
+
GLESVisitor.prototype.reset.call(this);
|
|
1888
|
+
this._outputDeclarations.clear();
|
|
1889
|
+
this._fragDataArrayRequired = false;
|
|
1890
|
+
this._fragDataIndices.clear();
|
|
1891
|
+
this._scannedFragmentFunctions.clear();
|
|
1892
|
+
};
|
|
1893
|
+
_proto.getOtherGlobal = function getOtherGlobal(data, out) {
|
|
1894
|
+
GLESVisitor.prototype.getOtherGlobal.call(this, data, out);
|
|
1895
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(this._outputDeclarations.values()), _step; !(_step = _iterator()).done;){
|
|
1896
|
+
var output = _step.value;
|
|
1897
|
+
out.push({
|
|
1898
|
+
text: output.unconditional ? output.text : ShaderInstructionEncoder.sharedDeclaration(output.text, Array.from(output.owners.values())),
|
|
1899
|
+
// A source macro block can start at zero and contain the first output use.
|
|
1900
|
+
index: -1
|
|
1901
|
+
});
|
|
1902
|
+
}
|
|
1903
|
+
};
|
|
1904
|
+
_proto.getAttributeProp = function getAttributeProp(prop) {
|
|
1905
|
+
return "in " + prop.typeInfo.typeLexeme + " " + prop.ident.lexeme + ";";
|
|
1906
|
+
};
|
|
1907
|
+
_proto.getVaryingProp = function getVaryingProp(prop) {
|
|
1908
|
+
var qualifier = this.context.stage === EShaderStage.FRAGMENT ? "in" : "out";
|
|
1909
|
+
return qualifier + " " + prop.typeInfo.typeLexeme + " " + prop.ident.lexeme + ";";
|
|
1910
|
+
};
|
|
1911
|
+
_proto.getMRTProp = function getMRTProp(prop) {
|
|
1912
|
+
return "layout(location = " + prop.mrtIndex + ") out vec4 " + prop.ident.lexeme + ";";
|
|
1913
|
+
};
|
|
1914
|
+
_proto.visitFunctionIdentifier = function visitFunctionIdentifier(node) {
|
|
1915
|
+
var children = node.children;
|
|
1916
|
+
var typeSpecifier = children[0];
|
|
1917
|
+
if (typeSpecifier.children.length !== 1 || typeSpecifier.structDependencies.length) {
|
|
1918
|
+
// Struct constructors still need the shared type-dependency visitor.
|
|
1919
|
+
return GLESVisitor.prototype.visitFunctionIdentifier.call(this, node);
|
|
1920
|
+
}
|
|
1921
|
+
var ident = node.lexeme;
|
|
1922
|
+
switch(node.ident){
|
|
1923
|
+
case "texture2D":
|
|
1924
|
+
case "textureCube":
|
|
1925
|
+
ident = "texture";
|
|
1926
|
+
break;
|
|
1927
|
+
case "texture2DProj":
|
|
1928
|
+
ident = "textureProj";
|
|
1929
|
+
break;
|
|
1930
|
+
case "texture2DLodEXT":
|
|
1931
|
+
case "textureCubeLodEXT":
|
|
1932
|
+
ident = "textureLod";
|
|
1933
|
+
break;
|
|
1934
|
+
case "texture2DGradEXT":
|
|
1935
|
+
case "textureCubeGradEXT":
|
|
1936
|
+
ident = "textureGrad";
|
|
1937
|
+
break;
|
|
1938
|
+
case "texture2DProjLodEXT":
|
|
1939
|
+
ident = "textureProjLod";
|
|
1940
|
+
break;
|
|
1941
|
+
case "texture2DProjGradEXT":
|
|
1942
|
+
ident = "textureProjGrad";
|
|
1943
|
+
break;
|
|
1944
|
+
}
|
|
1945
|
+
return ident;
|
|
1946
|
+
};
|
|
1947
|
+
_proto.visitVariableIdentifier = function visitVariableIdentifier(node) {
|
|
1948
|
+
var context = this.context;
|
|
1949
|
+
if (context.stage === EShaderStage.FRAGMENT && node.builtinSemantic === ShaderBuiltinSemantic.FragmentOutput0) {
|
|
1950
|
+
this._registerFragColorVariable();
|
|
1951
|
+
return V3_GL_FragColor;
|
|
1952
|
+
}
|
|
1953
|
+
if (context.stage === EShaderStage.FRAGMENT && node.builtinSemantic === ShaderBuiltinSemantic.FragmentDepth) {
|
|
1954
|
+
return "gl_FragDepth";
|
|
1955
|
+
}
|
|
1956
|
+
if (context.stage === EShaderStage.FRAGMENT && node.builtinSemantic === ShaderBuiltinSemantic.FragmentOutputArray) {
|
|
1957
|
+
this._registerFragDataArray();
|
|
1958
|
+
return V3_GL_FragData;
|
|
1959
|
+
}
|
|
1960
|
+
return GLESVisitor.prototype.visitVariableIdentifier.call(this, node);
|
|
1961
|
+
};
|
|
1962
|
+
_proto.visitPostfixExpression = function visitPostfixExpression(node) {
|
|
1963
|
+
if (!this._fragDataArrayRequired) {
|
|
1964
|
+
var index = this._fragDataIndices.get(node);
|
|
1965
|
+
if (index !== undefined) return this._registerFragDataVariable(index);
|
|
1966
|
+
}
|
|
1967
|
+
return GLESVisitor.prototype.visitPostfixExpression.call(this, node);
|
|
1968
|
+
};
|
|
1969
|
+
_proto.visitJumpStatement = function visitJumpStatement(node) {
|
|
1970
|
+
var mode = this.context.getFragmentReturnMode(node);
|
|
1971
|
+
var terminal = this.context.isTerminalInterfaceReturn(node);
|
|
1972
|
+
if (mode === "mrt") return terminal ? "" : "return;";
|
|
1973
|
+
if (mode === "color") {
|
|
1974
|
+
this._registerFragColorVariable();
|
|
1975
|
+
var expression = node.children[1];
|
|
1976
|
+
var assignment = V3_GL_FragColor + " = " + expression.codeGen(this) + ";";
|
|
1977
|
+
return terminal ? assignment : "{ " + assignment + " return; }";
|
|
1978
|
+
}
|
|
1979
|
+
return GLESVisitor.prototype.visitJumpStatement.call(this, node);
|
|
1980
|
+
};
|
|
1981
|
+
_proto._registerFragColorVariable = function _registerFragColorVariable() {
|
|
1982
|
+
this._registerOutput(V3_GL_FragColor, "out vec4 " + V3_GL_FragColor + ";");
|
|
1983
|
+
};
|
|
1984
|
+
_proto._registerOutput = function _registerOutput(name, text) {
|
|
1985
|
+
var output = this._outputDeclarations.get(name);
|
|
1986
|
+
if (!output) this._outputDeclarations.set(name, output = {
|
|
1987
|
+
text: text,
|
|
1988
|
+
owners: new Map(),
|
|
1989
|
+
unconditional: false
|
|
1990
|
+
});
|
|
1991
|
+
var owner = this.currentDeclarationOwner;
|
|
1992
|
+
if (owner) output.owners.set(owner.id, owner);
|
|
1993
|
+
else output.unconditional = true;
|
|
1994
|
+
};
|
|
1995
|
+
_proto.prepareFragment = function prepareFragment(entryInfo, outerGlobalMacroStatements) {
|
|
1996
|
+
var pending = entryInfo.functions.slice();
|
|
1997
|
+
while(pending.length){
|
|
1998
|
+
var _pending;
|
|
1999
|
+
var fn = pending.pop();
|
|
2000
|
+
if (this._scannedFragmentFunctions.has(fn)) continue;
|
|
2001
|
+
this._scannedFragmentFunctions.add(fn);
|
|
2002
|
+
this._scanFragmentOutputs(fn.astNode);
|
|
2003
|
+
(_pending = pending).push.apply(_pending, [].concat(fn.calledFunctions));
|
|
2004
|
+
}
|
|
2005
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(outerGlobalMacroStatements), _step; !(_step = _iterator()).done;){
|
|
2006
|
+
var macro = _step.value;
|
|
2007
|
+
this._scanFragmentOutputs(macro);
|
|
2008
|
+
}
|
|
2009
|
+
};
|
|
2010
|
+
_proto._scanFragmentOutputs = function _scanFragmentOutputs(node) {
|
|
2011
|
+
if (_instanceof(node, ASTNode.PostfixExpression) && node.children.length === 4) {
|
|
2012
|
+
var _ParserUtils_unwrapBareIdentifier;
|
|
2013
|
+
var base = node.children[0];
|
|
2014
|
+
var index = node.children[2];
|
|
2015
|
+
if (_instanceof(base, TreeNode) && _instanceof(index, TreeNode) && ((_ParserUtils_unwrapBareIdentifier = ParserUtils.unwrapBareIdentifier(base, {
|
|
2016
|
+
allowParens: true
|
|
2017
|
+
})) == null ? void 0 : _ParserUtils_unwrapBareIdentifier.builtinSemantic) === ShaderBuiltinSemantic.FragmentOutputArray) {
|
|
2018
|
+
var value = ParserUtils.constIntegerValue(index);
|
|
2019
|
+
if (value === undefined || value < 0) this._fragDataArrayRequired = true;
|
|
2020
|
+
else this._fragDataIndices.set(node, value);
|
|
2021
|
+
this._scanFragmentOutputs(index);
|
|
2022
|
+
return;
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
if (_instanceof(node, ASTNode.VariableIdentifier) && node.builtinSemantic === ShaderBuiltinSemantic.FragmentOutputArray) {
|
|
2026
|
+
this._fragDataArrayRequired = true;
|
|
2027
|
+
return;
|
|
2028
|
+
}
|
|
2029
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(node.children), _step; !(_step = _iterator()).done;){
|
|
2030
|
+
var child = _step.value;
|
|
2031
|
+
if (_instanceof(child, TreeNode)) this._scanFragmentOutputs(child);
|
|
2032
|
+
}
|
|
2033
|
+
};
|
|
2034
|
+
_proto._registerFragDataArray = function _registerFragDataArray() {
|
|
2035
|
+
this._registerOutput(V3_GL_FragData, "layout(location = 0) out vec4 " + V3_GL_FragData + "[gl_MaxDrawBuffers];");
|
|
2036
|
+
};
|
|
2037
|
+
_proto._registerFragDataVariable = function _registerFragDataVariable(index) {
|
|
2038
|
+
var name = "" + V3_GL_FragData + index;
|
|
2039
|
+
this._registerOutput(name, "layout(location = " + index + ") out vec4 " + name + ";");
|
|
2040
|
+
return name;
|
|
2041
|
+
};
|
|
2042
|
+
return GLES300Visitor;
|
|
2043
|
+
}(GLESVisitor);
|
|
2044
|
+
|
|
2045
|
+
/**
|
|
2046
|
+
* Static internal facade for GLES source generation.
|
|
2047
|
+
* @internal
|
|
2048
|
+
*/ var GLESBackend = /*#__PURE__*/ function() {
|
|
2049
|
+
function GLESBackend() {}
|
|
2050
|
+
/**
|
|
2051
|
+
* Generates one GLES program with request-owned visitor state.
|
|
2052
|
+
* @param ir - Request-owned neutral parser IR consumed read-only.
|
|
2053
|
+
* @param coreInfo - Entry and stage-interface facts derived from the same IR.
|
|
2054
|
+
* @param target - GLES language version to emit.
|
|
2055
|
+
* @returns Generated vertex and fragment source.
|
|
2056
|
+
* @internal
|
|
2057
|
+
*/ GLESBackend.generate = function generate(ir, coreInfo, target) {
|
|
2058
|
+
var glesInfo = new GLESShaderInfo(ir, coreInfo);
|
|
2059
|
+
if (glesInfo.mrtOutputIssues.length || glesInfo.invalidMrtReturnLocations.length) {
|
|
2060
|
+
Logger.error("MRT outputs require unique non-negative locations, vec4 members, and returns through an assigned struct variable.");
|
|
2061
|
+
return undefined;
|
|
2062
|
+
}
|
|
2063
|
+
if (glesInfo.invalidVaryingReturnLocations.length) {
|
|
2064
|
+
Logger.error("Varying vertex entries must return a struct variable or same-type function result.");
|
|
2065
|
+
return undefined;
|
|
2066
|
+
}
|
|
2067
|
+
if (glesInfo.structMemberOwnerIssues.length) {
|
|
2068
|
+
Logger.error("A struct member reference cannot be lowered safely across runtime macro expansion.");
|
|
2069
|
+
return undefined;
|
|
2070
|
+
}
|
|
2071
|
+
return target === ShaderLanguage.GLSLES100 ? GLESBackend._generateWithPool(GLESBackend._gles100VisitorPool, ir, coreInfo) : GLESBackend._generateWithPool(GLESBackend._gles300VisitorPool, ir, coreInfo);
|
|
2072
|
+
};
|
|
2073
|
+
GLESBackend._generateWithPool = function _generateWithPool(pool, ir, coreInfo) {
|
|
2074
|
+
var visitor = pool.get();
|
|
2075
|
+
try {
|
|
2076
|
+
return visitor.generate(ir, coreInfo);
|
|
2077
|
+
} catch (error) {
|
|
2078
|
+
visitor.dispose();
|
|
2079
|
+
if (!_instanceof(error, GSError)) throw error;
|
|
2080
|
+
Logger.error("" + (error.file ? "" + error.file + ": " : "") + (error.code ? "" + error.code + ": " : "") + error.toString());
|
|
2081
|
+
return undefined;
|
|
2082
|
+
} finally{
|
|
2083
|
+
pool.return(visitor);
|
|
2084
|
+
}
|
|
2085
|
+
};
|
|
2086
|
+
return GLESBackend;
|
|
2087
|
+
}();
|
|
2088
|
+
GLESBackend._gles100VisitorPool = new ReturnableObjectPool(GLES100Visitor);
|
|
2089
|
+
GLESBackend._gles300VisitorPool = new ReturnableObjectPool(GLES300Visitor);
|
|
2090
|
+
|
|
2091
|
+
var ShaderSourceParseError = /*#__PURE__*/ function(Error1) {
|
|
2092
|
+
_inherits(ShaderSourceParseError, Error1);
|
|
2093
|
+
function ShaderSourceParseError(errors) {
|
|
2094
|
+
var _this;
|
|
2095
|
+
_this = Error1.call(this, errors.map(function(error) {
|
|
2096
|
+
return error.toString();
|
|
2097
|
+
}).join("\n")) || this, _this.errors = errors;
|
|
2098
|
+
_this.name = "ShaderSourceParseError";
|
|
2099
|
+
return _this;
|
|
2100
|
+
}
|
|
2101
|
+
return ShaderSourceParseError;
|
|
2102
|
+
}(_wrap_native_super(Error));
|
|
2103
|
+
/**
|
|
2104
|
+
* Rejects a partial ShaderLab structure when source parsing produced errors.
|
|
2105
|
+
* @param result - ShaderLab source-parser result.
|
|
2106
|
+
* @returns Complete parsed ShaderLab structure.
|
|
2107
|
+
* @throws ShaderSourceParseError when structural source diagnostics exist.
|
|
2108
|
+
* @internal
|
|
2109
|
+
*/ function requireValidShaderSource(result) {
|
|
2110
|
+
if (result.errors.length) throw new ShaderSourceParseError(result.errors);
|
|
2111
|
+
return result.shaderSource;
|
|
2112
|
+
}
|
|
2113
|
+
/**
|
|
2114
|
+
* Generates one backend program from a parser-owned pass without reparsing it.
|
|
2115
|
+
* @param parsed - Neutral parser output.
|
|
2116
|
+
* @param vertexEntry - Vertex entry name.
|
|
2117
|
+
* @param fragmentEntry - Fragment entry name.
|
|
2118
|
+
* @param backend - Target GLES language.
|
|
2119
|
+
* @param coreInfo - Optional stage facts already derived from this exact parser result.
|
|
2120
|
+
* @returns Generated program, or `undefined` when parser or entry admission fails.
|
|
2121
|
+
* @internal
|
|
2122
|
+
*/ function generateParsedShaderPassData(parsed, vertexEntry, fragmentEntry, backend, coreInfo) {
|
|
2123
|
+
if (parsed.blockingErrors.length) {
|
|
2124
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(parsed.blockingErrors), _step; !(_step = _iterator()).done;){
|
|
2125
|
+
var error = _step.value;
|
|
2126
|
+
Logger.error(error.toString());
|
|
2127
|
+
}
|
|
2128
|
+
return undefined;
|
|
2129
|
+
}
|
|
2130
|
+
if (!parsed.ir) return undefined;
|
|
2131
|
+
var resolvedCoreInfo = coreInfo != null ? coreInfo : ShaderCoreInfo.create(parsed.ir, vertexEntry, fragmentEntry);
|
|
2132
|
+
return generateShaderProgram(parsed.ir, resolvedCoreInfo, backend, parsed.preprocessorExpressions);
|
|
2133
|
+
}
|
|
2134
|
+
function generateShaderProgram(ir, coreInfo, backend, preprocessorExpressions) {
|
|
2135
|
+
if (!coreInfo.vertexEntry.functions.length) {
|
|
2136
|
+
Logger.error("Vertex entry function '" + coreInfo.vertexEntry.name + "' not found.");
|
|
2137
|
+
return undefined;
|
|
2138
|
+
}
|
|
2139
|
+
if (!coreInfo.fragmentEntry.functions.length) {
|
|
2140
|
+
Logger.error("Fragment entry function '" + coreInfo.fragmentEntry.name + "' not found.");
|
|
2141
|
+
return undefined;
|
|
2142
|
+
}
|
|
2143
|
+
if (coreInfo.vertexEntry.hasDefiniteAmbiguity) {
|
|
2144
|
+
Logger.error("Vertex entry function '" + coreInfo.vertexEntry.name + "' resolves to multiple declarations.");
|
|
2145
|
+
return undefined;
|
|
2146
|
+
}
|
|
2147
|
+
if (coreInfo.fragmentEntry.hasDefiniteAmbiguity) {
|
|
2148
|
+
Logger.error("Fragment entry function '" + coreInfo.fragmentEntry.name + "' resolves to multiple declarations.");
|
|
2149
|
+
return undefined;
|
|
2150
|
+
}
|
|
2151
|
+
if (coreInfo.roleConflicts.length) {
|
|
2152
|
+
Logger.error("A shader IO struct cannot serve multiple stage-interface roles.");
|
|
2153
|
+
return undefined;
|
|
2154
|
+
}
|
|
2155
|
+
var result = GLESBackend.generate(ir, coreInfo, backend);
|
|
2156
|
+
if (result) {
|
|
2157
|
+
result.vertexShaderInstructions = ShaderInstructionEncoder.parse(result.vertex, preprocessorExpressions);
|
|
2158
|
+
result.fragmentShaderInstructions = ShaderInstructionEncoder.parse(result.fragment, preprocessorExpressions);
|
|
2159
|
+
result.vertex = ShaderInstructionEncoder.source(result.vertex);
|
|
2160
|
+
result.fragment = ShaderInstructionEncoder.source(result.fragment);
|
|
2161
|
+
}
|
|
2162
|
+
return result;
|
|
2163
|
+
}
|
|
2164
|
+
/**
|
|
2165
|
+
* Converts parser-owned render states into JSON-safe precompile data.
|
|
2166
|
+
* @param renderStates - Parsed render-state maps.
|
|
2167
|
+
* @returns Serializable constant and variable maps.
|
|
2168
|
+
* @internal
|
|
2169
|
+
*/ function serializeRenderStates(renderStates) {
|
|
2170
|
+
var constantMap = {};
|
|
2171
|
+
for(var key in renderStates.constantMap){
|
|
2172
|
+
var value = renderStates.constantMap[key];
|
|
2173
|
+
if (_instanceof(value, Color)) {
|
|
2174
|
+
constantMap[key] = [
|
|
2175
|
+
value.r,
|
|
2176
|
+
value.g,
|
|
2177
|
+
value.b,
|
|
2178
|
+
value.a
|
|
2179
|
+
];
|
|
2180
|
+
} else {
|
|
2181
|
+
constantMap[key] = value;
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
return {
|
|
2185
|
+
constantMap: constantMap,
|
|
2186
|
+
variableMap: renderStates.variableMap
|
|
2187
|
+
};
|
|
2188
|
+
}
|
|
2189
|
+
/**
|
|
2190
|
+
* Formats a parser failure with include-source attribution.
|
|
2191
|
+
* @param error - Parser failure.
|
|
2192
|
+
* @returns User-facing error text.
|
|
2193
|
+
* @internal
|
|
2194
|
+
*/ function formatShaderError(error) {
|
|
2195
|
+
var text = error.toString();
|
|
2196
|
+
return _instanceof(error, GSError) && error.file ? error.file + ": " + text : text;
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2199
|
+
/**
|
|
2200
|
+
* Offline-only ShaderLab to `.shaderc` compiler with deterministic validation.
|
|
2201
|
+
*
|
|
2202
|
+
* This class is intentionally excluded from the runtime compiler entry. CLI and bundler adapters import
|
|
2203
|
+
* it from `@galacean/engine-shader-compiler/precompile`.
|
|
2204
|
+
*/ var ShaderPrecompiler = /*#__PURE__*/ function() {
|
|
2205
|
+
function ShaderPrecompiler() {
|
|
2206
|
+
this._includeMap = Object.create(null);
|
|
2207
|
+
this._chunkOutputCache = new Map();
|
|
2208
|
+
this._sourceParserObjectPool = new ParserObjectPool();
|
|
2209
|
+
this._parserObjectPool = new ParserObjectPool();
|
|
2210
|
+
this._validatedParser = createValidatedShaderTargetParser(this._parserObjectPool);
|
|
2211
|
+
}
|
|
2212
|
+
var _proto = ShaderPrecompiler.prototype;
|
|
2213
|
+
/**
|
|
2214
|
+
* Replaces the logical include registry used by offline compilation.
|
|
2215
|
+
* @param includeMap - Canonical or normalizable include keys mapped to chunk sources.
|
|
2216
|
+
* @throws Error when multiple keys collide after normalization.
|
|
2217
|
+
*/ _proto.setIncludeMap = function setIncludeMap(includeMap) {
|
|
2218
|
+
this._includeMap = normalizeShaderIncludeMap(includeMap);
|
|
2219
|
+
this._chunkOutputCache.clear();
|
|
2220
|
+
};
|
|
2221
|
+
/**
|
|
2222
|
+
* Compiles complete ShaderLab source into a serializable `.shaderc` structure.
|
|
2223
|
+
* @param sourceCode - Complete ShaderLab source.
|
|
2224
|
+
* @param platformTarget - Target GLES language.
|
|
2225
|
+
* @param sourceFile - Optional logical root location used for relative includes and attribution.
|
|
2226
|
+
* @returns Serializable precompiled shader.
|
|
2227
|
+
* @throws Error when structural parsing, pass validation, or backend generation fails.
|
|
2228
|
+
*/ _proto.precompile = function precompile(sourceCode, platformTarget, sourceFile) {
|
|
2229
|
+
var _this = this;
|
|
2230
|
+
this._chunkOutputCache.clear();
|
|
2231
|
+
var shaderSource = requireValidShaderSource(ShaderSourceParser.parseStrict(sourceCode, this._sourceParserObjectPool));
|
|
2232
|
+
return {
|
|
2233
|
+
name: shaderSource.name,
|
|
2234
|
+
platformTarget: platformTarget,
|
|
2235
|
+
subShaders: shaderSource.subShaders.map(function(subShader) {
|
|
2236
|
+
return {
|
|
2237
|
+
name: subShader.name,
|
|
2238
|
+
tags: subShader.tags,
|
|
2239
|
+
passes: subShader.passes.map(function(pass) {
|
|
2240
|
+
if (pass.isUsePass) {
|
|
2241
|
+
return {
|
|
2242
|
+
name: pass.name,
|
|
2243
|
+
isUsePass: true,
|
|
2244
|
+
tags: pass.tags,
|
|
2245
|
+
renderStates: serializeRenderStates(pass.renderStates)
|
|
2246
|
+
};
|
|
2247
|
+
}
|
|
2248
|
+
var parsed = parseValidatedShaderPass(pass.contents, _this._includeMap, _this._chunkOutputCache, sourceFile, _this._parserObjectPool, _this._validatedParser, pass.contentScopeStarts);
|
|
2249
|
+
if (parsed.blockingErrors.length) {
|
|
2250
|
+
throw new Error([].concat([
|
|
2251
|
+
'Shader pass "' + shaderSource.name + "." + subShader.name + "." + pass.name + '" precompile failed:'
|
|
2252
|
+
], parsed.blockingErrors.map(formatShaderError)).join("\n"));
|
|
2253
|
+
}
|
|
2254
|
+
var coreInfo = parsed.ir ? ShaderCoreInfo$1.create(parsed.ir, pass.vertexEntry, pass.fragmentEntry, branchAnalysis.getDeclarationCoexistence, branchAnalysis.getBranchCoverage) : undefined;
|
|
2255
|
+
var program = generateParsedShaderPassData(parsed, pass.vertexEntry, pass.fragmentEntry, platformTarget, coreInfo);
|
|
2256
|
+
if (!program) {
|
|
2257
|
+
throw new Error('Shader pass "' + shaderSource.name + "." + subShader.name + "." + pass.name + '" precompile failed, please check the shader source code.');
|
|
2258
|
+
}
|
|
2259
|
+
return {
|
|
2260
|
+
name: pass.name,
|
|
2261
|
+
isUsePass: false,
|
|
2262
|
+
tags: pass.tags,
|
|
2263
|
+
renderStates: serializeRenderStates(pass.renderStates),
|
|
2264
|
+
vertexShaderInstructions: program.vertexShaderInstructions,
|
|
2265
|
+
fragmentShaderInstructions: program.fragmentShaderInstructions
|
|
2266
|
+
};
|
|
2267
|
+
})
|
|
2268
|
+
};
|
|
2269
|
+
})
|
|
2270
|
+
};
|
|
2271
|
+
};
|
|
2272
|
+
return ShaderPrecompiler;
|
|
2273
|
+
}();
|
|
2274
|
+
|
|
2275
|
+
export { ShaderPrecompiler };
|
|
2276
|
+
//# sourceMappingURL=precompile.module.js.map
|