From 5a75571ffd662caa72b6275f722ebf429f2179cc Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Tue, 19 May 2026 01:43:46 +0200 Subject: [PATCH] readme update --- README.md | 123 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 0046286..6aca07b 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,78 @@ # Crafter.Graphics -Vulkan-based graphics library built around C++20 modules and the bindless -`VK_EXT_descriptor_heap` extension. Provides window management, ray -tracing, and a compute-shader-driven UI on a single, opinionated stack. +Vulkan + WebGPU graphics library built around C++20 modules and +bindless heaps. Provides window management, ray tracing, and a +compute-shader-driven UI on a single, opinionated stack. Native +builds use Vulkan with `VK_EXT_descriptor_heap`; `wasm32-*` builds +target the browser via WebGPU and a DOM window backend. + +## Backends + +Backends are chosen at build time by the target triple: + +| Target | Window | Renderer | Shaders | +|---------------------|------------------------|---------------------|---------| +| native Linux | Wayland | Vulkan (heap-bound) | GLSL → SPIR-V | +| native Windows | Win32 | Vulkan (heap-bound) | GLSL → SPIR-V | +| `wasm32-*` (any) | DOM (canvas + JS env) | WebGPU | WGSL (loaded at runtime) | + +The two backends share the same C++ surface for the high-level pieces +(`UIRenderer`, `Mesh`, `RenderingElement3D`, `RTPass`, item structs, +`FontAtlas`, `Image2D`, `ComputeShader`). Backend-typed pieces +(`*Vulkan` vs `*WebGPU`) live behind `#ifdef CRAFTER_GRAPHICS_WINDOW_DOM`. +Vulkan ray tracing is hardware (`VK_KHR_ray_tracing_pipeline`); WebGPU +ray tracing is a library-built software path (BVH + traceRay in a +compute pipeline composed from user-supplied WGSL stages). ## What's in here -- **Window** — Wayland and Win32 backends, swapchain ring, frame pacing, - input events. Pick a backend at build time via the target triple. -- **Device** — single-Vulkan-instance bring-up. The library targets - `VK_EXT_descriptor_heap` exclusively; pipelines are created with +- **Window** — Wayland, Win32, and DOM backends, swapchain ring / canvas + framing, input events. Pick a backend at build time via the target + triple. The DOM backend routes every dynamic symbol through + [additional/dom-env.js](additional/dom-env.js) and + [additional/dom-webgpu.js](additional/dom-webgpu.js). +- **Device** *(Vulkan only)* — single-instance bring-up targeting + `VK_EXT_descriptor_heap`; pipelines are created with `VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT` so there are no descriptor-set layouts and push constants travel via `vkCmdPushDataEXT`. -- **DescriptorHeapVulkan** — bindless slot allocator. `AllocateImageSlots` - / `AllocateBufferSlots` / `AllocateSamplerSlots`, with byte-offset - helpers for direct descriptor writes. -- **VulkanBuffer\** — typed buffer with optional host mapping - and a `FlushDevice` that issues the right host-write barrier. -- **ImageVulkan\** — image + staging buffer, mip-chain support, - one-shot uploads via a command buffer. -- **PipelineRTVulkan / ShaderBindingTableVulkan / RTPass** — ray-tracing - pipeline, SBT, and a `RenderPass` that dispatches it. -- **ComputeShader** — the Tier 1 wrapper used by the UI system. Loads a - `.spv`, builds a heap-bound compute pipeline, dispatches with - `vkCmdPushDataEXT`. Use it directly for any custom compute. -- **UI** — three-tier UI system; see below. +- **DescriptorHeapVulkan / DescriptorHeapWebGPU** — bindless slot + allocators. Vulkan side allocates image/buffer/sampler slots in a + `VK_EXT_descriptor_heap`; WebGPU side resolves slots to JS-side + handle-table cookies that the dispatch bridge binds per pass. +- **VulkanBuffer\ / WebGPUBuffer\** — typed buffer. + Vulkan variant has optional host mapping and a `FlushDevice` that + issues the right host-write barrier; WebGPU variant goes through + `queue.writeBuffer` over the JS bridge. +- **ImageVulkan\ / Image2D\ / Image2DArray\** — + image + staging buffer with mip-chain support on Vulkan; on WebGPU, + `rgba8unorm` 2D / 2D-array textures created and written via the + bridge. Atlas (`r8unorm`, sub-region writes) is a separate path. +- **PipelineRTVulkan / PipelineRTWebGPU / ShaderBindingTableVulkan / + ShaderBindingTableWebGPU / RTPass** — ray-tracing pipelines. Vulkan + uses native RT pipelines + SBTs; WebGPU composes one compute + pipeline by stitching the traversal library, a generated hit-group + switch, and the user's raygen / closesthit / miss / anyhit WGSL. +- **ComputeShader / WebGPUComputeShader** — Tier 1 wrapper used by the + UI system. Vulkan loads a `.spv` and dispatches with + `vkCmdPushDataEXT`; WebGPU loads a user-supplied `.wgsl` blob at + runtime via `wgpuLoadCustomShader`. Use it directly for any custom + compute. +- **UI** — three-tier UI system; see below. The standard shaders ship + as four `.spv` blobs on native and four WGSL strings baked into the + WebGPU dispatcher. - **FontAtlas** — single-channel SDF atlas (1024×1024, 32pt base, shelf-packed, lazy `Ensure` per codepoint, dirty-flush via `Update`). + Backend-agnostic. - **Mesh / RenderingElement3D / Animation** — BLAS/TLAS construction - and 3D scene plumbing for the ray-tracing path. + and 3D scene plumbing. Vulkan calls `vkCmdBuildAccelerationStructures`; + WebGPU registers BLAS data (verts, idx, BVH nodes, primRemap, optional + per-vertex attribs) into global mesh heaps and builds the TLAS in a + library compute pass. +- **Clipboard / Input / Gamepad / Router / Dom** — input plumbing. + Gamepad uses libudev+libevdev on Linux and WGI on Windows; the DOM + backend exposes the host page DOM (`Dom::HtmlElement`) and a router + for hash-routed wasm apps. ## UI system (three tiers) @@ -78,27 +121,47 @@ The repository is built with `crafter-build` (a project-config based build system; the project description lives in `project.cpp`): ```bash -crafter-build # build the library -crafter-build -r # build and run (in an example directory) +crafter-build # native: Wayland on Linux, Win32 on Windows +crafter-build --target=wasm32-wasip1 # browser: DOM window + WebGPU renderer +crafter-build -r # build and run (in an example directory) ``` -The build picks the window backend automatically: Wayland on Linux, -Win32 on Windows / mingw. Cross-compile via the standard `--target=...` -flag. +The build picks the window + renderer pair automatically from the +target triple: any `wasm32-*` triple flips to DOM + WebGPU (no Vulkan +loader linked), everything else stays on the native Vulkan path. Each +example with both backends ships GLSL *and* WGSL copies of its shaders +side-by-side (e.g. [raygen.glsl](examples/Sponza/raygen.glsl) + +[raygen.wgsl](examples/Sponza/raygen.wgsl)); `project.cpp` selects the +right set per target. ## Examples See [examples/](examples/). Quick map: -- [HelloWindow](examples/HelloWindow/) — minimal window, no rendering. -- [VulkanTriangle](examples/VulkanTriangle/) — ray-traced triangle, the - smallest test of the bindless + ray-tracing path. +- [HelloWindow](examples/HelloWindow/) — minimal native window, no rendering. +- [HelloDom](examples/HelloDom/) — wasm-only smoke test of the DOM + partition: page-level events, `HtmlElement::CreateInBody`, and + `Router::PushState`-driven SPA navigation. No GPU work. +- [VulkanTriangle](examples/VulkanTriangle/) — ray-traced triangle on + both Vulkan and WebGPU. The smallest test of the bindless + RT path + on each backend. +- [Sponza](examples/Sponza/) — ray-traced Sponza atrium on both + backends. Exercises `.cmesh` / `.ctex` decompression (GPU + `VK_EXT_memory_decompression` on Vulkan, CPU on WebGPU) and a + textured closest-hit. See [its README](examples/Sponza/README.md) + for asset provenance. - [HelloUI](examples/HelloUI/) — UI smoke test using all three tiers (background quad, slider, progress bar, button with text label, cursor-tracking circle). - [CustomShader](examples/CustomShader/) — Tier 1 demo: a user-authored compute shader inverting RGB under a list of item-circles, dispatched - alongside the standard `drawQuads`. The "could attempt #2 do this?" test. + alongside the standard `drawQuads`. Shipped as both + [`.comp.glsl`](examples/CustomShader/inverse-circle.comp.glsl) and + [`.comp.wgsl`](examples/CustomShader/inverse-circle.comp.wgsl). +- [Decompression](examples/Decompression/) — `Crafter::Compression` + CPU round-trip smoke test (used by the WebGPU asset path). +- [InputSystem](examples/InputSystem/) — keyboard / mouse / gamepad + event surface check. ## License