Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rhi-cpp

A backend-neutral render hardware interface for C++20 game engines. Vulkan today; the dispatch seams for Metal and D3D12 are kept in place.

It covers the core device/resource layer, acceleration structures and SBT, a bindless descriptor set, the program/pipeline cache, a GPU profiler, a dual-queue resource uploader, typed pipeline descriptions with a hand-declared descriptor Layout model, OffsetAlloc, TimelineDeferral, an ImGui layer and a glTF loader.

Design

  • Handles are values, not pointers. Every resource is a POD struct wrapping a backend handle plus a cookie — a stable identity used as the descriptor-set cache key, because a raw backend handle is unsafe as identity (handles get reused). cookie == 0 means empty.
  • One barrier vocabulary. ResourceState combines access and layout into a single bit set; the backend derives image layouts, access masks and stage masks from it. Stage narrowing is optional and conservative by default.
  • Dynamic rendering only. There are no render-pass or framebuffer objects.
  • No reflection. Descriptor layouts are declared explicitly by the caller (rhi::Layout), not derived from SPIR-V. That keeps the program layer free of any shader-bytecode format.
  • Compile-time backend selection. Each handle carries a union { vk; mtl; } guarded by RHI_DEVICE_IMPL_*, and each entry point guards on IsTargetSelected(). In a single-backend build that folds to a constant.

Building

cmake -B build -G Ninja -DRHI_BUILD_TESTS=ON
cmake --build build
ctest --test-dir build

Requires CMake ≥ 3.24 and a C++20 compiler. Vulkan headers, volk and VMA are fetched automatically if not already present.

Options

Option Default
RHI_BACKEND_VULKAN ON
RHI_BACKEND_METAL OFF seams only — the implementation is not ported
RHI_ENABLE_RAYTRACING ON acceleration structures, RT pipelines, SBT
RHI_FRAMES_IN_FLIGHT 2 sizes the command ring, scratch allocators, deferral
RHI_BUILD_SHARED OFF
RHI_BUILD_EXAMPLES OFF needs SDL3
RHI_BUILD_TESTS OFF
RHI_ENABLE_IMGUI OFF
RHI_ENABLE_GLTF OFF
RHI_PROVIDE_VMA_IMPL ON turn off if the host already compiles VMA

Retrofitting into an existing engine

Engines that already vendor volk, VMA or Vulkan-Headers must not end up with a second copy. cmake/Dependencies.cmake resolves each dependency in this order: an existing target in the tree, then RHI_USE_EXTERNAL_<DEP>=ON (require, never fetch), then an installed config package, then FetchContent from a pinned tag.

# volk/VMA already declared by the engine
add_subdirectory(extern/rhi)
target_link_libraries(my_renderer PRIVATE rhi::core)

If the engine already compiles VMA in its own TU, add -DRHI_PROVIDE_VMA_IMPL=OFF.

Install and find_package(rhi) are also supported.

Code being migrated from the older RI* naming can include <rhi/compat/RICompat.h>, which aliases the previous type and macro spellings onto the rhi:: namespace.

Compiling Slang shaders

cmake/Slang.cmake is an optional build rule — nothing in rhi::core needs it, and including it is what turns it on:

include(Slang)

rhi_add_slang_shaders(my_renderer
  SOURCES ${CMAKE_CURRENT_LIST_DIR}/shaders/scene.vert.slang
          ${CMAKE_CURRENT_LIST_DIR}/shaders/scene.frag.slang
          ${CMAKE_CURRENT_LIST_DIR}/shaders/common.slang
  OUTPUT_DIR ${CMAKE_BINARY_DIR}/compiled_shaders)   # optional

Each source whose name ends in a stage suffix — .vert .frag .comp .cs .geom .tesc .tese .rgen .rchit .rmiss .rahit .rint .rcall .rt .3d, before the .slang — is compiled to SPIR-V as <OUTPUT_DIR>/<name>.spv (scene.vert.slangscene.vert.spv). Everything else in SOURCES is an include-only module: it gets no compile rule, but it does become a dependency of every shader that could import it, so editing a shared module rebuilds them. The outputs are attached to <target> through a <target>_shaders custom target.

Shaders are compiled with -fvk-use-entrypoint-name, which keeps the Slang function name as the SPIR-V OpEntryPoint — that name is how the program layer finds an entry point, so it is not optional.

slangc is resolved in this order: -DRHI_SLANGC=<path>, then a slangc on PATH, then the pinned prebuilt release downloaded into the build tree at configure time. If none of those produce a compiler, configuration still succeeds with a warning and no shaders are built.

Option Default
SLANG_VERSION 2026.11 pinned release for the download
RHI_SLANG_DOWNLOAD ON set OFF for an offline build
RHI_SLANGC (empty) path to a slangc to use as-is
RHI_SLANG_FLAGS (see the module) flags passed to every shader

Examples

cmake -B build-examples -G Ninja -DRHI_BUILD_EXAMPLES=ON
cmake --build build-examples
./build-examples/examples/00_clear
examples/common/ the SDL3 harness — window, WindowHandle, swapchain create/recreate, command ring, frame loop. This is the file to copy into an engine.
examples/00_clear acquire, clear to an animated colour, present. No Program, no pipeline, no shader.
examples/01_shader a fullscreen triangle from a Slang shader through Program + GraphicsPipelineDesc, with a push constant.
examples/02_mesh vertex/index buffers staged into device-local memory, a VertexInputDesc, a depth buffer and an MVP push constant.

Every example accepts --debug / --no-debug (validation layers; on by default in a debug build), --no-vsync, --video-driver <name> (x11 for RenderDoc, which cannot capture a Wayland surface) and --frames <n> (quit after n frames, for unattended smoke tests). Escape closes the window.

SDL3 is resolved the same way volk and VMA are — an existing SDL3::SDL3 target, then an installed package, then FetchContent of RHI_SDL3_TAG — so an engine that already vendors SDL does not get a second copy. The harness fills rhi::WindowHandle from SDL's native window properties rather than calling SDL_Vulkan_CreateSurface, because that handle is the seam rhi actually offers.

01 and 02 need slangc to compile their .slang sources; if none is found and the pinned prebuilt cannot be downloaded, configuration reports it and builds only 00_clear.

Licence

GPL-2.0-or-later. Contact the author for commercial licensing.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages