• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Engines
2
3Amber is designed to supported multiple graphics APIs. This is done through the
4engine layer. The parsing/executing side of Amber (which we'll call the
5frontend in this document) doesn't know anything about how the code is executed
6and is API agnostic. Mostly.
7
8
9## Engine Lifecycle
10The engine will go through several states as the script executes. First the
11engine will be created. The creation should not configure the backing graphics
12API. The creation just sets up the basic engine structure.
13
14```
15                                 Engine
16                                +------------------------------------+
17                                |              +----------+          |
18                       +---------------------->|  Create  |          |
19                       |        |              +----------+          |
20                       |        |                                    |                                                          +------------+
21                       |        |                                    |                                                  +------>|Entry Point |
22                       |        |             +------------+         |                                   +---------+    |       +------------+
23                       +--------------------->| Initialize |         |                       +---------->| Shaders +----+
24                       |        |             +------------+         |                       |           +---------+    |
25                       |        |                                    |                       |                          |       +--------------+
26    +----------+       |        |                                    |                       |                          +------>|Shader binary |
27    | Executor +-------+        |                                    |        +----------+   |        +---------------+         +--------------+
28    +----------+       |        |         *  +----------------+      |        |          |   +------->| Vertex Buffers|-----+
29                       +-------------------->|Create Pipeline +-------------->| Pipeline |---+        +---------------+     |
30                       |        |            +----------------+      |        |          |   |                              +--------+
31Executor execution     |        |                                    |        +----------+   |                                       |
32flows downwards        |        |                                    |                       |       +--------------------+          |
33                       |        |         * +---------------------+  |                       +------>| Colour Attachments |----------+
34                       +------------------->| Execute Do* methods |  |                       |       +--------------------+          |
35                       |        |           +---------------------+  |                       |                                       |
36                       |        |                                    |                       |                                       |      +--------------+
37                       |        |                                    |                       |      +-------------------------+      +----->| Backing data |
38                       |        |               +----------+         |                       +----->|Depth/Stencil Attachment |------+      +--------------+
39                       +----------------------->| Destroy  |         |                       |      +-------------------------+      |
40                                |               +----------+         |                       |                                       |
41                                |                                    |                       |           +-------------+             |
42                                |                                    |                       +---------->| Index Buffer|-------------+
43                                +------------------------------------+                       |           +-------------+             |
44                                                                                             |                                       |
45                                                                                             |          +---------------+            |
46                                                                                             +--------->| Other Buffers |------------+
47                                                                                                        +---------------+
48```
49
50Once created, the engine will be initialized. This initialization will receive
51the configured graphics API from the embedder. The engine can then setup any
52extra needed queues, verify features/extensions are available or do any extra
53configuration.
54
55With the engine initialized all of the pipelines will be created through a
56`CreatePipeline` method. The provided `amber::Pipeline` is fully specified
57at this point and provides:
58  * if this is a graphics or compute pipeline
59  * all shader information (including SPIR-V binary)
60  * all vertex/index buffer information.
61    * initial buffer data if provided
62    * descriptor set/binding information
63  * all colour attachments
64    * initial buffer data if provided
65    * location information
66  * all depth/stencil attachments
67  * all storage buffers
68    * initial buffer data if provided
69    * descriptor set/binding information
70  * framebuffer width/height
71
72The engine should go through and create all the needed pipeline resources.
73
74The shaders can be retrieved with `GetShaders`. The shader information provides
75the entry point to be used. The shader is pre-compiled and any optimizations
76will have been done already.
77
78Buffer data is stored depending on how it's used. For colour attachments use
79`GetcolorAttachments`. The depth/stencil is enabled if the `BufferInfo::buffer`
80pointer is not `nullptr` from `GetDepthBuffer`. The vertex buffers are retrieved
81from `GetVertexBuffers` and the index buffer is provided if `GetIndexBuffer`
82returns non-`nullptr`. For all other storage buffers the `GetBuffers` method
83will provide information on each buffer.
84
85Each of the buffers should be allocated and have the data from the buffers
86`ValuePtr` copied into the device side buffer.
87
88At this point, all information needed to run a pipeline should have been
89provided. The executor will then start running the commands provided in the
90script. This can request the engine to run compute pipelines, graphics pipelines
91or do various other things.
92
93There is an assumption that the data in the `amber::Buffer` for each of the
94buffers in the pipeline is always complete and up to date. This means when,
95for instance, a draw command executes on a pipeline each of the buffers needs
96to be read off the device and written back into the `amber::Buffer`.
97
98When the script is finished the engine destructor will be executed and must
99cleanup any resources created by the engine. It is the job of the embedder
100to shut down the graphics API.
101
102
103## API Layer
104The engine API is described in `src/engine.h`. The `Engine` base class must be
105implemented by the backend engine.
106
107
108### API Methods
109#### `Engine::Create`
110The engines are all created in `src/engine.cc`. The `Engine::Create` method
111will attempt to create the requested engine and return it if possible. When
112adding a new engine a new block needs to be added to this method. When
113`Engine::Create` is complete, the engine will be created but is _not_
114initialized.
115
116
117#### `Initialize`
118The engine is initialized through the `Initialize` method. The initialize will
119accept engine specific configuration as an `EngineConfig` parameter. This allows
120for clients to set configuration data needed for the engine. The assumption is
121that the engine itself does not initialize the graphics API. The API should
122have been provided and all needed information provided in the `EngineConfig`
123object.
124
125A `Delegate` object is also provided to the engine. The delegate object is used
126when the engine needs to talk back to the embedder. For instance, the delegates
127can tell the engine to `LogGraphicsCalls`. The engine then, should, call the
128`Log` method on the delegate for each internal graphics API method called.
129
130If the executing script specified specific features, instance or device
131extensions they will also be provided. The engine can use these as needed.
132
133
134#### `CreatePipeline`
135The `CreatePipeline` method is responsible for creating an engine specific
136version of the given `amber::Pipeline`. Each command which needs a pipeline
137will have the pipeline provided, so the engine must provide a way to go from
138the amber pipeline to the engine pipeline. There can also be multiple pipeline
139lines of a given type.
140
141All information on the pipeline will be provided including shader and buffer
142information.
143
144
145#### `DoClearColor`
146The `DoClearColor` command provides the colour that is to be used for a given
147pipeline when executing the `DoClear` command.
148
149
150#### `DoClearStencil`
151The `DoClearStencil` command provides the value that is to be used for clearing
152the stencil buffer for a given pipeline when `DoClear` is executed.
153
154
155#### `DoClearDepth`
156The `DoClearDepth` command provides the value that is to be used for clearing
157the depth buffer for a given pipeline when `DoClear` is executed.
158
159
160#### `DoClear`
161The `DoClear` command instructs the engine to clear the various colour and
162depth attachments for the given pipeline.
163
164
165#### `DoDrawRect`
166The `DoDrawRect` instructs the engine to draw the given pipeline in the box
167at (x,y) of size (width,height). The buffers must be read back into the backing
168`amber::Buffer` at the end of this method.
169
170
171#### `DoDrawGrid`
172The `DoDrawGrid` instructs the engine to draw the given pipeline in the box
173at (x,y) of size (width,height) split into cells (columns, rows). The buffers
174must be read back into the backing `amber::Buffer` at the end of this method.
175
176
177#### `DoDrawArrays`
178The `DoDrawArrays` instructs the engine to draw the given pipeline using
179the information in the attached vertex and index buffers.  The buffers must be
180read back into the backing `amber::Buffer` at the end of this method.
181
182
183#### `DoCompute`
184The `DoCompute` instructs the engine to execute the given compute pipeline with
185the provided (x,y,z) parameters.
186
187
188#### `DoEntryPoint`
189The `DoEntryPoint` command instructs the engine to change the entry point in
190the given pipeline for the give shader.
191
192
193#### `DoPatchParameterVertices`
194The `DoPatchParameterVertices` tells the engine to do a thing with some
195values....I don't really know what it means, heh.
196
197
198#### `DoBuffer`
199The `DoBuffer` command tells the engine that for a given pipeline the given
200data should be updated into the given buffer.
201
202
203#### `SetEngineData`
204There are cases where there is extra data for a given engine created by the
205front end system. That data is stored in a `EngineData` structure and passed
206into the engine through the `SetEngineData` method. The engine should make
207use if this data if it makes sense.
208
209
210## APIisms in the Frontend
211Most of the things which show up in the front end are the names for drawing
212topologies, image formats and other descriptions use the Vulkan names. So,
213`kR8G8B8A8_SINT` is directly from the Vulkan `VK_FORMAT_R8G8B8A8_SINT` type.
214In the case of image formats the engine will either need to convert to their own
215internal version, or ignore the type and use the `Format` components directly.
216