75 lines
4.8 KiB
Markdown
75 lines
4.8 KiB
Markdown
|
|
## This repository: Crafter.Graphics
|
||
|
|
|
||
|
|
The execution contexts to enumerate, beside the charter's:
|
||
|
|
- One source, several builds. `project.cpp` defines exactly one of
|
||
|
|
`CRAFTER_GRAPHICS_WINDOW_WAYLAND`, `CRAFTER_GRAPHICS_WINDOW_WIN32` and
|
||
|
|
`CRAFTER_GRAPHICS_WINDOW_DOM` from the target: native Linux (Wayland and
|
||
|
|
Vulkan), `x86_64-w64-mingw32` (Win32 and Vulkan, gamepads through
|
||
|
|
Windows.Gaming.Input), `wasm32-wasip1` (the DOM and WebGPU, through
|
||
|
|
`additional/dom-env.js` and `additional/dom-webgpu.js`) and
|
||
|
|
`aarch64-alpine-linux-musl` (Mesa Turnip: no descriptor heap, no ray
|
||
|
|
tracing). Code behind one backend's `#ifdef` is still the range's code,
|
||
|
|
and a change to one backend's half can leave the other's behind.
|
||
|
|
- One device, several paths, chosen at start-up: the descriptor heap or
|
||
|
|
the bindless descriptor-set fallback (`CRAFTER_GRAPHICS_NO_DESCRIPTOR_HEAP`
|
||
|
|
forces it), with each UI kernel's two SPIR-V builds; ray tracing or none
|
||
|
|
(heap-only; `Device::stageMask` drops its stage without it); Vulkan 1.4
|
||
|
|
or 1.3 (`CRAFTER_GRAPHICS_NO_VULKAN_1_4`); `swapchain_maintenance1` or
|
||
|
|
not; GPU memory decompression or the CPU path
|
||
|
|
(`Device::memoryDecompressionSupported`); the NVIDIA AS workaround on or
|
||
|
|
off (`Device::workaroundDescriptorHeapAS`,
|
||
|
|
`CRAFTER_GRAPHICS_NO_AS_WORKAROUND`); llvmpipe on a machine without a
|
||
|
|
GPU.
|
||
|
|
- The GPU timeline. Three frames in flight, a fence each: what lives per
|
||
|
|
frame is keyed by `Window::currentFrame`, what lives per swapchain image
|
||
|
|
by `currentImage`, and the image count follows the present mode. A
|
||
|
|
handle a frame in flight may still use is released through the deletion
|
||
|
|
queue (freed `framesInFlight` frames later) or after a wait for the GPU;
|
||
|
|
a freed descriptor slot is handed out again at once; a swapchain rebuild
|
||
|
|
asked for from a listener mid-frame (`Resize`, `SetPresentMode`) waits
|
||
|
|
for that frame's present, and `onResize` runs after it; a static owner
|
||
|
|
is destroyed after the driver is gone. Within one dispatch, Vulkan
|
||
|
|
orders nothing between workgroups.
|
||
|
|
- Re-entry from the platform. The Wayland listeners run inside
|
||
|
|
`wl_display_dispatch`, `wl_display_dispatch_pending` and
|
||
|
|
`wl_display_roundtrip`, which the frame loop, window creation,
|
||
|
|
`Device::Initialize` and the clipboard's reads call. Windows calls the
|
||
|
|
window procedure from the message loop and also synchronously from
|
||
|
|
inside `CreateWindowEx`, `SendMessage` and `DefWindowProc`. The DOM's
|
||
|
|
listeners in `dom-env.js` call the `__crafterDom_*` exports. A listener
|
||
|
|
can resize, close or destroy the window it was called for.
|
||
|
|
Windows.Gaming.Input reports gamepad connects and disconnects on threads
|
||
|
|
of its own, queued under a lock until the event loop takes them.
|
||
|
|
- Shared state: `Device`'s statics are process-wide; `Device::frameCounter`
|
||
|
|
is one clock for every window, which the deletion queue, the staging
|
||
|
|
rings and the font atlas's eviction run on; the deletion queue is shared
|
||
|
|
under `deletionMutex`. The caches keyed on a `Font*` alias a new font at
|
||
|
|
a freed one's address unless `UIRenderer::InvalidateFont` ran.
|
||
|
|
- Data the GPU and JavaScript read: an item or header struct is mirrored
|
||
|
|
byte for byte by a `std430` block in `shaders/ui-shared.glsl`, by the
|
||
|
|
WGSL in `dom-webgpu.js` and by every shader that includes it, the
|
||
|
|
examples' among them; one push block serves both builds, through
|
||
|
|
`vkCmdPushDataEXT` on the heap and `vkCmdPushConstants` in the set
|
||
|
|
build, within 256 bytes.
|
||
|
|
- Tests: each its own process, in parallel, with a 60 s timeout; every
|
||
|
|
test that calls `Device::Initialize` needs a Wayland display, and one
|
||
|
|
that lacks a capability exits 77 and pins nothing on that machine. A
|
||
|
|
validation check counts only in a run where the layer loaded.
|
||
|
|
|
||
|
|
Semantics to read on disk rather than recall: the Vulkan headers and
|
||
|
|
registry (`include/vulkan/`, `registry/vk.xml`) and Vulkan-Utility-Libraries
|
||
|
|
as cloned (`~/.cache/crafter.build/external/Vulkan-Headers-<hash>/`,
|
||
|
|
`Vulkan-Utility-Libraries-<hash>/`; several clones may sit side by side);
|
||
|
|
the Wayland protocols (`/run/host/usr/share/wayland/wayland.xml`,
|
||
|
|
`/run/host/usr/share/wayland-protocols/`, the generated code in `lib/`) and
|
||
|
|
the client headers (`/run/host/usr/include/wayland-client*.h`,
|
||
|
|
`xkbcommon/`); the MinGW headers (`/run/host/usr/x86_64-w64-mingw32/include/`);
|
||
|
|
libc++ and clang as the host installs them (`/run/host/usr/include/c++/v1`,
|
||
|
|
`/run/host/usr/lib/clang/<major>/include`); the vendored stb and libevdev
|
||
|
|
in `lib/`; Crafter.Event, Crafter.Math and Crafter.Asset as cloned
|
||
|
|
(`~/.cache/crafter.build/external/<Name>-<hash>/`). The crafter-build
|
||
|
|
Flatpak compiles with an LLVM of its own, which is not readable from
|
||
|
|
here: where a semantic may differ between LLVM releases, the host's
|
||
|
|
headers settle it for the host's build only. The Vulkan specification's
|
||
|
|
valid-usage rules, the WebGPU and WGSL specifications and Microsoft's API
|
||
|
|
documentation are not on disk: a semantic only they settle is unverified.
|