Skip to main content

Backends and validation

Choosing a backend​

Instance.init tries each backend in turn and returns the first one that starts successfully. You can read the backend it picked from instance.selected_backend.

const instance = try vit.Instance.init(gpa, .{
.backend = .{ .vulkan = true, .dx12 = true }, // leave unset for the platform default
.validation = .none,
});
std.log.info("using {s}", .{@tagName(instance.selected_backend)});

The default order depends on the platform:

PlatformOrder
WindowsDirectX 12, then Vulkan
Linux and AndroidVulkan
macOS and iOSMetal (not implemented yet), then Vulkan
Web (Emscripten)WebGPU

If the VITELLUS_BACKEND environment variable is set to vulkan, dx12, metal or webgpu, that backend is tried first, provided .backend allows it. This lets you switch backends without rebuilding:

VITELLUS_BACKEND=vulkan ./zig-out/bin/my-game

Validation​

.validation controls the debug layers:

LevelMeaning
.noneNo layers. Use this for release builds.
.coreStandard API validation.
.extendedCore validation plus extra checks, such as synchronisation validation.
.gpu_basedGPU-assisted validation. This is the slowest level and the most thorough.

A message from a validation layer means the code is wrong, even if the frame looks correct.

Adapters and capabilities​

const adapter = try vit.Adapter.init(instance, .{});
const info = adapter.info();
std.log.info("GPU: {s}", .{info.nameSlice()});

const caps = adapter.capabilities();
if (!caps.features.timestamp_query) return error.NoTimestamps;

const rgba8 = adapter.formatCapabilities(.rgba8_unorm);
if (!rgba8.usage.storage) return error.NoStorageImages;

instance.enumerateAdapters() returns every adapter on the selected backend. You own the slice and each adapter in it: deinit each adapter, then free the slice with the instance's allocator.