Table of Contents
Systems
The systems
| System | What it is | Depends on |
|---|---|---|
clsl |
The language, its definitions and programs, and clsl's conditions, in the package clsl; and the IR they compile through, clsl/ir. |
cl-threads, for the lock definitions are made under |
clsl/spirv |
SPIR-V, clsl/spirv: the grammar's tables, the module builder, the reader and the disassembler; and the back end, clsl/spirv-back-end, which translates the IR into SPIR-V. |
clsl |
clsl/vulkan |
The :vulkan target: SPIR-V 1.6 under Vulkan 1.4's rules. Programs load this system and use the package clsl. |
clsl, clsl/spirv |
clsl/gmath |
cl-gmath's types and functions in shader code, meaning what they mean in Lisp. | clsl, cl-gmath |
clsl/generator |
A build-time tool that writes spirv/grammar.lisp from the grammar files in grammar/. |
jzon |
clsl/test |
The test suite. | all of the above, cl-gfx, cl-gfx/vulkan, cl-vk, cl-gmath and Parachute |
clsl/glsl, which prints GLSL, and clsl/opengl, for OpenGL 4.5 and later,
come later.
clsl is plain Common Lisp, for SBCL. Loading it needs no foreign library, no
glslang and no JSON library, and nothing in it needs setting up again when a
saved image starts. The grammar's tables, which clsl/generator writes, are
committed in spirv/grammar.lisp, so only the generator itself needs jzon.
The tests need SPIRV-Tools and a Vulkan driver beside, as Development and
Testing says. The dependencies are pinned by commit
in clsl's stiftfile, with stift.
The packages
| Package | Use |
|---|---|
clsl |
Everything programs use: the definitions, programs, packing, conditions, and the language's own names. Use it beside common-lisp. |
clsl/ir |
The IR, for back ends, targets, tools and tests. Programs never need it. See The IR. |
clsl/spirv |
SPIR-V, which knows nothing of clsl's IR or language and may be used on its own. See SPIR-V. |
clsl/spirv-back-end |
The back end, whose entry point is translate-module, and spirv-target. See Targets. |
clsl/vulkan |
Exports vulkan-target alone, for back ends and tests; programs name the target :vulkan. |
clsl/gmath |
Exports nothing. Loading clsl/gmath is enough. |
clsl/generator |
The grammar generator. See Grammar and Generator. |
clsl/language, the language's implementation, and clsl/sys, which holds
the little code that is SBCL's own, the bits of floats and float arithmetic
with its traps masked, are internal. clsl/test holds the tests.
The API Reference lists the exports of clsl, clsl/vulkan
and clsl/gmath, and the IR and SPIR-V Reference
those of the others.
cl-gmath in shader code
Loading clsl/gmath makes cl-gmath's types type aliases of clsl's, and its
functions shader functions and shader macros of their names, which compute
what they compute in Lisp:
(asdf:load-system :clsl/gmath)
(define-function lambert ((normal cl-gmath:vec3) (light cl-gmath:vec3))
"How much LIGHT, a direction of length 1, falls on a surface facing NORMAL."
(max (cl-gmath:vec3-dot (cl-gmath:vec3-normalize normal) light) 0))
(define-shader lit :fragment ((normal :vec3) &uniform (light :vec3) (rotation cl-gmath:quat))
(let ((turned (cl-gmath:quat-rotate rotation light)))
(vec4 (vec3 (lambert normal turned)) 1)))
(mapcar (lambda (uniform) (list (uniform-name uniform) (uniform-type uniform)))
(program-uniforms (compile-program '(:fragment lit) :target :vulkan)))
;; => ((LIGHT :VEC3) (ROTATION :VEC4))
| cl-gmath's type | Is |
|---|---|
vec2, vec3, vec4 |
:vec2, :vec3, :vec4 |
quat |
a :vec4 of x, y, z and w, the real part |
mat3, mat4 |
:mat3, :mat4 |
mat3x2 |
a 2D affine transform: a :mat3x2, of 3 columns of 2, the x axis, the y axis and the origin |
dvec2, dvec3, dvec4, dquat, dmat3, dmat4, dmat3x2 |
the same of doubles |
A function takes the arguments it takes in Lisp, less result, as values are
copied: (setf v (cl-gmath:vec3+ a b)) stores a sum. Its scalars are :float
values, or :double values for the doubles' functions, and numbers written in
the code fit them. The accessors, as cl-gmath:vec3-x and cl-gmath:mref,
are places.
Shader code cannot signal an error: where cl-gmath signals a gmath-error for
arguments that have no answer, as the inverse of a singular matrix or a zero
quaternion normalised, shader code computes the same formulas, which give
what the GPU gives. The doubles' functions that need trigonometry, such as
cl-gmath:dquat-slerp, and the batch functions refuse to expand, saying why:
In SLERP: The macro CL-GMATH:DQUAT-SLERP could not expand (CL-GMATH:DQUAT-SLERP
A B 0.5d0): CL-GMATH:DQUAT-SLERP is refused in shader code: it takes the arc
cosine and sine of doubles, which GPUs compute of floats only: QUAT-SLERP of
the quaternions made floats, with (float q 1.0), computes them of floats.
in: (CL-GMATH:DQUAT-SLERP A B 0.5d0)
shader-documentation of a function says what it computes:
(shader-documentation 'cl-gmath:vec3-angle)
;; => "The shader form of CL-GMATH:VEC3-ANGLE: the angle between A and B, from 0 to pi, by
;; Kahan's formula, 2 atan2 (|A |B| - B |A||, |A |B| + B |A||); 0 if either is zero."
A package that uses both clsl and cl-gmath chooses between the names both
export with :shadowing-import-from: vec2 to vec4, dvec2 to dvec4,
mat3, mat3x2, mat4, dmat3, dmat3x2, dmat4, clamp, smoothstep,
radians and degrees. With clsl/gmath loaded, either's means the same in
shader code.