Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ShaderLab variable list declaration & CRLF break & macro #if bug #2465

Merged
merged 26 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6613ba2
feat: supprot global declaration list
Sway007 Dec 16, 2024
4130a87
feat: update unitest
Sway007 Dec 16, 2024
b27c4bd
feat: update unitest
Sway007 Dec 16, 2024
637d884
fix: last comment
Sway007 Dec 16, 2024
6f1fa10
feat: code opt
Sway007 Dec 16, 2024
e348595
feat: disable glsl compress for non mini package
Sway007 Dec 18, 2024
6c99773
Merge branch 'dev/1.4' of github.com:galacean/engine into dev/1.4
Sway007 Dec 25, 2024
c9fd98c
Merge branch 'dev/1.4' of github.com:galacean/engine into fix/shaderl…
Sway007 Dec 25, 2024
47da18a
feat: code opt
Sway007 Dec 26, 2024
8b0de12
feat: code opt
Sway007 Dec 26, 2024
cd47edc
fix: compatible with empty macro in if branch
Sway007 Dec 27, 2024
bc17b5e
Merge branch 'dev/1.4' of github.com:galacean/engine into dev/1.4
Sway007 Jan 2, 2025
b80c07d
Merge branch 'dev/1.4' of github.com:galacean/engine into dev/1.4
Sway007 Jan 2, 2025
6dac155
fix: shaderlab compatible with CRLF format
Sway007 Jan 2, 2025
3131488
Merge branch 'fix/shaderlab/crlf' into fix/shaderlab/global_decl_list
Sway007 Jan 2, 2025
fe9a4bd
Merge branch 'dev/1.4' of github.com:galacean/engine into dev/1.4
Sway007 Jan 2, 2025
f1efb56
Merge branch 'dev/1.4' of github.com:galacean/engine into dev/1.4
Sway007 Jan 6, 2025
d9a142a
Merge branch 'dev/1.4' of github.com:galacean/engine into dev/1.4
Sway007 Jan 7, 2025
3ec3b99
fix: ci
Sway007 Jan 3, 2025
35b5926
Merge branch 'dev/1.4' of github.com:galacean/engine into dev/1.4
Sway007 Jan 8, 2025
3748049
Merge branch 'dev/1.4' into fix/shaderlab/global_decl_list
Sway007 Jan 8, 2025
6cd03dd
feat: skip space compatible with multiple line
Sway007 Jan 8, 2025
f775ee5
feat: code opt
Sway007 Jan 8, 2025
b814758
feat: code opt
Sway007 Jan 8, 2025
ec9f4da
feat: code opt
Sway007 Jan 8, 2025
434742e
feat: code opt
Sway007 Jan 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/shader-lab/src/codeGen/CodeGenVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export abstract class CodeGenVisitor {
return this.defaultCodeGen(node.children);
}

visitGlobalVariableDeclaration(node: ASTNode.VariableDeclaration): string {
visitVariableDeclaration(node: ASTNode.VariableDeclaration): string {
const fullType = node.children[0];
if (fullType instanceof ASTNode.FullySpecifiedType && fullType.typeSpecifier.isCustom) {
VisitorContext.context.referenceGlobal(<string>fullType.type, ESymbolType.STRUCT);
Expand Down
2 changes: 1 addition & 1 deletion packages/shader-lab/src/codeGen/GLES300.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ASTNode } from "../parser/AST";
import { SymbolType } from "../parser/types";
import { BaseToken as Token } from "../common/BaseToken";
import { EKeyword, ETokenType, ShaderPosition } from "../common";
import { EKeyword, ETokenType } from "../common";
import { GLESVisitor } from "./GLESVisitor";
import { EShaderStage } from "../common/Enums";
import { ICodeSegment } from "./types";
Expand Down
2 changes: 1 addition & 1 deletion packages/shader-lab/src/common/BaseScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export default class BaseScanner {
const start = this.getCurPosition();
this.advance(2);
// single line comments
while (this.getCurChar() !== "\n") this._advance();
while (this.getCurChar() !== "\n" && !this.isEnd()) this._advance();
zhuxudong marked this conversation as resolved.
Show resolved Hide resolved
this.skipCommentsAndSpace();
return ShaderLab.createRange(start, this.getCurPosition());
} else if (this.peek(2) === "/*") {
Expand Down
1 change: 1 addition & 0 deletions packages/shader-lab/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export enum ETokenType {
COLON,
/** = */
EQUAL,
/** ; */
SEMICOLON,
/** ! */
BANG,
Expand Down
21 changes: 17 additions & 4 deletions packages/shader-lab/src/lalr/CFG.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,34 @@ const productionAndRules: [GrammarSymbol[], TranslationRule | undefined][] = [

...GrammarUtils.createProductionWithOptions(ENonTerminal.global_declaration, [
[ENonTerminal.precision_specifier],
[ENonTerminal.variable_declaration],
[ENonTerminal.variable_declaration_statement],
[ENonTerminal.struct_specifier],
[ENonTerminal.function_definition]
]),

...GrammarUtils.createProductionWithOptions(
ENonTerminal.variable_declaration,
[
[EKeyword.GS_RenderQueueType, ETokenType.ID, ETokenType.SEMICOLON],
[ENonTerminal.fully_specified_type, ETokenType.ID, ETokenType.SEMICOLON],
[ENonTerminal.fully_specified_type, ETokenType.ID, ENonTerminal.array_specifier, ETokenType.SEMICOLON]
[ENonTerminal.fully_specified_type, ETokenType.ID],
[ENonTerminal.fully_specified_type, ETokenType.ID, ENonTerminal.array_specifier]
],
ASTNode.VariableDeclaration.pool
),

...GrammarUtils.createProductionWithOptions(
ENonTerminal.variable_declaration_list,
[
[ENonTerminal.variable_declaration],
[ENonTerminal.variable_declaration_list, ETokenType.COMMA, ETokenType.ID],
[ENonTerminal.variable_declaration_list, ETokenType.COMMA, ETokenType.ID, ENonTerminal.array_specifier]
],
ASTNode.VariableDeclarationList.pool
),

...GrammarUtils.createProductionWithOptions(ENonTerminal.variable_declaration_statement, [
[ENonTerminal.variable_declaration_list, ETokenType.SEMICOLON]
]),

...GrammarUtils.createProductionWithOptions(
ENonTerminal.ext_builtin_type_specifier_nonarray,
[
Expand Down
11 changes: 0 additions & 11 deletions packages/shader-lab/src/lalr/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,6 @@ export default class GrammarUtils {
return ret;
}

static createProductionOptions(common: GrammarSymbol[], position: number, opts: GrammarSymbol[][]) {
const ret: GrammarSymbol[][] = [];
for (const opt of opts) {
const list = common.slice(0, position);
list.push(...opt);
list.push(...common.slice(position));
ret.push(list);
}
return ret;
}

static addMapSetItem<K, T>(map: Map<K, Set<T>>, k: K, v: T) {
const set = map.get(k) ?? new Set();
set.add(v);
Expand Down
66 changes: 53 additions & 13 deletions packages/shader-lab/src/parser/AST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,17 +234,23 @@
const fullyType = this.children[0] as FullySpecifiedType;
const id = this.children[1] as Token;
this.typeSpecifier = fullyType.typeSpecifier;
this.arraySpecifier = fullyType.typeSpecifier.arraySpecifier;

let sm: VarSymbol;
if (this.children.length === 2 || this.children.length === 4) {
const symbolType = new SymbolType(fullyType.type, fullyType.typeSpecifier.lexeme);
const symbolType = new SymbolType(fullyType.type, fullyType.typeSpecifier.lexeme, this.arraySpecifier);
const initializer = this.children[3] as Initializer;

sm = new VarSymbol(id.lexeme, symbolType, false, initializer);
} else {
const arraySpecifier = this.children[2] as ArraySpecifier;
// #if _VERBOSE
if (arraySpecifier && this.arraySpecifier) {
sa.error(arraySpecifier.location, "Array of array is not supported.");
}

Check warning on line 250 in packages/shader-lab/src/parser/AST.ts

View check run for this annotation

Codecov / codecov/patch

packages/shader-lab/src/parser/AST.ts#L249-L250

Added lines #L249 - L250 were not covered by tests
// #endif
this.arraySpecifier = arraySpecifier;
const symbolType = new SymbolType(fullyType.type, fullyType.typeSpecifier.lexeme, arraySpecifier);
const symbolType = new SymbolType(fullyType.type, fullyType.typeSpecifier.lexeme, this.arraySpecifier);
const initializer = this.children[4] as Initializer;

sm = new VarSymbol(id.lexeme, symbolType, false, initializer);
Expand Down Expand Up @@ -381,6 +387,9 @@
get arraySize(): number {
return (this.children?.[1] as ArraySpecifier)?.size;
}
get arraySpecifier(): ArraySpecifier {
return this.children[1] as ArraySpecifier;
}

get isCustom() {
return typeof this.type === "string";
Expand Down Expand Up @@ -459,7 +468,7 @@
else {
const id = child as VariableIdentifier;
if (!id.symbolInfo) {
sa.error(id.location, "Undeclared symbol:", id.lexeme);
sa.error(id.location, `Undeclared symbol: ${id.lexeme}`);
}
if (!ParserUtils.typeCompatible(EKeyword.INT, id.typeInfo)) {
sa.error(id.location, "Invalid integer.");
Expand Down Expand Up @@ -533,11 +542,6 @@
} else if (this.children.length === 4 || this.children.length === 6) {
const typeInfo = this.typeInfo;
const arraySpecifier = this.children[3] as ArraySpecifier;
// #if _VERBOSE
if (typeInfo.arraySpecifier && arraySpecifier) {
sa.error(arraySpecifier.location, "Array of array is not supported.");
}
// #endif
typeInfo.arraySpecifier = arraySpecifier;
const id = this.children[2] as Token;
sm = new VarSymbol(id.lexeme, typeInfo, false, this);
Expand Down Expand Up @@ -872,7 +876,7 @@
const fnSymbol = sa.symbolTable.lookup({ ident: fnIdent, symbolType: ESymbolType.FN, signature: paramSig });
if (!fnSymbol) {
// #if _VERBOSE
sa.error(this.location, "No overload function type found: ", functionIdentifier.ident);
sa.error(this.location, `No overload function type found: ${functionIdentifier.ident}`);
// #endif
return;
}
Expand Down Expand Up @@ -1398,21 +1402,57 @@
export class VariableDeclaration extends TreeNode {
static pool = ShaderLabUtils.createObjectPool(VariableDeclaration);

type: FullySpecifiedType;

override set(loc: ShaderRange, children: NodeChild[]) {
super.set(loc, children, ENonTerminal.variable_declaration);
}

override semanticAnalyze(sa: SematicAnalyzer): void {
const type = this.children[0] as FullySpecifiedType;
const ident = this.children[1] as Token;
let sm: VarSymbol;
sm = new VarSymbol(ident.lexeme, new SymbolType(type.type, type.typeSpecifier.lexeme), true, this);
this.type = type;
const sm = new VarSymbol(ident.lexeme, new SymbolType(type.type, type.typeSpecifier.lexeme), true, this);

sa.symbolTable.insert(sm);
}

override codeGen(visitor: CodeGenVisitor): string {
return visitor.visitGlobalVariableDeclaration(this);
return visitor.visitVariableDeclaration(this) + ";";
}
}

export class VariableDeclarationList extends TreeNode {
static pool = ShaderLabUtils.createObjectPool(VariableDeclarationList);

type: FullySpecifiedType;

override set(loc: ShaderRange, children: NodeChild[]): void {
super.set(loc, children, ENonTerminal.variable_declaration_list);
}

override semanticAnalyze(sa: SematicAnalyzer): void {
const { children } = this;
const length = children.length;
const variableDeclation = children[0] as VariableDeclaration;
const type = variableDeclation.type;
this.type = type;

if (length === 1) {
return;
}

const ident = children[2] as Token;

const newVariable = VariableDeclaration.pool.get();
if (length === 3) {
// variable_declaration_list ',' id
newVariable.set(ident.location, [type, ident]);

Check warning on line 1450 in packages/shader-lab/src/parser/AST.ts

View check run for this annotation

Codecov / codecov/patch

packages/shader-lab/src/parser/AST.ts#L1450

Added line #L1450 was not covered by tests
} else {
// variable_declaration_list ',' id array_specifier
newVariable.set(ident.location, [type, ident, children[3] as ArraySpecifier]);
}
newVariable.semanticAnalyze(sa);
Sway007 marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -1453,7 +1493,7 @@
this.symbolInfo = sa.symbolTable.lookup({ ident: token.lexeme, symbolType: ESymbolType.VAR }) as VarSymbol;
// #if _VERBOSE
if (!this.symbolInfo) {
sa.error(this.location, "undeclared identifier:", token.lexeme);
sa.error(this.location, `undeclared identifier: ${token.lexeme}`);
}
// #endif
}
Expand Down
2 changes: 2 additions & 0 deletions packages/shader-lab/src/parser/GrammarSymbol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export enum ENonTerminal {
// glsl
global_declaration,
variable_declaration,
variable_declaration_list,
variable_declaration_statement,
array_specifier_list,
array_specifier,
ext_builtin_type_specifier_nonarray,
Expand Down
9 changes: 5 additions & 4 deletions packages/shader-lab/src/parser/SemanticAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ShaderLab } from "../ShaderLab";
// #if _VERBOSE
import { GSError } from "../GSError";
// #endif
import { Logger } from "@galacean/engine";

export type TranslationRule<T = any> = (sa: SematicAnalyzer, ...tokens: NodeChild[]) => T;

Expand All @@ -24,7 +25,7 @@ export default class SematicAnalyzer {
private _shaderData = new ShaderData();

// #if _VERBOSE
readonly errors: GSError[] = [];
readonly errors: Error[] = [];
// #endif

get shaderData() {
Expand Down Expand Up @@ -64,13 +65,13 @@ export default class SematicAnalyzer {
return this._translationRuleTable.get(pid);
}

error(loc: ShaderRange, ...param: any[]) {
error(loc: ShaderRange, message: string) {
// #if _VERBOSE
const err = new GSError(GSErrorName.CompilationError, param.join(""), loc, ShaderLab._processingPassText);
const err = new GSError(GSErrorName.CompilationError, message, loc, ShaderLab._processingPassText);
this.errors.push(err);
return err;
// #else
throw new Error(param.join(""));
Logger.error(message);
// #endif
}
}
15 changes: 12 additions & 3 deletions packages/shader-lab/src/parser/TargetParser.y
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,25 @@ gs_shader_program:

global_declaration:
precision_specifier
| variable_declaration
| variable_declaration_statement
| struct_specifier
| function_definition
;

variable_declaration:
fully_specified_type id ';'
| fully_specified_type id array_specifier ';'
fully_specified_type id
| fully_specified_type id array_specifier
;

variable_declaration_list:
variable_declaration
| variable_declaration_list ',' id
| variable_declaration_list ',' id array_specifier
;

variable_declaration_statement:
variable_declaration_list ';'

variable_identifier:
id
;
Expand Down
3 changes: 3 additions & 0 deletions packages/shader-lab/src/parser/builtin/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,13 @@ BuiltinFunction._create("textureLod", EGenType.GVec4, EGenType.GSampler3D, EKeyw
BuiltinFunction._create("textureLod", EGenType.GVec4, EGenType.GSamplerCube, EKeyword.VEC3, EKeyword.FLOAT);
BuiltinFunction._create("textureLod", EKeyword.FLOAT, EKeyword.SAMPLER2D_SHADOW, EKeyword.VEC3, EKeyword.FLOAT);
BuiltinFunction._create("textureLod", EGenType.GVec4, EGenType.GSampler2DArray, EKeyword.VEC3, EKeyword.FLOAT);
BuiltinFunction._create("texture2DLodEXT", EGenType.GVec4, EGenType.GSampler2D, EKeyword.VEC2, EKeyword.FLOAT);
BuiltinFunction._create("texture2DLodEXT", EGenType.GVec4, EGenType.GSampler3D, EKeyword.VEC3, EKeyword.FLOAT);

BuiltinFunction._create("textureCube", EKeyword.SAMPLER_CUBE, EKeyword.VEC3);
BuiltinFunction._create("textureCube", EKeyword.SAMPLER_CUBE, EKeyword.VEC3, EKeyword.FLOAT);
BuiltinFunction._create("textureCubeLod", EKeyword.SAMPLER_CUBE, EKeyword.VEC3, EKeyword.FLOAT);
BuiltinFunction._create("textureCubeLodEXT", EGenType.GVec4, EGenType.GSamplerCube, EKeyword.VEC3, EKeyword.FLOAT);

BuiltinFunction._create(
"textureOffset",
Expand Down
19 changes: 19 additions & 0 deletions tests/src/shader-lab/shaders/demo.shader
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,20 @@ Shader "Water" {

/*Comment without leading space*/

// test global declaration list.
vec2 v1, v2[2], v3[3];

v2f vert(a2v v) {
v2f o;

vec2 weights[2], offsets[2];
weights[0] = vec2(.1);
offsets[1] = vec2(.1);

float[2] c;
c[0] = 1.0;
c[1] = .4;

o.v_uv = v.TEXCOORD_0;
vec4 tmp = renderer_MVMat * v.POSITION;
o.v_position = tmp.xyz;
Expand All @@ -109,6 +120,14 @@ Shader "Water" {
gl_FragColor = linearToGamma(gl_FragColor);
#endif


#define MATERIAL_ENABLE_SS_REFRACTION

#ifdef MATERIAL_ENABLE_SS_REFRACTION

// last lint comment
#endif

// For testing only (macro)
#if SCENE_SHADOW_TYPE == 2 || defined(XX_Macro)
gl_FragColor = linearToGamma(gl_FragColor);
Expand Down
Loading