gfx

index

Overview

The pixel engine. A Lua canvas sits on a C pixel surface. Around it are sprites, pixel fonts, the bake side of a tangent patch, a DRM/KMS console display, an X11 window display and a fixed-timestep frame loop.

This module re-exports the submodules' constructors. Each is documented in its submodule; gfx.display states the contract the two displays answer. The device the spheres draw on is bound here.

Submodules

ModuleDescription
gfx.canvasA pixel canvas: {r,g,b,a} colours and table options over the C gfx.core surface.
gfx.displayThe display contract, and the two helpers both displays share.
gfx.drmA canvas shown on a DRM/KMS card at a bare Linux console.
gfx.fontPixel-art text: strings drawn as scaled bitmap glyphs on a canvas.
gfx.font_defaultThe default 5x7 font for gfx.font: digits, A–Z, space and common punctuation.
gfx.loopA fixed-timestep frame loop on LEV.
gfx.patchThe bake side of a tangent patch.
gfx.spriteSprites: blit sources for the canvas.
gfx.x11A canvas shown in an X11 window, on a desktop.

Functions

NameSignature
use_deviceuse_device(dev) -> ok, err
device_statsdevice_stats() -> stats

use_device(dev) -> ok, err

Bind the compute device the spheres draw on, or unbind it

dev is a device from vk.open. After the call, canvas:sphere_tex dispatches on it when the call qualifies: no height, no source that is the canvas itself, a box of 16384 pixels or more. Every other call, and every call with gpu = false or under LILUSH_GFX_GPU=0, draws on the CPU from the same parse. The bytes are the CPU's.

The spheres dispatch on the device's second lane where vk.open took one, and on the first otherwise. So a program's own dispatches on the first lane hold a sphere up only where the device has one queue, or does not let the lane past them; device_stats names the lane.

A call with later = true is submitted and returns a ticket that canvas:sphere_land composites later, at most four open at once; the canvas documents the ticket's rules.

Nil unbinds. A device without fp64, on its own word, is refused and the binding standing stays: the shader computes in doubles. Binding builds the sphere pipeline; lavapipe compiles it through LLVM at the first draw, about half a second once a process. A device that refuses three submits in a row, or is lost, is unbound by itself, and the frame that found it out is drawn on the CPU; device_stats says so. Closing the device unbinds it. Unbinding drops the open tickets and lets go of every buffer a surface took at a land; the program writes them again from then on. Another device bound in its place unbinds it the same way, before the new pipeline is built: a binding that fails past the fp64 word leaves nothing bound.

Bind before the first frame: the thread pool starts on the first job that wants it, and a driver loaded after that is not seen by its hands.

device_stats() -> stats

Where the spheres drew

The counts run since the program started; mirrors reads what stands now.

fielddescription
boundwhether a device is bound
lanethe lane the spheres dispatch on, 1 or 2; absent while nothing is bound
callssphere calls past their parse
deviceof those, drawn on the device
fallbacksthe rest, by reason, below
uploadsa source's texels sent to the device: whole on first sight, its written box after
bytesthe bytes those uploads sent
landedbuffers a surface took as its mirror at a vk buffer's land, so nothing was sent
laterthe tickets, below
mirrorsthe mirrors standing now, below
detachedwhy the last device unbound itself: "refused", "lost" or "closed"; absent otherwise

The reasons: none, no device bound; off, gpu = false on the call or LILUSH_GFX_GPU=0; height, the call displaces; alias, a source is the canvas; small, a box under 16384 pixels; refused, the device refused the submit; lost, the device was lost under it, or under a ticket before its land, whose box then went undrawn.

The tickets: taken, later calls the device held open; open, those not yet landed; waited, lands that found the trace still running, so the frame had less to paint than the trace took; full, later calls drawn at once because four were open; failed, lands whose trace answered an error with the device standing, so the box went undrawn, since the parse went with the call, and the device stays bound. A ticket held open counts under device at its submit.

The mirrors: count and bytes, every surface's copy on the device; landed and landed_bytes, those a landing handed over, held until the mirror goes; unread and unread_bytes, the landed ones no call on the device has read since their landing, and the same buffer landed again stands unread again. A call the device takes reads its source and its windows; one that falls back reads nothing. The bytes are the surface's texels: one buffer landed on two surfaces counts twice.