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