Skip to content
antono2Public

About

Generated Vulkan and Vulkan Video bindings for V, with opt-in typed resource helpers and reproducible Khronos registry updates.

Topics

Resources

Stars

11 stars

Watchers

1 watching

Forks

Repository files navigation

Vulkan bindings for V

Project portfolio

Validate Vulkan bindings

Available as antono2.vulkan on VPM.

vulkan.v and vulkan_video.v are generated from Khronos' canonical Vulkan API registry. The package follows the semantic version in v.mod; VERSION records the Vulkan registry snapshot, while REGISTRY_COMMIT and VOLK_COMMIT make the bundled header and loader inputs reproducible.

Install and setup

Install the current bindings in your V module directory:

v install antono2.vulkan

This installs the repository's current default branch. For reproducible builds, select a package tag from the releases and append @<tag> to the module name in your install command or v.mod. Package versions and Khronos registry versions are separate; v.mod and VERSION record them respectively.

Then install or verify native runtime tools using the setup script at the default V module location:

v run "$HOME/.vmodules/antono2/vulkan/setup.vsh"

From a source checkout, use v run setup.vsh. The script supports Ubuntu and Debian, Fedora, Arch, openSUSE, macOS and Windows with winget. On Linux it installs a C compiler, Vulkan runtime tools and the VPM module; the bundled headers and Volk need no distribution development packages. The macOS and Windows helpers still use the Vulkan SDK to provide runtime tooling, but its headers are not required to compile this module. The script then verifies the result. For a read-only support check, run:

v run setup.vsh --check

v install antono2.vulkan includes the matching Khronos Vulkan C headers and Volk sources. The package compiles against these bundled files, even when the system has older Vulkan development headers or none installed. VULKAN_SDK is not needed to compile the module. setup.vsh --check verifies the bundled header version against VERSION and checks that Volk is present. The native Vulkan loader and a driver or software implementation are still needed to run Vulkan applications.

The SDK and loader cannot supply a hardware Vulkan implementation. If vulkaninfo cannot enumerate a device after setup, install or update the GPU vendor's driver. CI verifies the bundled headers and Volk against the pinned upstream revisions recorded by this repository.

First use

Applications using the binding directly must initialize Volk before the first Vulkan call, then load instance- and device-level commands after creating the corresponding handles:

import antono2.vulkan as vk

if vk.initialize_loader() != .success {
	panic('Vulkan loader initialization failed')
}
// create the Vulkan instance
vk.load_instance_commands(instance)
// create the Vulkan device
vk.load_device_commands(device)

Platform extensions

Enable a platform extension when building code that uses its raw types or commands. The V flag also enables the matching Vulkan C header macro:

v -d vulkan_xlib run your_app.v

For XCB or Wayland, use vulkan_xcb or vulkan_wayland instead. Other flags follow the registry platform names, such as vulkan_win32, vulkan_android and vulkan_metal. Applications and windowing libraries may need native window-system headers for the selected platform (for example Xlib or Wayland). Extension name and spec-version constants are available without these flags, so applications can still query extension support before selecting a backend.

Historical Vulkan versions

The original tags from v1.3.290 through v1.4.335 are preserved exactly as published. They use a source layout accepted by the V compiler available at the time, but not by current V releases. For a historical Vulkan version with a current V compiler, install its matching +vcompat.1 tag instead:

v install https://github.com/antono2/vulkan@v1.4.335+vcompat.1

Compatibility tags contain bindings regenerated from the same tagged Khronos Vulkan registry. They do not move or replace the original tags. v1.4.362 and later tags already use the current layout and need no compatibility suffix.

Examples

examples/ergonomic_lifecycle exercises the opt-in convenience API from instance creation through queue submission and ordered cleanup. It is a headless validation smoke test and does not open a window:

v run examples/ergonomic_lifecycle

For windowed rendering, see the tested GLFW/Vulkan example in antono2/v_imgui_examples and the Vulkan/OpenCL particle renderer in antono2/opencl. The canonical binding-generator tests remain in antono2/v_vulkan_bindings.

Ergonomic API (opt in)

The generated module remains the complete low-level binding. The opt-in antono2.vulkan.ergonomic submodule adds typed errors, instance lifecycle helpers, physical-device and queue-family discovery and validated single- or multi-queue logical-device ownership. It also provides explicit memory-type selection and owned buffer/device-memory allocation, owned command pools and primary command-buffer lifecycle helpers, synchronization objects, checked queue submission, owned 2D images and views and explicit image-layout transition recording without modifying generated files. Presentation helpers collect and select surface formats, present modes, extents, image counts and composite alpha modes. Host-visible buffers support checked persistent mappings and coherent uploads, while owned shader modules accept validated SPIR-V words or bytes. See the ergonomic API design.

For Vulkan host allocations, InstanceOptions.allocator and DeviceOptions.allocator accept optional &vk.AllocationCallbacks. The owner copies the callback structure and passes it to matching destruction calls; device child owners inherit the device's allocator. Keep callback functions and pUserData state alive until the corresponding owners are destroyed. Instance and device allocators are independent. These callbacks do not replace Vulkan device-memory allocation or the companion memory allocator module.

Owning ergonomic wrappers are @[nocopy], and constructors return owned pointers. Store them in mut variables so they can be destroyed, pass those pointers directly without adding another & and destroy children before parents. Destruction is explicit and idempotent; borrowed queues, discovery snapshots and raw Vulkan handles remain copyable. See the complete ownership model.

OwnedBuffer and OwnedImage deliberately use one Vulkan memory allocation per resource so their ownership stays obvious in small programs. Applications that create many resources should use the companion antono2.vkmemalloc module, which provides policy-based memory selection and class-safe block suballocation. It depends on this binding and remains separate to avoid a circular dependency in the low-level Vulkan package.

Instance and device configuration can validate requested names before Vulkan is called:

mut instance := vke.new_instance_with_options(vke.InstanceOptions{
	application_name: 'my app'
	extensions: ['VK_KHR_surface']
})!

family := physical_device.find_queue_family(u32(vk.QueueFlagBits.graphics)) or {
	return error('no graphics queue')
}
mut device := physical_device.new_device_with_options(vke.DeviceOptions{
	queue_requests: [vke.DeviceQueueRequest{
		queue_family: family
		priorities: [f32(1.0)]
	}]
	extensions: ['VK_KHR_swapchain']
})!

Each priority requests the queue at the same zero-based index in its family. Use one DeviceQueueRequest per distinct family; device.queues exposes the created queues in request order and device.queue remains the first one.

The CI lifecycle smoke test runs the ergonomic path from instance creation through queue submission and cleanup under VK_LAYER_KHRONOS_validation. Run it locally with:

VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  v run examples/ergonomic_lifecycle

Supported toolchains

The validation workflow records the exact compiler, runner, registry and loader pins used for CI.

Platform Compiler lane Validation
Linux Pinned release V, GCC and TinyCC Compile, unit tests and validation-layer lifecycle run
macOS Pinned release V, Clang Compile and unit tests
Windows Pinned release V, MSVC Compile and unit tests
Linux Pinned V3, TinyCC Required strict frontend checks; advisory C backend smoke tests
Linux Current V master, GCC Advisory compiler compatibility checks

Current V master selects V3 by default and can fall back to its compatibility compiler. The separate pinned V3 lane requires -new-compiler frontend checks so that fallback cannot hide type-checking failures. Its C backend and the moving-master lane remain advisory while compiler compatibility is verified.

The generated registry snapshot determines which declarations are available. The installed Vulkan loader and driver must still support every command, extension and feature an application requests. Successful compilation alone does not establish runtime device support.

Generate and maintain

The generator is maintained in antono2/v_vulkan_bindings. Its scheduled updater proposes registry and bundled-header changes for review; package release tags are prepared separately after CI passes. Keep README instructions aligned with these workflows. Link to release metadata and CI pins for changing version details, and retain explicit historical versions only where they explain compatibility.

Thanks

Source navigation

vulkan.v and vulkan_video.v are registry-generated API declarations. Update their source in v_vulkan_bindings rather than editing individual declarations. Keep registry versions and regeneration changes separate from handwritten convenience-layer edits.

loader.v selects and initializes native dispatch; c/ contains the local bridge to Volk. ergonomic/ contains discovery, configuration, allocation and resource-lifetime helpers. Start with examples/ for their initialization and cleanup order, and ci/ for loader and ABI smoke checks. Vendored headers retain their upstream license and provenance comments.

The generator owns the purpose and regeneration comments in both generated files. These introductions were regenerated from Vulkan-Docs tag v1.4.365 (commit 8c9361ba8180c1f4164c0bf79de2f6e817770b0d), with all declarations verified unchanged. Select Vulkan-Docs using this module's VERSION; the generator repository's historical default snapshot may be older. Despite its name, REGISTRY_COMMIT pins Vulkan-Headers, not Vulkan-Docs. Keep that C-header pin and VOLK_COMMIT aligned with the inputs described in the vendor guide.

About

Generated Vulkan and Vulkan Video bindings for V, with opt-in typed resource helpers and reproducible Khronos registry updates.

Topics

Resources

Stars

11 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages