fp64Lower
이 페이지에서

fp64Lower()

함수, f64 에뮬레이션 분류

Rewrite every f64 value in a module into its two-f32 emulation, so that no backend has to spell the type.

import { fp64Lower } from 'typeshade'

시그니처, 설명, 예제는 커밋 c66579bf의 컴파일러 소스에서 그대로 가져온 영어 원문입니다.

구문

function fp64Lower(m: ModuleDecl, opts?: Fp64LowerOptions): ModuleDecl

매개변수

m ModuleDecl

the module to lower.

opts선택 사항 Fp64LowerOptions

flavor selects which primitives back the helpers; see Fp64Flavor.

반환값

ModuleDecl

a new module with its f64 declarations and bodies rewritten and the helper functions appended, or m itself when it contains no f64.

예외

SD0041

SD0041 for an operation on f64 operands that has no emulation.

SD0042

SD0042 when the module declares a _fp64 binding whose type differs from the guard’s.

SD0043

SD0043 when the module declares a function named df64_* or a struct named DF64Vec* or DF64Mat*; those names are reserved for the injected helpers.

SD0044

SD0044 for an f64 in an interpolated @location struct field, a fragment input, or a stage entry’s return value; interpolating a (hi, lo) pair is numerically wrong.

설명

An f64 scalar becomes a vec2<f32> holding a (hi, lo) pair, vecN<f64> becomes a DF64VecN struct of two vecN<f32> planes, matNxN<f64> becomes a DF64MatN struct, and the arithmetic, comparisons and supported builtins over them become calls to injected df64_* helper functions, which are appended to the module’s funcs. A module with no f64 anywhere is returned as the same object.

Supported on f64 operands: + - * /, negation, the six comparisons, sqrt, abs, min, max, mix (with an f32 interpolant), floor, fract, sin, cos, widening from f32 and narrowing to f32. On vecN<f64> additionally dot, length, distance, normalize and the componentwise forms of the list above; on matNxN<f64>, * and transpose. Any other builtin on an f64 operand throws; narrow the operand to f32 first when you need one.

Two kinds of multiply take a cheaper form. x * x, when x has no side effect, is df64_sqr(x), the multiply specialised to one operand. A multiply by a power-of-two literal, or a divide by such a literal, scales the two words of the pair by an f32 literal, which is exact barring overflow and underflow. A scale that can grow the value (|s| > 1) is taken only when x is computed at run time, so that WGSL never evaluates a constant that overflows while it creates the shader; a constant x keeps the general multiply.

When an injected helper reads the runtime guard, the pass also declares the _fp64 guard binding at group 0, first index past the module’s own group-0 bindings. Declare fp64Guard in the module to pin that slot yourself. The host writes 1.0 into it. Those helpers take the guard as a trailing _fp64_g: f32 parameter rather than fetching it themselves, and every call of one from the module’s own functions passes the texel fetch as that argument. The emit functions then read it once per function, into a let named _fp64_g at the top of the body, after the optimizer has run.

The emit functions run this pass for you; pass fp64Flavor in EmitOptions to select the flavour there. Call it directly when you want to inspect the lowered module.

예제

예제

import { fp64Lower } from 'typeshade'
// authored: a ModuleDecl whose functions use f64
const lowered = fp64Lower(authored, { flavor: 'integer' })
// lowered.funcs ends with the df64_* helpers the module needs

관련 가이드

함께 보기

소스

src/core/passes/fp64-lower.ts, 1543행, 커밋 c66579bf 기준

이 페이지 편집 문제 보고