Skip to content
Kavachकवच

GPU Screens

● Intermediate4 minBefore this: WindowsSpec 14.24

std.gpu draws into a window with the GPU: a screen for the window, a frame for each picture, cleared and shown at the screen's rate. Drawing triangles with shaders written in Kavach comes next.

use std.window
use std.gpu

fn main() ! Error uses Window {
    const win = try window.open("Hello", 640, 480)
    const screen = try gpu.screen(win)
    let open = true
    while open {
        for e in win.poll() {
            match e {
                Event.Closed => {
                    open = false
                },
                _ => {},
            }
        }
        const frame = try screen.frame()
        frame.clear(0.1, 0.2, 0.3)
        frame.show()
    }
}
main.kav, from spec 14.24: Kavach code
  • gpu.screen(win) gives what draws into the window, using the program's GPU.
  • screen.frame() gives the next picture, as big as the window is now. It waits for the screen's next refresh when the last picture isn't shown yet (vsync), so the loop runs at the screen's rate.
  • frame.clear(r, g, b) fills it with one color, each part from 0 to 1, and frame.show() puts it on the screen. A frame never shown is thrown away.
  • Drawing changes the program's own windows, so it needs Window.
  • Where there is no GPU, or the window can't be drawn into, it fails with GpuError.Unavailable(reason). So does a frame of a minimized window; the next frame() tries again.

A private function may leave its uses out, and the compiler works it out. A pub one must say it, so a function that draws for other modules names Window:

use std.window
use std.gpu

pub fn paint(win: AppWindow) ! GpuError {
    const screen = try gpu.screen(win)
    const frame = try screen.frame()
    frame.clear(0.1, 0.2, 0.3)
    frame.show()
}

fn main() uses Window {
    const win = window.open("Hello", 640, 480) catch _ => return
    paint(win) catch _ => {}
}

The compiler refused the program:

kavach run screen-needs-window.kav

error: `paint` is `pub`, so it must say what it uses: add `uses Window` (through `screen`) (spec 8.1)
screen-needs-window.kav: Kavach code, then what running it prints

Every function and method

Function or methodGives
gpu.screen(win) -> Screen ! GpuErrorWhat draws into the window win, using the program's GPU
screen.frame() -> Frame ! GpuErrorThe next picture to draw, as big as the window is now. It waits for the screen's next refresh when the last picture isn't shown yet (vsync), so a loop of frames runs at the screen's rate
frame.clear(r, g, b)Fills the picture with one color; each part is a Float32 from 0 to 1
frame.draw(pipeline, vertices)Draws vertices through pipeline (15.3)
frame.draw(pipeline, vertices, instances: items)The same once for each item of items, which the vertex fn gets as its second parameter
frame.draw(pipeline, vertices, instances: items, with: shared)The same, shared given to every vertex as the vertex fn's last parameter
frame.show()Puts the picture on the screen
gpu.pipeline(vertex_fn, fragment_fn) -> PipelineA pipeline drawing triangles with a gpu vertex fn and a gpu fragment fn (15.3)

Built now: gpu.screen, frame, clear and show. frame.draw and gpu.pipeline are specified but not built yet: they come with the shaders below.

Coming next: shaders in Kavach

Triangles will be drawn by two kinds of gpu fn: a gpu vertex fn works out where each corner goes on the screen, and a gpu fragment fn gives the color of each pixel inside. This is the spec's example; it doesn't compile yet:

type Corner {
    x: Float32
    y: Float32
}

type Dot {
    x: Float32
    y: Float32
    heat: Float32
}

type Camera {
    zoom: Float32
}

type Lit {
    position: (Float32, Float32, Float32, Float32)
    heat: Float32
}

gpu vertex fn place(c: Corner, d: Dot, cam: Camera) -> Lit {
    Lit(position: ((c.x + d.x) * cam.zoom, (c.y + d.y) * cam.zoom, 0.0, 1.0), heat: d.heat)
}

gpu fragment fn glow(l: Lit) -> (Float32, Float32, Float32, Float32) {
    (l.heat, 0.2, 1.0 - l.heat, 1.0)
}

const dots = gpu.pipeline(place, glow)
frame.draw(dots, square, instances: swarm, with: Camera(zoom: 1.0))
from spec 15.3, not built yet: Kavach code

A list a GPU map made, and that is still in GPU memory, will be drawn from there with nothing copied: a particle swarm moved by a map each frame is drawn where it is. See GPU for gpu fn and map today.