@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 CHANGED
@@ -6964,11 +6964,14 @@
6964
6964
  var PostfixExpression = function(ExpressionAstNode) {
6965
6965
  _inherits$1(PostfixExpression, ExpressionAstNode);
6966
6966
  function PostfixExpression() {
6967
- return ExpressionAstNode.apply(this, arguments) || this;
6967
+ var _this;
6968
+ _this = ExpressionAstNode.apply(this, arguments) || this, _this.resolvedMemberOwners = EMPTY_STRUCT_DECLARATIONS;
6969
+ return _this;
6968
6970
  }
6969
6971
  var _proto = PostfixExpression.prototype;
6970
6972
  _proto.init = function init() {
6971
6973
  ExpressionAstNode.prototype.init.call(this);
6974
+ this.resolvedMemberOwners = EMPTY_STRUCT_DECLARATIONS;
6972
6975
  if (this.children.length === 1) {
6973
6976
  var child = this.children[0];
6974
6977
  this.type = child.type;
@@ -6985,7 +6988,8 @@
6985
6988
  if (reference) sa.shaderData.directMemberOwnerReferences.push(reference);
6986
6989
  }
6987
6990
  if (typeof base.type === "string") {
6988
- PostfixExpression._checkStructField(sa, base.type, children[2], this._branch);
6991
+ var _PostfixExpression__checkStructField;
6992
+ this.resolvedMemberOwners = (_PostfixExpression__checkStructField = PostfixExpression._checkStructField(sa, base.type, children[2], this._branch)) != null ? _PostfixExpression__checkStructField : EMPTY_STRUCT_DECLARATIONS;
6989
6993
  }
6990
6994
  }
6991
6995
  };
@@ -7031,10 +7035,9 @@
7031
7035
  sa.reportBranchAmbiguity(field.location, structName + "." + field.lexeme, "struct-member-presence", field.lexeme, structName);
7032
7036
  return;
7033
7037
  }
7034
- if (memberTypeDivergent) {
7035
- return;
7036
- }
7037
- if (firstProp) return;
7038
+ if (memberTypeDivergent || firstProp) return structs.map(function(symbol) {
7039
+ return symbol.astNode;
7040
+ });
7038
7041
  sa.reportUndeclaredStructMember(field.location, structName, field.lexeme);
7039
7042
  };
7040
7043
  return PostfixExpression;
@@ -13718,8 +13721,69 @@
13718
13721
  return Constructor;
13719
13722
  }
13720
13723
 
13724
+ /**
13725
+ * Words that ShaderLab accepts as identifiers but GLSL ES 1.00 or 3.00 reserves. GLES100 output also runs as
13726
+ * GLSL ES 3.00 on WebGL2, so both versions apply to every target.
13727
+ */ 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(" "));
13728
+ /**
13729
+ * Tests whether GLSL ES rejects an identifier that ShaderLab accepts.
13730
+ * @param name - Source identifier
13731
+ * @returns Whether the identifier uses a reserved word or namespace
13732
+ * @internal
13733
+ */ function isUnsafeGLSLIdentifier(name) {
13734
+ return reservedWords.has(name) || name.startsWith("gl_") || name.includes("__");
13735
+ }
13736
+ /**
13737
+ * Allocates generated identifiers that avoid source identifiers and each other.
13738
+ * @internal
13739
+ */ var NameAllocator = /*#__PURE__*/ function() {
13740
+ function NameAllocator() {
13741
+ this._used = new Set();
13742
+ this._names = new Map();
13743
+ }
13744
+ var _proto = NameAllocator.prototype;
13745
+ /**
13746
+ * Reserves a source identifier so that generated names never shadow it.
13747
+ * @param name - Source identifier
13748
+ */ _proto.reserve = function reserve(name) {
13749
+ this._used.add(name);
13750
+ };
13751
+ /**
13752
+ * Keeps a source identifier when GLSL accepts it, otherwise assigns a legal name to its identity.
13753
+ * @param key - Source declaration or namespace identity
13754
+ * @param name - Source identifier
13755
+ * @returns Identifier used by the declaration and its references
13756
+ */ _proto.sourceName = function sourceName(key, name) {
13757
+ if (!isUnsafeGLSLIdentifier(name)) return name;
13758
+ return this.allocate(key, name.startsWith("gl_") ? "user_" + name : "" + name + "_");
13759
+ };
13760
+ /**
13761
+ * Returns the same identifier for every request with the same key.
13762
+ * @param key - Identity of the generated declaration, independent of its spelling
13763
+ * @param preferred - Readable base name. Repeated underscores collapse to one, because WebGL rejects `__`
13764
+ * @returns An identifier that differs from every reserved and previously allocated name
13765
+ */ _proto.allocate = function allocate(key, preferred) {
13766
+ var name = this._names.get(key);
13767
+ if (name === undefined) {
13768
+ var base = preferred.replace(/_{2,}/g, "_");
13769
+ var separator = base.endsWith("_") ? "" : "_";
13770
+ name = base;
13771
+ for(var suffix = 1; this._used.has(name); suffix++)name = "" + base + separator + suffix;
13772
+ this._used.add(name);
13773
+ this._names.set(key, name);
13774
+ }
13775
+ return name;
13776
+ };
13777
+ /** Releases all reservations and allocations between compilation requests. */ _proto.reset = function reset() {
13778
+ this._used.clear();
13779
+ this._names.clear();
13780
+ };
13781
+ return NameAllocator;
13782
+ }();
13783
+
13721
13784
  /** @internal */ var VisitorContext = /*#__PURE__*/ function() {
13722
13785
  function VisitorContext() {
13786
+ this.names = new NameAllocator();
13723
13787
  this._lookupSymbol = new SymbolInfo("", null);
13724
13788
  this._structRoles = new Map();
13725
13789
  this._vertexUnresolvedVariableRoles = new Map();
@@ -13736,16 +13800,12 @@
13736
13800
  this._referencedGlobalMacroASTs = [];
13737
13801
  this._structVariableRoles = new Map();
13738
13802
  this.codeCache = new Map();
13739
- this.fragmentReturnModes = new Map();
13740
- this.terminalInterfaceReturns = new Set();
13741
13803
  this.reset();
13742
13804
  }
13743
13805
  var _proto = VisitorContext.prototype;
13744
13806
  _proto.reset = function reset(resetAll) {
13745
13807
  if (resetAll === void 0) resetAll = true;
13746
13808
  this.codeCache.clear();
13747
- this.fragmentReturnModes.clear();
13748
- this.terminalInterfaceReturns.clear();
13749
13809
  if (resetAll) {
13750
13810
  this.attributeStructs.length = 0;
13751
13811
  this.attributeList.length = 0;
@@ -13849,30 +13909,6 @@
13849
13909
  }
13850
13910
  return resolvedRole;
13851
13911
  };
13852
- /**
13853
- * Marks a value-return belonging to a fragment entry for backend lowering.
13854
- * @param statement - Exact return statement identity.
13855
- * @param mode - Fragment output contract of the containing entry declaration.
13856
- */ _proto.registerFragmentReturn = function registerFragmentReturn(statement, mode) {
13857
- this.fragmentReturnModes.set(statement, mode);
13858
- };
13859
- /**
13860
- * Finds the output contract for a fragment-entry return statement.
13861
- * @param statement - Return statement identity.
13862
- * @returns Output mode, or `undefined` for ordinary helper/vertex returns.
13863
- */ _proto.getFragmentReturnMode = function getFragmentReturnMode(statement) {
13864
- return this.fragmentReturnModes.get(statement);
13865
- };
13866
- /** Marks a syntactically final interface return whose control-flow exit can be omitted. */ _proto.registerTerminalInterfaceReturn = function registerTerminalInterfaceReturn(statement) {
13867
- this.terminalInterfaceReturns.add(statement);
13868
- };
13869
- /**
13870
- * Tests whether an interface return is the final syntactic statement in its function.
13871
- * @param statement - Return statement identity.
13872
- * @returns Whether backend lowering may omit a trailing `return;`.
13873
- */ _proto.isTerminalInterfaceReturn = function isTerminalInterfaceReturn(statement) {
13874
- return this.terminalInterfaceReturns.has(statement);
13875
- };
13876
13912
  _proto.referenceAttribute = function referenceAttribute(ident) {
13877
13913
  this._referenceProp(ident.lexeme, this.attributeList, this._referencedAttributeList);
13878
13914
  };
@@ -13949,7 +13985,7 @@
13949
13985
  var child = _step.value;
13950
13986
  if (_instanceof(child, BaseToken)) {
13951
13987
  // Legacy opaque `#define` lexemes carry the directive verbatim; expression-style defines use the AST path
13952
- ret.array.push(child.lexeme);
13988
+ ret.array.push(this.tokenLexeme(child));
13953
13989
  } else {
13954
13990
  ret.array.push(child.codeGen(this));
13955
13991
  }
@@ -13959,6 +13995,16 @@
13959
13995
  pool.return(ret);
13960
13996
  return result;
13961
13997
  };
13998
+ /**
13999
+ * Spells a source token in the generated code.
14000
+ * @param token - Source token
14001
+ * @returns Generated text for the token
14002
+ */ _proto.tokenLexeme = function tokenLexeme(token) {
14003
+ return token.lexeme;
14004
+ };
14005
+ _proto.interfaceMemberName = function interfaceMemberName(name) {
14006
+ return name;
14007
+ };
13962
14008
  _proto.visitPostfixExpression = function visitPostfixExpression(node) {
13963
14009
  var children = node.children;
13964
14010
  var derivationLength = children.length;
@@ -13979,13 +14025,13 @@
13979
14025
  var unresolvedName = ParserUtils.extractDirectIdentLexeme(postExpr);
13980
14026
  role = symbols.length ? context.getStructVarRole(symbols) : unresolvedName ? context.getUnresolvedStructVarRole(unresolvedName) : undefined;
13981
14027
  }
14028
+ if (!directRoot) role = context.getStructRole(node.resolvedMemberOwners);
13982
14029
  if (role) {
13983
14030
  if (role === ShaderStructRole.Attribute) context.referenceAttribute(prop);
13984
14031
  else if (role === ShaderStructRole.Varying) context.referenceVarying(prop);
13985
14032
  else context.referenceMRTProp(prop);
13986
- return prop.lexeme;
13987
14033
  }
13988
- return postExpr.codeGen(this) + "." + prop.lexeme;
14034
+ return postExpr.codeGen(this) + "." + (role ? this.interfaceMemberName(prop.lexeme) : prop.lexeme);
13989
14035
  } else {
13990
14036
  return postExpr.codeGen(this) + "." + prop.codeGen(this);
13991
14037
  }
@@ -14020,35 +14066,6 @@
14020
14066
  var symbol = _step.value;
14021
14067
  this.referenceFunction(symbol, node.location.start.index, node._branch);
14022
14068
  }
14023
- var paramList = call.children[2];
14024
- if (_instanceof(paramList, ASTNode.FunctionCallParameterList)) {
14025
- var astNodes = paramList.paramNodes;
14026
- var finalSymbol = this.context._referencedGlobals[call.fnSymbol.ident].find(function(candidate) {
14027
- return _instanceof(candidate, FnSymbol) && candidate.equal(call.fnSymbol);
14028
- });
14029
- var paramInfoList = (finalSymbol != null ? finalSymbol : call.fnSymbol).astNode.protoType.parameterList;
14030
- var context = this.context;
14031
- var params = astNodes.filter(function(_, i) {
14032
- var _paramInfoList_i;
14033
- var parameter = paramInfoList == null ? void 0 : (_paramInfoList_i = paramInfoList[i]) == null ? void 0 : _paramInfoList_i.astNode;
14034
- // Drop struct-IO parameters (attribute/varying/mrt) — they're flattened
14035
- // into top-level declarations and no longer exist as function-call args.
14036
- return !_instanceof(parameter, ASTNode.ParameterDeclaration) || !parameter.symbol || !context.getStructVarRole([
14037
- parameter.symbol
14038
- ]);
14039
- });
14040
- var paramsCode = "";
14041
- for(var i = 0, length = params.length; i < length; i++){
14042
- var astNode = params[i];
14043
- var code = astNode.codeGen(this);
14044
- if (_instanceof(astNode, ASTNode.MacroCallArgBlock) || i === 0) {
14045
- paramsCode += code;
14046
- } else {
14047
- paramsCode += ", " + code;
14048
- }
14049
- }
14050
- return call.fnSymbol.ident + "(" + paramsCode + ")";
14051
- }
14052
14069
  }
14053
14070
  return this.defaultCodeGen(node.children);
14054
14071
  };
@@ -14057,25 +14074,7 @@
14057
14074
  var paramList = children[2];
14058
14075
  if (_instanceof(paramList, ASTNode.FunctionCallParameterList)) {
14059
14076
  var astNodes = paramList.paramNodes;
14060
- var context = this.context;
14061
- // Drop bare IO-struct args only when the macro aliases a user fn (whose
14062
- // formal was flattened). All other shapes preserve args verbatim.
14063
- var params;
14064
- if (node.isFunctionLikeMacro || !node.aliasesNonBuiltinIdent) {
14065
- params = astNodes;
14066
- } else {
14067
- params = astNodes.filter(function(arg) {
14068
- if (_instanceof(arg, ASTNode.AssignmentExpression)) {
14069
- var variableParam = ParserUtils.unwrapBareIdentifier(arg, {
14070
- allowParens: false
14071
- });
14072
- if (variableParam && context.getStructVarRole(variableParam.resolvedValueSymbols())) {
14073
- return false;
14074
- }
14075
- }
14076
- return true;
14077
- });
14078
- }
14077
+ var params = astNodes;
14079
14078
  var paramsCode = "";
14080
14079
  for(var i = 0, length = params.length; i < length; i++){
14081
14080
  var argNode = params[i];
@@ -14101,8 +14100,7 @@
14101
14100
  };
14102
14101
  /**
14103
14102
  * Code-generate a `#define` macro parsed as expression AST. Produces a `#define`
14104
- * directive whose value is the AST-rewritten string — so varying flattening
14105
- * happens naturally via `visitPostfixExpression` inside the AST walk.
14103
+ * directive whose value retains ordinary expression and member-access semantics.
14106
14104
  */ _proto.visitMacroDefine = function visitMacroDefine(node) {
14107
14105
  // For function-like macros, preserve the original `(params)` lexeme verbatim —
14108
14106
  // the parameter list is user-authored text that shouldn't be canonicalized.
@@ -14124,79 +14122,27 @@
14124
14122
  var fullType = children[0];
14125
14123
  if (_instanceof(fullType, ASTNode.FullySpecifiedType) && fullType.typeSpecifier.isCustom) {
14126
14124
  var context = this.context;
14127
- // Global interface variables are flattened and therefore are not emitted as uniforms.
14125
+ // Global interface variables are mutable shader values, not material bindings.
14128
14126
  if (context.getStructVarRole([
14129
14127
  node.declarator.symbol
14130
14128
  ])) {
14131
- return "";
14129
+ return this.defaultCodeGen(children);
14132
14130
  }
14133
14131
  context.referenceGlobal(fullType.type, ESymbolType.STRUCT);
14134
14132
  }
14135
14133
  return "uniform " + this.defaultCodeGen(children);
14136
14134
  };
14137
14135
  _proto.visitDeclaration = function visitDeclaration(node) {
14138
- var context = this.context;
14139
- var children = node.children;
14140
- var child = children[0];
14141
- if (_instanceof(child, ASTNode.InitDeclaratorList)) {
14142
- var first = child.children[0];
14143
- var _child_declarator;
14144
- var declarator = (_child_declarator = child.declarator) != null ? _child_declarator : _instanceof(first, ASTNode.SingleDeclaration) ? first.declarator : undefined;
14145
- var role = declarator && context.getStructVarRole([
14146
- declarator.symbol
14147
- ]);
14148
- if (role === ShaderStructRole.Varying || role === ShaderStructRole.Mrt) return "";
14149
- }
14150
- return this.defaultCodeGen(children);
14136
+ return this.defaultCodeGen(node.children);
14151
14137
  };
14152
14138
  _proto.visitFunctionParameterList = function visitFunctionParameterList(node) {
14153
- var context = this.context;
14154
- var params = node.parameterInfoList.filter(function(item) {
14155
- var parameter = item.astNode;
14156
- return !_instanceof(parameter, ASTNode.ParameterDeclaration) || !parameter.symbol || !context.getStructVarRole([
14157
- parameter.symbol
14158
- ]);
14159
- });
14160
- var out = "";
14161
- for(var i = 0, length = params.length; i < length; i++){
14162
- var item = params[i];
14163
- var astNode = item.astNode;
14164
- var code = astNode.codeGen(this);
14165
- if (_instanceof(astNode, ASTNode.MacroParamBlock) || i === 0) {
14166
- out += code;
14167
- } else {
14168
- out += ", " + code;
14169
- }
14170
- }
14171
- return out;
14139
+ return this.defaultCodeGen(node.children);
14172
14140
  };
14173
14141
  _proto.visitFunctionHeader = function visitFunctionHeader(node) {
14174
- var returnType = node.returnType.typeSpecifier;
14175
- if (this.context.getStructRole(returnType.structDeclarations) === ShaderStructRole.Varying) {
14176
- return "void " + node.ident.lexeme + "(";
14177
- }
14178
14142
  return this.defaultCodeGen(node.children);
14179
14143
  };
14180
14144
  _proto.visitJumpStatement = function visitJumpStatement(node) {
14181
- var children = node.children;
14182
- var cmd = children[0];
14183
- if (cmd.type === Keyword.RETURN) {
14184
- var expr = children[1];
14185
- if (_instanceof(expr, ASTNode.Expression)) {
14186
- var returnVar = ParserUtils.unwrapNodeByType(expr, NoneTerminal.variable_identifier);
14187
- if (returnVar && this.context.getStructVarRole(returnVar.resolvedValueSymbols()) === ShaderStructRole.Varying) {
14188
- return this.context.isTerminalInterfaceReturn(node) ? "" : "return;";
14189
- }
14190
- var returnFnCall = ParserUtils.unwrapNodeByType(expr, NoneTerminal.function_call);
14191
- var calledFunction = returnFnCall == null ? void 0 : returnFnCall.children[0];
14192
- var returnDeclarations = _instanceof(calledFunction == null ? void 0 : calledFunction.fnSymbol, FnSymbol) ? calledFunction.fnSymbol.astNode.protoType.returnType.typeSpecifier.structDeclarations : [];
14193
- if (this.context.getStructRole(returnDeclarations) === ShaderStructRole.Varying) {
14194
- var call = "" + expr.codeGen(this) + ";";
14195
- return this.context.isTerminalInterfaceReturn(node) ? call : "{ " + call + " return; }";
14196
- }
14197
- }
14198
- }
14199
- return this.defaultCodeGen(children);
14145
+ return this.defaultCodeGen(node.children);
14200
14146
  };
14201
14147
  _proto.visitFunctionIdentifier = function visitFunctionIdentifier(node) {
14202
14148
  return this.defaultCodeGen(node.children);
@@ -14205,63 +14151,10 @@
14205
14151
  return this.defaultCodeGen(node.children);
14206
14152
  };
14207
14153
  _proto.visitStructSpecifier = function visitStructSpecifier(node) {
14208
- var _this = this;
14209
- var context = this.context;
14210
- var varyingStructs = context.varyingStructs, attributeStructs = context.attributeStructs, mrtStructs = context.mrtStructs;
14211
- var isVaryingStruct = varyingStructs.indexOf(node) !== -1;
14212
- var isAttributeStruct = attributeStructs.indexOf(node) !== -1;
14213
- var isMRTStruct = mrtStructs.indexOf(node) !== -1;
14214
- if (isVaryingStruct || isAttributeStruct || isMRTStruct) {
14215
- var _result;
14216
- var result = [];
14217
- (_result = result).push.apply(_result, [].concat(node.macroExpressions.map(function(item) {
14218
- return {
14219
- text: _instanceof(item, BaseToken) ? item.lexeme : item.codeGen(_this),
14220
- index: item.location.start.index
14221
- };
14222
- })));
14223
- for(var _iterator = _create_for_of_iterator_helper_loose(node.propList), _step; !(_step = _iterator()).done;){
14224
- var prop = _step.value;
14225
- var _context__referencedVaryingList_name, _context__referencedAttributeList_name, _context__referencedMRTList_name;
14226
- var name = prop.ident.lexeme;
14227
- if (isVaryingStruct && ((_context__referencedVaryingList_name = context._referencedVaryingList[name]) == null ? void 0 : _context__referencedVaryingList_name.indexOf(prop)) >= 0) {
14228
- result.push({
14229
- text: "" + this.getVaryingProp(prop) + "\n",
14230
- index: prop.ident.location.start.index
14231
- });
14232
- } else if (isAttributeStruct && ((_context__referencedAttributeList_name = context._referencedAttributeList[name]) == null ? void 0 : _context__referencedAttributeList_name.indexOf(prop)) >= 0) {
14233
- result.push({
14234
- text: "" + this.getAttributeProp(prop) + "\n",
14235
- index: prop.ident.location.start.index
14236
- });
14237
- } else if (isMRTStruct && ((_context__referencedMRTList_name = context._referencedMRTList[name]) == null ? void 0 : _context__referencedMRTList_name.indexOf(prop)) >= 0) {
14238
- result.push({
14239
- text: "" + this.getMRTProp(prop) + "\n",
14240
- index: prop.ident.location.start.index
14241
- });
14242
- }
14243
- }
14244
- var text = result.sort(function(a, b) {
14245
- return a.index - b.index;
14246
- }).map(function(item) {
14247
- return item.text;
14248
- }).join("");
14249
- return text;
14250
- } else {
14251
- return this.defaultCodeGen(node.children);
14252
- }
14154
+ return this.defaultCodeGen(node.children);
14253
14155
  };
14254
14156
  _proto.visitFunctionDefinition = function visitFunctionDefinition(fnNode) {
14255
- var fnName = fnNode.protoType.ident.lexeme;
14256
- var context = this.context;
14257
- var terminal = ParserUtils.lastStatement(fnNode.statements);
14258
- if (_instanceof(terminal, ASTNode.JumpStatement)) context.registerTerminalInterfaceReturn(terminal);
14259
- if (fnName == context.stageEntry) {
14260
- var statements = fnNode.statements.codeGen(this);
14261
- return "void main() " + statements;
14262
- } else {
14263
- return this.defaultCodeGen(fnNode.children);
14264
- }
14157
+ return this.defaultCodeGen(fnNode.children);
14265
14158
  };
14266
14159
  return CodeGenVisitor;
14267
14160
  }();
@@ -14630,7 +14523,7 @@
14630
14523
  _inherits(GLESVisitor, CodeGenVisitor);
14631
14524
  function GLESVisitor() {
14632
14525
  var _this;
14633
- _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 = [];
14526
+ _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 = [];
14634
14527
  return _this;
14635
14528
  }
14636
14529
  var _proto = GLESVisitor.prototype;
@@ -14646,6 +14539,8 @@
14646
14539
  this._variableCodeSegments.clear();
14647
14540
  this._deferredPrototypes.clear();
14648
14541
  this._declarationReferences.clear();
14542
+ this._inputHelperBodies.clear();
14543
+ this._inputHelperGroups.clear();
14649
14544
  this._currentDeclaration = undefined;
14650
14545
  };
14651
14546
  /**
@@ -14653,6 +14548,10 @@
14653
14548
  * @internal
14654
14549
  */ _proto.dispose = function dispose() {
14655
14550
  this.context.reset();
14551
+ this.context.names.reset();
14552
+ this._globalNames.clear();
14553
+ this._escapedDeclarations.clear();
14554
+ this._vertexOutputNames = undefined;
14656
14555
  this.reset();
14657
14556
  };
14658
14557
  /**
@@ -14660,8 +14559,15 @@
14660
14559
  * @param data - Parser-owned shader facts.
14661
14560
  * @param out - Destination code segments.
14662
14561
  */ _proto.getOtherGlobal = function getOtherGlobal(data, out) {
14663
- for(var _iterator = _create_for_of_iterator_helper_loose(data.globalPrecisions), _step; !(_step = _iterator()).done;){
14664
- var precision = _step.value;
14562
+ for(var _iterator = _create_for_of_iterator_helper_loose(this._inputHelperGroups.values()), _step; !(_step = _iterator()).done;){
14563
+ var _step_value = _step.value, name = _step_value.name, fallback = _step_value.fallback;
14564
+ out.push({
14565
+ text: ShaderInstructionEncoder.declaration("void " + name + "() {}", fallback) + ShaderInstructionEncoder.reference(0, fallback.id),
14566
+ index: -1
14567
+ });
14568
+ }
14569
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(data.globalPrecisions), _step1; !(_step1 = _iterator1()).done;){
14570
+ var precision = _step1.value;
14665
14571
  out.push({
14666
14572
  text: precision.codeGen(this),
14667
14573
  index: precision.location.start.index
@@ -14674,14 +14580,39 @@
14674
14580
  * @param coreInfo - Entry and stage-interface facts derived from the same IR.
14675
14581
  * @returns Generated vertex and fragment source.
14676
14582
  */ _proto.generate = function generate(ir, coreInfo) {
14677
- var _this = this;
14583
+ var _this, _loop = function(_i, _iter) {
14584
+ var _iter__i = _iter[_i], stage = _iter__i[0], variables = _iter__i[1];
14585
+ var inputRole = stage === EShaderStage.VERTEX ? ShaderStructRole.Attribute : ShaderStructRole.Varying;
14586
+ _this._globalInputs.set(stage, Array.from(variables).filter(function(param) {
14587
+ var variable = param[0], role = param[1];
14588
+ return role === inputRole && _instanceof(variable.astNode, ASTNode.VariableDeclaration);
14589
+ }).map(function(param) {
14590
+ var variable = param[0];
14591
+ return variable;
14592
+ }));
14593
+ };
14594
+ var _this1 = this;
14678
14595
  var _context_attributeStructs, _context_attributeList, _context_varyingStructs, _context_varyingList, _context_mrtStructs, _context_mrtList;
14679
14596
  this.context.reset();
14597
+ this.context.names.reset();
14598
+ this._globalNames.clear();
14599
+ this._escapedDeclarations.clear();
14600
+ this._vertexOutputNames = undefined;
14680
14601
  this.reset();
14681
14602
  var node = ir.program;
14682
14603
  var shaderData = node.shaderData;
14683
14604
  var context = this.context;
14684
14605
  context._passSymbolTable = shaderData.symbolTable;
14606
+ var hasUnsafeIdentifier = false;
14607
+ var _ir_source_match;
14608
+ 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;){
14609
+ var name = _step.value;
14610
+ context.names.reserve(name);
14611
+ hasUnsafeIdentifier || (hasUnsafeIdentifier = isUnsafeGLSLIdentifier(name));
14612
+ }
14613
+ shaderData.symbolTable.forEach(function(symbol) {
14614
+ return _this1._globalNames.add(symbol.ident);
14615
+ });
14685
14616
  var outerGlobalMacroDeclarations = coreInfo.outerGlobalMacroDeclarations;
14686
14617
  var io = coreInfo.io;
14687
14618
  (_context_attributeStructs = context.attributeStructs).push.apply(_context_attributeStructs, [].concat(io.attributeStructs));
@@ -14702,23 +14633,50 @@
14702
14633
  io.fragmentStructVariableRoles.forEach(function(role, variable) {
14703
14634
  context.registerStructVar(variable, role, EShaderStage.FRAGMENT);
14704
14635
  });
14636
+ if (hasUnsafeIdentifier) this._collectEscapedDeclarations(node);
14637
+ this._globalInputs.clear();
14638
+ for(var _i = 0, _iter = [
14639
+ [
14640
+ EShaderStage.VERTEX,
14641
+ io.vertexStructVariableRoles
14642
+ ],
14643
+ [
14644
+ EShaderStage.FRAGMENT,
14645
+ io.fragmentStructVariableRoles
14646
+ ]
14647
+ ]; _i < _iter.length; _i++)_this = this, _loop(_i, _iter);
14705
14648
  this._sourceIR = ir;
14706
14649
  this._outerMacroDeclarations = outerGlobalMacroDeclarations;
14707
14650
  try {
14708
14651
  coreInfo.deferredDeclarationOwnership.forEach(function(owner, symbol) {
14709
- return _this._declarationOwners.set(symbol.astNode, owner);
14652
+ return _this1._declarationOwners.set(symbol.astNode, owner);
14710
14653
  });
14654
+ var nextInputOwner = 0;
14655
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(this._declarationOwners.values()), _step1; !(_step1 = _iterator1()).done;){
14656
+ var owner = _step1.value;
14657
+ nextInputOwner = Math.max(nextInputOwner, owner.id, owner.group);
14658
+ }
14659
+ for(var _iterator2 = _create_for_of_iterator_helper_loose(this._globalInputs.values()), _step2; !(_step2 = _iterator2()).done;){
14660
+ var variables = _step2.value;
14661
+ for(var _iterator3 = _create_for_of_iterator_helper_loose(variables), _step3; !(_step3 = _iterator3()).done;){
14662
+ var variable = _step3.value;
14663
+ if (this._declarationOwners.has(variable.astNode)) continue;
14664
+ var id = ++nextInputOwner;
14665
+ this._declarationOwners.set(variable.astNode, {
14666
+ id: id,
14667
+ group: id,
14668
+ sourceScope: variable.sourceScope
14669
+ });
14670
+ }
14671
+ }
14711
14672
  if (this._declarationOwners.size) {
14712
- var nextId = 0;
14713
- var nextGroup = 0;
14714
- this._declarationOwners.forEach(function(owner) {
14715
- nextId = Math.max(nextId, owner.id);
14716
- nextGroup = Math.max(nextGroup, owner.group);
14717
- });
14673
+ // `nextInputOwner` already exceeds every owner id and group.
14674
+ var nextId = nextInputOwner;
14675
+ var nextGroup = nextInputOwner;
14718
14676
  // Reachability follows the selected declaration, including dependencies without an override.
14719
14677
  shaderData.symbolTable.forEach(function(symbol) {
14720
- if (symbol.astNode && !_this._declarationOwners.has(symbol.astNode)) {
14721
- _this._declarationOwners.set(symbol.astNode, {
14678
+ if (symbol.astNode && !_this1._declarationOwners.has(symbol.astNode)) {
14679
+ _this1._declarationOwners.set(symbol.astNode, {
14722
14680
  id: ++nextId,
14723
14681
  group: ++nextGroup,
14724
14682
  sourceScope: symbol.sourceScope
@@ -14728,54 +14686,71 @@
14728
14686
  context.onReferenceGlobal = function(symbols) {
14729
14687
  var _this_currentDeclarationOwner;
14730
14688
  var _this_currentDeclarationOwner_id;
14731
- var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner = _this.currentDeclarationOwner) == null ? void 0 : _this_currentDeclarationOwner.id) != null ? _this_currentDeclarationOwner_id : 0;
14689
+ var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner = _this1.currentDeclarationOwner) == null ? void 0 : _this_currentDeclarationOwner.id) != null ? _this_currentDeclarationOwner_id : 0;
14732
14690
  for(var _iterator = _create_for_of_iterator_helper_loose(symbols), _step; !(_step = _iterator()).done;){
14733
14691
  var symbol = _step.value;
14734
- _this._referenceDeclaration(from, symbol.astNode);
14692
+ _this1._referenceDeclaration(from, symbol.astNode);
14735
14693
  }
14736
14694
  };
14737
14695
  var propDeclarations = new Map();
14738
- for(var _iterator = _create_for_of_iterator_helper_loose([].concat(io.attributeStructs, io.varyingStructs, io.mrtStructs)), _step; !(_step = _iterator()).done;){
14739
- var struct = _step.value;
14740
- for(var _iterator1 = _create_for_of_iterator_helper_loose(struct.propList), _step1; !(_step1 = _iterator1()).done;){
14741
- var prop = _step1.value;
14696
+ for(var _iterator4 = _create_for_of_iterator_helper_loose([].concat(io.attributeStructs, io.varyingStructs, io.mrtStructs)), _step4; !(_step4 = _iterator4()).done;){
14697
+ var struct = _step4.value;
14698
+ for(var _iterator5 = _create_for_of_iterator_helper_loose(struct.propList), _step5; !(_step5 = _iterator5()).done;){
14699
+ var prop = _step5.value;
14742
14700
  propDeclarations.set(prop, struct);
14743
14701
  }
14744
14702
  }
14745
14703
  context.onReferenceStructProps = function(props) {
14746
14704
  var _this_currentDeclarationOwner;
14747
14705
  var _this_currentDeclarationOwner_id;
14748
- var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner = _this.currentDeclarationOwner) == null ? void 0 : _this_currentDeclarationOwner.id) != null ? _this_currentDeclarationOwner_id : 0;
14706
+ var from = (_this_currentDeclarationOwner_id = (_this_currentDeclarationOwner = _this1.currentDeclarationOwner) == null ? void 0 : _this_currentDeclarationOwner.id) != null ? _this_currentDeclarationOwner_id : 0;
14749
14707
  for(var _iterator = _create_for_of_iterator_helper_loose(props), _step; !(_step = _iterator()).done;){
14750
14708
  var prop = _step.value;
14751
- _this._referenceDeclaration(from, propDeclarations.get(prop));
14709
+ _this1._referenceDeclaration(from, propDeclarations.get(prop));
14752
14710
  }
14753
14711
  };
14754
14712
  }
14755
14713
  if (coreInfo.unsupportedDeferredDeclarations.length) {
14756
14714
  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);
14757
14715
  }
14716
+ this._fragmentVaryingProps.clear();
14717
+ var fragment = this._fragmentMain(coreInfo.fragmentEntry, shaderData, outerGlobalMacroDeclarations);
14718
+ var vertex = this._vertexMain(coreInfo.vertexEntry, shaderData, outerGlobalMacroDeclarations);
14758
14719
  return {
14759
- vertex: this._vertexMain(coreInfo.vertexEntry, shaderData, outerGlobalMacroDeclarations),
14760
- fragment: this._fragmentMain(coreInfo.fragmentEntry, shaderData, outerGlobalMacroDeclarations)
14720
+ vertex: vertex,
14721
+ fragment: fragment,
14722
+ vertexOutputNames: this._vertexOutputNames
14761
14723
  };
14762
14724
  } finally{
14763
14725
  this._sourceIR = undefined;
14764
14726
  this._outerMacroDeclarations = [];
14727
+ this._globalInputs.clear();
14765
14728
  this._declarationOwners.clear();
14766
14729
  context.onReferenceGlobal = undefined;
14767
14730
  context.onReferenceStructProps = undefined;
14731
+ this._fragmentVaryingProps.clear();
14732
+ this._globalNames.clear();
14733
+ this._escapedDeclarations.clear();
14734
+ this._vertexOutputNames = undefined;
14735
+ context.reset();
14736
+ context.names.reset();
14768
14737
  }
14769
14738
  };
14770
14739
  _proto._vertexMain = function _vertexMain(entryInfo, data, outerGlobalMacroDeclarations) {
14771
14740
  var context = this.context;
14772
14741
  context.stage = EShaderStage.VERTEX;
14773
14742
  context.stageEntry = entryInfo.name;
14743
+ for(var _iterator = _create_for_of_iterator_helper_loose(this._fragmentVaryingProps), _step; !(_step = _iterator()).done;){
14744
+ var prop = _step.value;
14745
+ context.referenceVarying(prop.ident);
14746
+ }
14774
14747
  // Attribute/varying structs were collected in ShaderCoreInfo
14775
14748
  // Pre-walk global `#define` values so referenced struct properties emit `attribute`/`varying` declarations.
14776
14749
  this._preRegisterGlobalMacroRefs(outerGlobalMacroDeclarations);
14777
14750
  var globalCodeArray = this._globalCodeArray;
14778
14751
  context.referenceGlobal(entryInfo.name, ESymbolType.FN);
14752
+ this._referenceInterfaceDependencies([].concat(context.attributeStructs, context.varyingStructs));
14753
+ this._initializeGlobalInputs();
14779
14754
  this._getGlobalSymbol(globalCodeArray);
14780
14755
  this._getCustomStruct(context.attributeStructs, globalCodeArray);
14781
14756
  this._getCustomStruct(context.varyingStructs, globalCodeArray);
@@ -14792,28 +14767,17 @@
14792
14767
  return globalCode;
14793
14768
  };
14794
14769
  _proto._fragmentMain = function _fragmentMain(entryInfo, data, outerGlobalMacroStatements) {
14795
- var _this = this;
14796
14770
  var context = this.context;
14797
14771
  context.stage = EShaderStage.FRAGMENT;
14798
14772
  context.stageEntry = entryInfo.name;
14799
14773
  this.prepareFragment(entryInfo, outerGlobalMacroStatements);
14800
- // Every value-return must preserve early-exit control flow after entry return values are
14801
- // lowered into fragment outputs.
14802
- entryInfo.functions.forEach(function(fnSymbol) {
14803
- var returnType = fnSymbol.astNode.protoType.returnType;
14804
- var mode = returnType.type === Keyword.VEC4 ? "color" : returnType.typeSpecifier.structDeclarations.some(function(struct) {
14805
- return context.hasStructRole(struct, ShaderStructRole.Mrt);
14806
- }) ? "mrt" : undefined;
14807
- if (mode) {
14808
- var statements = fnSymbol.astNode.statements;
14809
- _this._registerFragmentReturns(statements, mode, ParserUtils.lastStatement(statements));
14810
- }
14811
- });
14812
14774
  // Struct-variable identities are already populated from ShaderCoreInfo; just pre-walk macro
14813
14775
  // refs so struct codegen sees the references.
14814
14776
  this._preRegisterGlobalMacroRefs(outerGlobalMacroStatements);
14815
14777
  var globalCodeArray = this._globalCodeArray;
14816
14778
  context.referenceGlobal(entryInfo.name, ESymbolType.FN);
14779
+ this._referenceInterfaceDependencies([].concat(context.varyingStructs, context.mrtStructs));
14780
+ this._initializeGlobalInputs();
14817
14781
  this._getGlobalSymbol(globalCodeArray);
14818
14782
  this._getCustomStruct(context.varyingStructs, globalCodeArray);
14819
14783
  this._getCustomStruct(context.mrtStructs, globalCodeArray);
@@ -14825,10 +14789,347 @@
14825
14789
  }).map(function(item) {
14826
14790
  return item.text;
14827
14791
  }).join("\n");
14828
- context.reset();
14792
+ for(var _iterator = _create_for_of_iterator_helper_loose(Object.values(context._referencedVaryingList)), _step; !(_step = _iterator()).done;){
14793
+ var props = _step.value;
14794
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(props), _step1; !(_step1 = _iterator1()).done;){
14795
+ var prop = _step1.value;
14796
+ this._fragmentVaryingProps.add(prop);
14797
+ }
14798
+ }
14799
+ context.reset(false);
14829
14800
  this.reset();
14830
14801
  return globalCode;
14831
14802
  };
14803
+ _proto._referenceInterfaceDependencies = function _referenceInterfaceDependencies(structs) {
14804
+ for(var _iterator = _create_for_of_iterator_helper_loose(structs), _step; !(_step = _iterator()).done;){
14805
+ var struct = _step.value;
14806
+ this._currentDeclaration = struct;
14807
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(struct.propList), _step1; !(_step1 = _iterator1()).done;){
14808
+ var prop = _step1.value;
14809
+ var _prop_typeInfo_arraySpecifier;
14810
+ for(var _iterator2 = _create_for_of_iterator_helper_loose(prop.typeInfo.structDeclarations), _step2; !(_step2 = _iterator2()).done;){
14811
+ var dependency = _step2.value;
14812
+ if (dependency.ident) this.context.referenceGlobal(dependency.ident.lexeme, ESymbolType.STRUCT);
14813
+ }
14814
+ (_prop_typeInfo_arraySpecifier = prop.typeInfo.arraySpecifier) == null ? void 0 : _prop_typeInfo_arraySpecifier.codeGen(this);
14815
+ }
14816
+ }
14817
+ this._currentDeclaration = undefined;
14818
+ };
14819
+ /**
14820
+ * Resolves an interface member's global name, shared by both stages for varyings.
14821
+ * @param prop - Interface member
14822
+ * @param role - Stage-interface role of the member's structure
14823
+ * @returns Generated global identifier
14824
+ */ _proto.interfaceName = function interfaceName(prop, role) {
14825
+ var context = this.context;
14826
+ var name = prop.ident.lexeme;
14827
+ var isOutput = role === ShaderStructRole.Mrt;
14828
+ var sameName = function(item) {
14829
+ return item.ident.lexeme === name;
14830
+ };
14831
+ var conflicts = this._globalNames.has(name) || // Vertex attributes and fragment outputs share a stage scope with varyings.
14832
+ !isOutput && (context.attributeList.some(sameName) || context.mrtList.some(sameName));
14833
+ var key = (isOutput ? "output" : "varying") + ":" + name;
14834
+ var generated = isUnsafeGLSLIdentifier(name) ? context.names.sourceName(key, name) : conflicts ? context.names.allocate(key, name) : name;
14835
+ if (!isOutput && context.stage === EShaderStage.VERTEX && generated !== name) {
14836
+ var _this__vertexOutputNames;
14837
+ ((_this__vertexOutputNames = this._vertexOutputNames) != null ? _this__vertexOutputNames : this._vertexOutputNames = Object.create(null))[name] = generated;
14838
+ }
14839
+ return generated;
14840
+ };
14841
+ _proto.interfaceMemberName = function interfaceMemberName(name) {
14842
+ return this.context.names.sourceName("member:" + name, name);
14843
+ };
14844
+ _proto._interfaceTypeName = function _interfaceTypeName(struct) {
14845
+ var name = struct.ident.lexeme;
14846
+ return this.context.names.sourceName("type:" + name, name);
14847
+ };
14848
+ /**
14849
+ * Escapes interface-typed variables whose names GLSL ES reserves.
14850
+ * @param name - Source name
14851
+ * @param structs - Struct declarations of the variable type
14852
+ * @returns The escaped name, or the source name when no escape is necessary
14853
+ */ _proto._interfaceVariableName = function _interfaceVariableName(name, structs) {
14854
+ return (structs == null ? void 0 : structs.length) && this.context.getStructRole(structs) ? this.context.names.sourceName("variable:" + name, name) : name;
14855
+ };
14856
+ _proto._collectEscapedDeclarations = function _collectEscapedDeclarations(node) {
14857
+ if (_instanceof(node, ASTNode.TypeSpecifier) && this.context.getStructRole(node.structDeclarations)) {
14858
+ var _node_structDeclarations__ident;
14859
+ var token = node.children[0].children[0];
14860
+ if (_instanceof(token, BaseToken) && token.lexeme === ((_node_structDeclarations__ident = node.structDeclarations[0].ident) == null ? void 0 : _node_structDeclarations__ident.lexeme)) {
14861
+ var name = this._interfaceTypeName(node.structDeclarations[0]);
14862
+ if (name !== token.lexeme) this._escapedDeclarations.set(token, name);
14863
+ }
14864
+ }
14865
+ var identifier;
14866
+ var structs;
14867
+ if (_instanceof(node, ASTNode.ParameterDeclarator)) {
14868
+ var _node_typeInfo;
14869
+ identifier = node.ident;
14870
+ structs = (_node_typeInfo = node.typeInfo) == null ? void 0 : _node_typeInfo.structDeclarations;
14871
+ } else {
14872
+ var _declarator_typeInfo;
14873
+ // Local, global and multi-variable declarations share the parser's `declarator` record.
14874
+ var declarator = node.declarator;
14875
+ identifier = declarator == null ? void 0 : declarator.identifier;
14876
+ structs = declarator == null ? void 0 : (_declarator_typeInfo = declarator.typeInfo) == null ? void 0 : _declarator_typeInfo.structDeclarations;
14877
+ }
14878
+ if (identifier) {
14879
+ var name1 = this._interfaceVariableName(identifier.lexeme, structs);
14880
+ if (name1 !== identifier.lexeme) this._escapedDeclarations.set(identifier, name1);
14881
+ }
14882
+ for(var _iterator = _create_for_of_iterator_helper_loose(node.children), _step; !(_step = _iterator()).done;){
14883
+ var child = _step.value;
14884
+ if (_instanceof(child, TreeNode)) this._collectEscapedDeclarations(child);
14885
+ }
14886
+ };
14887
+ _proto.tokenLexeme = function tokenLexeme(token) {
14888
+ var _this__escapedDeclarations_get;
14889
+ return (_this__escapedDeclarations_get = this._escapedDeclarations.get(token)) != null ? _this__escapedDeclarations_get : token.lexeme;
14890
+ };
14891
+ _proto._escapedReference = function _escapedReference(node) {
14892
+ var token = node.children[0];
14893
+ if (!this._escapedDeclarations.size || !_instanceof(token, BaseToken) || !isUnsafeGLSLIdentifier(token.lexeme)) {
14894
+ return undefined;
14895
+ }
14896
+ var symbols = node.resolvedValueSymbols();
14897
+ if (!symbols.length) {
14898
+ // Macro values can lack symbols. The stage's unambiguous name-to-role map binds them, as for member access.
14899
+ return this.context.getUnresolvedStructVarRole(token.lexeme) ? this.context.names.sourceName("variable:" + token.lexeme, token.lexeme) : undefined;
14900
+ }
14901
+ var name;
14902
+ for(var _iterator = _create_for_of_iterator_helper_loose(symbols), _step; !(_step = _iterator()).done;){
14903
+ var symbol = _step.value;
14904
+ var _symbol_dataType;
14905
+ 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([
14906
+ symbol.astNode
14907
+ ]) ? this._interfaceTypeName(symbol.astNode) : token.lexeme;
14908
+ // Branch candidates must agree, otherwise the reference keeps its source spelling.
14909
+ if (name !== undefined && name !== candidate) return undefined;
14910
+ name = candidate;
14911
+ }
14912
+ return name;
14913
+ };
14914
+ _proto._transferName = function _transferName(struct, read) {
14915
+ return this.context.names.allocate((read ? "read" : "write") + ":" + struct.ident.lexeme, (read ? "read" : "write") + "_" + struct.ident.lexeme);
14916
+ };
14917
+ _proto.visitStructSpecifier = function visitStructSpecifier(node) {
14918
+ var _this = this;
14919
+ var context = this.context;
14920
+ var role = context.getStructRole([
14921
+ node
14922
+ ]);
14923
+ if (!role) return CodeGenVisitor.prototype.visitStructSpecifier.call(this, node);
14924
+ var typeName = this._interfaceTypeName(node);
14925
+ var memberCode = function(emit) {
14926
+ var segments = node.macroExpressions.map(function(item) {
14927
+ return {
14928
+ text: _instanceof(item, BaseToken) ? item.lexeme : item.codeGen(_this),
14929
+ index: item.location.start.index
14930
+ };
14931
+ });
14932
+ for(var _iterator = _create_for_of_iterator_helper_loose(node.propList), _step; !(_step = _iterator()).done;){
14933
+ var prop = _step.value;
14934
+ if (!retain(prop)) continue;
14935
+ segments.push({
14936
+ text: emit(prop),
14937
+ index: prop.ident.location.start.index
14938
+ });
14939
+ }
14940
+ return segments.sort(function(a, b) {
14941
+ return a.index - b.index;
14942
+ }).map(function(item) {
14943
+ return item.text;
14944
+ }).join("\n");
14945
+ };
14946
+ var references = role === ShaderStructRole.Attribute ? context._referencedAttributeList : role === ShaderStructRole.Varying ? context._referencedVaryingList : context._referencedMRTList;
14947
+ var used = function(prop) {
14948
+ var _references_prop_ident_lexeme;
14949
+ return !!((_references_prop_ident_lexeme = references[prop.ident.lexeme]) == null ? void 0 : _references_prop_ident_lexeme.includes(prop));
14950
+ };
14951
+ // Interface members have no array wire form, and GLSL ES 1.00 functions cannot return structures that contain
14952
+ // arrays. GLES100 therefore omits array members from interface structures.
14953
+ var retain = function(prop) {
14954
+ return _this.supportsArrayStructReturn || !_this._containsArray(prop);
14955
+ };
14956
+ var declaration = function(prop) {
14957
+ var _prop_typeInfo_arraySpecifier;
14958
+ var _prop_typeInfo_arraySpecifier_codeGen;
14959
+ 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 : "") + ";";
14960
+ };
14961
+ var structCode;
14962
+ var hasRetainedField = node.propList.some(retain);
14963
+ if (hasRetainedField && !node.macroExpressions.length) {
14964
+ structCode = "struct " + typeName + " {\n" + memberCode(declaration) + "\n};";
14965
+ } else {
14966
+ var hasFields = context.names.allocate(node, "" + typeName + "_has_fields");
14967
+ var padding = context.names.allocate("empty-interface-member", "interface_padding");
14968
+ // A macro configuration can remove every source field; GLSL still requires a nonempty struct.
14969
+ structCode = "#undef " + hasFields + "\nstruct " + typeName + " {\n" + memberCode(function(prop) {
14970
+ return declaration(prop) + "\n#define " + hasFields + "\n";
14971
+ }) + "\n#ifndef " + hasFields + "\nfloat " + padding + ";\n#endif\n};\n#undef " + hasFields + "\n";
14972
+ }
14973
+ var declarations = memberCode(function(prop) {
14974
+ var _this_getMRTProp;
14975
+ return !used(prop) ? "" : role === ShaderStructRole.Attribute ? _this.getAttributeProp(prop) : role === ShaderStructRole.Varying ? _this.getVaryingProp(prop) : (_this_getMRTProp = _this.getMRTProp(prop)) != null ? _this_getMRTProp : "";
14976
+ });
14977
+ var read = role === ShaderStructRole.Attribute || role === ShaderStructRole.Varying && context.stage === EShaderStage.FRAGMENT;
14978
+ var value = context.names.allocate("interface-value", "interface_value");
14979
+ var assignments = memberCode(function(prop) {
14980
+ if (!used(prop)) return "";
14981
+ var wire = role === ShaderStructRole.Attribute ? prop.ident.lexeme : role === ShaderStructRole.Mrt ? _this.mrtOutput(prop) : _this.interfaceName(prop, role);
14982
+ var member = value + "." + _this.interfaceMemberName(prop.ident.lexeme);
14983
+ return read ? member + " = " + wire + ";" : wire + " = " + member + ";";
14984
+ });
14985
+ var transfer = read ? typeName + " " + this._transferName(node, true) + "() { " + typeName + " " + value + ";\n" + assignments + "\nreturn " + value + "; }" : "void " + this._transferName(node, false) + "(" + typeName + " " + value + ") {\n" + assignments + "\n}";
14986
+ return structCode + "\n" + declarations + "\n" + transfer;
14987
+ };
14988
+ _proto._containsArray = function _containsArray(prop, visited) {
14989
+ var _this = this;
14990
+ if (visited === void 0) visited = new Set();
14991
+ if (prop.typeInfo.arraySpecifier) return true;
14992
+ for(var _iterator = _create_for_of_iterator_helper_loose(prop.typeInfo.structDeclarations), _step; !(_step = _iterator()).done;){
14993
+ var struct = _step.value;
14994
+ if (visited.has(struct)) continue;
14995
+ visited.add(struct);
14996
+ if (struct.propList.some(function(member) {
14997
+ return _this._containsArray(member, visited);
14998
+ })) return true;
14999
+ }
15000
+ return false;
15001
+ };
15002
+ _proto.defaultCodeGen = function defaultCodeGen(children) {
15003
+ var _this = this;
15004
+ var parent = _instanceof(children[0], TreeNode) ? children[0].parent : undefined;
15005
+ if (_instanceof(parent, ASTNode.EqualityExpression) && children.length === 3) {
15006
+ var observe = function(node) {
15007
+ if (_instanceof(node, ASTNode.VariableIdentifier)) {
15008
+ for(var _iterator = _create_for_of_iterator_helper_loose(node.resolvedValueSymbols()), _step; !(_step = _iterator()).done;){
15009
+ var symbol = _step.value;
15010
+ var _symbol_dataType;
15011
+ var _symbol_dataType_structDeclarations;
15012
+ 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;){
15013
+ var struct = _step1.value;
15014
+ _this._observeWholeStruct(struct);
15015
+ }
15016
+ }
15017
+ }
15018
+ if (_instanceof(node, ASTNode.FunctionCallGeneric)) {
15019
+ var _node_fnSymbol;
15020
+ var declaration = (_node_fnSymbol = node.fnSymbol) == null ? void 0 : _node_fnSymbol.astNode;
15021
+ if (_instanceof(declaration, ASTNode.StructSpecifier)) _this._observeWholeStruct(declaration);
15022
+ else if (_instanceof(declaration, ASTNode.FunctionDefinition)) {
15023
+ for(var _iterator2 = _create_for_of_iterator_helper_loose(declaration.protoType.returnType.typeSpecifier.structDeclarations), _step2; !(_step2 = _iterator2()).done;){
15024
+ var struct1 = _step2.value;
15025
+ _this._observeWholeStruct(struct1);
15026
+ }
15027
+ }
15028
+ }
15029
+ for(var _iterator3 = _create_for_of_iterator_helper_loose(node.children), _step3; !(_step3 = _iterator3()).done;){
15030
+ var child = _step3.value;
15031
+ if (_instanceof(child, TreeNode)) observe(child);
15032
+ }
15033
+ };
15034
+ for(var _iterator = _create_for_of_iterator_helper_loose(children), _step; !(_step = _iterator()).done;){
15035
+ var child = _step.value;
15036
+ if (_instanceof(child, TreeNode) && typeof child.type === "string") observe(child);
15037
+ }
15038
+ }
15039
+ return CodeGenVisitor.prototype.defaultCodeGen.call(this, children);
15040
+ };
15041
+ _proto._observeWholeStruct = function _observeWholeStruct(struct) {
15042
+ var role = this.context.getStructRole([
15043
+ struct
15044
+ ]);
15045
+ for(var _iterator = _create_for_of_iterator_helper_loose(struct.propList), _step; !(_step = _iterator()).done;){
15046
+ var prop = _step.value;
15047
+ if (role === ShaderStructRole.Attribute) this.context.referenceAttribute(prop.ident);
15048
+ else if (role === ShaderStructRole.Varying) this.context.referenceVarying(prop.ident);
15049
+ else if (role === ShaderStructRole.Mrt) this.context.referenceMRTProp(prop.ident);
15050
+ }
15051
+ };
15052
+ _proto.visitFunctionHeader = function visitFunctionHeader(node) {
15053
+ if (node.ident.lexeme === "main" && this.context.stageEntry === "main") {
15054
+ return node.returnType.codeGen(this) + " " + this.context.names.allocate("entry-main", "entry_main") + "(";
15055
+ }
15056
+ return CodeGenVisitor.prototype.visitFunctionHeader.call(this, node);
15057
+ };
15058
+ _proto.visitFunctionIdentifier = function visitFunctionIdentifier(node) {
15059
+ var call = node.parent;
15060
+ if (node.lexeme === "main" && this.context.stageEntry === "main" && _instanceof(call, ASTNode.FunctionCallGeneric) && _instanceof(call.fnSymbol, FnSymbol)) {
15061
+ return this.context.names.allocate("entry-main", "entry_main");
15062
+ }
15063
+ return CodeGenVisitor.prototype.visitFunctionIdentifier.call(this, node);
15064
+ };
15065
+ _proto.visitFunctionDefinition = function visitFunctionDefinition(fnNode) {
15066
+ var definition = CodeGenVisitor.prototype.visitFunctionDefinition.call(this, fnNode);
15067
+ if (fnNode.protoType.ident.lexeme !== this.context.stageEntry) return definition;
15068
+ var args = [];
15069
+ var parameters = [];
15070
+ var _fnNode_protoType_parameterList;
15071
+ for(var _iterator = _create_for_of_iterator_helper_loose((_fnNode_protoType_parameterList = fnNode.protoType.parameterList) != null ? _fnNode_protoType_parameterList : []), _step; !(_step = _iterator()).done;){
15072
+ var parameter = _step.value;
15073
+ if (!parameter.ident || !parameter.typeInfo) continue;
15074
+ var struct = parameter.typeInfo.structDeclarations[0];
15075
+ if (struct) {
15076
+ var name = this.context.names.allocate(parameter, "input_" + parameter.ident.lexeme);
15077
+ parameters.push(this._interfaceTypeName(struct) + " " + name + " = " + this._transferName(struct, true) + "();");
15078
+ args.push(name);
15079
+ }
15080
+ }
15081
+ var name1 = fnNode.protoType.ident.lexeme;
15082
+ var entryName = name1 === "main" ? this.context.names.allocate("entry-main", "entry_main") : name1;
15083
+ var call = entryName + "(" + args.join(", ") + ")";
15084
+ var type = fnNode.protoType.returnType;
15085
+ var struct1 = type.typeSpecifier.structDeclarations[0];
15086
+ var statement;
15087
+ if (struct1) {
15088
+ statement = this._transferName(struct1, false) + "(" + call + ");";
15089
+ } else if (this.context.stage === EShaderStage.FRAGMENT && type.type === Keyword.VEC4) {
15090
+ statement = this.fragmentColorOutput() + " = " + call + ";";
15091
+ } else statement = "" + call + ";";
15092
+ var inputs = this._initializeGlobalInputs();
15093
+ return definition + "\nvoid main() {\n" + inputs.join("\n") + "\n" + parameters.join("\n") + "\n" + statement + " }";
15094
+ };
15095
+ _proto._initializeGlobalInputs = function _initializeGlobalInputs() {
15096
+ var calls = new Set();
15097
+ var _this__globalInputs_get;
15098
+ 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;){
15099
+ var variable = _step.value;
15100
+ this.context.referenceGlobal(variable.ident, ESymbolType.VAR);
15101
+ var struct = variable.dataType.structDeclarations[0];
15102
+ var owner = this._declarationOwners.get(variable.astNode);
15103
+ this._referenceDeclaration(owner.id, struct);
15104
+ var group = this._inputHelperGroups.get(owner.group);
15105
+ if (!group) {
15106
+ var nextId = 0;
15107
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(this._declarationOwners.values()), _step1; !(_step1 = _iterator1()).done;){
15108
+ var declaration = _step1.value;
15109
+ nextId = Math.max(nextId, declaration.id);
15110
+ }
15111
+ for(var _iterator2 = _create_for_of_iterator_helper_loose(this._inputHelperGroups.values()), _step2; !(_step2 = _iterator2()).done;){
15112
+ var helper = _step2.value;
15113
+ nextId = Math.max(nextId, helper.fallback.id);
15114
+ }
15115
+ // A missing conditional input selects the no-op; an active declaration selects its own initializer.
15116
+ var fallback = {
15117
+ id: nextId + 1,
15118
+ group: owner.group,
15119
+ sourceScope: -1
15120
+ };
15121
+ var name = this.context.names.allocate("input-initializer:" + owner.group, "initialize_" + variable.ident);
15122
+ this._inputHelperGroups.set(owner.group, group = {
15123
+ name: name,
15124
+ fallback: fallback
15125
+ });
15126
+ }
15127
+ var target = this._interfaceVariableName(variable.ident, variable.dataType.structDeclarations);
15128
+ this._inputHelperBodies.set(variable.astNode, "void " + group.name + "() { " + target + " = " + this._transferName(struct, true) + "(); }");
15129
+ calls.add("" + group.name + "();");
15130
+ }
15131
+ return Array.from(calls);
15132
+ };
14832
15133
  _proto.prepareFragment = function prepareFragment(entryInfo, outerGlobalMacroStatements) {
14833
15134
  };
14834
15135
  /**
@@ -14858,17 +15159,6 @@
14858
15159
  }
14859
15160
  }
14860
15161
  };
14861
- _proto._registerFragmentReturns = function _registerFragmentReturns(node, mode, terminal) {
14862
- if (_instanceof(node, ASTNode.JumpStatement) && node.children.length === 3) {
14863
- this.context.registerFragmentReturn(node, mode);
14864
- if (node === terminal) this.context.registerTerminalInterfaceReturn(node);
14865
- return;
14866
- }
14867
- for(var _iterator = _create_for_of_iterator_helper_loose(node.children), _step; !(_step = _iterator()).done;){
14868
- var child = _step.value;
14869
- if (_instanceof(child, TreeNode)) this._registerFragmentReturns(child, mode, terminal);
14870
- }
14871
- };
14872
15162
  _proto._getGlobalSymbol = function _getGlobalSymbol(out) {
14873
15163
  var context = this.context;
14874
15164
  // Set iteration includes dependencies discovered while generating earlier declarations.
@@ -14989,11 +15279,6 @@
14989
15279
  for(var _iterator2 = _create_for_of_iterator_helper_loose((_prototype_parameterList = prototype.parameterList) != null ? _prototype_parameterList : []), _step2; !(_step2 = _iterator2()).done;){
14990
15280
  var parameter = _step2.value;
14991
15281
  var _parameter_typeInfo;
14992
- if (_instanceof(parameter.astNode, ASTNode.ParameterDeclaration) && parameter.astNode.symbol && this.context.getStructVarRole([
14993
- parameter.astNode.symbol
14994
- ])) {
14995
- continue;
14996
- }
14997
15282
  var _parameter_typeInfo_structDeclarations;
14998
15283
  this._prepareForwardTypes((_parameter_typeInfo_structDeclarations = (_parameter_typeInfo = parameter.typeInfo) == null ? void 0 : _parameter_typeInfo.structDeclarations) != null ? _parameter_typeInfo_structDeclarations : [], anchor, typeAnchor);
14999
15284
  }
@@ -15001,12 +15286,9 @@
15001
15286
  }
15002
15287
  };
15003
15288
  _proto._getForwardSignature = function _getForwardSignature(prototype) {
15004
- var _this, _loop = function() {
15289
+ var _loop = function() {
15005
15290
  var parameter = _step.value;
15006
15291
  var declaration = parameter.astNode;
15007
- if (_instanceof(declaration, ASTNode.ParameterDeclaration) && declaration.symbol && _this.context.getStructVarRole([
15008
- declaration.symbol
15009
- ])) return "continue";
15010
15292
  var tokens = [];
15011
15293
  var visit = function(node) {
15012
15294
  if (_instanceof(node, BaseToken)) {
@@ -15021,7 +15303,7 @@
15021
15303
  };
15022
15304
  var parameters = [];
15023
15305
  var _prototype_parameterList;
15024
- for(var _iterator = _create_for_of_iterator_helper_loose((_prototype_parameterList = prototype.parameterList) != null ? _prototype_parameterList : []), _step; !(_step = _iterator()).done;)_this = this, _loop();
15306
+ for(var _iterator = _create_for_of_iterator_helper_loose((_prototype_parameterList = prototype.parameterList) != null ? _prototype_parameterList : []), _step; !(_step = _iterator()).done;)_loop();
15025
15307
  return prototype.returnType.codeGen(this) + "(" + parameters.join(",") + ")";
15026
15308
  };
15027
15309
  _proto._canBranchesOverlap = function _canBranchesOverlap(left, right) {
@@ -15074,7 +15356,8 @@
15074
15356
  };
15075
15357
  var code = CodeGenVisitor.prototype.visitVariableIdentifier.call(this, node);
15076
15358
  for(var _iterator = _create_for_of_iterator_helper_loose(node.resolvedSymbols()), _step; !(_step = _iterator()).done;)_this = this, _loop();
15077
- return code;
15359
+ var _this__escapedReference;
15360
+ return (_this__escapedReference = this._escapedReference(node)) != null ? _this__escapedReference : code;
15078
15361
  };
15079
15362
  _proto._getForwardDeclarations = function _getForwardDeclarations(out) {
15080
15363
  var _this, _loop = function() {
@@ -15250,6 +15533,7 @@
15250
15533
  _proto._getCustomStruct = function _getCustomStruct(structNodes, out) {
15251
15534
  for(var _iterator = _create_for_of_iterator_helper_loose(structNodes), _step; !(_step = _iterator()).done;){
15252
15535
  var node = _step.value;
15536
+ if (this._structCodeSegments.has(node)) continue;
15253
15537
  var text = node.codeGen(this);
15254
15538
  if (!node.isInMacroBranch) {
15255
15539
  out.push({
@@ -15374,7 +15658,8 @@
15374
15658
  };
15375
15659
  _proto._declaration = function _declaration(text, node, activate) {
15376
15660
  if (activate === void 0) activate = true;
15377
- return ShaderInstructionEncoder.declaration(text, this._declarationOwners.get(node), activate);
15661
+ var initializer = text && this._inputHelperBodies.get(node);
15662
+ return ShaderInstructionEncoder.declaration(initializer ? text + "\n" + initializer : text, this._declarationOwners.get(node), activate);
15378
15663
  };
15379
15664
  _create_class(GLESVisitor, [
15380
15665
  {
@@ -15390,57 +15675,29 @@
15390
15675
  var GLES100Visitor = /*#__PURE__*/ function(GLESVisitor) {
15391
15676
  _inherits(GLES100Visitor, GLESVisitor);
15392
15677
  function GLES100Visitor() {
15393
- return GLESVisitor.apply(this, arguments) || this;
15678
+ var _this;
15679
+ _this = GLESVisitor.apply(this, arguments) || this, _this.supportsArrayStructReturn = false;
15680
+ return _this;
15394
15681
  }
15395
15682
  var _proto = GLES100Visitor.prototype;
15396
15683
  _proto.getAttributeProp = function getAttributeProp(prop) {
15397
15684
  return "attribute " + prop.typeInfo.typeLexeme + " " + prop.ident.lexeme + ";";
15398
15685
  };
15399
15686
  _proto.getVaryingProp = function getVaryingProp(prop) {
15400
- return "varying " + prop.typeInfo.typeLexeme + " " + prop.ident.lexeme + ";";
15687
+ return "varying " + prop.typeInfo.typeLexeme + " " + this.interfaceName(prop, ShaderStructRole.Varying) + ";";
15401
15688
  };
15402
15689
  _proto.getMRTProp = function getMRTProp() {
15403
15690
  return "";
15404
15691
  };
15405
- _proto.visitPostfixExpression = function visitPostfixExpression(node) {
15406
- var children = node.children;
15407
- var postExpr = children[0];
15408
- var context = this.context;
15409
- var directRoot = _instanceof(postExpr, ASTNode.PostfixExpression) ? ParserUtils.unwrapBareIdentifier(postExpr, {
15410
- allowParens: true
15411
- }) : undefined;
15412
- var _directRoot_resolvedValueSymbols;
15413
- var directSymbols = (_directRoot_resolvedValueSymbols = directRoot == null ? void 0 : directRoot.resolvedValueSymbols()) != null ? _directRoot_resolvedValueSymbols : [];
15414
- var unresolvedName = _instanceof(postExpr, ASTNode.PostfixExpression) ? ParserUtils.extractDirectIdentLexeme(postExpr) : null;
15415
- var directRole = directRoot ? directSymbols.length ? context.getStructVarRole(directSymbols) : unresolvedName ? context.getUnresolvedStructVarRole(unresolvedName) : undefined : undefined;
15416
- if (directRole === ShaderStructRole.Mrt) {
15417
- var propReferenced = children[2];
15418
- var prop = context.mrtList.find(function(item) {
15419
- return item.ident.lexeme === propReferenced.lexeme;
15420
- });
15421
- // The parser already validated struct fields (UndeclaredStructMember); a miss here is an
15422
- // already-errored shader, so emit nothing rather than re-report.
15423
- if (!prop) return "";
15424
- return "gl_FragData[" + prop.mrtIndex + "]";
15425
- }
15426
- return GLESVisitor.prototype.visitPostfixExpression.call(this, node);
15692
+ _proto.fragmentColorOutput = function fragmentColorOutput() {
15693
+ return "gl_FragColor";
15427
15694
  };
15428
- _proto.visitJumpStatement = function visitJumpStatement(node) {
15429
- var mode = this.context.getFragmentReturnMode(node);
15430
- var terminal = this.context.isTerminalInterfaceReturn(node);
15431
- if (mode === "mrt") return terminal ? "" : "return;";
15432
- if (mode === "color") {
15433
- var expression = node.children[1];
15434
- var assignment = "gl_FragColor = " + expression.codeGen(this) + ";";
15435
- return terminal ? assignment : "{ " + assignment + " return; }";
15436
- }
15437
- return GLESVisitor.prototype.visitJumpStatement.call(this, node);
15695
+ _proto.mrtOutput = function mrtOutput(prop) {
15696
+ return "gl_FragData[" + prop.mrtIndex + "]";
15438
15697
  };
15439
15698
  return GLES100Visitor;
15440
15699
  }(GLESVisitor);
15441
15700
 
15442
- var V3_GL_FragColor = "GS_glFragColor";
15443
- var V3_GL_FragData = "GS_glFragData";
15444
15701
  var GLES300Visitor = /*#__PURE__*/ function(GLESVisitor) {
15445
15702
  _inherits(GLES300Visitor, GLESVisitor);
15446
15703
  function GLES300Visitor() {
@@ -15472,15 +15729,15 @@
15472
15729
  };
15473
15730
  _proto.getVaryingProp = function getVaryingProp(prop) {
15474
15731
  var qualifier = this.context.stage === EShaderStage.FRAGMENT ? "in" : "out";
15475
- return qualifier + " " + prop.typeInfo.typeLexeme + " " + prop.ident.lexeme + ";";
15732
+ return qualifier + " " + prop.typeInfo.typeLexeme + " " + this.interfaceName(prop, ShaderStructRole.Varying) + ";";
15476
15733
  };
15477
15734
  _proto.getMRTProp = function getMRTProp(prop) {
15478
- return "layout(location = " + prop.mrtIndex + ") out vec4 " + prop.ident.lexeme + ";";
15735
+ return "layout(location = " + prop.mrtIndex + ") out vec4 " + this.interfaceName(prop, ShaderStructRole.Mrt) + ";";
15479
15736
  };
15480
15737
  _proto.visitFunctionIdentifier = function visitFunctionIdentifier(node) {
15481
15738
  var children = node.children;
15482
15739
  var typeSpecifier = children[0];
15483
- if (typeSpecifier.children.length !== 1 || typeSpecifier.structDependencies.length) {
15740
+ if (!node.isBuiltin || typeSpecifier.children.length !== 1 || typeSpecifier.structDependencies.length) {
15484
15741
  // Struct constructors still need the shared type-dependency visitor.
15485
15742
  return GLESVisitor.prototype.visitFunctionIdentifier.call(this, node);
15486
15743
  }
@@ -15514,14 +15771,14 @@
15514
15771
  var context = this.context;
15515
15772
  if (context.stage === EShaderStage.FRAGMENT && node.builtinSemantic === ShaderBuiltinSemantic.FragmentOutput0) {
15516
15773
  this._registerFragColorVariable();
15517
- return V3_GL_FragColor;
15774
+ return this._fragmentColorName();
15518
15775
  }
15519
15776
  if (context.stage === EShaderStage.FRAGMENT && node.builtinSemantic === ShaderBuiltinSemantic.FragmentDepth) {
15520
15777
  return "gl_FragDepth";
15521
15778
  }
15522
15779
  if (context.stage === EShaderStage.FRAGMENT && node.builtinSemantic === ShaderBuiltinSemantic.FragmentOutputArray) {
15523
15780
  this._registerFragDataArray();
15524
- return V3_GL_FragData;
15781
+ return this._fragmentDataName();
15525
15782
  }
15526
15783
  return GLESVisitor.prototype.visitVariableIdentifier.call(this, node);
15527
15784
  };
@@ -15532,20 +15789,22 @@
15532
15789
  }
15533
15790
  return GLESVisitor.prototype.visitPostfixExpression.call(this, node);
15534
15791
  };
15535
- _proto.visitJumpStatement = function visitJumpStatement(node) {
15536
- var mode = this.context.getFragmentReturnMode(node);
15537
- var terminal = this.context.isTerminalInterfaceReturn(node);
15538
- if (mode === "mrt") return terminal ? "" : "return;";
15539
- if (mode === "color") {
15540
- this._registerFragColorVariable();
15541
- var expression = node.children[1];
15542
- var assignment = V3_GL_FragColor + " = " + expression.codeGen(this) + ";";
15543
- return terminal ? assignment : "{ " + assignment + " return; }";
15544
- }
15545
- return GLESVisitor.prototype.visitJumpStatement.call(this, node);
15792
+ _proto.fragmentColorOutput = function fragmentColorOutput() {
15793
+ this._registerFragColorVariable();
15794
+ return this._fragmentColorName();
15795
+ };
15796
+ _proto.mrtOutput = function mrtOutput(prop) {
15797
+ return this.interfaceName(prop, ShaderStructRole.Mrt);
15798
+ };
15799
+ _proto._fragmentColorName = function _fragmentColorName() {
15800
+ return this.context.names.allocate("fragment-output", "output_color");
15801
+ };
15802
+ _proto._fragmentDataName = function _fragmentDataName() {
15803
+ return this.context.names.allocate("fragment-output-array", "output_colors");
15546
15804
  };
15547
15805
  _proto._registerFragColorVariable = function _registerFragColorVariable() {
15548
- this._registerOutput(V3_GL_FragColor, "out vec4 " + V3_GL_FragColor + ";");
15806
+ var name = this._fragmentColorName();
15807
+ this._registerOutput(name, "out vec4 " + name + ";");
15549
15808
  };
15550
15809
  _proto._registerOutput = function _registerOutput(name, text) {
15551
15810
  var output = this._outputDeclarations.get(name);
@@ -15598,10 +15857,11 @@
15598
15857
  }
15599
15858
  };
15600
15859
  _proto._registerFragDataArray = function _registerFragDataArray() {
15601
- this._registerOutput(V3_GL_FragData, "layout(location = 0) out vec4 " + V3_GL_FragData + "[gl_MaxDrawBuffers];");
15860
+ var name = this._fragmentDataName();
15861
+ this._registerOutput(name, "layout(location = 0) out vec4 " + name + "[gl_MaxDrawBuffers];");
15602
15862
  };
15603
15863
  _proto._registerFragDataVariable = function _registerFragDataVariable(index) {
15604
- var name = "" + V3_GL_FragData + index;
15864
+ var name = this.context.names.allocate("fragment-output:" + index, "output_color_" + index);
15605
15865
  this._registerOutput(name, "layout(location = " + index + ") out vec4 " + name + ";");
15606
15866
  return name;
15607
15867
  };
@@ -15790,7 +16050,7 @@
15790
16050
 
15791
16051
  /**
15792
16052
  * Version of the shader compiler package, replaced with the package version during builds.
15793
- */ var version = "2.0.0-alpha.54";
16053
+ */ var version = "2.0.0-alpha.56";
15794
16054
  engineCore.Logger.info("Galacean Engine Shader Compiler Version: " + version);
15795
16055
 
15796
16056
  exports.GSError = GSError;