4 Home
dxtr edited this page 2026-10-14 19:22:51 +02:00

cl-gfx

cl-gfx is a portable GPU API for Common Lisp at roughly the level of WebGPU. It covers devices, buffers, textures, samplers, shaders, bind groups, pipelines, render and compute passes, render bundles and presenting to windows. The backend today is Vulkan 1.4, and OpenGL 4.5 comes next. No type or handle of either graphics API appears in the public API.

cl-gfx is one of the libraries of the Pyssel game engine, but it does not depend on the engine and is usable on its own.

A first look

This renders a triangle offscreen and reads the image back:

(asdf:load-system :cl-gfx/vulkan)

(defpackage #:example
  (:use #:cl)
  (:local-nicknames (#:gfx #:cl-gfx)))
(in-package #:example)

(defun shader (name)
  (asdf:system-relative-pathname "cl-gfx" (format nil "tests/shaders/~A.spv" name)))

(gfx:with-device (device)
  (let* ((image (gfx:create-texture device :width 64 :height 64 :format :rgba8-unorm
                                           :usage '(:render-target :copy-src)))
         (pipeline (gfx:create-render-pipeline
                    device
                    :vertex (gfx:create-shader-module device (shader "triangle.vert"))
                    :fragment (gfx:create-shader-module device (shader "triangle.frag"))
                    ;; Per vertex: a position and a color, three floats each.
                    :vertex-buffers '((:stride 24 :attributes ((0 :float32x3 0)
                                                               (1 :float32x3 12))))
                    :color-formats '(:rgba8-unorm)))
         (vertices (gfx:create-buffer device :size 72 :usage '(:vertex))))
    ;; Clip space has y down, as Vulkan's has: the apex is at y -0.5.
    (gfx:write-buffer vertices (make-array 18 :element-type 'single-float
                                              :initial-contents '( 0.0 -0.5 0.0  1.0 0.0 0.0
                                                                  -0.5  0.5 0.0  0.0 1.0 0.0
                                                                   0.5  0.5 0.0  0.0 0.0 1.0)))
    (gfx:with-frame (frame device)
      (gfx:with-render-pass (pass frame :color ((image :clear '(0 0 0 1))))
        (gfx:set-pipeline pass pipeline)
        (gfx:set-vertex-buffer pass 0 vertices)
        (gfx:draw pass 3)))
    (gfx:read-texture image)))
;; => a vector of 16384 bytes: 64 by 64 texels, red, green, blue, alpha

To draw into a window instead, see Surfaces and Windows.

Pages

Using cl-gfx

Reference

Status

Early work. Done: buffers; textures of every shape, with mipmaps and multisampling; samplers, including comparing ones; bind groups of uniform, storage and texel buffers, textures and storage textures; render pipelines with tessellation and geometry shaders; compute pipelines; render and compute passes with per-resource barriers; render bundles; presenting; and writing and reading buffers and textures. The OpenGL backend comes next.

Licence

MIT.