# 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. ## 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 `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. - **FontAtlas** — single-channel SDF atlas (1024×1024, 32pt base, shelf-packed, lazy `Ensure` per codepoint, dirty-flush via `Update`). - **Mesh / RenderingElement3D / Animation** — BLAS/TLAS construction and 3D scene plumbing for the ray-tracing path. ## UI system (three tiers) The UI is *deliberately* layered to balance no-boilerplate against no-lock-in: - **Tier 1 — `ComputeShader`.** Load any `.spv`, dispatch with push constants, library inserts inter-dispatch barriers. The escape hatch: if the standard shaders don't fit, write your own compute and dispatch it next to them. - **Tier 2 — `UIRenderer` + standard shaders.** Four shipped compute shaders (`drawQuads`, `drawCircles`, `drawImages`, `drawText`), POD item structs (`QuadItem`, `CircleItem`, `ImageItem`, `GlyphItem`), a shared GLSL contract in [shaders/ui-shared.glsl](shaders/ui-shared.glsl), and helpers (`RegisterBuffer`, `RegisterImage`, `RegisterSampler`, `FillHeader`, `Dispatch*`, `ShapeText`). You build your own per-shader SSBOs (manual batching) and call one `Dispatch*` per shader type per frame. Item array order = draw order. - **Tier 3 — stateless presentation functions.** `DrawButton`, `DrawCheckbox`, `DrawSlider`, `DrawProgressBar`. Each is a small function that *appends* items to your buffers — they don't dispatch. Colors come in as small inline `*Colors` aggregates, no library `Theme` type. **The source is the customization API**: if a component doesn't fit, copy its body and edit it. No virtual hooks, no extension points. What's *not* in the UI: widget tree, layout engine (just a `Rect::SubRect` carving helper), theming, hit-testing, focus management. State for interactive components (hover, drag, focus) lives in user-owned POD structs, not the library. ### UI dispatch model Standard shaders dispatch one workgroup per 8×8 *screen tile* — each thread iterates every item in the SSBO in array order, accumulating into a local `dst`, and stores once. Total cost is `O(W·H·N)`; works well up to a few hundred items at 1080p. Splitting one buffer into multiple dispatches doesn't help — the same total work plus barrier overhead. If you need to render thousands of UI items, you want a different shader (tile binning, per-item-list resolve), not more dispatches. ## Build 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) ``` The build picks the window backend automatically: Wayland on Linux, Win32 on Windows / mingw. Cross-compile via the standard `--target=...` flag. ## 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. - [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. ## License LGPL 3.0. See per-file headers and `LICENSE`.