배정밀도 에뮬레이션

배정밀도 에뮬레이션

두 타깃 모두 64비트 부동소수점이 없습니다. f64는 f32 두 워드 쌍이며, 백엔드가 보기 전에 vec2<f32>와 df64_ 호출로 바뀝니다. fp64-lane-stripes가 f32 경로와 f64 (emulated) 경로를 나란히 그립니다.

  • f64 스칼라

    f32 두 워드의 쌍이 되고, 연산마다 df64_ 호출이 붙습니다. fp64-lane-stripes

    TypeScript
    export function widened(a: f64, b: f64): f64 {
    return a * b + a
    }
    생성된 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);
    }
  • f64 리터럴

    f64라고 밝힌 자리의 리터럴은 배정밀도 값을 그대로 지닙니다.

    TypeScript
    export function stripe(a: f64): f64 {
    const width: f64 = 0.125
    return a * width
    }
    생성된 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);
    }
  • f64 벡터

    배정밀도 벡터입니다. hi 평면과 lo 평면으로 하향 변환됩니다. vec2d는 vec2f64의 짧은 표기입니다.

    TypeScript
    export function narrowed(
    p: vec3f64, q: vec2d
    ): f32 {
    return f32(p.x) + f32(q.y)
    }
    생성된 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)));
    }
  • f64 내장 함수

    스칼라에서 내장 함수 열 개, 벡터에서 열세 개가 에뮬레이션 본체를 가집니다.

    TypeScript
    export function rooted(a: f64): f64 {
    return sqrt(abs(a))
    }
    생성된 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);
    }
  • f64 본체가 없는 내장 함수

    거절

    호출 자리에서 거절하며, 그 열 개와 좁히는 방법을 함께 알려 줍니다.

    TypeScript
    export function rounded(a: f64): f64 {
    return ceil(a)
    }

    컴파일러 진단

    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)).

  • 유니폼 안의 f64

    _fp64 텍스처가 주입됩니다. 호스트가 1.0으로 채우고, 리플렉션이 다른 바인딩처럼 보여 줍니다.

    TypeScript
    class Uniforms {
    origin: f64
    span: f32
    }
    declare const u: uniform<Uniforms>
    생성된 WGSL
    @group(0) @binding(1) var _fp64: texture_2d<f32>;
  • 스테이지 사이의 f64

    거절

    배정밀도 값은 필요한 스테이지에서 읽거나, 경계에서 f32로 좁히십시오.

    TypeScript
    @fragment
    export function fs(
    @location(0) depth: f64
    ): vec4 {
    return vec4(f32(depth))
    }

    컴파일러 진단

    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.

이 페이지 편집 문제 보고