Emulated double
Neither target has a 64-bit float. An f64 is a pair of f32 words, rewritten into vec2<f32> and df64_ calls before either backend sees it. fp64-lane-stripes draws the f32 and f64 (emulated) paths side by side.
-
f64scalarA pair of
f32words, with adf64_call for each operation. fp64-lane-stripesTypeScript export function widened(a: f64, b: f64): f64 {return a * b + a}Emitted WGSL fn widened(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> {let _fp64_g = textureLoad(_fp64, vec2<i32>(0, 0), 0).x;return df64_add(df64_mul(a, b, _fp64_g), a, _fp64_g);} -
f64literalA literal in a declared
f64position keeps the whole double.TypeScript export function stripe(a: f64): f64 {const width: f64 = 0.125return a * width}Emitted WGSL fn stripe(a: vec2<f32>) -> vec2<f32> {let _fp64_g = textureLoad(_fp64, vec2<i32>(0, 0), 0).x;let width = vec2<f32>(0.125, 0.0);return df64_mul(a, width, _fp64_g);} -
f64vectorA vector of doubles, lowered into a hi plane and a lo plane.
vec2dis the short spelling ofvec2f64.TypeScript export function narrowed(p: vec3f64, q: vec2d): f32 {return f32(p.x) + f32(q.y)}Emitted WGSL fn narrowed(p: DF64Vec3, q: DF64Vec2) -> f32 {return (df64_narrow(vec2<f32>(p.hi.x, p.lo.x)) + df64_narrow(vec2<f32>(q.hi.y, q.lo.y)));} -
Builtin on an
f64Ten builtins have an emulated body on a scalar and thirteen on a vector.
TypeScript export function rooted(a: f64): f64 {return sqrt(abs(a))}Emitted WGSL fn rooted(a: vec2<f32>) -> vec2<f32> {let _fp64_g = textureLoad(_fp64, vec2<i32>(0, 0), 0).x;return df64_sqrt(df64_abs(a), _fp64_g);} -
Builtin with no
Refusedf64bodyRefused at the call, which names the ten and the narrow to write.
TypeScript export function rounded(a: f64): f64 {return ceil(a)}Compiler diagnostic
TS8036 ceil has no emulated-double form; got f64. On an f64 the pass lowers abs, cos, floor, fract, max, min, mix, round, sin and sqrt — narrow first, e.g. ceil(f32(x)).
-
f64in a uniformA
_fp64texture is injected, which the host fills with1.0. Reflection lists it like any binding.TypeScript class Uniforms {origin: f64span: f32}declare const u: uniform<Uniforms>Emitted WGSL @group(0) @binding(1) var _fp64: texture_2d<f32>; -
Refusedf64across stagesRead the double in the stage that needs it, or narrow it to an
f32at the boundary.TypeScript @fragmentexport function fs(@location(0) depth: f64): vec4 {return vec4(f32(depth))}Compiler diagnostic
TS8038 Parameter "depth" carries f64: an emulated double is a pair of f32 words, and a @location varying interpolates each word on its own, which is not the interpolation of the double. Narrow it with f32(x), or compute the double in the stage that needs it — a uniform or storage binding carries an f64 and every stage can read one.