1e5c31af7Sopenharmony_ci# Amber 2e5c31af7Sopenharmony_ci 3e5c31af7Sopenharmony_ciAmber is a multi-API shader test framework. Graphics and compute bugs can be 4e5c31af7Sopenharmony_cicaptured and communicated through a scripting interface. This removes the need 5e5c31af7Sopenharmony_cito program to the low level interface when reproducing bugs. 6e5c31af7Sopenharmony_ci 7e5c31af7Sopenharmony_ciAmber is broken into multiple layers: the applications, the parsing components 8e5c31af7Sopenharmony_ciand the script execution. 9e5c31af7Sopenharmony_ci 10e5c31af7Sopenharmony_ci## Applications 11e5c31af7Sopenharmony_ciThere are currently two applications, the `[amber](../samples/amber.cc)` 12e5c31af7Sopenharmony_ciapplication and the Amber integration into the 13e5c31af7Sopenharmony_ci[Vulkan Conformance Test Suite 'CTS'](https://github.com/KhronosGroup/VK-GL-CTS/tree/master/external/vulkancts/modules/vulkan/amber). These applications are responsible 14e5c31af7Sopenharmony_cifor configuring the script execution environment (setting up Vulkan, Dawn or 15e5c31af7Sopenharmony_cianother engine), calling into the parsing code to generate a test script and 16e5c31af7Sopenharmony_cithen passing that script into the script execution component. 17e5c31af7Sopenharmony_ci 18e5c31af7Sopenharmony_ciWe require the application to configure the execution engine. This allows the 19e5c31af7Sopenharmony_ciapplication to handle loading function pointers, doing configuration and other 20e5c31af7Sopenharmony_cisetups as required. There are no hardcoded assumptions in Amber as to how you're 21e5c31af7Sopenharmony_cisetting up the API to be tested. 22e5c31af7Sopenharmony_ci 23e5c31af7Sopenharmony_ciThis engine configuration is done through the `VulkanEngineConfig` in 24e5c31af7Sopenharmony_ci`amber/amber_vulkan.h` or the `DawnEngineConfig` in `amber/amber_dawn.h`. 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ciThe sample application does this configuration through the config_helper 27e5c31af7Sopenharmony_ciclasses. `samples/config_helper_vulkan.*` and `samples/config_helper_dawn.*`. 28e5c31af7Sopenharmony_ciFor the CTS, the Vulkan engine is already configured and we just set the 29e5c31af7Sopenharmony_ci`VulkanEngineConfig` as needed. 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ciAccessing Amber itself is done through the `Amber` class in `amber/amber.h`. We 32e5c31af7Sopenharmony_cirequire the application to parse and execute a script as two separate steps. 33e5c31af7Sopenharmony_ciThis separation allows for the shaders to be retrieved after a parse command 34e5c31af7Sopenharmony_ciand then pre-compiled and passed into the execution. Passing the compiled 35e5c31af7Sopenharmony_cishaders is optional. 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ci### Delegate 38e5c31af7Sopenharmony_ciA delegate object can be provided to Amber, for observing internal operations as 39e5c31af7Sopenharmony_cithe script is executed. The delegate can be a null pointer, to indicate no 40e5c31af7Sopenharmony_ciobservations are requested. 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ciIf the delegate is provided and the `LogGraphicsCalls` method returns 43e5c31af7Sopenharmony_ci`true` then the Vulkan API wrappers will call `Log` for each call into Vulkan. 44e5c31af7Sopenharmony_ciIf the `LogGraphicsCallsTime` also returns `true` then timings for those 45e5c31af7Sopenharmony_ciVulkan calls will also be recorded. The timestamps are retrieved from the 46e5c31af7Sopenharmony_ci`GetTimestampNS` callback. 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_ci### Buffer Extractions 49e5c31af7Sopenharmony_ciAmber can be instructed to retrieve the contents of buffers when execution is 50e5c31af7Sopenharmony_cicomplete. This is done through the `extractions` list in the Amber `Options` 51e5c31af7Sopenharmony_cistructure. You must set the `buffer_name` for each of the buffers you want to 52e5c31af7Sopenharmony_ciextract. When Amber completes it will fill out the `width`, `height` and set 53e5c31af7Sopenharmony_ciof `Value` objects for that buffer. 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_ci### Execution 56e5c31af7Sopenharmony_ciThere are two methods to execute a parsed script: `Execute` and 57e5c31af7Sopenharmony_ci`ExecuteWithShaderData`. They both accept the `Recipe` and `Options`, the 58e5c31af7Sopenharmony_ci`ExecuteWithShaderData` also accepts a map of shader name to data. The data 59e5c31af7Sopenharmony_ciis the compiled SPIR-V binary for the shader. This allows you to compile and 60e5c31af7Sopenharmony_cicache the shader if needed. 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_ci## Parsing component 63e5c31af7Sopenharmony_ciAmber can use scripts written in two dialects: 64e5c31af7Sopenharmony_ci[AmberScript](amber_script.md), and [VkScript](vk_script.md). The `AmberScript` 65e5c31af7Sopenharmony_ciparser will be used if the first 7 characters of the script are 66e5c31af7Sopenharmony_ci`#!amber`, otherwise the `VkScript` parser will be used. The parsers both 67e5c31af7Sopenharmony_cigenerate a `Script` which is our representation of the script file. 68e5c31af7Sopenharmony_ci 69e5c31af7Sopenharmony_ci### AmberScript 70e5c31af7Sopenharmony_ciThe AmberScript format maps closely to the format stored in the script objects. 71e5c31af7Sopenharmony_ciAs such, there is a single Parser class for AmberScript which produces all of 72e5c31af7Sopenharmony_cithe needed script components. 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_ci### VkScript 75e5c31af7Sopenharmony_ciFor VkScript we do a bit of work to make the script match AmberScript. A default 76e5c31af7Sopenharmony_cipipeline is generated and all content in the script is considered part of the 77e5c31af7Sopenharmony_cigenerated pipeline. We generate names for all of the buffers in the file. The 78e5c31af7Sopenharmony_ciframebuffer is named `framebuffer`. The generated depth buffer is named 79e5c31af7Sopenharmony_ci`depth_buffer`. For other buffers, we generate a name of `AutoBuf-<num>` where 80e5c31af7Sopenharmony_cithe number is the current number of buffers seen counting from 0. 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ciThe VkScript parser is broken into three major chunks. The `Parser`, 83e5c31af7Sopenharmony_ci`SectionParser` and `CommandParser`. The `Parser` is the overall driver for the 84e5c31af7Sopenharmony_ciparser. The `SectionParser` breaks the input file into the overall chunks (each 85e5c31af7Sopenharmony_ciof the sections separated by the \[blocks]). The `CommandParser` parses the 86e5c31af7Sopenharmony_ci`[test]` section specifically. For other sections they're parsed directly in 87e5c31af7Sopenharmony_cithe `Parser` object. 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ci### Parsed Representation 90e5c31af7Sopenharmony_ciThe `Script` object owns all of the pipelines, buffers, shaders, and command 91e5c31af7Sopenharmony_ciobjects. Other objects hold pointers but the script holds the `unique_ptr` for 92e5c31af7Sopenharmony_cithese objects. 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ci``` 95e5c31af7Sopenharmony_ci +--------+ +--------------+ 96e5c31af7Sopenharmony_ci | Script |---------------->| Requirements | 97e5c31af7Sopenharmony_ci +--------+ +--------------+ 98e5c31af7Sopenharmony_ci | 99e5c31af7Sopenharmony_ci +------------------+------------+--------+----------------------+ 100e5c31af7Sopenharmony_ci | | | | 101e5c31af7Sopenharmony_ci v v v v 102e5c31af7Sopenharmony_ci +---------+ +---------+ +---------+ +---------+ 103e5c31af7Sopenharmony_ci | +--------+ | +---------+ | +----------+ | +---------+ 104e5c31af7Sopenharmony_ci +--| +--------+ +--| +--------+ +--| +----------+ +--| +---------+ 105e5c31af7Sopenharmony_ci +--| Shader | +--| Buffer | +--| Pipeline | +--| Command | 106e5c31af7Sopenharmony_ci +--------+ +--------+ +----------+ +---------+ 107e5c31af7Sopenharmony_ci ^ ^ ^ | | ^ | | 108e5c31af7Sopenharmony_ci | | | | | +---------------+ | 109e5c31af7Sopenharmony_ciEntry point | | +-----------------+ | | 110e5c31af7Sopenharmony_ciOptimizations | | Descriptor Set | | 111e5c31af7Sopenharmony_ciType | | Binding | | 112e5c31af7Sopenharmony_ciCompiled Shader| | Attachment Location | | 113e5c31af7Sopenharmony_ci | | | | 114e5c31af7Sopenharmony_ci +------------------------------------------+ | 115e5c31af7Sopenharmony_ci | | 116e5c31af7Sopenharmony_ci +-----------------------------------------------+ 117e5c31af7Sopenharmony_ci BufferCommand 118e5c31af7Sopenharmony_ci``` 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ciA `Script` contains shaders, pipelines, buffers, and commands. Pipelines 121e5c31af7Sopenharmony_cicontain shaders and buffers. An Amber buffer corresponds to either a buffer 122e5c31af7Sopenharmony_ciresource or an image resource in the backend engine's API. 123e5c31af7Sopenharmony_ciScript execution assumes that after executing a command, each `Buffer` object 124e5c31af7Sopenharmony_cihas a reference to the latest data for that buffer or image copied into 125e5c31af7Sopenharmony_cithe buffers memory. This means that a draw command will need to copy buffer data to 126e5c31af7Sopenharmony_cithe device, execute the draw, and then copy the device data back into the 127e5c31af7Sopenharmony_cibuffer. Amber does not do any extra calls to fill the buffers. Then engine must 128e5c31af7Sopenharmony_cikeep that data in sync. 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ciThe `Pipeline` object holds the context for a given set of tests. This includes 131e5c31af7Sopenharmony_cishaders, colour attachments, depth/stencil attachment, data buffers, etc. The 132e5c31af7Sopenharmony_cicolour attachments will have their `Attachment Location` while data buffers 133e5c31af7Sopenharmony_ciwill have a `Descriptor Set` and `Binding` provided. 134e5c31af7Sopenharmony_ci 135e5c31af7Sopenharmony_ci## Execution 136e5c31af7Sopenharmony_ciWhen the script is executed the pipeline shaders will be compiled, if not 137e5c31af7Sopenharmony_ciprovided through the shader map. This will fill in the `Compiled Shader` data 138e5c31af7Sopenharmony_ciin the each pipeline shader object. The `CreatePipeline` call will then be 139e5c31af7Sopenharmony_ciexecuted for a given pipeline. 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_ciWith the pipelines created the `Command` objects will be executed. Each 142e5c31af7Sopenharmony_ci`Command` knows the Amber `Pipeline` associated with it, that `Pipeline` pointer 143e5c31af7Sopenharmony_ciis provided in the command execution and can be used to lookup the 144e5c31af7Sopenharmony_ciengine-specific representation of a pipeline. 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ciWhen the `Probe` and `ProbeSSBO` commands are encountered they are not passed 147e5c31af7Sopenharmony_cito the engine but sent to the `Verifier`. This will validate that the data 148e5c31af7Sopenharmony_ciin the specified buffer matches the test data. As mentioned above, this assumes 149e5c31af7Sopenharmony_cithat the Amber `Buffer` is kept up to date with the current device memory as we 150e5c31af7Sopenharmony_cido not attempt to fill in the buffers before executing the `Probe*` calls. 151