@galacean/engine-shader-compiler 2.0.0-alpha.54 → 2.0.0-alpha.56
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/dist/browser.js +575 -315
- 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 +566 -309
- package/dist/main.js.map +1 -1
- package/dist/module.js +567 -310
- package/dist/module.js.map +1 -1
- package/dist/precompile.main.js +566 -308
- package/dist/precompile.main.js.map +1 -1
- package/dist/precompile.module.js +567 -309
- package/dist/precompile.module.js.map +1 -1
- package/package.json +5 -5
- package/types/codeGen/CodeGenVisitor.d.ts +9 -2
- package/types/codeGen/GLES100.d.ts +3 -3
- package/types/codeGen/GLES300.d.ts +4 -1
- package/types/codeGen/GLESVisitor.d.ts +45 -2
- package/types/codeGen/NameAllocator.d.ts +36 -0
- package/types/codeGen/VisitorContext.d.ts +2 -24
package/dist/module.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReturnableObjectPool, ShaderPreprocessorDirective, Logger, ShaderLanguage } from '@galacean/engine-core';
|
|
2
|
-
import { SymbolInfo, EShaderStage, VarSymbol, BaseToken, ParserUtils, ShaderStructRole, ESymbolType, FnSymbol, ASTNode,
|
|
2
|
+
import { SymbolInfo, EShaderStage, VarSymbol, BaseToken, ParserUtils, ShaderStructRole, ESymbolType, FnSymbol, ASTNode, parsePreprocessorExpression, toPreprocessorCondition, mapExpandedShaderError, GSError, GSErrorName, TreeNode, StructSymbol, Keyword, canInheritanceBranchesCover, getLexicalDeclarationCoexistence, ShaderBuiltinSemantic, GLESShaderInfo, ShaderCoreInfo, normalizeShaderIncludeMap, ShaderSourceParser, parseRuntimeShaderPass, getParsedShaderPassPayload, ParserObjectPool, createRuntimeShaderTargetParser } from '@galacean/engine-shader-parser/internal';
|
|
3
3
|
export { GSError, GSErrorName } from '@galacean/engine-shader-parser/internal';
|
|
4
4
|
import '@galacean/engine-math';
|
|
5
5
|
|
|
@@ -152,8 +152,69 @@ function _create_class(Constructor, protoProps, staticProps) {
|
|
|
152
152
|
return Constructor;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
/**
|
|
156
|
+
* Words that ShaderLab accepts as identifiers but GLSL ES 1.00 or 3.00 reserves. GLES100 output also runs as
|
|
157
|
+
* GLSL ES 3.00 on WebGL2, so both versions apply to every target.
|
|
158
|
+
*/ var reservedWords = new Set(("asm attribute active atomic_uint case cast centroid class coherent common default double dvec2 dvec3 dvec4 " + "enum extern external filter fixed flat fvec2 fvec3 fvec4 goto half hvec2 hvec3 hvec4 iimage1D iimage1DArray " + "iimage2D iimage2DArray iimage3D iimageBuffer iimageCube image1D image1DArray image2D image2DArray image3D " + "imageBuffer imageCube inline input interface isampler1D isampler1DArray isampler2D isampler2DArray " + "isampler2DMS isampler2DMSArray isampler2DRect isampler3D isamplerBuffer isamplerCube layout long mat2x2 " + "mat2x3 mat2x4 mat3x2 mat3x3 mat3x4 mat4x2 mat4x3 mat4x4 namespace noinline noperspective output packed " + "partition patch public readonly resource restrict sample sampler1D sampler1DArray sampler1DArrayShadow " + "sampler1DShadow sampler2DArray sampler2DArrayShadow sampler2DMS sampler2DMSArray sampler2DRect " + "sampler2DRectShadow sampler2DShadow sampler3D sampler3DRect samplerBuffer samplerCubeShadow short sizeof " + "smooth static subroutine superp switch template this typedef uimage1D uimage1DArray uimage2D uimage2DArray " + "uimage3D uimageBuffer uimageCube uint union unsigned usampler1D usampler1DArray usampler2D usampler2DArray " + "usampler2DMS usampler2DMSArray usampler2DRect usampler3D usamplerBuffer usamplerCube using uvec2 uvec3 uvec4 " + "varying volatile writeonly").split(" "));
|
|
159
|
+
/**
|
|
160
|
+
* Tests whether GLSL ES rejects an identifier that ShaderLab accepts.
|
|
161
|
+
* @param name - Source identifier
|
|
162
|
+
* @returns Whether the identifier uses a reserved word or namespace
|
|
163
|
+
* @internal
|
|
164
|
+
*/ function isUnsafeGLSLIdentifier(name) {
|
|
165
|
+
return reservedWords.has(name) || name.startsWith("gl_") || name.includes("__");
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Allocates generated identifiers that avoid source identifiers and each other.
|
|
169
|
+
* @internal
|
|
170
|
+
*/ var NameAllocator = /*#__PURE__*/ function() {
|
|
171
|
+
function NameAllocator() {
|
|
172
|
+
this._used = new Set();
|
|
173
|
+
this._names = new Map();
|
|
174
|
+
}
|
|
175
|
+
var _proto = NameAllocator.prototype;
|
|
176
|
+
/**
|
|
177
|
+
* Reserves a source identifier so that generated names never shadow it.
|
|
178
|
+
* @param name - Source identifier
|
|
179
|
+
*/ _proto.reserve = function reserve(name) {
|
|
180
|
+
this._used.add(name);
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Keeps a source identifier when GLSL accepts it, otherwise assigns a legal name to its identity.
|
|
184
|
+
* @param key - Source declaration or namespace identity
|
|
185
|
+
* @param name - Source identifier
|
|
186
|
+
* @returns Identifier used by the declaration and its references
|
|
187
|
+
*/ _proto.sourceName = function sourceName(key, name) {
|
|
188
|
+
if (!isUnsafeGLSLIdentifier(name)) return name;
|
|
189
|
+
return this.allocate(key, name.startsWith("gl_") ? "user_" + name : "" + name + "_");
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* Returns the same identifier for every request with the same key.
|
|
193
|
+
* @param key - Identity of the generated declaration, independent of its spelling
|
|
194
|
+
* @param preferred - Readable base name. Repeated underscores collapse to one, because WebGL rejects `__`
|
|
195
|
+
* @returns An identifier that differs from every reserved and previously allocated name
|
|
196
|
+
*/ _proto.allocate = function allocate(key, preferred) {
|
|
197
|
+
var name = this._names.get(key);
|
|
198
|
+
if (name === undefined) {
|
|
199
|
+
var base = preferred.replace(/_{2,}/g, "_");
|
|
200
|
+
var separator = base.endsWith("_") ? "" : "_";
|
|
201
|
+
name = base;
|
|
202
|
+
for(var suffix = 1; this._used.has(name); suffix++)name = "" + base + separator + suffix;
|
|
203
|
+
this._used.add(name);
|
|
204
|
+
this._names.set(key, name);
|
|
205
|
+
}
|
|
206
|
+
return name;
|
|
207
|
+
};
|
|
208
|
+
/** Releases all reservations and allocations between compilation requests. */ _proto.reset = function reset() {
|
|
209
|
+
this._used.clear();
|
|
210
|
+
this._names.clear();
|
|
211
|
+
};
|
|
212
|
+
return NameAllocator;
|
|
213
|
+
}();
|
|
214
|
+
|
|
155
215
|
/** @internal */ var VisitorContext = /*#__PURE__*/ function() {
|
|
156
216
|
function VisitorContext() {
|
|
217
|
+
this.names = new NameAllocator();
|
|
157
218
|
this._lookupSymbol = new SymbolInfo("", null);
|
|
158
219
|
this._structRoles = new Map();
|
|
159
220
|
this._vertexUnresolvedVariableRoles = new Map();
|
|
@@ -170,16 +231,12 @@ function _create_class(Constructor, protoProps, staticProps) {
|
|
|
170
231
|
this._referencedGlobalMacroASTs = [];
|
|
171
232
|
this._structVariableRoles = new Map();
|
|
172
233
|
this.codeCache = new Map();
|
|
173
|
-
this.fragmentReturnModes = new Map();
|
|
174
|
-
this.terminalInterfaceReturns = new Set();
|
|
175
234
|
this.reset();
|
|
176
235
|
}
|
|
177
236
|
var _proto = VisitorContext.prototype;
|
|
178
237
|
_proto.reset = function reset(resetAll) {
|
|
179
238
|
if (resetAll === void 0) resetAll = true;
|
|
180
239
|
this.codeCache.clear();
|
|
181
|
-
this.fragmentReturnModes.clear();
|
|
182
|
-
this.terminalInterfaceReturns.clear();
|
|
183
240
|
if (resetAll) {
|
|
184
241
|
this.attributeStructs.length = 0;
|
|
185
242
|
this.attributeList.length = 0;
|
|
@@ -283,30 +340,6 @@ function _create_class(Constructor, protoProps, staticProps) {
|
|
|
283
340
|
}
|
|
284
341
|
return resolvedRole;
|
|
285
342
|
};
|
|
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
343
|
_proto.referenceAttribute = function referenceAttribute(ident) {
|
|
311
344
|
this._referenceProp(ident.lexeme, this.attributeList, this._referencedAttributeList);
|
|
312
345
|
};
|
|
@@ -383,7 +416,7 @@ var TempArray = /*#__PURE__*/ function() {
|
|
|
383
416
|
var child = _step.value;
|
|
384
417
|
if (_instanceof(child, BaseToken)) {
|
|
385
418
|
// Legacy opaque `#define` lexemes carry the directive verbatim; expression-style defines use the AST path
|
|
386
|
-
ret.array.push(child
|
|
419
|
+
ret.array.push(this.tokenLexeme(child));
|
|
387
420
|
} else {
|
|
388
421
|
ret.array.push(child.codeGen(this));
|
|
389
422
|
}
|
|
@@ -393,6 +426,16 @@ var TempArray = /*#__PURE__*/ function() {
|
|
|
393
426
|
pool.return(ret);
|
|
394
427
|
return result;
|
|
395
428
|
};
|
|
429
|
+
/**
|
|
430
|
+
* Spells a source token in the generated code.
|
|
431
|
+
* @param token - Source token
|
|
432
|
+
* @returns Generated text for the token
|
|
433
|
+
*/ _proto.tokenLexeme = function tokenLexeme(token) {
|
|
434
|
+
return token.lexeme;
|
|
435
|
+
};
|
|
436
|
+
_proto.interfaceMemberName = function interfaceMemberName(name) {
|
|
437
|
+
return name;
|
|
438
|
+
};
|
|
396
439
|
_proto.visitPostfixExpression = function visitPostfixExpression(node) {
|
|
397
440
|
var children = node.children;
|
|
398
441
|
var derivationLength = children.length;
|
|
@@ -413,13 +456,13 @@ var TempArray = /*#__PURE__*/ function() {
|
|
|
413
456
|
var unresolvedName = ParserUtils.extractDirectIdentLexeme(postExpr);
|
|
414
457
|
role = symbols.length ? context.getStructVarRole(symbols) : unresolvedName ? context.getUnresolvedStructVarRole(unresolvedName) : undefined;
|
|
415
458
|
}
|
|
459
|
+
if (!directRoot) role = context.getStructRole(node.resolvedMemberOwners);
|
|
416
460
|
if (role) {
|
|
417
461
|
if (role === ShaderStructRole.Attribute) context.referenceAttribute(prop);
|
|
418
462
|
else if (role === ShaderStructRole.Varying) context.referenceVarying(prop);
|
|
419
463
|
else context.referenceMRTProp(prop);
|
|
420
|
-
return prop.lexeme;
|
|
421
464
|
}
|
|
422
|
-
return postExpr.codeGen(this) + "." + prop.lexeme;
|
|
465
|
+
return postExpr.codeGen(this) + "." + (role ? this.interfaceMemberName(prop.lexeme) : prop.lexeme);
|
|
423
466
|
} else {
|
|
424
467
|
return postExpr.codeGen(this) + "." + prop.codeGen(this);
|
|
425
468
|
}
|
|
@@ -454,35 +497,6 @@ var TempArray = /*#__PURE__*/ function() {
|
|
|
454
497
|
var symbol = _step.value;
|
|
455
498
|
this.referenceFunction(symbol, node.location.start.index, node._branch);
|
|
456
499
|
}
|
|
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
500
|
}
|
|
487
501
|
return this.defaultCodeGen(node.children);
|
|
488
502
|
};
|
|
@@ -491,25 +505,7 @@ var TempArray = /*#__PURE__*/ function() {
|
|
|
491
505
|
var paramList = children[2];
|
|
492
506
|
if (_instanceof(paramList, ASTNode.FunctionCallParameterList)) {
|
|
493
507
|
var astNodes = paramList.paramNodes;
|
|
494
|
-
var
|
|
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
|
-
}
|
|
508
|
+
var params = astNodes;
|
|
513
509
|
var paramsCode = "";
|
|
514
510
|
for(var i = 0, length = params.length; i < length; i++){
|
|
515
511
|
var argNode = params[i];
|
|
@@ -535,8 +531,7 @@ var TempArray = /*#__PURE__*/ function() {
|
|
|
535
531
|
};
|
|
536
532
|
/**
|
|
537
533
|
* Code-generate a `#define` macro parsed as expression AST. Produces a `#define`
|
|
538
|
-
* directive whose value
|
|
539
|
-
* happens naturally via `visitPostfixExpression` inside the AST walk.
|
|
534
|
+
* directive whose value retains ordinary expression and member-access semantics.
|
|
540
535
|
*/ _proto.visitMacroDefine = function visitMacroDefine(node) {
|
|
541
536
|
// For function-like macros, preserve the original `(params)` lexeme verbatim —
|
|
542
537
|
// the parameter list is user-authored text that shouldn't be canonicalized.
|
|
@@ -558,79 +553,27 @@ var TempArray = /*#__PURE__*/ function() {
|
|
|
558
553
|
var fullType = children[0];
|
|
559
554
|
if (_instanceof(fullType, ASTNode.FullySpecifiedType) && fullType.typeSpecifier.isCustom) {
|
|
560
555
|
var context = this.context;
|
|
561
|
-
// Global interface variables are
|
|
556
|
+
// Global interface variables are mutable shader values, not material bindings.
|
|
562
557
|
if (context.getStructVarRole([
|
|
563
558
|
node.declarator.symbol
|
|
564
559
|
])) {
|
|
565
|
-
return
|
|
560
|
+
return this.defaultCodeGen(children);
|
|
566
561
|
}
|
|
567
562
|
context.referenceGlobal(fullType.type, ESymbolType.STRUCT);
|
|
568
563
|
}
|
|
569
564
|
return "uniform " + this.defaultCodeGen(children);
|
|
570
565
|
};
|
|
571
566
|
_proto.visitDeclaration = function visitDeclaration(node) {
|
|
572
|
-
|
|
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);
|
|
567
|
+
return this.defaultCodeGen(node.children);
|
|
585
568
|
};
|
|
586
569
|
_proto.visitFunctionParameterList = function visitFunctionParameterList(node) {
|
|
587
|
-
|
|
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;
|
|
570
|
+
return this.defaultCodeGen(node.children);
|
|
606
571
|
};
|
|
607
572
|
_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
573
|
return this.defaultCodeGen(node.children);
|
|
613
574
|
};
|
|
614
575
|
_proto.visitJumpStatement = function visitJumpStatement(node) {
|
|
615
|
-
|
|
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);
|
|
576
|
+
return this.defaultCodeGen(node.children);
|
|
634
577
|
};
|
|
635
578
|
_proto.visitFunctionIdentifier = function visitFunctionIdentifier(node) {
|
|
636
579
|
return this.defaultCodeGen(node.children);
|
|
@@ -639,63 +582,10 @@ var TempArray = /*#__PURE__*/ function() {
|
|
|
639
582
|
return this.defaultCodeGen(node.children);
|
|
640
583
|
};
|
|
641
584
|
_proto.visitStructSpecifier = function visitStructSpecifier(node) {
|
|
642
|
-
|
|
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
|
-
}
|
|
585
|
+
return this.defaultCodeGen(node.children);
|
|
687
586
|
};
|
|
688
587
|
_proto.visitFunctionDefinition = function visitFunctionDefinition(fnNode) {
|
|
689
|
-
|
|
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
|
-
}
|
|
588
|
+
return this.defaultCodeGen(fnNode.children);
|
|
699
589
|
};
|
|
700
590
|
return CodeGenVisitor;
|
|
701
591
|
}();
|
|
@@ -1064,7 +954,7 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1064
954
|
_inherits(GLESVisitor, CodeGenVisitor);
|
|
1065
955
|
function GLESVisitor() {
|
|
1066
956
|
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 = [];
|
|
957
|
+
_this = CodeGenVisitor.apply(this, arguments) || this, _this.supportsArrayStructReturn = true, /** Names of pass-scope declarations, which stage-interface globals must not redeclare. */ _this._globalNames = new Set(), /** Interface type and variable tokens whose source names GLSL ES rejects. */ _this._escapedDeclarations = new Map(), _this._fragmentVaryingProps = new Set(), _this._globalInputs = new Map(), _this._inputHelperBodies = new Map(), _this._inputHelperGroups = new Map(), _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
958
|
return _this;
|
|
1069
959
|
}
|
|
1070
960
|
var _proto = GLESVisitor.prototype;
|
|
@@ -1080,6 +970,8 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1080
970
|
this._variableCodeSegments.clear();
|
|
1081
971
|
this._deferredPrototypes.clear();
|
|
1082
972
|
this._declarationReferences.clear();
|
|
973
|
+
this._inputHelperBodies.clear();
|
|
974
|
+
this._inputHelperGroups.clear();
|
|
1083
975
|
this._currentDeclaration = undefined;
|
|
1084
976
|
};
|
|
1085
977
|
/**
|
|
@@ -1087,6 +979,10 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1087
979
|
* @internal
|
|
1088
980
|
*/ _proto.dispose = function dispose() {
|
|
1089
981
|
this.context.reset();
|
|
982
|
+
this.context.names.reset();
|
|
983
|
+
this._globalNames.clear();
|
|
984
|
+
this._escapedDeclarations.clear();
|
|
985
|
+
this._vertexOutputNames = undefined;
|
|
1090
986
|
this.reset();
|
|
1091
987
|
};
|
|
1092
988
|
/**
|
|
@@ -1094,8 +990,15 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1094
990
|
* @param data - Parser-owned shader facts.
|
|
1095
991
|
* @param out - Destination code segments.
|
|
1096
992
|
*/ _proto.getOtherGlobal = function getOtherGlobal(data, out) {
|
|
1097
|
-
for(var _iterator = _create_for_of_iterator_helper_loose(
|
|
1098
|
-
var
|
|
993
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(this._inputHelperGroups.values()), _step; !(_step = _iterator()).done;){
|
|
994
|
+
var _step_value = _step.value, name = _step_value.name, fallback = _step_value.fallback;
|
|
995
|
+
out.push({
|
|
996
|
+
text: ShaderInstructionEncoder.declaration("void " + name + "() {}", fallback) + ShaderInstructionEncoder.reference(0, fallback.id),
|
|
997
|
+
index: -1
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(data.globalPrecisions), _step1; !(_step1 = _iterator1()).done;){
|
|
1001
|
+
var precision = _step1.value;
|
|
1099
1002
|
out.push({
|
|
1100
1003
|
text: precision.codeGen(this),
|
|
1101
1004
|
index: precision.location.start.index
|
|
@@ -1108,14 +1011,39 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1108
1011
|
* @param coreInfo - Entry and stage-interface facts derived from the same IR.
|
|
1109
1012
|
* @returns Generated vertex and fragment source.
|
|
1110
1013
|
*/ _proto.generate = function generate(ir, coreInfo) {
|
|
1111
|
-
var _this =
|
|
1014
|
+
var _this, _loop = function(_i, _iter) {
|
|
1015
|
+
var _iter__i = _iter[_i], stage = _iter__i[0], variables = _iter__i[1];
|
|
1016
|
+
var inputRole = stage === EShaderStage.VERTEX ? ShaderStructRole.Attribute : ShaderStructRole.Varying;
|
|
1017
|
+
_this._globalInputs.set(stage, Array.from(variables).filter(function(param) {
|
|
1018
|
+
var variable = param[0], role = param[1];
|
|
1019
|
+
return role === inputRole && _instanceof(variable.astNode, ASTNode.VariableDeclaration);
|
|
1020
|
+
}).map(function(param) {
|
|
1021
|
+
var variable = param[0];
|
|
1022
|
+
return variable;
|
|
1023
|
+
}));
|
|
1024
|
+
};
|
|
1025
|
+
var _this1 = this;
|
|
1112
1026
|
var _context_attributeStructs, _context_attributeList, _context_varyingStructs, _context_varyingList, _context_mrtStructs, _context_mrtList;
|
|
1113
1027
|
this.context.reset();
|
|
1028
|
+
this.context.names.reset();
|
|
1029
|
+
this._globalNames.clear();
|
|
1030
|
+
this._escapedDeclarations.clear();
|
|
1031
|
+
this._vertexOutputNames = undefined;
|
|
1114
1032
|
this.reset();
|
|
1115
1033
|
var node = ir.program;
|
|
1116
1034
|
var shaderData = node.shaderData;
|
|
1117
1035
|
var context = this.context;
|
|
1118
1036
|
context._passSymbolTable = shaderData.symbolTable;
|
|
1037
|
+
var hasUnsafeIdentifier = false;
|
|
1038
|
+
var _ir_source_match;
|
|
1039
|
+
for(var _iterator = _create_for_of_iterator_helper_loose((_ir_source_match = ir.source.match(/[A-Za-z_][A-Za-z0-9_]*/g)) != null ? _ir_source_match : []), _step; !(_step = _iterator()).done;){
|
|
1040
|
+
var name = _step.value;
|
|
1041
|
+
context.names.reserve(name);
|
|
1042
|
+
hasUnsafeIdentifier || (hasUnsafeIdentifier = isUnsafeGLSLIdentifier(name));
|
|
1043
|
+
}
|
|
1044
|
+
shaderData.symbolTable.forEach(function(symbol) {
|
|
1045
|
+
return _this1._globalNames.add(symbol.ident);
|
|
1046
|
+
});
|
|
1119
1047
|
var outerGlobalMacroDeclarations = coreInfo.outerGlobalMacroDeclarations;
|
|
1120
1048
|
var io = coreInfo.io;
|
|
1121
1049
|
(_context_attributeStructs = context.attributeStructs).push.apply(_context_attributeStructs, [].concat(io.attributeStructs));
|
|
@@ -1136,23 +1064,50 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1136
1064
|
io.fragmentStructVariableRoles.forEach(function(role, variable) {
|
|
1137
1065
|
context.registerStructVar(variable, role, EShaderStage.FRAGMENT);
|
|
1138
1066
|
});
|
|
1067
|
+
if (hasUnsafeIdentifier) this._collectEscapedDeclarations(node);
|
|
1068
|
+
this._globalInputs.clear();
|
|
1069
|
+
for(var _i = 0, _iter = [
|
|
1070
|
+
[
|
|
1071
|
+
EShaderStage.VERTEX,
|
|
1072
|
+
io.vertexStructVariableRoles
|
|
1073
|
+
],
|
|
1074
|
+
[
|
|
1075
|
+
EShaderStage.FRAGMENT,
|
|
1076
|
+
io.fragmentStructVariableRoles
|
|
1077
|
+
]
|
|
1078
|
+
]; _i < _iter.length; _i++)_this = this, _loop(_i, _iter);
|
|
1139
1079
|
this._sourceIR = ir;
|
|
1140
1080
|
this._outerMacroDeclarations = outerGlobalMacroDeclarations;
|
|
1141
1081
|
try {
|
|
1142
1082
|
coreInfo.deferredDeclarationOwnership.forEach(function(owner, symbol) {
|
|
1143
|
-
return
|
|
1083
|
+
return _this1._declarationOwners.set(symbol.astNode, owner);
|
|
1144
1084
|
});
|
|
1085
|
+
var nextInputOwner = 0;
|
|
1086
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(this._declarationOwners.values()), _step1; !(_step1 = _iterator1()).done;){
|
|
1087
|
+
var owner = _step1.value;
|
|
1088
|
+
nextInputOwner = Math.max(nextInputOwner, owner.id, owner.group);
|
|
1089
|
+
}
|
|
1090
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(this._globalInputs.values()), _step2; !(_step2 = _iterator2()).done;){
|
|
1091
|
+
var variables = _step2.value;
|
|
1092
|
+
for(var _iterator3 = _create_for_of_iterator_helper_loose(variables), _step3; !(_step3 = _iterator3()).done;){
|
|
1093
|
+
var variable = _step3.value;
|
|
1094
|
+
if (this._declarationOwners.has(variable.astNode)) continue;
|
|
1095
|
+
var id = ++nextInputOwner;
|
|
1096
|
+
this._declarationOwners.set(variable.astNode, {
|
|
1097
|
+
id: id,
|
|
1098
|
+
group: id,
|
|
1099
|
+
sourceScope: variable.sourceScope
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1145
1103
|
if (this._declarationOwners.size) {
|
|
1146
|
-
|
|
1147
|
-
var
|
|
1148
|
-
|
|
1149
|
-
nextId = Math.max(nextId, owner.id);
|
|
1150
|
-
nextGroup = Math.max(nextGroup, owner.group);
|
|
1151
|
-
});
|
|
1104
|
+
// `nextInputOwner` already exceeds every owner id and group.
|
|
1105
|
+
var nextId = nextInputOwner;
|
|
1106
|
+
var nextGroup = nextInputOwner;
|
|
1152
1107
|
// Reachability follows the selected declaration, including dependencies without an override.
|
|
1153
1108
|
shaderData.symbolTable.forEach(function(symbol) {
|
|
1154
|
-
if (symbol.astNode && !
|
|
1155
|
-
|
|
1109
|
+
if (symbol.astNode && !_this1._declarationOwners.has(symbol.astNode)) {
|
|
1110
|
+
_this1._declarationOwners.set(symbol.astNode, {
|
|
1156
1111
|
id: ++nextId,
|
|
1157
1112
|
group: ++nextGroup,
|
|
1158
1113
|
sourceScope: symbol.sourceScope
|
|
@@ -1162,54 +1117,71 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1162
1117
|
context.onReferenceGlobal = function(symbols) {
|
|
1163
1118
|
var _this_currentDeclarationOwner;
|
|
1164
1119
|
var _this_currentDeclarationOwner_id;
|
|
1165
|
-
var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner =
|
|
1120
|
+
var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner = _this1.currentDeclarationOwner) == null ? void 0 : _this_currentDeclarationOwner.id) != null ? _this_currentDeclarationOwner_id : 0;
|
|
1166
1121
|
for(var _iterator = _create_for_of_iterator_helper_loose(symbols), _step; !(_step = _iterator()).done;){
|
|
1167
1122
|
var symbol = _step.value;
|
|
1168
|
-
|
|
1123
|
+
_this1._referenceDeclaration(from, symbol.astNode);
|
|
1169
1124
|
}
|
|
1170
1125
|
};
|
|
1171
1126
|
var propDeclarations = new Map();
|
|
1172
|
-
for(var
|
|
1173
|
-
var struct =
|
|
1174
|
-
for(var
|
|
1175
|
-
var prop =
|
|
1127
|
+
for(var _iterator4 = _create_for_of_iterator_helper_loose([].concat(io.attributeStructs, io.varyingStructs, io.mrtStructs)), _step4; !(_step4 = _iterator4()).done;){
|
|
1128
|
+
var struct = _step4.value;
|
|
1129
|
+
for(var _iterator5 = _create_for_of_iterator_helper_loose(struct.propList), _step5; !(_step5 = _iterator5()).done;){
|
|
1130
|
+
var prop = _step5.value;
|
|
1176
1131
|
propDeclarations.set(prop, struct);
|
|
1177
1132
|
}
|
|
1178
1133
|
}
|
|
1179
1134
|
context.onReferenceStructProps = function(props) {
|
|
1180
1135
|
var _this_currentDeclarationOwner;
|
|
1181
1136
|
var _this_currentDeclarationOwner_id;
|
|
1182
|
-
var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner =
|
|
1137
|
+
var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner = _this1.currentDeclarationOwner) == null ? void 0 : _this_currentDeclarationOwner.id) != null ? _this_currentDeclarationOwner_id : 0;
|
|
1183
1138
|
for(var _iterator = _create_for_of_iterator_helper_loose(props), _step; !(_step = _iterator()).done;){
|
|
1184
1139
|
var prop = _step.value;
|
|
1185
|
-
|
|
1140
|
+
_this1._referenceDeclaration(from, propDeclarations.get(prop));
|
|
1186
1141
|
}
|
|
1187
1142
|
};
|
|
1188
1143
|
}
|
|
1189
1144
|
if (coreInfo.unsupportedDeferredDeclarations.length) {
|
|
1190
1145
|
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
1146
|
}
|
|
1147
|
+
this._fragmentVaryingProps.clear();
|
|
1148
|
+
var fragment = this._fragmentMain(coreInfo.fragmentEntry, shaderData, outerGlobalMacroDeclarations);
|
|
1149
|
+
var vertex = this._vertexMain(coreInfo.vertexEntry, shaderData, outerGlobalMacroDeclarations);
|
|
1192
1150
|
return {
|
|
1193
|
-
vertex:
|
|
1194
|
-
fragment:
|
|
1151
|
+
vertex: vertex,
|
|
1152
|
+
fragment: fragment,
|
|
1153
|
+
vertexOutputNames: this._vertexOutputNames
|
|
1195
1154
|
};
|
|
1196
1155
|
} finally{
|
|
1197
1156
|
this._sourceIR = undefined;
|
|
1198
1157
|
this._outerMacroDeclarations = [];
|
|
1158
|
+
this._globalInputs.clear();
|
|
1199
1159
|
this._declarationOwners.clear();
|
|
1200
1160
|
context.onReferenceGlobal = undefined;
|
|
1201
1161
|
context.onReferenceStructProps = undefined;
|
|
1162
|
+
this._fragmentVaryingProps.clear();
|
|
1163
|
+
this._globalNames.clear();
|
|
1164
|
+
this._escapedDeclarations.clear();
|
|
1165
|
+
this._vertexOutputNames = undefined;
|
|
1166
|
+
context.reset();
|
|
1167
|
+
context.names.reset();
|
|
1202
1168
|
}
|
|
1203
1169
|
};
|
|
1204
1170
|
_proto._vertexMain = function _vertexMain(entryInfo, data, outerGlobalMacroDeclarations) {
|
|
1205
1171
|
var context = this.context;
|
|
1206
1172
|
context.stage = EShaderStage.VERTEX;
|
|
1207
1173
|
context.stageEntry = entryInfo.name;
|
|
1174
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(this._fragmentVaryingProps), _step; !(_step = _iterator()).done;){
|
|
1175
|
+
var prop = _step.value;
|
|
1176
|
+
context.referenceVarying(prop.ident);
|
|
1177
|
+
}
|
|
1208
1178
|
// Attribute/varying structs were collected in ShaderCoreInfo
|
|
1209
1179
|
// Pre-walk global `#define` values so referenced struct properties emit `attribute`/`varying` declarations.
|
|
1210
1180
|
this._preRegisterGlobalMacroRefs(outerGlobalMacroDeclarations);
|
|
1211
1181
|
var globalCodeArray = this._globalCodeArray;
|
|
1212
1182
|
context.referenceGlobal(entryInfo.name, ESymbolType.FN);
|
|
1183
|
+
this._referenceInterfaceDependencies([].concat(context.attributeStructs, context.varyingStructs));
|
|
1184
|
+
this._initializeGlobalInputs();
|
|
1213
1185
|
this._getGlobalSymbol(globalCodeArray);
|
|
1214
1186
|
this._getCustomStruct(context.attributeStructs, globalCodeArray);
|
|
1215
1187
|
this._getCustomStruct(context.varyingStructs, globalCodeArray);
|
|
@@ -1226,28 +1198,17 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1226
1198
|
return globalCode;
|
|
1227
1199
|
};
|
|
1228
1200
|
_proto._fragmentMain = function _fragmentMain(entryInfo, data, outerGlobalMacroStatements) {
|
|
1229
|
-
var _this = this;
|
|
1230
1201
|
var context = this.context;
|
|
1231
1202
|
context.stage = EShaderStage.FRAGMENT;
|
|
1232
1203
|
context.stageEntry = entryInfo.name;
|
|
1233
1204
|
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
1205
|
// Struct-variable identities are already populated from ShaderCoreInfo; just pre-walk macro
|
|
1247
1206
|
// refs so struct codegen sees the references.
|
|
1248
1207
|
this._preRegisterGlobalMacroRefs(outerGlobalMacroStatements);
|
|
1249
1208
|
var globalCodeArray = this._globalCodeArray;
|
|
1250
1209
|
context.referenceGlobal(entryInfo.name, ESymbolType.FN);
|
|
1210
|
+
this._referenceInterfaceDependencies([].concat(context.varyingStructs, context.mrtStructs));
|
|
1211
|
+
this._initializeGlobalInputs();
|
|
1251
1212
|
this._getGlobalSymbol(globalCodeArray);
|
|
1252
1213
|
this._getCustomStruct(context.varyingStructs, globalCodeArray);
|
|
1253
1214
|
this._getCustomStruct(context.mrtStructs, globalCodeArray);
|
|
@@ -1259,10 +1220,347 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1259
1220
|
}).map(function(item) {
|
|
1260
1221
|
return item.text;
|
|
1261
1222
|
}).join("\n");
|
|
1262
|
-
context.
|
|
1223
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(Object.values(context._referencedVaryingList)), _step; !(_step = _iterator()).done;){
|
|
1224
|
+
var props = _step.value;
|
|
1225
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(props), _step1; !(_step1 = _iterator1()).done;){
|
|
1226
|
+
var prop = _step1.value;
|
|
1227
|
+
this._fragmentVaryingProps.add(prop);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
context.reset(false);
|
|
1263
1231
|
this.reset();
|
|
1264
1232
|
return globalCode;
|
|
1265
1233
|
};
|
|
1234
|
+
_proto._referenceInterfaceDependencies = function _referenceInterfaceDependencies(structs) {
|
|
1235
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(structs), _step; !(_step = _iterator()).done;){
|
|
1236
|
+
var struct = _step.value;
|
|
1237
|
+
this._currentDeclaration = struct;
|
|
1238
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(struct.propList), _step1; !(_step1 = _iterator1()).done;){
|
|
1239
|
+
var prop = _step1.value;
|
|
1240
|
+
var _prop_typeInfo_arraySpecifier;
|
|
1241
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(prop.typeInfo.structDeclarations), _step2; !(_step2 = _iterator2()).done;){
|
|
1242
|
+
var dependency = _step2.value;
|
|
1243
|
+
if (dependency.ident) this.context.referenceGlobal(dependency.ident.lexeme, ESymbolType.STRUCT);
|
|
1244
|
+
}
|
|
1245
|
+
(_prop_typeInfo_arraySpecifier = prop.typeInfo.arraySpecifier) == null ? void 0 : _prop_typeInfo_arraySpecifier.codeGen(this);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
this._currentDeclaration = undefined;
|
|
1249
|
+
};
|
|
1250
|
+
/**
|
|
1251
|
+
* Resolves an interface member's global name, shared by both stages for varyings.
|
|
1252
|
+
* @param prop - Interface member
|
|
1253
|
+
* @param role - Stage-interface role of the member's structure
|
|
1254
|
+
* @returns Generated global identifier
|
|
1255
|
+
*/ _proto.interfaceName = function interfaceName(prop, role) {
|
|
1256
|
+
var context = this.context;
|
|
1257
|
+
var name = prop.ident.lexeme;
|
|
1258
|
+
var isOutput = role === ShaderStructRole.Mrt;
|
|
1259
|
+
var sameName = function(item) {
|
|
1260
|
+
return item.ident.lexeme === name;
|
|
1261
|
+
};
|
|
1262
|
+
var conflicts = this._globalNames.has(name) || // Vertex attributes and fragment outputs share a stage scope with varyings.
|
|
1263
|
+
!isOutput && (context.attributeList.some(sameName) || context.mrtList.some(sameName));
|
|
1264
|
+
var key = (isOutput ? "output" : "varying") + ":" + name;
|
|
1265
|
+
var generated = isUnsafeGLSLIdentifier(name) ? context.names.sourceName(key, name) : conflicts ? context.names.allocate(key, name) : name;
|
|
1266
|
+
if (!isOutput && context.stage === EShaderStage.VERTEX && generated !== name) {
|
|
1267
|
+
var _this__vertexOutputNames;
|
|
1268
|
+
((_this__vertexOutputNames = this._vertexOutputNames) != null ? _this__vertexOutputNames : this._vertexOutputNames = Object.create(null))[name] = generated;
|
|
1269
|
+
}
|
|
1270
|
+
return generated;
|
|
1271
|
+
};
|
|
1272
|
+
_proto.interfaceMemberName = function interfaceMemberName(name) {
|
|
1273
|
+
return this.context.names.sourceName("member:" + name, name);
|
|
1274
|
+
};
|
|
1275
|
+
_proto._interfaceTypeName = function _interfaceTypeName(struct) {
|
|
1276
|
+
var name = struct.ident.lexeme;
|
|
1277
|
+
return this.context.names.sourceName("type:" + name, name);
|
|
1278
|
+
};
|
|
1279
|
+
/**
|
|
1280
|
+
* Escapes interface-typed variables whose names GLSL ES reserves.
|
|
1281
|
+
* @param name - Source name
|
|
1282
|
+
* @param structs - Struct declarations of the variable type
|
|
1283
|
+
* @returns The escaped name, or the source name when no escape is necessary
|
|
1284
|
+
*/ _proto._interfaceVariableName = function _interfaceVariableName(name, structs) {
|
|
1285
|
+
return (structs == null ? void 0 : structs.length) && this.context.getStructRole(structs) ? this.context.names.sourceName("variable:" + name, name) : name;
|
|
1286
|
+
};
|
|
1287
|
+
_proto._collectEscapedDeclarations = function _collectEscapedDeclarations(node) {
|
|
1288
|
+
if (_instanceof(node, ASTNode.TypeSpecifier) && this.context.getStructRole(node.structDeclarations)) {
|
|
1289
|
+
var _node_structDeclarations__ident;
|
|
1290
|
+
var token = node.children[0].children[0];
|
|
1291
|
+
if (_instanceof(token, BaseToken) && token.lexeme === ((_node_structDeclarations__ident = node.structDeclarations[0].ident) == null ? void 0 : _node_structDeclarations__ident.lexeme)) {
|
|
1292
|
+
var name = this._interfaceTypeName(node.structDeclarations[0]);
|
|
1293
|
+
if (name !== token.lexeme) this._escapedDeclarations.set(token, name);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
var identifier;
|
|
1297
|
+
var structs;
|
|
1298
|
+
if (_instanceof(node, ASTNode.ParameterDeclarator)) {
|
|
1299
|
+
var _node_typeInfo;
|
|
1300
|
+
identifier = node.ident;
|
|
1301
|
+
structs = (_node_typeInfo = node.typeInfo) == null ? void 0 : _node_typeInfo.structDeclarations;
|
|
1302
|
+
} else {
|
|
1303
|
+
var _declarator_typeInfo;
|
|
1304
|
+
// Local, global and multi-variable declarations share the parser's `declarator` record.
|
|
1305
|
+
var declarator = node.declarator;
|
|
1306
|
+
identifier = declarator == null ? void 0 : declarator.identifier;
|
|
1307
|
+
structs = declarator == null ? void 0 : (_declarator_typeInfo = declarator.typeInfo) == null ? void 0 : _declarator_typeInfo.structDeclarations;
|
|
1308
|
+
}
|
|
1309
|
+
if (identifier) {
|
|
1310
|
+
var name1 = this._interfaceVariableName(identifier.lexeme, structs);
|
|
1311
|
+
if (name1 !== identifier.lexeme) this._escapedDeclarations.set(identifier, name1);
|
|
1312
|
+
}
|
|
1313
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(node.children), _step; !(_step = _iterator()).done;){
|
|
1314
|
+
var child = _step.value;
|
|
1315
|
+
if (_instanceof(child, TreeNode)) this._collectEscapedDeclarations(child);
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
_proto.tokenLexeme = function tokenLexeme(token) {
|
|
1319
|
+
var _this__escapedDeclarations_get;
|
|
1320
|
+
return (_this__escapedDeclarations_get = this._escapedDeclarations.get(token)) != null ? _this__escapedDeclarations_get : token.lexeme;
|
|
1321
|
+
};
|
|
1322
|
+
_proto._escapedReference = function _escapedReference(node) {
|
|
1323
|
+
var token = node.children[0];
|
|
1324
|
+
if (!this._escapedDeclarations.size || !_instanceof(token, BaseToken) || !isUnsafeGLSLIdentifier(token.lexeme)) {
|
|
1325
|
+
return undefined;
|
|
1326
|
+
}
|
|
1327
|
+
var symbols = node.resolvedValueSymbols();
|
|
1328
|
+
if (!symbols.length) {
|
|
1329
|
+
// Macro values can lack symbols. The stage's unambiguous name-to-role map binds them, as for member access.
|
|
1330
|
+
return this.context.getUnresolvedStructVarRole(token.lexeme) ? this.context.names.sourceName("variable:" + token.lexeme, token.lexeme) : undefined;
|
|
1331
|
+
}
|
|
1332
|
+
var name;
|
|
1333
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(symbols), _step; !(_step = _iterator()).done;){
|
|
1334
|
+
var symbol = _step.value;
|
|
1335
|
+
var _symbol_dataType;
|
|
1336
|
+
var candidate = _instanceof(symbol, VarSymbol) ? this._interfaceVariableName(token.lexeme, (_symbol_dataType = symbol.dataType) == null ? void 0 : _symbol_dataType.structDeclarations) : _instanceof(symbol, StructSymbol) && this.context.getStructRole([
|
|
1337
|
+
symbol.astNode
|
|
1338
|
+
]) ? this._interfaceTypeName(symbol.astNode) : token.lexeme;
|
|
1339
|
+
// Branch candidates must agree, otherwise the reference keeps its source spelling.
|
|
1340
|
+
if (name !== undefined && name !== candidate) return undefined;
|
|
1341
|
+
name = candidate;
|
|
1342
|
+
}
|
|
1343
|
+
return name;
|
|
1344
|
+
};
|
|
1345
|
+
_proto._transferName = function _transferName(struct, read) {
|
|
1346
|
+
return this.context.names.allocate((read ? "read" : "write") + ":" + struct.ident.lexeme, (read ? "read" : "write") + "_" + struct.ident.lexeme);
|
|
1347
|
+
};
|
|
1348
|
+
_proto.visitStructSpecifier = function visitStructSpecifier(node) {
|
|
1349
|
+
var _this = this;
|
|
1350
|
+
var context = this.context;
|
|
1351
|
+
var role = context.getStructRole([
|
|
1352
|
+
node
|
|
1353
|
+
]);
|
|
1354
|
+
if (!role) return CodeGenVisitor.prototype.visitStructSpecifier.call(this, node);
|
|
1355
|
+
var typeName = this._interfaceTypeName(node);
|
|
1356
|
+
var memberCode = function(emit) {
|
|
1357
|
+
var segments = node.macroExpressions.map(function(item) {
|
|
1358
|
+
return {
|
|
1359
|
+
text: _instanceof(item, BaseToken) ? item.lexeme : item.codeGen(_this),
|
|
1360
|
+
index: item.location.start.index
|
|
1361
|
+
};
|
|
1362
|
+
});
|
|
1363
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(node.propList), _step; !(_step = _iterator()).done;){
|
|
1364
|
+
var prop = _step.value;
|
|
1365
|
+
if (!retain(prop)) continue;
|
|
1366
|
+
segments.push({
|
|
1367
|
+
text: emit(prop),
|
|
1368
|
+
index: prop.ident.location.start.index
|
|
1369
|
+
});
|
|
1370
|
+
}
|
|
1371
|
+
return segments.sort(function(a, b) {
|
|
1372
|
+
return a.index - b.index;
|
|
1373
|
+
}).map(function(item) {
|
|
1374
|
+
return item.text;
|
|
1375
|
+
}).join("\n");
|
|
1376
|
+
};
|
|
1377
|
+
var references = role === ShaderStructRole.Attribute ? context._referencedAttributeList : role === ShaderStructRole.Varying ? context._referencedVaryingList : context._referencedMRTList;
|
|
1378
|
+
var used = function(prop) {
|
|
1379
|
+
var _references_prop_ident_lexeme;
|
|
1380
|
+
return !!((_references_prop_ident_lexeme = references[prop.ident.lexeme]) == null ? void 0 : _references_prop_ident_lexeme.includes(prop));
|
|
1381
|
+
};
|
|
1382
|
+
// Interface members have no array wire form, and GLSL ES 1.00 functions cannot return structures that contain
|
|
1383
|
+
// arrays. GLES100 therefore omits array members from interface structures.
|
|
1384
|
+
var retain = function(prop) {
|
|
1385
|
+
return _this.supportsArrayStructReturn || !_this._containsArray(prop);
|
|
1386
|
+
};
|
|
1387
|
+
var declaration = function(prop) {
|
|
1388
|
+
var _prop_typeInfo_arraySpecifier;
|
|
1389
|
+
var _prop_typeInfo_arraySpecifier_codeGen;
|
|
1390
|
+
return prop.typeInfo.typeLexeme + " " + _this.interfaceMemberName(prop.ident.lexeme) + ((_prop_typeInfo_arraySpecifier_codeGen = (_prop_typeInfo_arraySpecifier = prop.typeInfo.arraySpecifier) == null ? void 0 : _prop_typeInfo_arraySpecifier.codeGen(_this)) != null ? _prop_typeInfo_arraySpecifier_codeGen : "") + ";";
|
|
1391
|
+
};
|
|
1392
|
+
var structCode;
|
|
1393
|
+
var hasRetainedField = node.propList.some(retain);
|
|
1394
|
+
if (hasRetainedField && !node.macroExpressions.length) {
|
|
1395
|
+
structCode = "struct " + typeName + " {\n" + memberCode(declaration) + "\n};";
|
|
1396
|
+
} else {
|
|
1397
|
+
var hasFields = context.names.allocate(node, "" + typeName + "_has_fields");
|
|
1398
|
+
var padding = context.names.allocate("empty-interface-member", "interface_padding");
|
|
1399
|
+
// A macro configuration can remove every source field; GLSL still requires a nonempty struct.
|
|
1400
|
+
structCode = "#undef " + hasFields + "\nstruct " + typeName + " {\n" + memberCode(function(prop) {
|
|
1401
|
+
return declaration(prop) + "\n#define " + hasFields + "\n";
|
|
1402
|
+
}) + "\n#ifndef " + hasFields + "\nfloat " + padding + ";\n#endif\n};\n#undef " + hasFields + "\n";
|
|
1403
|
+
}
|
|
1404
|
+
var declarations = memberCode(function(prop) {
|
|
1405
|
+
var _this_getMRTProp;
|
|
1406
|
+
return !used(prop) ? "" : role === ShaderStructRole.Attribute ? _this.getAttributeProp(prop) : role === ShaderStructRole.Varying ? _this.getVaryingProp(prop) : (_this_getMRTProp = _this.getMRTProp(prop)) != null ? _this_getMRTProp : "";
|
|
1407
|
+
});
|
|
1408
|
+
var read = role === ShaderStructRole.Attribute || role === ShaderStructRole.Varying && context.stage === EShaderStage.FRAGMENT;
|
|
1409
|
+
var value = context.names.allocate("interface-value", "interface_value");
|
|
1410
|
+
var assignments = memberCode(function(prop) {
|
|
1411
|
+
if (!used(prop)) return "";
|
|
1412
|
+
var wire = role === ShaderStructRole.Attribute ? prop.ident.lexeme : role === ShaderStructRole.Mrt ? _this.mrtOutput(prop) : _this.interfaceName(prop, role);
|
|
1413
|
+
var member = value + "." + _this.interfaceMemberName(prop.ident.lexeme);
|
|
1414
|
+
return read ? member + " = " + wire + ";" : wire + " = " + member + ";";
|
|
1415
|
+
});
|
|
1416
|
+
var transfer = read ? typeName + " " + this._transferName(node, true) + "() { " + typeName + " " + value + ";\n" + assignments + "\nreturn " + value + "; }" : "void " + this._transferName(node, false) + "(" + typeName + " " + value + ") {\n" + assignments + "\n}";
|
|
1417
|
+
return structCode + "\n" + declarations + "\n" + transfer;
|
|
1418
|
+
};
|
|
1419
|
+
_proto._containsArray = function _containsArray(prop, visited) {
|
|
1420
|
+
var _this = this;
|
|
1421
|
+
if (visited === void 0) visited = new Set();
|
|
1422
|
+
if (prop.typeInfo.arraySpecifier) return true;
|
|
1423
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(prop.typeInfo.structDeclarations), _step; !(_step = _iterator()).done;){
|
|
1424
|
+
var struct = _step.value;
|
|
1425
|
+
if (visited.has(struct)) continue;
|
|
1426
|
+
visited.add(struct);
|
|
1427
|
+
if (struct.propList.some(function(member) {
|
|
1428
|
+
return _this._containsArray(member, visited);
|
|
1429
|
+
})) return true;
|
|
1430
|
+
}
|
|
1431
|
+
return false;
|
|
1432
|
+
};
|
|
1433
|
+
_proto.defaultCodeGen = function defaultCodeGen(children) {
|
|
1434
|
+
var _this = this;
|
|
1435
|
+
var parent = _instanceof(children[0], TreeNode) ? children[0].parent : undefined;
|
|
1436
|
+
if (_instanceof(parent, ASTNode.EqualityExpression) && children.length === 3) {
|
|
1437
|
+
var observe = function(node) {
|
|
1438
|
+
if (_instanceof(node, ASTNode.VariableIdentifier)) {
|
|
1439
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(node.resolvedValueSymbols()), _step; !(_step = _iterator()).done;){
|
|
1440
|
+
var symbol = _step.value;
|
|
1441
|
+
var _symbol_dataType;
|
|
1442
|
+
var _symbol_dataType_structDeclarations;
|
|
1443
|
+
if (_instanceof(symbol, VarSymbol)) for(var _iterator1 = _create_for_of_iterator_helper_loose((_symbol_dataType_structDeclarations = (_symbol_dataType = symbol.dataType) == null ? void 0 : _symbol_dataType.structDeclarations) != null ? _symbol_dataType_structDeclarations : []), _step1; !(_step1 = _iterator1()).done;){
|
|
1444
|
+
var struct = _step1.value;
|
|
1445
|
+
_this._observeWholeStruct(struct);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
if (_instanceof(node, ASTNode.FunctionCallGeneric)) {
|
|
1450
|
+
var _node_fnSymbol;
|
|
1451
|
+
var declaration = (_node_fnSymbol = node.fnSymbol) == null ? void 0 : _node_fnSymbol.astNode;
|
|
1452
|
+
if (_instanceof(declaration, ASTNode.StructSpecifier)) _this._observeWholeStruct(declaration);
|
|
1453
|
+
else if (_instanceof(declaration, ASTNode.FunctionDefinition)) {
|
|
1454
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(declaration.protoType.returnType.typeSpecifier.structDeclarations), _step2; !(_step2 = _iterator2()).done;){
|
|
1455
|
+
var struct1 = _step2.value;
|
|
1456
|
+
_this._observeWholeStruct(struct1);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
for(var _iterator3 = _create_for_of_iterator_helper_loose(node.children), _step3; !(_step3 = _iterator3()).done;){
|
|
1461
|
+
var child = _step3.value;
|
|
1462
|
+
if (_instanceof(child, TreeNode)) observe(child);
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1465
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(children), _step; !(_step = _iterator()).done;){
|
|
1466
|
+
var child = _step.value;
|
|
1467
|
+
if (_instanceof(child, TreeNode) && typeof child.type === "string") observe(child);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
return CodeGenVisitor.prototype.defaultCodeGen.call(this, children);
|
|
1471
|
+
};
|
|
1472
|
+
_proto._observeWholeStruct = function _observeWholeStruct(struct) {
|
|
1473
|
+
var role = this.context.getStructRole([
|
|
1474
|
+
struct
|
|
1475
|
+
]);
|
|
1476
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(struct.propList), _step; !(_step = _iterator()).done;){
|
|
1477
|
+
var prop = _step.value;
|
|
1478
|
+
if (role === ShaderStructRole.Attribute) this.context.referenceAttribute(prop.ident);
|
|
1479
|
+
else if (role === ShaderStructRole.Varying) this.context.referenceVarying(prop.ident);
|
|
1480
|
+
else if (role === ShaderStructRole.Mrt) this.context.referenceMRTProp(prop.ident);
|
|
1481
|
+
}
|
|
1482
|
+
};
|
|
1483
|
+
_proto.visitFunctionHeader = function visitFunctionHeader(node) {
|
|
1484
|
+
if (node.ident.lexeme === "main" && this.context.stageEntry === "main") {
|
|
1485
|
+
return node.returnType.codeGen(this) + " " + this.context.names.allocate("entry-main", "entry_main") + "(";
|
|
1486
|
+
}
|
|
1487
|
+
return CodeGenVisitor.prototype.visitFunctionHeader.call(this, node);
|
|
1488
|
+
};
|
|
1489
|
+
_proto.visitFunctionIdentifier = function visitFunctionIdentifier(node) {
|
|
1490
|
+
var call = node.parent;
|
|
1491
|
+
if (node.lexeme === "main" && this.context.stageEntry === "main" && _instanceof(call, ASTNode.FunctionCallGeneric) && _instanceof(call.fnSymbol, FnSymbol)) {
|
|
1492
|
+
return this.context.names.allocate("entry-main", "entry_main");
|
|
1493
|
+
}
|
|
1494
|
+
return CodeGenVisitor.prototype.visitFunctionIdentifier.call(this, node);
|
|
1495
|
+
};
|
|
1496
|
+
_proto.visitFunctionDefinition = function visitFunctionDefinition(fnNode) {
|
|
1497
|
+
var definition = CodeGenVisitor.prototype.visitFunctionDefinition.call(this, fnNode);
|
|
1498
|
+
if (fnNode.protoType.ident.lexeme !== this.context.stageEntry) return definition;
|
|
1499
|
+
var args = [];
|
|
1500
|
+
var parameters = [];
|
|
1501
|
+
var _fnNode_protoType_parameterList;
|
|
1502
|
+
for(var _iterator = _create_for_of_iterator_helper_loose((_fnNode_protoType_parameterList = fnNode.protoType.parameterList) != null ? _fnNode_protoType_parameterList : []), _step; !(_step = _iterator()).done;){
|
|
1503
|
+
var parameter = _step.value;
|
|
1504
|
+
if (!parameter.ident || !parameter.typeInfo) continue;
|
|
1505
|
+
var struct = parameter.typeInfo.structDeclarations[0];
|
|
1506
|
+
if (struct) {
|
|
1507
|
+
var name = this.context.names.allocate(parameter, "input_" + parameter.ident.lexeme);
|
|
1508
|
+
parameters.push(this._interfaceTypeName(struct) + " " + name + " = " + this._transferName(struct, true) + "();");
|
|
1509
|
+
args.push(name);
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
var name1 = fnNode.protoType.ident.lexeme;
|
|
1513
|
+
var entryName = name1 === "main" ? this.context.names.allocate("entry-main", "entry_main") : name1;
|
|
1514
|
+
var call = entryName + "(" + args.join(", ") + ")";
|
|
1515
|
+
var type = fnNode.protoType.returnType;
|
|
1516
|
+
var struct1 = type.typeSpecifier.structDeclarations[0];
|
|
1517
|
+
var statement;
|
|
1518
|
+
if (struct1) {
|
|
1519
|
+
statement = this._transferName(struct1, false) + "(" + call + ");";
|
|
1520
|
+
} else if (this.context.stage === EShaderStage.FRAGMENT && type.type === Keyword.VEC4) {
|
|
1521
|
+
statement = this.fragmentColorOutput() + " = " + call + ";";
|
|
1522
|
+
} else statement = "" + call + ";";
|
|
1523
|
+
var inputs = this._initializeGlobalInputs();
|
|
1524
|
+
return definition + "\nvoid main() {\n" + inputs.join("\n") + "\n" + parameters.join("\n") + "\n" + statement + " }";
|
|
1525
|
+
};
|
|
1526
|
+
_proto._initializeGlobalInputs = function _initializeGlobalInputs() {
|
|
1527
|
+
var calls = new Set();
|
|
1528
|
+
var _this__globalInputs_get;
|
|
1529
|
+
for(var _iterator = _create_for_of_iterator_helper_loose((_this__globalInputs_get = this._globalInputs.get(this.context.stage)) != null ? _this__globalInputs_get : []), _step; !(_step = _iterator()).done;){
|
|
1530
|
+
var variable = _step.value;
|
|
1531
|
+
this.context.referenceGlobal(variable.ident, ESymbolType.VAR);
|
|
1532
|
+
var struct = variable.dataType.structDeclarations[0];
|
|
1533
|
+
var owner = this._declarationOwners.get(variable.astNode);
|
|
1534
|
+
this._referenceDeclaration(owner.id, struct);
|
|
1535
|
+
var group = this._inputHelperGroups.get(owner.group);
|
|
1536
|
+
if (!group) {
|
|
1537
|
+
var nextId = 0;
|
|
1538
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(this._declarationOwners.values()), _step1; !(_step1 = _iterator1()).done;){
|
|
1539
|
+
var declaration = _step1.value;
|
|
1540
|
+
nextId = Math.max(nextId, declaration.id);
|
|
1541
|
+
}
|
|
1542
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(this._inputHelperGroups.values()), _step2; !(_step2 = _iterator2()).done;){
|
|
1543
|
+
var helper = _step2.value;
|
|
1544
|
+
nextId = Math.max(nextId, helper.fallback.id);
|
|
1545
|
+
}
|
|
1546
|
+
// A missing conditional input selects the no-op; an active declaration selects its own initializer.
|
|
1547
|
+
var fallback = {
|
|
1548
|
+
id: nextId + 1,
|
|
1549
|
+
group: owner.group,
|
|
1550
|
+
sourceScope: -1
|
|
1551
|
+
};
|
|
1552
|
+
var name = this.context.names.allocate("input-initializer:" + owner.group, "initialize_" + variable.ident);
|
|
1553
|
+
this._inputHelperGroups.set(owner.group, group = {
|
|
1554
|
+
name: name,
|
|
1555
|
+
fallback: fallback
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1558
|
+
var target = this._interfaceVariableName(variable.ident, variable.dataType.structDeclarations);
|
|
1559
|
+
this._inputHelperBodies.set(variable.astNode, "void " + group.name + "() { " + target + " = " + this._transferName(struct, true) + "(); }");
|
|
1560
|
+
calls.add("" + group.name + "();");
|
|
1561
|
+
}
|
|
1562
|
+
return Array.from(calls);
|
|
1563
|
+
};
|
|
1266
1564
|
_proto.prepareFragment = function prepareFragment(entryInfo, outerGlobalMacroStatements) {
|
|
1267
1565
|
};
|
|
1268
1566
|
/**
|
|
@@ -1292,17 +1590,6 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1292
1590
|
}
|
|
1293
1591
|
}
|
|
1294
1592
|
};
|
|
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
1593
|
_proto._getGlobalSymbol = function _getGlobalSymbol(out) {
|
|
1307
1594
|
var context = this.context;
|
|
1308
1595
|
// Set iteration includes dependencies discovered while generating earlier declarations.
|
|
@@ -1423,11 +1710,6 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1423
1710
|
for(var _iterator2 = _create_for_of_iterator_helper_loose((_prototype_parameterList = prototype.parameterList) != null ? _prototype_parameterList : []), _step2; !(_step2 = _iterator2()).done;){
|
|
1424
1711
|
var parameter = _step2.value;
|
|
1425
1712
|
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
1713
|
var _parameter_typeInfo_structDeclarations;
|
|
1432
1714
|
this._prepareForwardTypes((_parameter_typeInfo_structDeclarations = (_parameter_typeInfo = parameter.typeInfo) == null ? void 0 : _parameter_typeInfo.structDeclarations) != null ? _parameter_typeInfo_structDeclarations : [], anchor, typeAnchor);
|
|
1433
1715
|
}
|
|
@@ -1435,12 +1717,9 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1435
1717
|
}
|
|
1436
1718
|
};
|
|
1437
1719
|
_proto._getForwardSignature = function _getForwardSignature(prototype) {
|
|
1438
|
-
var
|
|
1720
|
+
var _loop = function() {
|
|
1439
1721
|
var parameter = _step.value;
|
|
1440
1722
|
var declaration = parameter.astNode;
|
|
1441
|
-
if (_instanceof(declaration, ASTNode.ParameterDeclaration) && declaration.symbol && _this.context.getStructVarRole([
|
|
1442
|
-
declaration.symbol
|
|
1443
|
-
])) return "continue";
|
|
1444
1723
|
var tokens = [];
|
|
1445
1724
|
var visit = function(node) {
|
|
1446
1725
|
if (_instanceof(node, BaseToken)) {
|
|
@@ -1455,7 +1734,7 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1455
1734
|
};
|
|
1456
1735
|
var parameters = [];
|
|
1457
1736
|
var _prototype_parameterList;
|
|
1458
|
-
for(var _iterator = _create_for_of_iterator_helper_loose((_prototype_parameterList = prototype.parameterList) != null ? _prototype_parameterList : []), _step; !(_step = _iterator()).done;)
|
|
1737
|
+
for(var _iterator = _create_for_of_iterator_helper_loose((_prototype_parameterList = prototype.parameterList) != null ? _prototype_parameterList : []), _step; !(_step = _iterator()).done;)_loop();
|
|
1459
1738
|
return prototype.returnType.codeGen(this) + "(" + parameters.join(",") + ")";
|
|
1460
1739
|
};
|
|
1461
1740
|
_proto._canBranchesOverlap = function _canBranchesOverlap(left, right) {
|
|
@@ -1508,7 +1787,8 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1508
1787
|
};
|
|
1509
1788
|
var code = CodeGenVisitor.prototype.visitVariableIdentifier.call(this, node);
|
|
1510
1789
|
for(var _iterator = _create_for_of_iterator_helper_loose(node.resolvedSymbols()), _step; !(_step = _iterator()).done;)_this = this, _loop();
|
|
1511
|
-
|
|
1790
|
+
var _this__escapedReference;
|
|
1791
|
+
return (_this__escapedReference = this._escapedReference(node)) != null ? _this__escapedReference : code;
|
|
1512
1792
|
};
|
|
1513
1793
|
_proto._getForwardDeclarations = function _getForwardDeclarations(out) {
|
|
1514
1794
|
var _this, _loop = function() {
|
|
@@ -1684,6 +1964,7 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1684
1964
|
_proto._getCustomStruct = function _getCustomStruct(structNodes, out) {
|
|
1685
1965
|
for(var _iterator = _create_for_of_iterator_helper_loose(structNodes), _step; !(_step = _iterator()).done;){
|
|
1686
1966
|
var node = _step.value;
|
|
1967
|
+
if (this._structCodeSegments.has(node)) continue;
|
|
1687
1968
|
var text = node.codeGen(this);
|
|
1688
1969
|
if (!node.isInMacroBranch) {
|
|
1689
1970
|
out.push({
|
|
@@ -1808,7 +2089,8 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1808
2089
|
};
|
|
1809
2090
|
_proto._declaration = function _declaration(text, node, activate) {
|
|
1810
2091
|
if (activate === void 0) activate = true;
|
|
1811
|
-
|
|
2092
|
+
var initializer = text && this._inputHelperBodies.get(node);
|
|
2093
|
+
return ShaderInstructionEncoder.declaration(initializer ? text + "\n" + initializer : text, this._declarationOwners.get(node), activate);
|
|
1812
2094
|
};
|
|
1813
2095
|
_create_class(GLESVisitor, [
|
|
1814
2096
|
{
|
|
@@ -1824,57 +2106,29 @@ ShaderInstructionEncoder._FUNC_MACRO_RE = /^(\w+)\(([^)]*)\)\s*(.*)/;
|
|
|
1824
2106
|
var GLES100Visitor = /*#__PURE__*/ function(GLESVisitor) {
|
|
1825
2107
|
_inherits(GLES100Visitor, GLESVisitor);
|
|
1826
2108
|
function GLES100Visitor() {
|
|
1827
|
-
|
|
2109
|
+
var _this;
|
|
2110
|
+
_this = GLESVisitor.apply(this, arguments) || this, _this.supportsArrayStructReturn = false;
|
|
2111
|
+
return _this;
|
|
1828
2112
|
}
|
|
1829
2113
|
var _proto = GLES100Visitor.prototype;
|
|
1830
2114
|
_proto.getAttributeProp = function getAttributeProp(prop) {
|
|
1831
2115
|
return "attribute " + prop.typeInfo.typeLexeme + " " + prop.ident.lexeme + ";";
|
|
1832
2116
|
};
|
|
1833
2117
|
_proto.getVaryingProp = function getVaryingProp(prop) {
|
|
1834
|
-
return "varying " + prop.typeInfo.typeLexeme + " " + prop.
|
|
2118
|
+
return "varying " + prop.typeInfo.typeLexeme + " " + this.interfaceName(prop, ShaderStructRole.Varying) + ";";
|
|
1835
2119
|
};
|
|
1836
2120
|
_proto.getMRTProp = function getMRTProp() {
|
|
1837
2121
|
return "";
|
|
1838
2122
|
};
|
|
1839
|
-
_proto.
|
|
1840
|
-
|
|
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);
|
|
2123
|
+
_proto.fragmentColorOutput = function fragmentColorOutput() {
|
|
2124
|
+
return "gl_FragColor";
|
|
1861
2125
|
};
|
|
1862
|
-
_proto.
|
|
1863
|
-
|
|
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);
|
|
2126
|
+
_proto.mrtOutput = function mrtOutput(prop) {
|
|
2127
|
+
return "gl_FragData[" + prop.mrtIndex + "]";
|
|
1872
2128
|
};
|
|
1873
2129
|
return GLES100Visitor;
|
|
1874
2130
|
}(GLESVisitor);
|
|
1875
2131
|
|
|
1876
|
-
var V3_GL_FragColor = "GS_glFragColor";
|
|
1877
|
-
var V3_GL_FragData = "GS_glFragData";
|
|
1878
2132
|
var GLES300Visitor = /*#__PURE__*/ function(GLESVisitor) {
|
|
1879
2133
|
_inherits(GLES300Visitor, GLESVisitor);
|
|
1880
2134
|
function GLES300Visitor() {
|
|
@@ -1906,15 +2160,15 @@ var GLES300Visitor = /*#__PURE__*/ function(GLESVisitor) {
|
|
|
1906
2160
|
};
|
|
1907
2161
|
_proto.getVaryingProp = function getVaryingProp(prop) {
|
|
1908
2162
|
var qualifier = this.context.stage === EShaderStage.FRAGMENT ? "in" : "out";
|
|
1909
|
-
return qualifier + " " + prop.typeInfo.typeLexeme + " " + prop.
|
|
2163
|
+
return qualifier + " " + prop.typeInfo.typeLexeme + " " + this.interfaceName(prop, ShaderStructRole.Varying) + ";";
|
|
1910
2164
|
};
|
|
1911
2165
|
_proto.getMRTProp = function getMRTProp(prop) {
|
|
1912
|
-
return "layout(location = " + prop.mrtIndex + ") out vec4 " + prop.
|
|
2166
|
+
return "layout(location = " + prop.mrtIndex + ") out vec4 " + this.interfaceName(prop, ShaderStructRole.Mrt) + ";";
|
|
1913
2167
|
};
|
|
1914
2168
|
_proto.visitFunctionIdentifier = function visitFunctionIdentifier(node) {
|
|
1915
2169
|
var children = node.children;
|
|
1916
2170
|
var typeSpecifier = children[0];
|
|
1917
|
-
if (typeSpecifier.children.length !== 1 || typeSpecifier.structDependencies.length) {
|
|
2171
|
+
if (!node.isBuiltin || typeSpecifier.children.length !== 1 || typeSpecifier.structDependencies.length) {
|
|
1918
2172
|
// Struct constructors still need the shared type-dependency visitor.
|
|
1919
2173
|
return GLESVisitor.prototype.visitFunctionIdentifier.call(this, node);
|
|
1920
2174
|
}
|
|
@@ -1948,14 +2202,14 @@ var GLES300Visitor = /*#__PURE__*/ function(GLESVisitor) {
|
|
|
1948
2202
|
var context = this.context;
|
|
1949
2203
|
if (context.stage === EShaderStage.FRAGMENT && node.builtinSemantic === ShaderBuiltinSemantic.FragmentOutput0) {
|
|
1950
2204
|
this._registerFragColorVariable();
|
|
1951
|
-
return
|
|
2205
|
+
return this._fragmentColorName();
|
|
1952
2206
|
}
|
|
1953
2207
|
if (context.stage === EShaderStage.FRAGMENT && node.builtinSemantic === ShaderBuiltinSemantic.FragmentDepth) {
|
|
1954
2208
|
return "gl_FragDepth";
|
|
1955
2209
|
}
|
|
1956
2210
|
if (context.stage === EShaderStage.FRAGMENT && node.builtinSemantic === ShaderBuiltinSemantic.FragmentOutputArray) {
|
|
1957
2211
|
this._registerFragDataArray();
|
|
1958
|
-
return
|
|
2212
|
+
return this._fragmentDataName();
|
|
1959
2213
|
}
|
|
1960
2214
|
return GLESVisitor.prototype.visitVariableIdentifier.call(this, node);
|
|
1961
2215
|
};
|
|
@@ -1966,20 +2220,22 @@ var GLES300Visitor = /*#__PURE__*/ function(GLESVisitor) {
|
|
|
1966
2220
|
}
|
|
1967
2221
|
return GLESVisitor.prototype.visitPostfixExpression.call(this, node);
|
|
1968
2222
|
};
|
|
1969
|
-
_proto.
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
2223
|
+
_proto.fragmentColorOutput = function fragmentColorOutput() {
|
|
2224
|
+
this._registerFragColorVariable();
|
|
2225
|
+
return this._fragmentColorName();
|
|
2226
|
+
};
|
|
2227
|
+
_proto.mrtOutput = function mrtOutput(prop) {
|
|
2228
|
+
return this.interfaceName(prop, ShaderStructRole.Mrt);
|
|
2229
|
+
};
|
|
2230
|
+
_proto._fragmentColorName = function _fragmentColorName() {
|
|
2231
|
+
return this.context.names.allocate("fragment-output", "output_color");
|
|
2232
|
+
};
|
|
2233
|
+
_proto._fragmentDataName = function _fragmentDataName() {
|
|
2234
|
+
return this.context.names.allocate("fragment-output-array", "output_colors");
|
|
1980
2235
|
};
|
|
1981
2236
|
_proto._registerFragColorVariable = function _registerFragColorVariable() {
|
|
1982
|
-
this.
|
|
2237
|
+
var name = this._fragmentColorName();
|
|
2238
|
+
this._registerOutput(name, "out vec4 " + name + ";");
|
|
1983
2239
|
};
|
|
1984
2240
|
_proto._registerOutput = function _registerOutput(name, text) {
|
|
1985
2241
|
var output = this._outputDeclarations.get(name);
|
|
@@ -2032,10 +2288,11 @@ var GLES300Visitor = /*#__PURE__*/ function(GLESVisitor) {
|
|
|
2032
2288
|
}
|
|
2033
2289
|
};
|
|
2034
2290
|
_proto._registerFragDataArray = function _registerFragDataArray() {
|
|
2035
|
-
|
|
2291
|
+
var name = this._fragmentDataName();
|
|
2292
|
+
this._registerOutput(name, "layout(location = 0) out vec4 " + name + "[gl_MaxDrawBuffers];");
|
|
2036
2293
|
};
|
|
2037
2294
|
_proto._registerFragDataVariable = function _registerFragDataVariable(index) {
|
|
2038
|
-
var name = "" +
|
|
2295
|
+
var name = this.context.names.allocate("fragment-output:" + index, "output_color_" + index);
|
|
2039
2296
|
this._registerOutput(name, "layout(location = " + index + ") out vec4 " + name + ";");
|
|
2040
2297
|
return name;
|
|
2041
2298
|
};
|
|
@@ -2224,7 +2481,7 @@ function generateShaderProgram(ir, coreInfo, backend, preprocessorExpressions) {
|
|
|
2224
2481
|
|
|
2225
2482
|
/**
|
|
2226
2483
|
* Version of the shader compiler package, replaced with the package version during builds.
|
|
2227
|
-
*/ var version = "2.0.0-alpha.
|
|
2484
|
+
*/ var version = "2.0.0-alpha.56";
|
|
2228
2485
|
Logger.info("Galacean Engine Shader Compiler Version: " + version);
|
|
2229
2486
|
|
|
2230
2487
|
export { ShaderCompiler, version };
|