Verification
On this page

Verification

On every push

The repository's CI runs these on every push and pull request, in the CI workflow:

  1. The same module compiles to a CPU function that runs in f64 arithmetic. In its default mode only its equality tests round to f32 first, so they agree with the GPU; an f32 mode that rounds after every operation is opt-in. The test suite checks that function against known answers and against a second CPU backend, generated JavaScript, which must match it bit for bit. It says nothing about what rounding does on a driver, and no GPU output is compared against it in this repository. Where WGSL fixes a result and GLSL ES 3.00 does not, the oracle follows WGSL (Rule 11.5no test checks this yet). src/core/oracle.ts
  2. The compile gate emits every registered example, hands each WGSL emit to Tint inside headless Chromium, and compiles and links both GLSL ES 3.00 stages of every renderable example on a real WebGL2 context. It also hands each compiler a shader that cannot compile: if either accepts that non-program, the gate fails and the verdicts on the examples do not count. scripts/compile-gate.ts
  3. Golden files hold the emitted bytes of every example, so any change in a backend surfaces as a diff in review. emit-goldens.test.ts

The same pass on both backends

The gradient pass from the front page, drawn once by each backend. No pixel comparison between the two is committed yet.

Gradient pass (source twin) shader, written in TypeScript and compiled by TypeShade, rendered at build time.
Drawn on WebGPU at build time, from the compiled WGSL.
Gradient pass (source twin) shader, written in TypeScript and compiled by TypeShade, rendered at build time.
Drawn on WebGL2 at build time, from the compiled GLSL ES 3.00.

At author time

The uniform block is declared once, and every field read is typed against that declaration. Misspell one and the editor says so, before a string reaches a GPU, and the compiler refuses the file with the same code.

typed-error.shade.ts
"use typeshade"
class Uniforms {
time: f32
top: vec4
bottom: vec4
}
declare const u: uniform<Uniforms>
@fragment
export function main(@location(0) uv: vec2): vec4 {
const t = uv.y + u.time * 0.05
return vec4(mix(u.bottom.rgb, u.colour.rgb, t), 1.0)
}

error TS8022 at line 14, column 35: Unknown field "colour" on Uniforms.

reflect(), std140, 48 bytes
field type offset size
time f32 0 4
top vec4<f32> 16 16
bottom vec4<f32> 32 16
The wrong read on line 14, the diagnostic it produces, and the std140 layout reflect() recovers for the block it reads from: 48 bytes over 3 fields. The gap after the first field is alignment.

Edit this page Report a problem