Skip to content

Repository files navigation

NoGraphicsAPI

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.

What changes from classic rendering?

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.

What a draw's data looks like

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.

Native implementations

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.

Hardware requirements

Metal 4

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.

Vulkan 1.4

The Vulkan backend targets little-endian x86-64; utility math requires AVX2 and FMA. Vulkan 1.4 alone is insufficient. Required extensions include:

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.

macOS installation and quick start

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_triangle

See building and integration for iOS builds and Metal validation for known test limitations.

Windows installation and quick start

  1. Install Visual Studio 2022 with the Desktop development with C++ workload, including the Windows SDK. The supplied msvc preset targets Visual Studio 2022 x64.
  2. Install CMake 3.24+ and make cmake available on PATH.
  3. Install the Vulkan SDK 1.4.357+. Shader validation requires SPIRV-Tools 2026.3+; make the SDK's Bin directory, containing spirv-val.exe, available on PATH.
  4. Use Slang 2026.14.1+ from the Vulkan SDK, or download a standalone Windows x64 release, extract it, and add its bin directory to PATH.
  5. 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.exe

To 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.exe

To install the Release libraries and headers locally:

cmake --install build-msvc --config Release --prefix ./install

The 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.

Examples

  • 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.

Documentation

License

NoGraphicsAPI and NoGraphicsAPIUtility use the MIT License. See third-party notices for bundled assets and dependencies.

About

Minimal graphics API. Built on top of latest Vulkan extensions. As close as possibly to my "No Graphics API" blog post and the SIGGRAPH talk.

Resources

Stars

1.6k stars

Watchers

17 watching

Forks

Releases

Packages

Contributors

Languages