6 Getting Started
dxtr edited this page 2026-10-18 16:13:19 +02:00

Getting Started

Requirements

  • SBCL.
  • The Vulkan loader: libvulkan.so.1 on Linux, vulkan-1.dll on Windows. On Debian and Ubuntu, the package libvulkan1.
  • A Vulkan 1.4 driver. Any GPU driver of recent years will do. Without a GPU, Mesa's software driver lavapipe works (mesa-vulkan-drivers on Debian and Ubuntu).
  • Optionally, the Khronos validation layer (vulkan-validationlayers), which checks every use of the API during development. See Instances and Validation.

No C compiler and no Vulkan headers are needed: the bindings are generated ahead of time and committed.

Installing

cl-vk is not in Quicklisp. With stift, require it in your project's stiftfile:

stift get https://fakehacker.cc/dxtr/cl-vk.git

cl-vk's own stiftfile requires cl-ffi, the foreign function interface it calls Vulkan through, which is not in Quicklisp either, so it comes along as an indirect entry. xmls, for the generator only, is pinned there for cl-vk's own tests and tools, and a project that requires cl-vk does not fetch it.

Without stift, clone both repositories somewhere ASDF finds them, such as ~/common-lisp/.

Loading

(asdf:load-system :cl-vk)

This loads the raw layer, cl-vk/ffi, too, and loads the Vulkan loader library. If the loader cannot be found, cl-ffi signals a cl-ffi:load-foreign-library-error, which lists each file it tried and why: install the loader (above).

Refer to the packages through package-local nicknames. The examples in this wiki use these:

(defpackage #:example
  (:use #:cl)
  (:local-nicknames (#:vk #:cl-vk)            ; the idiomatic API
                    (#:vks #:cl-vk/structs)   ; struct names
                    (#:vk-ffi #:cl-vk/ffi)))     ; the raw layer, when needed
(in-package #:example)

What is installed?

Three functions ask the system before you create anything:

(vk:instance-version)
;; => (1 4 363)          ; the highest Vulkan version the loader supports

(vk:available-layers)
;; => ("VK_LAYER_KHRONOS_validation" ...)

(vk:available-instance-extensions)
;; => ("VK_KHR_surface" "VK_KHR_wayland_surface" "VK_EXT_debug_utils" ...)

A first program: list the GPUs

(vk:with-instance (instance)
  (mapcar (lambda (gpu)
            (list (vk:physical-device-name gpu)
                  (vk:physical-device-type gpu)
                  (vk:physical-device-api-version gpu)))
          (vk:physical-devices instance)))
;; => (("llvmpipe (LLVM 21.1.8, 256 bits)" :CPU (1 4 354)))

with-instance creates a Vulkan 1.4 instance and destroys it when its body is left. physical-devices describes each GPU, or software renderer, the instance can use.

A device and a swapchain

The example on Home goes further: it creates a headless surface (one that presents nowhere, for tests), a device with the swapchain extension and two Vulkan 1.3 features, and a swapchain. The steps are the ones every Vulkan program takes:

  1. Instance: create-instance / with-instance, with the instance extensions you need, such as "VK_KHR_surface" and the one for your window system.
  2. Surface: your window system library creates a VkSurfaceKHR and gives it to adopt-surface. For tests, create-headless-surface.
  3. Physical device: pick one of physical-devices.
  4. Device: create-device / with-device, with the device extensions and features you need.
  5. Swapchain: create-swapchain.
  6. Each frame: acquire-next-image, record and submit commands, present.

Recipes has a complete program that clears the screen every frame. It runs as is on a headless surface.

Development with validation

While developing, create the instance with :validation t. The Khronos validation layer then checks every call, and take-debug-messages returns what it found:

(vk:with-instance (instance :validation t)
  ;; ... use Vulkan ...
  (remove :error (vk:take-debug-messages instance)
          :key #'vk:debug-message-severity :test-not #'eq))
;; => ()   ; no errors

Next

  • Concepts explains the two layers and how objects relate.
  • Structs explains how to fill Vulkan structs, which most of the work of calling Vulkan is.