2 Live Pipelines
dxtr edited this page 2026-10-19 18:24:37 +02:00

Live Pipelines

make-pipeline makes a render pipeline from a clsl program, by the name define-program gave it or by its stages, and keeps it in step with its shaders. When a shader, or a shader function it calls, is redefined, the engine notices at the next frame's sync point. It recompiles the pipeline, swaps the new one in, and destroys the old one once the frames in flight are done with it. Reloading code that has not changed keeps the pipeline as it is.

An engine makes one pipeline for each program and set of options. Asking make-pipeline again for the same, in any order of the options, as the painters of each of an engine's renderers do, gives the pipeline made then, which a redefinition rebuilds once for all who asked. Each request lets go of it with destroy-pipeline, which destroys it once every request has. clsl keeps the programs it compiles, so engines that draw with the same program, as the editor's and a play's do, compile it once (see clsl's wiki, Programs).

A mistake rarely gets that far. clsl checks a definition when it is evaluated, and a definition that fails its check is never stored, so the error shows at the REPL. What only shows when the program is recompiled, such as a vertex shader that now passes values the fragment shader does not take, keeps the old pipeline drawing. The engine then warns with pipeline-not-rebuilt, and pipeline-error returns the error until a later redefinition fixes it.

A program is compiled for the engine's device, and refused with a pyssel-error if it has no vertex shader, or if the device lacks a feature it needs, such as doubles or geometry shaders, as clsl:program-features names them. Without :vertex-buffers, a pipeline reads the vertex shader's inputs from one buffer at slot 0, each vertex's inputs side by side in the order of their locations, as clsl:program-vertex-buffers lays them out after every rebuild: floats, doubles, integers and their vectors, complex numbers as two floats, and float pairs as their high parts, then their low parts. Doubles are read as 32-bit words, which clsl puts together again, so they work on any GPU whose shaders have doubles. With :step :instance, the buffer advances an instance at a time. Without :color-formats, it draws into the engine's window. A program with tessellation draws patches of the size its control shader takes. The other options are cl-gfx's create-render-pipeline options.

Shaders with uniforms read them through cl-gfx bind groups, one for each of clsl's uniform groups: :frame at 0, :material at 1 and :draw at 2, each with its uniform block at binding 0 and its textures after, as clsl:program-layout-entries gives them. clsl:pack-uniforms fills a uniform buffer from the shaders' variables and the values given. (pipeline-bind-group-layout pipeline :material) is the layout to make a group from with gfx:create-bind-group, and (clsl:uniform-group-index :material) the index to set it at. A rebuild keeps the layouts while the uniforms stay the same, so the groups go on fitting. pipeline-render-pipeline is the cl-gfx pipeline drawn with now, for code that records it into a render bundle and must record again after a rebuild.

Frames allocate nothing in steady state. The tests measure it.