blob: 586d529bc9494c1a8ee3474dc013245d69fee697 [file] [log] [blame] [view]
dan sinclairb6841782020-09-21 16:00:11 +00001# Tint Architecture
2
3```
Ben Clayton00eb8df2021-02-23 16:08:09 +00004 ┏━━━━━━━━┓ ┏━━━━━━┓
5 ┃ SPIR━V ┃ ┃ WGSL ┃
6 ┗━━━━┃━━━┛ ┗━━━┃━━┛
7 ▼ ▼
8 ┏━━━━━━━━━┃━━━━━━━━━━━━━━━━━━━━━━━━━━━┃━━━━━━━━┓
9 ┃ ┃ Reader ┃ ┃
10 ┃ ┃ ┃ ┃
11 ┃ ┏━━━━━━━┻━━━━━━┓ ┏━━━━━━┻━━━━━━┓ ┃
12 ┃ ┃ SPIRV-Reader ┃ ┃ WGSL-Reader ┃ ┃
13 ┃ ┗━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━┛ ┃
14 ┗━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┛
15
16 ┏━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━┓
17 ┃ ProgramBuilder ┃
18 ┃ (mutable) ┃
Ben Clayton8b0ceea2022-07-15 17:16:49 +000019 ┏━━━━━━━━━━━━►┫ ┏━━━━━┓ ┏━━━━━━━━━┓ ┃
20 ┃ ┃ ┃ AST ┃ ┃ Symbols ┃ ┃
21 ┃ ┃ ┗━━━━━┛ ┗━━━━━━━━━┛ ┃
Ben Clayton00eb8df2021-02-23 16:08:09 +000022 ┃ ┗━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┛
23 ┃ ▼
24 ┃ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┃┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
Ben Clayton8b0ceea2022-07-15 17:16:49 +000025 ▲ ┆ Resolve ▼ ┆
Ben Clayton00eb8df2021-02-23 16:08:09 +000026 ┏━━━┻━━━┓ ┆ ┏━━━━━━━━┻━━━━━━━━┓ ┆
Ben Clayton5f0ea112021-03-09 10:54:37 +000027 ┃ Clone ┃ ┆ ┃ Resolver ┃ ┆
Ben Clayton00eb8df2021-02-23 16:08:09 +000028 ┗━━━┳━━━┛ ┆ ┗━━━━━━━━━━━━━━━━━┛ ┆
29 ▲ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┃┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
30 ┃ ▼
31 ┃ ┏━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━┓
32 ┃ ┃ Program ┃
33 ┃ ┃ (immutable) ┃
Ben Clayton8b0ceea2022-07-15 17:16:49 +000034 ┣━━━━━━◄┫ ┏━━━━━┓ ┏━━━━━━━━━━┓ ┏━━━━━━━━━┓ ┃
35 ┃ ┃ ┃ AST ┃ ┃ Semantic ┃ ┃ Symbols ┃ ┃
36 ┃ ┃ ┗━━━━━┛ ┗━━━━━━━━━━┛ ┗━━━━━━━━━┛ ┃
Ben Clayton00eb8df2021-02-23 16:08:09 +000037 ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┛
38 ▲ ▼
Antonio Maioranod15391e2021-04-08 14:08:47 +000039┏━━━━━┻━━━━━┓ ┃ ┏━━━━━━━━━━━┓
40┃ Transform ┃◄━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━►┃ Inspector ┃
41┗━━━━━━━━━━━┛ ┃ ┗━━━━━━━━━━━┛
Ben Clayton00eb8df2021-02-23 16:08:09 +000042
Ben Clayton5f60eb72022-02-15 14:02:47 +000043┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
44┃ Writers ┃
45┃ ┃
46┃ ┏━━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━┓┏━━━━━━━━━━━━┓ ┃
47┃ ┃ SPIRV-Writer ┃┃ WGSL-Writer ┃┃ HLSL-Writer ┃┃ GLSL-Writer ┃┃ MSL-Writer ┃ ┃
48┃ ┗━━━━━━━┳━━━━━━┛┗━━━━━━┳━━━━━━┛┗━━━━━━┳━━━━━━┛┗━━━━━━┳━━━━━━┛┗━━━━━━┳━━━━━┛ ┃
49┗━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━━━━━━━━┃━━━━━━━┛
50 ▼ ▼ ▼ ▼ ▼
51 ┏━━━━┻━━━┓ ┏━━━┻━━┓ ┏━━━┻━━┓ ┏━━━┻━━┓ ┏━━┻━━┓
52 ┃ SPIR-V ┃ ┃ WGSL ┃ ┃ HLSL ┃ ┃ GLSL ┃ ┃ MSL ┃
53 ┗━━━━━━━━┛ ┗━━━━━━┛ ┗━━━━━━┛ ┗━━━━━━┛ ┗━━━━━┛
dan sinclairb6841782020-09-21 16:00:11 +000054```
55
Ben Clayton00eb8df2021-02-23 16:08:09 +000056## Reader
57
58Readers are responsible for parsing a shader program and populating a
Ben Clayton8b0ceea2022-07-15 17:16:49 +000059`ProgramBuilder` with the parsed AST and symbol information.
dan sinclairb6841782020-09-21 16:00:11 +000060
61The WGSL reader is a recursive descent parser. It closely follows the WGSL
62grammar in the naming of the parse methods.
63
Ben Clayton00eb8df2021-02-23 16:08:09 +000064## ProgramBuilder
65
Ben Clayton8b0ceea2022-07-15 17:16:49 +000066A `ProgramBuilder` is the interface to construct an immutable `Program`.
67There are a large number of helper methods for simplifying the creation of the
68AST nodes. A `ProgramBuilder` can only be used once, and must be discarded after
Ben Clayton00eb8df2021-02-23 16:08:09 +000069the `Program` is constructed.
70
Ben Clayton915ceca2023-07-29 13:12:58 +000071A `Program` is built from the `ProgramBuilder` via a call to
72`resolver::Resolve()`, which will perform validation and semantic analysis.
73The returned program will contain the semantic information which can be obtained
74by calling `Program::Sem()`.
Ben Clayton00eb8df2021-02-23 16:08:09 +000075
76At any time before building the `Program`, `ProgramBuilder::IsValid()` may be
Ben Clayton8b0ceea2022-07-15 17:16:49 +000077called to ensure that no error diagnostics have been raised during the
78construction of the AST. This includes parser syntax errors, but not semantic
79validation which happens during the `Resolve` phase.
Ben Clayton00eb8df2021-02-23 16:08:09 +000080
81If further changes to the `Program` are needed (say via a `Transform`) then a
82new `ProgramBuilder` can be produced by cloning the `Program` into a new
83`ProgramBuilder`.
84
85Unlike `Program`s, `ProgramBuilder`s are not part of the public Tint API.
dan sinclairb6841782020-09-21 16:00:11 +000086
87## AST
88
Ben Clayton00eb8df2021-02-23 16:08:09 +000089The Abstract Syntax Tree is a directed acyclic graph of `ast::Node`s which
90encode the syntactic structure of the WGSL program.
dan sinclairb6841782020-09-21 16:00:11 +000091
Ben Clayton00eb8df2021-02-23 16:08:09 +000092The root of the AST is the `ast::Module` class which holds each of the declared
Ben Clayton8b0ceea2022-07-15 17:16:49 +000093functions, variables and user declared types (type aliases and structures).
David Neto6d6aed52020-10-08 21:18:45 +000094
Ben Clayton00eb8df2021-02-23 16:08:09 +000095Each `ast::Node` represents a **single** part of the program's source, and so
96`ast::Node`s are not shared.
David Neto6d6aed52020-10-08 21:18:45 +000097
Ben Clayton00eb8df2021-02-23 16:08:09 +000098The AST does not perform any verification of its content. For example, the
Ben Clayton8b0ceea2022-07-15 17:16:49 +000099`ast::Array` node has numeric size parameter, which is not validated to be
100within the WGSL specification limits until validation of the `Resolver`.
Ben Clayton00eb8df2021-02-23 16:08:09 +0000101
102## Semantic information
103
Antonio Maiorano5cd71b82021-04-16 19:07:51 +0000104Semantic information is held by `sem::Node`s which describe the program at
Ben Clayton00eb8df2021-02-23 16:08:09 +0000105a higher / more abstract level than the AST. This includes information such as
Ben Claytonb85e6922022-02-02 23:07:11 +0000106the resolved type of each expression, the resolved overload of a builtin
Ben Clayton00eb8df2021-02-23 16:08:09 +0000107function call, and the module scoped variables used by each function.
108
Ben Clayton5f0ea112021-03-09 10:54:37 +0000109Semantic information is generated by the `Resolver` when the `Program`
Ben Clayton00eb8df2021-02-23 16:08:09 +0000110is built from a `ProgramBuilder`.
111
Antonio Maiorano5cd71b82021-04-16 19:07:51 +0000112The `sem::Info` class holds a map of `ast::Node`s to `sem::Node`s.
Ben Clayton00eb8df2021-02-23 16:08:09 +0000113This map is **many-to-one** - i.e. while a AST node might have a single
114corresponding semantic node, the reverse may not be true. For example:
Antonio Maiorano5cd71b82021-04-16 19:07:51 +0000115many `ast::IdentifierExpression` nodes may map to a single `sem::Variable`,
116and so the `sem::Variable` does not have a single corresponding
Ben Clayton00eb8df2021-02-23 16:08:09 +0000117`ast::Node`.
118
119Unlike `ast::Node`s, semantic nodes may not necessarily form a directed acyclic
120graph, and the semantic graph may contain diamonds.
121
Ben Clayton8b0ceea2022-07-15 17:16:49 +0000122## Types
123
124AST types are regular AST nodes, in that they uniquely represent a single part
125of the parsed source code. Unlike semantic types, identical AST types are not
126de-duplicated as they refer to the source usage of the type.
127
128Semantic types are constructed during the `Resolver` phase, and are held by
129the `Program` or `ProgramBuilder`.
130
131Each `sem::Type` node **uniquely** represents a particular WGSL type within the
132program, so you can compare `type::Type*` pointers to check for type
133equivalence. For example, a `Program` will only hold one instance of the
134`sem::I32` semantic type, no matter how many times an `i32` is mentioned in the
135source program.
136
137WGSL type aliases resolve to their target semantic type. For example, given:
138
139```wgsl
140type MyI32 = i32;
141const a : i32 = 1;
142const b : MyI32 = 2;
143```
144
145The **semantic** types for the variables `a` and `b` will both be the same
146`sem::I32` node pointer.
147
Ben Clayton00eb8df2021-02-23 16:08:09 +0000148## Symbols
149
150Symbols represent a unique string identifier in the source program. These string
151identifiers are transformed into symbols within the `Reader`s.
152
153During the Writer phase, symbols may be emitted as strings using a `Namer`.
154A `Namer` may output the symbol in any form that preserves the uniqueness of
155that symbol.
dan sinclairb6841782020-09-21 16:00:11 +0000156
Ben Clayton5f0ea112021-03-09 10:54:37 +0000157## Resolver
dan sinclairb6841782020-09-21 16:00:11 +0000158
Ben Clayton5f0ea112021-03-09 10:54:37 +0000159The `Resolver` will automatically run when a `Program` is built.
160A `Resolver` creates the `Program`s semantic information by analyzing the
Ben Clayton00eb8df2021-02-23 16:08:09 +0000161`Program`s AST and type information.
dan sinclairb6841782020-09-21 16:00:11 +0000162
Antonio Maioranod15391e2021-04-08 14:08:47 +0000163The `Resolver` will validate to make sure the generated `Program` is
164semantically valid.
Ben Clayton00eb8df2021-02-23 16:08:09 +0000165
166## Program
167
168A `Program` holds an immutable version of the information from the
169`ProgramBuilder` along with semantic information generated by the
Ben Clayton5f0ea112021-03-09 10:54:37 +0000170`Resolver`.
Ben Clayton00eb8df2021-02-23 16:08:09 +0000171
Ben Clayton8b0ceea2022-07-15 17:16:49 +0000172`Program::IsValid()` may be called to ensure the program is structurally correct
173**and** semantically valid, and that the `Resolver` did not report any errors
174during validation.
Ben Clayton00eb8df2021-02-23 16:08:09 +0000175
176Unlike the `ProgramBuilder`, a `Program` is fully immutable, and is part of the
177public Tint API. The immutable nature of `Program`s make these entirely safe
178to share between multiple threads without the use of synchronization primitives.
dan sinclairb6841782020-09-21 16:00:11 +0000179
dan sinclair66377ce2020-10-08 14:24:55 +0000180## Inspector
181
Ben Clayton00eb8df2021-02-23 16:08:09 +0000182The inspectors job is to go through the `Program` and pull out various pieces of
dan sinclair66377ce2020-10-08 14:24:55 +0000183information. The information may be used to pass information into the downstream
184compilers (things like specialization constants) or may be used to pass into
185transforms to update the AST before generating the resulting code.
dan sinclairb6841782020-09-21 16:00:11 +0000186
Ben Clayton00eb8df2021-02-23 16:08:09 +0000187The input `Program` to the inspector must be valid (pass validation).
188
dan sinclairb6841782020-09-21 16:00:11 +0000189## Transforms
190
Ben Clayton00eb8df2021-02-23 16:08:09 +0000191There maybe various transforms we want to run over the `Program`.
192This is for things like Vertex Pulling or Robust Buffer Access.
dan sinclairb6841782020-09-21 16:00:11 +0000193
Ben Clayton00eb8df2021-02-23 16:08:09 +0000194A transform operates by cloning the input `Program` into a new `ProgramBuilder`,
195applying the required changes, and then finally building and returning a new
Ben Clayton5f0ea112021-03-09 10:54:37 +0000196output `Program`. As the resolver is always run when a `Program` is built,
Ben Clayton00eb8df2021-02-23 16:08:09 +0000197Transforms will always emit a `Program` with semantic information.
dan sinclairb6841782020-09-21 16:00:11 +0000198
Ben Clayton00eb8df2021-02-23 16:08:09 +0000199The input `Program` to a transform must be valid (pass validation).
200If the input `Program` of a transform is valid then the transform must guarantee
201that the output program is also valid.
dan sinclairb6841782020-09-21 16:00:11 +0000202
203## Writers
204
Ben Clayton00eb8df2021-02-23 16:08:09 +0000205A writer is responsible for writing the `Program` in the target shader language.
206
207The input `Program` to a writer must be valid (pass validation).