vulkan-go

module
v1.4.349 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 10, 2026 License: Apache-2.0

README

vulkan-go

Unofficial Go bindings for Vulkan, auto-generated from vk.xml.

Installation

go get github.com/lukem570/vulkan-go/pkg/raw

Quick Start

import vk "github.com/lukem570/vulkan-go/pkg/raw"

// Initialize Vulkan (must be called first)
if err := vk.Initialize(); err != nil {
    log.Fatal(err)
}

instance, err := vk.CreateInstance(&vk.InstanceCreateInfo{
    ApplicationInfo: &vk.ApplicationInfo{
        ApplicationName: "my-app",
        ApiVersion:      vk.MakeApiVersion(0, 1, 4, 0),
    },
}, nil)
if err != nil {
    log.Fatal(err)
}
defer instance.Destroy(nil)

vk.LoadInstance(instance)

Examples

See the test/ directory for full working examples:

  • triangle — windowed graphics pipeline with GLFW, swapchain, render pass, and shader modules
  • compute — headless compute pipeline with buffer readback
  • surface — surface creation and physical device selection with GLFW

API Changes from Vulkan

Initialization

Vulkan-go uses Volk to load the Vulkan dynamic library at runtime. Call Initialize() before any other Vulkan function, then call LoadInstance and LoadDevice after creating them to load extension function pointers:

vk.Initialize()

instance, _ := vk.CreateInstance(...)
vk.LoadInstance(instance)

device, _ := physDevice.CreateDevice(...)
vk.LoadDevice(device)
Methods on handles

Commands that take a handle as their first parameter become methods on that handle:

// C
vkDestroyInstance(instance, pAllocator);
vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
// Go
instance.Destroy(pAllocator)
device, err := physDevice.CreateDevice(createInfo, nil)
Return values

Functions that write to an output pointer parameter return that value directly (along with error for VkResult-returning functions):

// C
VkResult vkCreateFence(VkDevice, const VkFenceCreateInfo*, const VkAllocationCallbacks*, VkFence* pFence);
// Go
fence, err := device.CreateFence(&vk.FenceCreateInfo{}, nil)
Arrays

Length+pointer pairs in structs are collapsed into a single Go slice:

// C
struct VkSubmitInfo {
    uint32_t        waitSemaphoreCount;
    VkSemaphore*    pWaitSemaphores;
    // ...
};
// Go
vk.SubmitInfo{
    WaitSemaphores: []*vk.Semaphore{sem},
}
Safe pNext chaining

Every struct that supports pNext has a Next field typed as the Structure interface, which ensures only compatible structs can be chained. The sType field is set automatically:

type Structure interface {
    GetType() StructureType
}
// Type-safe chaining — sType is set automatically
instance, err := vk.CreateInstance(&vk.InstanceCreateInfo{
    Next: &vk.ValidationFeaturesEXT{
        Next: &vk.DebugUtilsMessengerCreateInfoEXT{ /* ... */ },
        EnabledValidationFeatures: []vk.ValidationFeatureEnableEXT{
            vk.ValidationFeatureEnableBestPracticesEXT,
        },
    },
    // ...
}, nil)
Function pointer callbacks

PFN fields on structs accept Go closures directly. The binding layer handles CGo trampoline setup automatically:

messenger, err := instance.CreateDebugUtilsMessengerEXT(&vk.DebugUtilsMessengerCreateInfoEXT{
    MessageSeverity: vk.DebugUtilsMessageSeverityFlagsEXT(
        vk.DebugUtilsMessageSeverityErrorBitEXT |
            vk.DebugUtilsMessageSeverityWarningBitEXT,
    ),
    MessageType: vk.DebugUtilsMessageTypeFlagsEXT(
        vk.DebugUtilsMessageTypeValidationBitEXT |
            vk.DebugUtilsMessageTypePerformanceBitEXT,
    ),
    PfnUserCallback: func(
        severity vk.DebugUtilsMessageSeverityFlagBitsEXT,
        types vk.DebugUtilsMessageTypeFlagsEXT,
        data *vk.DebugUtilsMessengerCallbackDataEXT,
        userData unsafe.Pointer,
    ) bool {
        fmt.Println("vulkan:", data.Message)
        return false
    },
}, nil)
GLFW interop

Surface creation with go-gl/glfw requires passing the instance handle and converting the returned surface pointer:

surfPtr, err := window.CreateWindowSurface((*byte)(instance.Handle()), nil)
surface := vk.SurfaceKHRFromGLFW(surfPtr)
defer instance.DestroySurfaceKHR(surface, nil)

Code Generation

Bindings are generated from mod/Vulkan-Headers/registry/vk.xml using the generator in cmd/gen/. Configuration (API version, extensions, platforms) is in config.yml.

go run ./cmd/gen

Generated output: pkg/raw/vulkan.go, pkg/raw/vulkan_linux.go, pkg/raw/vulkan_windows.go, pkg/raw/volk_wrappers.{c,h}

Overhead

All Go structs are deep-copied to their C counterparts on each call. This is the cost of the safe, idiomatic API surface.

Directories

Path Synopsis
cmd
gen command
pkg
raw
test
compute command
surface command
triangle command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL