1# Amber
2
3Amber is a multi-API shader test framework.
4
5Amber lets you capture and communicate shader bugs with the fluidity and ease of
6a scripting flow:
7
8* No graphics API programming is required.
9  * Supports Vulkan graphics API
10  * WIP: Supports [Dawn][Dawn] graphics API
11* A single text string (or file) maps to a single graphics API pipeline test
12  case. The text includes:
13  * Input data, including buffers and images.
14  * Shaders.
15  * Expectations for the result of running the pipeline.
16* Shaders can be expressed in binary form (as hex), in SPIR-V assembly, or in a
17  higher level shader language.
18* After executing the pipeline, result buffers and images can be saved to output
19  files.
20
21Amber is influenced by [Talvos][Talvos] and [VkRunner][VkRunner].
22The [VkScript](docs/vk_script.md) syntax matches the format used by VkRunner.
23
24This is not an officially supported Google product.
25
26## Writing Amber Tests
27Working with Amber involves writing input test files. Some example files can be
28see in the [tests/cases](tests/cases) folder.
29
30The main input format is [Amberscript](docs/amber_script.md). New features are
31added to AmberScript as Amber is enhanced. This is the preferred format in which
32new script files are written.
33
34### Clear test as AmberScript
35
36```groovy
37SHADER vertex vtex_shader PASSTHROUGH
38SHADER fragment frag_shader GLSL
39#version 430
40
41layout(location = 0) in vec4 color_in;
42layout(location = 0) out vec4 color_out;
43
44void main() {
45  color_out = color_in;
46}
47END
48
49BUFFER img_buf FORMAT B8G8R8A8_UNORM
50
51PIPELINE graphics my_pipeline
52  ATTACH vtex_shader
53  ATTACH frag_shader
54
55  FRAMEBUFFER_SIZE 256 256
56  BIND BUFFER img_buf AS color LOCATION 0
57END
58
59CLEAR my_pipeline
60EXPECT img_buf IDX 0 0 SIZE 256 256 EQ_RGBA 0 0 0 0
61```
62
63The [VkScript](docs/vk_script.md) format is supported for historic reasons. It
64is based off, and very closely matches, the format accepted by VkRunner. There
65are no new features being added to VkScript, it is for historical use.
66
67### Clear test as VkScript
68
69```
70[require]
71VK_KHR_get_physical_device_properties2
72
73[vertex shader passthrough]
74
75[fragment shader]
76#version 430
77
78layout(location = 0) in vec4 color_in;
79layout(location = 0) out vec4 color_out;
80
81void main() {
82  color_out = color_in;
83}
84
85[test]
86clear
87relative probe rect rgba (0.0, 0.0, 1.0, 1.0) (0, 0, 0, 0)
88```
89
90## Requirements
91
92 * Recommended: Configure at least one backend. See [Backends](#backends) below.
93 * Git
94 * CMake (version 3.7+ enables automatic discovery of an installed Vulkan SDK)
95 * Ninja (or other build tool)
96 * Python, for fetching dependencies and building Vulkan wrappers
97
98
99## Building
100```
101git clone https://github.com/google/amber.git
102cd amber
103./tools/git-sync-deps
104mkdir -p out/Debug
105cd out/Debug
106cmake -GNinja ../..
107ninja
108```
109
110Alternatives:
111
112* On Windows, Amber normally statically links against the C runtime library.
113  To override this and link against a shared C runtime, CMake option
114  `-DAMBER_ENABLE_SHARED_CRT`.
115  This will cause Amber to be built with `/MD` for release builds or `/MDd` for
116  debug builds.
117
118### Android
119
120* Android build needs Android SDK 28, Android NDK r21, Java 8. If you prefer
121  other versions of Android SDK, Android NDK, Java, then you can change
122  `ANDROID_PLATFORM` and `ANDROID_BUILD_TOOL_VERSION` in
123  `tools/build-amber-sample.sh`.
124* Set up Android SDK path by running
125  `export ANDROID_SDK_HOME=path/to/Android/SDK` in your shell.
126* Set up Android NDK path by running
127  `export ANDROID_NDK_HOME=path/to/Android/NDK` in your shell.
128* Generate a KeyStore using `keytool` command and set up `KEY_STORE_PATH`
129  env variable for the KeyStore file path.
130* Run `./tools/build-amber-sample.sh [build output directory path]`.
131
132#### Android plain executable
133
134It is possible to obtain a plain executable for Android, as opposed to an APK,
135with the following:
136
137```
138git clone https://github.com/google/amber.git
139cd amber
140./tools/git-sync-deps
141
142./tools/update_build_version.py . samples/ third_party/
143./tools/update_vk_wrappers.py . .
144
145mkdir build
146cd build
147mkdir app
148mkdir libs
149${ANDROID_NDK_HOME}/ndk-build -C ../samples NDK_PROJECT_PATH=. NDK_LIBS_OUT=`pwd`/libs NDK_APP_OUT=`pwd`/app
150```
151
152The list of target ABIs can be configured in `samples/jni/Application.mk` by
153editing the APP_ABI entry:
154
155```
156APP_ABI := arm64-v8a armeabi-v7a x86 x86_64
157```
158
159The resulting executable will be produced as
160`build/app/local/<abi>/amber_ndk`. This executable can be run via the adb shell
161on your device, e.g. under `/data/local/tmp` (`/sdcard` is generally not
162suitable because it is mounted with a non-executable flag). Also, vulkan layers
163may not be available to this executable as it is not an app, so make sure to use
164the `-d` flag to disable Vulkan layers:
165
166```
167adb push build/app/local/<abi>/amber_ndk /data/local/tmp
168adb shell
169# Now on device shell
170cd /data/local/tmp
171./amber_ndk -d <shader-test-files>
172```
173
174### Optional Components
175
176The components which build up Amber can be enabled or disabled as needed. Any
177option with `_SKIP_` in the name is on by default, any with `_USE_` is off by
178default.
179
180The available flags which can be defined are:
181 * AMBER_SKIP_TESTS -- Skip building Amber unit tests
182 * AMBER_SKIP_SAMPLES -- Skip building the Amber sample applications
183 * AMBER_SKIP_SPIRV_TOOLS -- Disable the SPIRV-Tools integration
184 * AMBER_SKIP_SHADERC -- Disable the ShaderC integration
185 * AMBER_SKIP_LODEPNG -- Disable the LodePNG integration
186 * AMBER_USE_DXC -- Enables DXC as a shader compiler
187 * AMBER_USE_LOCAL_VULKAN -- Does not try to find the Vulkan SDK, builds needed
188                             components locally
189 * AMBER_USE_CLSPV -- Enables CLSPV as a shader compiler
190 * AMBER_USE_SWIFTSHADER -- Builds Swiftshader so it can be used as a Vulkan ICD
191
192```
193cmake -DAMBER_SKIP_TESTS=True -DAMBER_SKIP_SPIRV_TOOLS=True -GNinja ../..
194```
195
196#### DXC
197
198DXC can be enabled in Amber by adding the `-DAMBER_USE_DXC=true` flag when
199running cmake.
200
201## Build Bots
202
203There are a number of build bots to verify Amber continues to compile and run
204on the various targets. Due to bot limitations, the integration tests are not
205being run on the bots, just the unit tests.
206
207## Backends
208
209Amber is designed to run against different graphics APIs.
210Amber will build if no graphics API is found, but will only allow verifying the
211syntax of the amber script files.
212
213Currently the Vulkan and Dawn graphics APIs are supported.
214
215### Using Vulkan as a backend
216
217A Vulkan implementation is found by CMake in the following priority order:
218
219 * If `AMBER_USE_LOCAL_VULKAN` is enable the headers, loader and layers will be
220   built locally and not found on the system.
221 * If an enclosing CMake project includes the
222   [Vulkan-Headers][Vulkan-Headers]
223   CMake project, then headers will be picked up from there.
224
225   In this case the CMake variable `Vulkan_LIBRARIES` can name the
226   Vulkan library, or a default of `vulkan` will be used.
227
228 * If you have CMake 3.7 or later, then the Vulkan implementation will
229   be found from a Vulkan SDK as published by LunarG.
230
231   Environment variables:
232   * `VULKAN_SDK` should point to the platform-specific SDK directory
233     that contains the `include` and `lib` directories.
234   * `VK_ICD_FILENAMES` should point to the ICD JSON file.
235   * `VK_LAYER_PATH` should point to the explicit\_layer.d folder.
236   * `LD_LIBRARY_PATH` must contain the $VULKAN_SDK/lib/ folder for the
237     validation libraries.
238
239   ```
240   export VULKAN_SDK=$HOME/vulkan-macos-1.1.85.0/macOS
241   export VK_ICD_FILENAMES=$VULKAN_SDK/etc/vulkan/icd.d/MoltenVK_icd.json
242   export VK_LAYER_PATH=$VULKAN_SDK/etc/vulkan/explicit_layer.d
243   export LD_LIBRARY_PATH=$VULKAN_SDK/lib:$LD_LIBRARY_PATH
244   ```
245
246### Using Dawn as a backend
247
248We assume you have built [Dawn][Dawn] from source, and have access to both the
249source and build trees. To build a Dawn backend for Amber, set the following
250CMake variables when configuring Amber:
251
252  * `Dawn_INCLUDE_DIR`: The directory containing `dawn/dawn_export.h`
253    (in the source tree).
254  * `Dawn_GEN_INCLUDE_DIR`: The directory containing generated header
255    `dawn/dawncpp.h` (in the build output tree).
256  * `Dawn_LIBRARY_DIR`: The directory containing the `dawn_native` library (in
257    the build output tree).
258
259### Using SwiftShader as a backend
260
261SwiftShader, if available, can be used by by exporting the `VK_ICD_FILENAMES`
262environment variable and using it directly. If SwiftShader is not installed it
263can be built with Amber by setting `AMBER_ENABLE_SWIFTSHADER` during the
264configure step of CMake.
265
266
267```
268mkdir out/sw
269cd out/sw
270cmake -GNinja -DAMBER_ENABLE_SWIFTSHADER=TRUE ../..
271ninja
272export VK_ICD_FILENAMES=$PWD/Linux/vk_swiftshader_icd.json
273./amber -d -V    # Should see SwiftShader listed as device
274./amber -d ../../tests/cases/clear.amber
275```
276
277## Amber Samples
278
279The build will generate an `out/Debug/amber` executable which can be used to
280run amber scripts. The script can be used as
281`out/Debug/amber <path to amber file>`.
282
283```
284out/Debug/amber tests/cases/clear.amber
285```
286
287The sample app returns a value of 0 on success or non-zero on error. Any issues
288encountered should be displayed on the console.
289
290Run `out/Debug/amber -h` to see a description of the program's command line options.
291
292Example AmberScript files can be found in the [tests/cases](tests/cases)
293directory in this repository.
294Also the [Vulkan Conformance Test
295Suite](https://github.com/KhronosGroup/VK-GL-CTS) contains many real-world
296examples in its
297[external/vulkancts/data/vulkan/amber](https://github.com/KhronosGroup/VK-GL-CTS/tree/master/external/vulkancts/data/vulkan/amber)
298subdirectory.
299
300By default, `out/Debug/amber` supports saving the output image into '.png'
301file. You can disable this by passing `-DAMBER_SKIP_LODEPNG=true` to cmake.
302
303The `image_diff` program will also be created. This allows comparing two images
304using the Amber buffer comparison methods.
305
306## Contributing
307
308Please see the [CONTRIBUTING](CONTRIBUTING.md) and
309[CODE_OF_CONDUCT](CODE_OF_CONDUCT.md) files on how to contribute to Amber.
310
311
312## References
313[Dawn]: https://dawn.googlesource.com/dawn/
314[Talvos]: https://talvos.github.io/
315[Vulkan-Headers]: https://github.com/KhronosGroup/Vulkan-Headers
316[VkRunner]: https://github.com/igalia/vkrunner
317
318