NoGraphicsAPI is a C++20 graphics library designed for the latest Metal 4 devices and Vulkan 1.4 devices with
VK_EXT_descriptor_heap, VK_KHR_device_address_commands, and VK_EXT_mesh_shader.
It implements the ideas in Sebastian Aaltonen's No Graphics API
with GPU pointers, descriptor heaps, and shared Slang shaders.
The goal is to make GPU programming feel more like working with ordinary memory and data structures: GPU pointers for data, heap indices for textures, and one GPU pointer to the arguments of each draw or dispatch.
Metal 4 and Vulkan are supported native backends. CMake selects Metal on macOS/iOS and Vulkan on Windows/Linux. Both use the same C++ API and Slang sources. Windows and macOS include windowed examples; Linux currently supports headless use.
A conventional renderer creates buffer objects, describes vertex and resource-binding layouts, and assembles bindings before drawing. The blog asks how much of this machinery modern bindless hardware still needs. NoGraphicsAPI makes that alternative data model the foundation of the library:
- Memory allocation without buffer objects. Allocate GPU heaps and partition them with an application-side allocator. Mapped heaps provide CPU and GPU addresses, so the CPU can write data directly. Vertex data, constants, and arbitrary structures are allocations, not separate public buffer types.
- Typed GPU pointers. Shaders follow 64-bit pointers stored in shared C++/Slang structures. Arrays, pointer arithmetic, and nested data structures work without buffer descriptors or binding slots. Vertex shaders fetch their own vertices; there is no vertex-layout declaration.
- Bindless textures and samplers. The application owns descriptor heaps and chooses their indices. Materials carry those indices as data. Changing materials does not require constructing or rebinding per-material descriptor sets.
- Root arguments instead of binding tables. Each draw or dispatch receives a GPU pointer to a structure containing GPU pointers, texture indices, and constants. The CPU and shader share its declaration; there are no descriptor-set layouts or pipeline layouts to keep in agreement.
- Less pipeline-state coupling. Resource-binding and vertex layouts are absent from pipeline creation. Viewport, scissor, and depth/stencil state are set independently, reducing pipeline permutations. Rasterization, blending, and attachment formats still belong to pipeline objects.
- Barriers without resource lists. Synchronization describes which work produces and consumes data, not a list of buffer and image transitions. Applications do not track image layouts.
This is a low-level library: the application still owns allocation policy, resource lifetime, and GPU synchronization. The optional NoGraphicsAPIUtility library supplies shared shader types, math, allocators, upload queues, and deferred deletion without making them part of the graphics API.
Declare the arguments once in a shared C++/Slang header:
struct RootArguments
{
Vertex* vertices;
Material* material;
float4x4 transform;
uint32 texture_index;
};Allocate a root from application-owned mapped storage, fill it through the CPU address, then pass its GPU address:
const gpu::GpuCpuRange<RootArguments> root = bump_allocator.allocate<RootArguments>();
*root.cpu = {
.vertices = vertex_memory.gpu,
.material = material_memory.gpu,
.transform = transform,
.texture_index = texture_index,
};
gpu::draw(commands, root.gpu, vertex_count);With <NoGraphicsAPI/shader.slang>, the shader accesses the same data directly:
GPU_ROOT(RootArguments, root);
Vertex vertex = root.vertices[vertex_id];
Material material = *root.material;
Texture2D<float4> texture = gpu_texture<Texture2D<float4>>(root.texture_index);Draws and dispatches take GPU root pointers directly, including roots written by earlier GPU work. All graphics stages share the same root. Keep each root allocation alive and stable until its GPU use completes. See the design comparison for the remaining differences and the shader guide for complete examples.
Metal 4 supplies native GPU addresses, draw/dispatch commands that accept those addresses, and
MTLTextureViewPool for indexed textures. Vulkan supplies the equivalent model through device-address
commands and descriptor heaps. See Metal implementation and
Vulkan implementation for how these map to NoGraphicsAPI.
Requires macOS, iOS or iPadOS 26+ and Apple GPU family 7 or newer with Metal 4.
| Platform | Supported devices |
|---|---|
| Mac | Apple silicon Macs (M1 and newer) |
| iPhone | iPhone 12 and newer (A14 and newer) |
| iPad Pro | 2021 and newer (M1 and newer) |
| iPad Air | 2020 and newer (A14 and newer) |
| iPad mini | 2021 and newer (A15 and newer) |
| iPad | 2022 and newer (A14 and newer) |
See Apple's supported devices. Direct task/mesh draws work throughout this baseline; indirect mesh draws require A17 Pro / M3 or newer. BC texture compression is a separate capability. See Metal implementation for these limits and validation for tested hardware and known issues. Intel Macs, Simulator, tvOS and visionOS are not supported targets.
The Vulkan backend targets little-endian x86-64; utility math requires AVX2 and FMA. Vulkan 1.4 alone is insufficient. Required extensions include:
VK_EXT_descriptor_heap— application-owned descriptor heaps.VK_KHR_device_address_commands— commands operating on GPU addresses.VK_EXT_mesh_shader— task and mesh shaders.VK_KHR_shader_untyped_pointers— descriptor-heap shader support.
VK_KHR_unified_image_layouts is optional and makes the backend's common image layout efficient.
See the Vulkan implementation for the complete feature contract.
Missing required extensions are the main reason for unsupported GPUs below; the remaining requirements are more widely supported on recent GPUs.
The table preserves the driver reports checked on 5 September 2026. These are compatibility snapshots, not a live driver list. The checked Windows packages were AMD Adrenalin 26.9.1 and NVIDIA 616.64 WHQL.
| Architecture | Driver snapshot | Products | CPU-visible heap | Required extensions |
|---|---|---|---|---|
| AMD RDNA 2 (dGPU) | Windows / Adrenalin 26.9.1 | RX 6000 | PCIe ReBAR or 🔴 256 MiB fixed BAR |
🔴 Unsupported |
| AMD RDNA 2 (iGPU) | Windows / Adrenalin 26.9.1 | 600M | UMA | 🔴 Unsupported |
| AMD RDNA 2 (iGPU) | Linux / Mesa RADV 26.2+ | Steam Deck | UMA | Supported |
| AMD RDNA 3 (dGPU) | Windows / Adrenalin 26.9.1 | RX 7000 | PCIe ReBAR | Supported |
| AMD RDNA 3 (iGPU) | Windows / Adrenalin 26.9.1 | 700M | UMA | Supported |
| AMD RDNA 4 (dGPU) | Windows / Adrenalin 26.9.1 | RX 9000 | PCIe ReBAR | Supported |
| NVIDIA Turing | Windows / NVIDIA 616.64 | GTX 16 series | 🔴 256 MiB fixed BAR | Supported |
| NVIDIA Turing | Windows / NVIDIA 616.64 | RTX 20 series | 🔴 256 MiB fixed BAR | Supported |
| NVIDIA Ampere | Windows / NVIDIA 616.64 | RTX 30 series | PCIe ReBAR | Supported |
| NVIDIA Ada Lovelace | Windows / NVIDIA 616.64 | RTX 40 series | PCIe ReBAR | Supported |
| NVIDIA Blackwell | Windows / NVIDIA 616.64 | RTX 50 series | PCIe ReBAR | Supported |
🔴 marks missing extensions or a capacity-limited fixed BAR. Mapped heaps require coherent CPU-visible GPU memory. Enable ReBAR where available on discrete GPUs; integrated GPUs use UMA. A fixed BAR can still work, but limits mapped-heap capacity. Separate GPU-only allocations can use the remaining VRAM. UMA heap sizes depend on system configuration.
The checked Windows RDNA 2 reports lack descriptor-heap support. Pascal / GTX 10 lacks the required extensions. Intel Windows support was not verified; the checked Arc report also lacks required extensions. Mesa RADV and ANV 26.2+ expose the required extensions on the reported Linux/SteamOS targets.
See known driver issues for observed problems and workarounds.
Install Xcode 26+ with its Metal compiler, CMake, and Slang 2026.18.2+. Build the examples and tests:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_SYSROOT=macosx -DNOGRAPHICSAPI_BUILD_EXAMPLES=ON \
-DNOGRAPHICSAPI_BUILD_TESTS=ON -DNOGRAPHICSAPI_SLANGC=/path/to/slangc
cmake --build build
ctest --test-dir build --output-on-failure
build/examples/triangle/example_triangleSee building and integration for iOS builds and Metal validation for known test limitations.
- Install Visual Studio 2022 with the
Desktop development with C++ workload,
including the Windows SDK. The supplied
msvcpreset targets Visual Studio 2022 x64. - Install CMake 3.24+ and make
cmakeavailable onPATH. - Install the Vulkan SDK 1.4.357+. Shader validation requires
SPIRV-Tools 2026.3+; make the SDK's
Bindirectory, containingspirv-val.exe, available onPATH. - Use Slang 2026.14.1+ from the Vulkan SDK, or download a standalone Windows x64 release,
extract it, and add its
bindirectory toPATH. - Install a GPU driver meeting the hardware requirements above. The Vulkan SDK does not replace the GPU driver.
Clone the repository or download its source archive, then open PowerShell in the repository directory. Configure, build, test, and run the triangle example:
cmake --preset msvc
cmake --build --preset msvc-release
ctest --preset msvc-release
.\build-msvc\examples\triangle\Release\example_triangle.exeTo open the generated solution in Visual Studio, use build-msvc/NoGraphicsAPI.sln.
For a validation-enabled Debug build, use msvc-debug in the build and test commands.
If the shader tools are not on PATH, supply their locations when configuring. Adjust these example
paths to your installations:
cmake --preset msvc -DNOGRAPHICSAPI_SLANGC=C:/Slang/2026.14.1/bin/slangc.exe -DNOGRAPHICSAPI_SPIRV_VAL=C:/VulkanSDK/1.4.357.0/Bin/spirv-val.exeTo install the Release libraries and headers locally:
cmake --install build-msvc --config Release --prefix ./installThe install includes the independent NoGraphicsAPI and NoGraphicsAPIUtility CMake packages. See building and integration for using them in your own project or building the library without examples and tests.
- Triangle — the smallest rendering example.
- Cube — GPU-pointer vertex fetch and bindless textures.
- Deferred renderer — compute simulation and mesh-shader rendering.
The executables are under build-msvc/examples/<example>/Release when using the supplied preset.
- Comparison with No Graphics API
- Vulkan implementation
- Metal 4 implementation
- Slang shaders and root ABI
- Public API
- Metal validation and limitations
- Building and integration
NoGraphicsAPI and NoGraphicsAPIUtility use the MIT License. See third-party notices for bundled assets and dependencies.