# Nabla: a modular C++ layer for Vulkan, OptiX and CUDA interoperation

> Nabla is an Apache-2.0 C++ rendering library that ties Vulkan, OptiX and CUDA into one framework, with a curated extension profile, SPIR-V driven layout creation and a CPU to GPU asset path. The interop layer is real, but the install story is thin and part of the framework is still marked unfinished.

**Devsh-Graphics-Programming/Nabla** — Vulkan, OptiX and CUDA Interoperation Modular Rendering Library and Framework for PC/Linux/Android

- Repository: https://github.com/Devsh-Graphics-Programming/Nabla
- Website: http://devsh.eu
- Stars: 718 · Forks: 73
- Language: C++
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/devsh-graphics-programming-nabla

## Three graphics APIs that normally refuse to share a process

Most teams that need ray tracing in production end up gluing three graphics APIs together by hand: a modern Vulkan core, NVIDIA's OptiX for ray queries, and CUDA for general compute. Nabla is a C++ library and framework that ships that gluing as the product itself. Its stated scope is a modular rendering library and framework for Vulkan, OptiX and CUDA interoperation on PC, Linux and Android, and its topic list names the exact domains it aims at, including computer graphics, GPGPU, path tracing, physically based rendering, shaders, SPIR-V and the OptiX denoiser.

The audience is engine programmers and technical artists who need ray tracing and physically based rendering now and cannot spend a year on API plumbing. The project page carries sections titled Need Our Expertise? and Join Our Team, so this is a commercial style operation offering help around the code rather than a purely academic exercise. The homepage listed for the repository is devsh.eu, and the project also runs a Discord server for contact.

## A curated Vulkan profile instead of the whole extension surface

The first entry in the project's feature list is a Nabla Core Profile, described as exposing a curated set of Vulkan extensions. That word carries the design decision. A renderer that enables the entire Vulkan extension surface inherits a long tail of features that are missing on the exact hardware you ship to, and every consumer then has to guard against them at runtime. A curated profile pins a subset the library has decided to carry, which is a narrower contract but a survivable one.

The same list names physical device selection and filtering as its own capability, and the excerpt does not spell out how selection actually happens or what the filter criteria are. The excerpt also calls out a full embrace of buffer device address and descriptor indexing, two Vulkan features that relax descriptor and buffer binding rules. For a library built around interoperation, device choice is the hard part: an OptiX capable NVIDIA device, a CUDA compute device and a Vulkan physical device may not be the same object, and reconciling them is exactly the code that is painful to write and easy to get subtly wrong.

## SPIR-V introspection replaces hand written descriptor layouts

One headline feature is worded as treating SPIR-V and Vulkan as first-class citizens, and two further entries, SPIR-V introspection and layout creation, and Nabla Extensions, extend the idea. Introspection matters for a practical reason: in Vulkan, descriptor set layouts are normally written by hand and must agree exactly with the resource usage the shader compiler reports. Deriving the layout from compiled SPIR-V removes a whole category of mismatch bugs, which is the kind of saving that justifies a framework instead of a thin wrapper.

The compiler side is treated as a service rather than a local batch step. The image gallery at the top of the project page includes a panel for the Nabla Shader Compiler and Godbolt docker integration, and the repository ships a root compose file that runs that image. A Godbolt style front end means a shader can be compiled and inspected in the browser against the same toolchain the engine uses, which shortens the loop when a binding mismatch appears at runtime.

## Lifecycle tracking and an event handler for work that crosses the CPU boundary

Two entries describe what the runtime does with work that crosses the CPU and GPU boundary: a Nabla Event Handler, described in the project README as a bridge between GPU and CPU synchronization, and GPU object lifecycle tracking. The first names a mechanism, a handler that sequences host and device work. The second addresses a failure mode that interoperation code hits constantly, where a resource is released on the host while the GPU still has commands in flight, or where a buffer is read after the code that created it has left scope. Lifecycle tracking exists to make that class of bug observable rather than intermittent.

Those two section titles are the only description on offer here. The excerpt shows no API surface, no synchronization primitive, and no statement about whether waits are blocking. The top-level tree of the repository carries include/, src/, source/, tests, tools and docs directories, so the headers are where you would go to read the actual contract. Treat the feature list as a set of intentions and confirm the details in code before designing around them.

## Running the shader compiler container, and the Windows bind mounts that stop it

The project publishes no single install command for the library itself, and the tree does not contain one in the places a reader would look first. What it does contain is a compose file at the root, next to a docker/ directory and a CMakeLists.txt with CMakePresets.json, tied to the shader compiler image shown in the project gallery. The compose file is the one place where the project hands the reader an exact configuration, and reading it end to end exposes several constraints at once.

```yaml
services:
  nsc:
    container_name: nsc-godbolt
    image: ghcr.io/devsh-graphics-programming/nabla-shader-compiler-godbolt:latest
    isolation: process
    ports:
      - "80:10240"
    restart: always
```

The image comes from GitHub Container Registry under the devsh-graphics-programming organisation, the service is named nsc, and the container is called nsc-godbolt. The port mapping publishes container port 10240 on host port 80, so a browser session against the local machine reaches the compiler front end. The isolation: process setting means the container does not run its own virtual machine, and restart: always brings the compiler back after a host reboot.

The rest of the file is where the friction starts. It also binds two Windows directories into the container, one for ICU globalization data and one for System32, and it joins an external docker_default network. Those two bind mounts are a Windows only arrangement. On a Linux host the source paths C:\Windows\Globalization\ICU and C:\Windows\System32 simply do not exist, and Compose will refuse to start the service until the volumes section is rewritten. That is the first thing to fix, and it is also the clearest sign that the primary development environment is Windows even though the library targets PC, Linux and Android.

## Cancellable async I/O, a virtual file system and the CPU to GPU asset converter

Cancellable future-based async I/O, data transfer utilities, a virtual file system and an asset system all appear as separate entries, and they reveal the least about their internals. The combination suggests a renderer that loads and streams data on background threads and can abandon a request that is no longer needed, which matters when a camera moves quickly and a large asset turns out to be irrelevant to the frame. The virtual file system sits above the operating system layer so that the same asset path can resolve differently depending on where the content physically lives, and the asset converter, described as running from CPU to GPU, marks the boundary where data is transformed for device memory rather than uploaded as it is.

The same list includes unit-tested BxDFs for physically based rendering, which is the part most likely to be reusable outside the framework, since a bidirectional scattering function library has value even in a renderer that is not Nabla. On the CPU side the v0.9.0.0 release added a Morton Code HLSL/C++ library and a Vertex Welder, and CMake 4.x support came in the same release, so the asset tooling and the build system are being worked on in the same area. The v0.9.1.0 release then updated the GLM, GLI and DirectX Shader Compiler dependencies, the math and compiler libraries a rendering core leans on hardest.

## Unfinished corners: property pools, TODO links and a release stream behind the pushes

Several corners of the framework are openly incomplete. Property pools are labelled in progress and described as a GPU entity component system, and the table of contents reserves a separate section for Coming Soon, so parts of the design are stated before they are finished. The image gallery is also broader than the shipped feature set: several of its links point to TODO placeholders, and one row of images is labelled as a GDI to Nabla port, which reads as a demonstration of the framework's reach rather than a finished compatibility layer.

The version numbering carries four parts and moves fast. The newest tag is v0.10.0.0, labelled RayTracing Invocation Reorder and dated 2026-04-25. Before it, v0.9.1.0 from 2025-12-24 brought a Debug Draw extension together with GLM, GLI and DirectX Shader Compiler updates, and v0.9.0.0 from 2025-12-14 brought the Morton code library, CMake 4.x support and the Vertex Welder. The repository is not archived and the last push to the master branch was on 2026-10-19, but the gap between that push and the newest tag is not documented in the files shown, and no changelog is included, so you cannot tell from the repository alone which changes are in a released package.

On licensing, Nabla is Apache-2.0, a permissive licence that includes an express patent grant. This is not legal advice, and the practical caveat is the usual one for a rendering framework: the tree contains a 3rdparty/ directory and a .gitmodules file, so bundled dependencies carry their own terms and should be checked before a product ships.

## Conclusion

Nabla fits a team that has to ship ray tracing or physically based rendering across Vulkan, OptiX and CUDA in a single codebase and would rather not write that interop layer itself. It fits badly a small team that needs a runnable sample this week, because the project ships no install command and the one container configuration in the tree is Windows specific. Before committing, check that the headers under include/ expose the API your design assumes, that the SPIR-V introspection path can produce descriptor layouts matching your own shaders, and that the OptiX denoiser and CUDA pieces you need are present in the current tree. The last push was on 2026-10-19, so the code is current, but the documented feature set stops at the v0.10.0.0 tag from 2026-04-25.

## FAQ

### What does Nabla do and who is it for?

Nabla is a modular rendering library and framework written in C++ that interops Vulkan, OptiX and CUDA across PC, Linux and Android. It targets engine developers and technical artists who need ray tracing, GPGPU compute and physically based rendering without writing the interop layer themselves.

### How do I install and build Nabla?

The project does not publish a single install command. The tree contains CMakeLists.txt, CMakePresets.json and cmake/ directories for the build, and a compose file at the root that runs the shader compiler image ghcr.io/devsh-graphics-programming/nabla-shader-compiler-godbolt:latest, though that file binds Windows directories and needs editing on Linux.

### Which graphics APIs can Nabla talk to at the same time?

Vulkan, OptiX and CUDA, with the project describing itself as a modular rendering library and framework for their interoperation. Its feature list adds a curated Vulkan extension profile, physical device selection and filtering, buffer device address and descriptor indexing, plus a Debug Draw extension added in the v0.9.1.0 release.

### When was Nabla last updated and what are its recent releases?

The last push to the master branch was on 2026-10-19 and the repository is not archived. Recent releases are v0.10.0.0 for RayTracing Invocation Reorder on 2026-04-25, v0.9.1.0 for the Debug Draw extension plus GLM, GLI and DirectX Shader Compiler updates on 2025-12-24, and v0.9.0.0 for the Morton Code HLSL/C++ library, CMake 4.x support and a Vertex Welder on 2025-12-14.

## Sources

- [Devsh-Graphics-Programming/Nabla on GitHub](https://github.com/Devsh-Graphics-Programming/Nabla)
- [License: Apache-2.0](https://github.com/Devsh-Graphics-Programming/Nabla/blob/master/LICENSE)
- [Project website](http://devsh.eu)
- [README](https://github.com/Devsh-Graphics-Programming/Nabla/blob/master/README.md)
- [Releases](https://github.com/Devsh-Graphics-Programming/Nabla/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/devsh-graphics-programming-nabla
