5 Home
dxtr edited this page 2026-10-15 09:28:58 +02:00

cl-gsl

Shaders written in Common Lisp. You define shader functions and shader stages as Lisp, with typed parameters and inferred types everywhere else. cl-gsl checks them as soon as they are evaluated, translates them to GLSL, and compiles that to SPIR-V for Vulkan 1.3.

Archived. clsl, which writes SPIR-V itself and needs neither glslang nor a C++ compiler, so that it runs on Windows too, replaced cl-gsl as the shader compiler of the Pyssel engine on 2026-10-15. cl-gsl and this manual are kept, read-only, as a record.

(asdf:load-system :cl-gsl)

(defpackage #:example
  (:use #:cl #:cl-gsl))
(in-package #:example)

(define-shader triangle-vertex :vertex ((position :vec3) (color :vec3))
  "Place each vertex where its POSITION says, and pass its COLOR on."
  (values (vec4 position 1) color))

(define-function brightness ((color :vec3))
  "Return the perceived brightness of the linear COLOR."
  (dot color (vec3 0.2126 0.7152 0.0722)))

(define-shader triangle-fragment :fragment ((color :vec3))
  "Draw COLOR, dimmed where it is bright."
  (vec4 (mix color (* color 0.5) (brightness color)) 1))

(defvar *program*
  (compile-program :vertex 'triangle-vertex :fragment 'triangle-fragment))

(program-spirv *program* :vertex)    ; => #(119734787 67072 ...), 32-bit words
(program-vertex-inputs *program*)
;; => (#S(VERTEX-INPUT :NAME POSITION :LOCATION 0 :TYPE :VEC3)
;;     #S(VERTEX-INPUT :NAME COLOR :LOCATION 1 :TYPE :VEC3))
(write-string (program-glsl *program* :fragment))

What it gives you

  • Lisp syntax and Lisp meaning. Shader code uses Common Lisp's own operators where their meaning carries over: let, if, cond, case, setf, incf, dotimes, loop, values, multiple-value-bind, flet, labels, macrolet, floor, mod, ash, ldb and so on. It adds what is particular to shaders: vec3, dot, mix, sample, image-store, dfdx, atomic-incf and the rest.
  • Type inference. Only parameters carry types. Everything else is inferred, and a mistake is reported when the definition is evaluated, naming the definition and the form, and saying what would fit.
  • Every stage. Vertex, tessellation control, tessellation evaluation, geometry, fragment and compute.
  • Interactive redefinition. A program keeps the definitions it was compiled from, knows when one of them changes, and can recompile itself. A frame loop can follow edits made at the REPL.
  • Everything a GPU layer needs to bind resources. Vertex input locations, uniform block offsets, bind group layouts, workgroup sizes and patch sizes, plus pack-uniforms to fill uniform buffers from Lisp values without allocating.
  • No GPU dependency. cl-gsl produces SPIR-V words and metadata. cl-gfx takes them as they are, and so can anything else that takes SPIR-V.

Pages

Page What it covers
Getting Started Building glslang, loading the system, a first program, running the tests
Shader Code Defining functions, variables and inference, control flow, loops, several values, structs, arrays, local functions, where shader code is not Lisp
Types Every shader type: scalars, vectors, matrices, doubles, complex numbers and ratios, structs, arrays, textures and images
Structs Defining structs, constructors and accessors, structs as uniforms and in storage buffers, their layout, packing them from Lisp
Stages Vertex, fragment, tessellation, geometry and compute shaders, their inputs, outputs and options
Uniforms and Resources &uniform, groups and bind groups, shader variables, storage buffers and images, memory layout, packing uniform buffers
Textures and Images Sampling, fetching, gathering, querying, storage images
Compute Shaders Workgroups, invocation IDs, shared variables, atomics, barriers
Programs compile-program, what a program tells you, redefinition and recompiling, using it with cl-gfx
Extending Shader Code Shader macros, type aliases, inline GLSL, and cl-gmath's names through cl-gsl/gmath
Operator Reference Every operator of the shader language, by category
Errors and Threads The conditions cl-gsl signals, and what may be shared between threads
API Reference Every exported Lisp function, macro, type and condition

Systems

System What it is
cl-gsl The shader language and compiler.
cl-gsl/gmath Optional glue: cl-gmath's type and function names in shader code.
cl-gsl/ffi Raw CFFI bindings to glslang's C interface. Internal; cl-gsl uses it.
cl-gsl-build The ASDF extension that links glslang into a shared library. Internal.
cl-gsl/test The Parachute test suite.

cl-gsl is part of the Pyssel game engine, but it does not depend on the engine and can be used on its own.