| # Architecture |
| |
| This document should be updated semi-regularly. Feel free to open an issue if it hasn't been updated in more than a year. |
| |
| ## Goals |
| |
| The major goal of Vello is to provide a high quality GPU accelerated renderer suitable for a range of 2D graphics applications, including rendering for GUI applications, creative tools, and scientific visualization. |
| |
| Vello emerges from being a research project, which attempts to answer these hypotheses: |
| |
| - To what extent is a compute-centered approach better than rasterization ([Direct2D])? |
| - To what extent do advanced GPU features (subgroups, descriptor arrays, device-scoped barriers) help? |
| - Can we improve quality and extend the imaging model in useful ways? |
| |
| Another goal of the overall project is to explain how the renderer is built, and to advance the state of building applications on GPU compute shaders more generally. |
| Much of the progress on Vello is documented in blog entries. |
| See [doc/blogs.md](doc/blogs.md) for pointers to those. |
| |
| Ideally, we'd like our documentation to be more structured; we may refactor it in the future (see [#488]). |
| |
| |
| ## Roadmap |
| |
| The [roadmap for 2023](doc/roadmap_2023.md) is still largely applicable. |
| The "Semi-stable encoding format" section and most of the "CPU fallback" section can be considered implemented. |
| |
| Our current priority is to fill in missing features and to fix rendering artifacts, so that Vello can reach feature parity with other 2D graphics engines. |
| |
| |
| ## File structure |
| |
| The repository is structured as such: |
| |
| - `doc/` - Various documents detailing the vision for Vello as it was developed. This directory should probably be refactored away; adding to it not recommended. |
| - `examples/` - Example projects using Vello. Each example is its own crate, with its own dependencies. The simplest example is called `simple`. |
| - `vello/` - Code for the main `vello` crate. |
| - `vello_encoding/` - Types that represent the data that needs to be rendered. |
| - `vello_shaders/` - Infrastructure to preprocess and cross-compile shaders at compile time; see "Shader templating". |
| - `shader/` - This is where the magic happens. WGSL shaders that define the compute operations (often variations of prefix sum) that Vello does to render a scene. |
| - `shared/` - Shared types, functions and constants included in other shaders through non-standard `#import` preprocessor directives (see "Shader templating"). |
| - `cpu/` - Functions that perform the same work as their equivalently-named WGSL shaders for the CPU fallbacks. The name is a bit loose; they're "shaders" in the sense that they work on resource bindings with the exact same layout as actual GPU shaders. |
| - `vello_tests/` - Helper code for writing tests; current has a single smoke test and not much else. |
| |
| |
| ## Shader templating |
| |
| WGSL has no meta-programming support, which limits code-sharing. |
| We use a strategy common to many projects (eg Bevy) which is to implement a limited, simple preprocessor for our shaders. |
| |
| This preprocessor implements the following directives: |
| |
| 1. `import`, which imports from `shader/shared` |
| 2. `ifdef`, `ifndef`, `else` and `endif`, as standard. |
| These must be at the start of their lines. |
| Note that there is no support for creating definitions in-shader, these are only specified externally (in `src/shaders.rs`). |
| Note also that this definitions cannot currently be used in-code (`import`s may be used instead) |
| |
| This format is compatible with [`wgsl-analyzer`], which we recommend using. |
| If you run into any issues, please report them on Zulip ([#gpu > wgsl-analyzer issues](https://xi.zulipchat.com/#narrow/stream/197075-gpu/topic/wgsl-analyzer.20issues)), and/or on the [`wgsl-analyzer`] issue tracker. |
| Note that new imports must currently be added to `.vscode/settings.json` for this support to work correctly. |
| `wgsl-analyzer` only supports imports in very few syntactic locations, so we limit their use to these places. |
| |
| |
| ## Path encoding |
| |
| See [Path segment encoding](./doc/pathseg.md) document. |
| |
| |
| ## Intermediary layers |
| |
| There are multiple layers of separation between "draw shape in Scene" and "commands are sent to wgpu": |
| |
| - First, everything you do in `Scene` appends data to an `Encoding`. |
| The encoding owns multiple buffers representing compressed path commands, draw commands, transforms, etc. It's a linearized representation of the things you asked the `Scene` to draw. |
| - From that encoding, we generate a `Recording`, which is an array of commands; each `Command` represents an operation interacting with the GPU (think "upload buffer", "dispatch", "download buffer", etc). |
| - We then use `WgpuEngine` to send these commands to the actual GPU. |
| |
| In principle, other backends could consume a `Recording`, but for now the only implemented wgpu backend is `WgpuEngine`. |
| |
| |
| ### CPU rendering |
| |
| The code in `vello_shaders/src/cpu/*.rs` and `vello_shaders/src/cpu.rs` provides *some* support for CPU-side rendering. It's in an awkward place right now: |
| |
| - It's called through WgpuEngine, so the dependency on wgpu is still there. |
| - Fine rasterization (the part at the end that puts pixels on screen) doesn't work in CPU yet (see [#386]). |
| - Every single WGSL shader needs a CPU equivalent, which is pretty cumbersome. |
| |
| Still, it's useful for testing and debugging. |
| |
| |
| [`wgsl-analyzer`]: https://marketplace.visualstudio.com/items?itemName=wgsl-analyzer.wgsl-analyzer |
| [direct2d]: https://docs.microsoft.com/en-us/windows/win32/direct2d/direct2d-portal |
| [#488]: https://github.com/linebender/vello/issues/488 |
| [#467]: https://github.com/linebender/vello/issues/467 |
| [#386]: https://github.com/linebender/vello/issues/386 |