Vulkan Bindings for C3

November 6, 2025 ยท View on GitHub

Installation

Copy vulkan.c3l to your project's lib folder and you are good to go. In your code file, import the library

import vk;

If you are using GLFW, you may need to turn on a flag to enable vulkan support on GLFW

module std::core::env;
const bool GLFW_INCLUDE_VULKAN = true;
import glfw;

Running example

Install C3C, Vulkan SDK, GLFW. Compile Shader

glslc src/shaders/shader.frag -o src/shaders/frag.spv
glslc src/shaders/shader.vert -o src/shaders/vert.spv

Then run

c3c run

If you don't want to install those dependencies on your system, you can use a nix flake to set them up for you

nix develop
# inside nix environment
glslc src/shaders/shader.frag -o src/shaders/frag.spv
glslc src/shaders/shader.vert -o src/shaders/vert.spv
c3c run

screenshot

Usage

Use caseCC3 Equivalent
Function namingvkFunctionNamevk::functionName
Constant namingVK_CONSTANT_NAMEvk::CONSTANT_NAME
Struct namingVkStructNamevk::StructName
Enum typeVkEnumNamevk::EnumName
Enum valueVK_ENUM_NAME_VALUEvk::EnumName.VALUE
Flag typeVkFlagNamevk::FlagName as bitstruct
Error typeVK_ERROR_NOT_READYvk::error::NOT_READY
String typechar *ZString
Error handlingVkResult vkBeginCommandBuffer(VkCommandBuffer, const VkCommandBufferBeginInfo*)fn void? beginCommandBuffer(CommandBuffer, CommandBufferBeginInfo*)
Array extractionVkResult VkEnumerateInstanceExtensionProperties(char*, int*, VkExtensionProperties*)fn ExtensionProperties[]? enumerateInstanceExtensionProperties(ZString)
Value extractionVkResult vkCreateInstance(const VkInstanceCreateInfo*, const VkAllocationCallbacks*, VkInstance*)fn Instance? createInstance(InstanceCreateInfo*, AllocationCallbacks* = null)

Error Handling

You can handle errors manually like this:

vk::ApplicationInfo app_info = {
    .s_type = vk::StructureType.APPLICATION_INFO,
    .p_application_name = "Fortknight",
    .application_version = vk::@make_version(1, 0, 0),
    .p_engine_name = "Soreal Engine",
    .engine_version = vk::@make_version(1, 0, 0),
    .api_version = vk::API_VERSION_1_3,
};
vk::InstanceCreateInfo createInfo = {
    .s_type = vk::StructureType.INSTANCE_CREATE_INFO,
    .p_application_info = &app_info,
};

fn void create() {
    Instance? instance = vk::createInstance(&createInfo);
    if (catch excuse = instance) {
        if (excuse == vk::error::NOT_READY) {
            io::printfn("not ready to create instance");
        } else {
            io::printfn("something went wrong while creating instance");
        }
    }
    // continue using instance
}

Or you can use shorthand like so:

fn void create() {
    Instance instance = vk::createInstance(&createInfo)!!; // immediate crash on error
}

Credits

This binding was made possible thank to the initial effort from Odin's.