Rewrite the README for Dawn.

This commit is contained in:
Corentin Wallez 2018-08-16 13:50:49 +02:00 committed by Corentin Wallez
parent 94c92fa5e7
commit 3b24668283
1 changed files with 58 additions and 112 deletions

170
README.md
View File

@ -1,123 +1,69 @@
# NXT, standalone part
# Dawn, a WebGPU implementation
NXT is an unoriginal name for Chromiums investigation and prototyping of a NeXT generation graphics API for the Web. This repository contains a native library implementing Dawn on multiple backends, as well as some code generators used for the integration in Chromium. Dawn is not an official Google product.
Dawn (formerly NXT) is an open-source and cross-platform implementation of the work-in-progress WebGPU standard.
It exposes a C/C++ API that maps almost one-to-one to the WebGPU IDL and can be managed as part of a larger system such as a Web browser.
We focused on efforts on two axis:
Dawn provides several WebGPU building blocks:
- **WebGPU C/C++ headers** that applications and other building blocks use.
- **A "native" implementation of WebGPU** using platforms' GPU APIs:
- **D3D12** on Windows 10
- **Metal** on OSX (and eventually iOS)
- **Vulkan** on Windows, Linux (eventually ChromeOS and Android too)
- OpenGL as best effort where available
- **A client-server implementation of WebGPU** for applications that are in a sandbox without access to native drivers
- An investigation of the constraints coming from the Web and in particular portability, for which we looked at the intersection of the designs of D3D12, Metal, Vulkan, OpenGL and D3D11. See links to some of our investigations below.
- A prototype API inspired by all of D3D12, Metal and Vulkan, but none in particular. The API works on two backends: OpenGL and Metal and is usable from native code (think WebAssembly) and from Javascript inside of Chrome. Our focus was not to have a complete API but to show the breadth of potential usage.
## Directory structure
Were making our investigation and prototype public to provide another example for the upcoming discussion in the “GPU for the Web” W3C community group.
- `dawn.json`: description of the API used to drive code generators.
- `examples`: examples showing how Dawn is used.
- `generator`: code generator for files produces from `dawn.json`
- `templates`: Jinja2 templates for the generator
- `scripts`: scripts to support things like continuous testing, build files, etc.
- `src`:
- `common`: helper code shared between core Dawn libraries and tests/samples
- `dawn_native`: native implementation of WebGPU, one subfolder per backend
- `dawn_wire`: client-server implementation of WebGPU
- `include`: public headers for Dawn
- `tests`: internal Dawn tests
- `end2end`: WebGPU tests performing GPU operations
- `unittests`: unittests and by extension tests not using the GPU
- `validation`: WebGPU validation tests not using the GPU (frontend tests)
- `utils`: helper code to use Dawn used by tests and samples
- `third_party`: directory where dependencies live as well as their buildfiles.
NXT currently has the following features:
## Building Dawn
- Command buffers, graphics and compute pipelines
- Textures, samplers, vertex / index / uniform / storage buffers.
- Descriptor sets (called bind groups) and push constants
- SPIRV for the shading language
- Validation
Dawn uses the Chromium build system and dependency management so you need to [install depot_tools] and add it to the PATH.
Then get the source as follows:
NXT is missing a lot of things to be usable for anything else than prototyping:
- Render-targets / render passes
- Most of the fixed function pipeline state
- Barriers / resource transitions and GPU - CPU synchronization
- Buffer mapping
- ...
We chose to use SPIRV in our prototype because it was the only language that had translators to other shading languages, thanks to SPIRV-Cross which saved us a ton of work. [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross) didnt have an HLSL backend so we didnt attempt a D3D12 backend (and D3D11 was too limiting for our prototype API). Only the Metal and the OpenGL backends are functional at this time. The OpenGL backend let us integrate in Chromium very easily.
## Links
An [overview document](https://docs.google.com/document/d/1-lAvR9GXaNJiqUIpm3N2XuGUWv_JrkpGizDN0bNq7wY) of the goals and design of NXT.
Some of the investigations we made on the design of potential backend APIs:
- [Binding model investigation](https://drive.google.com/open?id=1_xeTnk6DlN7YmePQQAlnHndA043rgwBzUYtatk5y7kQ)
- [Data uploads investigation](https://drive.google.com/open?id=1Mi9l14zG8HzJ5Z6107SdPhON0mq4d-3SUI8iS631nek)
- [Resource creation investigation](https://drive.google.com/open?id=1hK1SkTFkXJXPjyla0EEl1fOIwJSc6T41AV2mGiovyFU)
- [Vertex setup investigation](https://drive.google.com/open?id=1SIUpdg-6Xm5FFF1ktdBfnR5oRKjyPAfXir7Drui4cYM)
[Another presentation](https://drive.google.com/open?id=1mLQEM__twfivV7nJLDBIomS9pegOYkJQWyM6lTse4PQ) about our work with more details on the architecture of the prototype, and a [video](https://youtu.be/ThlZ5K4hJvo) of the demo we showed.
TODO: add a link to the NXT-chromium repo once it is uploaded.
## Key elements of the prototypes architecture
### Builder pattern for object creation
In NXT, object creation is done through builder objects that gather initialization parameters with a fluent interface and return the initialized object when GetResult() is called.
In addition to the improved type-safety and subjective prettiness compared to giant constructors, this style enables additional optimizations. For example this removes the need for any check for an object being built and allows backend to forget parameters it might not care about.
Heres an example of buffer creation:
```cpp
dawn::Buffer buffer = device.CreateBufferBuilder()
.SetUsage(dawn::BufferUsageBit::Uniform | dawn::BufferUsageBit::Mapped)
.SetSize(42)
.GetResult();
```
### The wire client-server and error handling
What we call the wire is an API command buffer for NXT. The name was chosen to avoid conflict with the “command buffer” concept in graphics APIs.
Originally OpenGL was designed as a client-server architecture with asynchronous errors and objects that could be used by the client before they were created by server. Over time more client state-tracking was added but the core asynchronous structure remained. This enabled OpenGL ES 2 / WebGL to be implemented in Chromium in which the web page and the GPU driver live in different processes. In addition to security this separation helps with performance in CPU-bound WebGL apps.
For this reason we built Dawn as a network-transparent API so that it could integrate nicely in the Chromium architecture, and we believe any next-generation Web API would have to be network-transparent too.
In NXT, as in OpenGL, API objects can be used immediately after they have been created on the client, even if the server hasnt seen the creation command yet. If object creation succeeds, everything happens transparently otherwise the object is tagged as being an error. Dawn calls with error-tagged objects use the following rules:
- Functions result in a noop.
- Functions returning an object return an error value.
- Builder methods mark the builder as an error value.
The idea is that a whole bunch of object creation can be done when the application loads, then all the objects checked once for any error. The concept presented above is similar to [promise pipelining](http://www.erights.org/elib/distrib/pipeline.html) and to the [Maybe monad](https://en.wikipedia.org/wiki/Monad_(functional_programming)#The_Maybe_monad).
Currently the wire only has client to server communication and there is no way to know the error status of objects or read API data like the content of buffers. In our prototype the wire is responsible for object lifetime validation.
### Code generation
Our prototype heavily relies on code generation. It greatly improved iteration time on the API as the generators kept the Javascript bindings, IDL files, wire, C++ bindings and friends up to date. But it reduced flexibility in the API shape as adding as changing the shape required modifying all generators in non-trivial ways.
For example, Dawn can only return objects which prevents mapping buffers or even reading back single pixel values. There is currently no way to know the error status on the client side. These improvements, and more, are planned, and contributions are welcome.
Other generators include:
- A C-header with the definition of dawnProcTable that is the “real” underlying Dawn API exposed by the backends.
- Glue code generating dawnProcTable for a backend with simple validation included (enum value checks etc.)
- A mock API for testing
## Structure of the code
Here are the main files and directories:
```
/dawn.json - the JSON file describing the API that is used by the code generators
/examples - example code that was also used for end2end testing (it is not possible to do automated testing without being able to read back data)
/generator - The code generator and its templates
/generator/templates - The code generator templates
/generator/templates/blink - Templates used in the integration with Chromium
/src - Non-generator code for the ANGLE-like library
/src/backend
/src/backend/common - Handles all the state tracking and validation
/src/backend/metal - the Metal backend
/src/backend/opengl - the OpenGL backend
/src/wire - Glue code and interfaces for the wire
/third_party - external dependencies
```
## Getting and building the code
NXT standalone is a CMake project with git submodules. To download and build it, do the following:
[install depots_tools]: http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up
```sh
git clone --recursive <insert github git repo url here>
cd <directory name>
mkdir build && cd build
cmake ..
make
# Run executables in examples/, --help will provide the options to choose the backend (compute only works on Metal on OSX) and the command buffer.
# Clone the repo as "dawn"
git clone https://github.com/google/nxt-standalone.git dawn && cd dawn
# Bootstrap the gclient configuration
cp scripts/standalone.gclient .gclient
# Fetch external dependencies and toolchains with gclient
gclient sync
```
It is currently known to compile on Linux and OSX, and has some warnings on Windows when using MSVC (it doesnt handle code reachability in enum class switches correctly).
Then generate build files using `gn args out/Debug` or `gn args out/Release`.
A text editor will appear asking build options, the most common option is `is_debug=true/false`; otherwise `gn args out/Release --list` shows all the possible options.
Then use `ninja -C out/Release` to build dawn and for example `./out/Release/dawn_end2end_tests` to run the tests.
## Contributing
Please read and follow [CONTRIBUTING.md](/CONTRIBUTING.md).
Dawn doesn't have a formal coding style yet, except what's defined by our clang format style.
Overall try to use the same style and convention as code around your change.
## License
Please see [LICENSE](/LICENSE).
## Disclaimer
This is not an officially supported Google product.