Run the compiled program

Run the compiled program

A vertex and a fragment entry, and a host that runs them as an engine does. The module's default export is its manifest; the host loads it with rt.load() on the program runtime, makes a render pipeline, and draws a full-screen triangle into a texture each frame, binding the uniform by name. Then it reads the texture back (Rules 11.10, 11.11).

Runs on WebGPUWebGL2

The compiler checks this list: a tier is on it exactly when the host's whole run gives the reference with that tier alone. Its journeys gate runs each host on WebGPU and on WebGL2, and its unit suite runs each one on the CPU tier.

"use typeshade";
/* @example
{
"title": "Host: run the compiled program",
"blurb": "A vertex and a fragment entry, and a host that runs them as an engine does. The module's default export is its manifest; the host loads it with `rt.load()` on the program runtime, makes a render pipeline, and draws a full-screen triangle into a texture each frame, binding the uniform by name. Then it reads the texture back (Rules 11.10, 11.11).",
"renderable": true
}
*/
class Sky {
size: vec2;
time: f32;
}
declare const sky: uniform<Sky>;
class VsOut {
@builtin("position") pos: vec4;
}
class Color {
@location(0) color: vec4;
}
// Three vertices that cover the target: the host draws `{ count: 3 }` and binds no vertex buffer.
@vertex
export function vs(@builtin("vertex_index") vi: u32): VsOut {
const x = f32(i32(vi) / 2) * 4. - 1.;
const y = f32(i32(vi) % 2) * 4. - 1.;
return { pos: vec4(x, y, 0., 1.) };
}
@fragment
export function fs(@builtin("position") p: vec4): Color {
const uv = p.xy / sky.size;
return { color: vec4(uv.x, 1. - uv.y, 0.5 + 0.5 * cos(sky.time), 1.) };
}
// Run a module's compiled program on the program runtime, as an engine does (surface §69, Rules
// 11.10 and 11.11).
//
// A shader module's default export is its manifest: the WGSL, the GLSL ES 3.00 programs, and each
// binding with its layout. `typeshade/runtime` loads it on WebGPU, or on WebGL2, and makes the
// pipelines; the host records frames and binds values by name.
import { runtime } from 'typeshade/runtime';
import program from './host-program.shade.ts';
/** Draw a frame into a `width` by `height` texture at each of `times`, then read it back:
* RGBA, one byte to a channel, the top row first. */
export async function run(
width = 32,
height = 32,
times: readonly number[] = [0, 0.5, 1.25],
): Promise<Uint8Array> {
const rt = await runtime(); // the default runtime: WebGPU, or WebGL2
const pipeline = await rt.load(program).render({ targets: ['rgba8unorm'] });
const target = rt.texture({ size: [width, height], format: 'rgba8unorm' });
for (const time of times) {
const frame = rt.frame();
frame.pass({ color: [target] }, (pass) =>
pass.draw(pipeline, { sky: { size: [width, height], time } }, { count: 3 }),
);
await frame.submit();
}
const pixels = await target.read(); // the last frame
target.destroy();
return pixels;
}

Both files are the compiler's own at commit 91c2fe31, from the examples directory.

Module on GitHubHost file on GitHub

Edit this page Report a problem