검증 방식
푸시마다 하는 검사
저장소의 CI는 푸시와 풀 리퀘스트마다 CI 워크플로에서 다음을 실행합니다.
- 같은 모듈을 f64 산술로 실행되는 CPU 함수로도 컴파일합니다. 이것이 기준값을 내는 오라클입니다. 기본 모드에서는 동등 비교만 먼저 f32로 반올림해 GPU와 맞추고, 연산마다 반올림하는 f32 모드는 따로 켭니다. 테스트는 이 함수를 알려진 답과 맞춰 보고, 생성된 JavaScript라는 두 번째 CPU 백엔드와도 맞춰 봅니다. 둘은 비트 단위로 같아야 합니다. 오라클은 드라이버의 반올림에 대해서는 아무것도 말해 주지 않습니다. 이 저장소에서는 GPU 출력을 오라클과 맞춰 보지 않습니다. WGSL은 결과를 정해 두었는데 GLSL ES 3.00은 정하지 않은 곳에서는 오라클이 WGSL을 따른다(규칙 11.5아직 확인하는 테스트 없음). src/core/oracle.ts
- 컴파일 게이트는 등록된 예제를 전부 출력합니다. WGSL은 헤드리스 Chromium 안의 Tint에 넘기고, 렌더링 가능한 예제의 GLSL ES 3.00 두 단계는 실제 WebGL2 컨텍스트에서 컴파일하고 링크합니다. 컴파일될 수 없는 셰이더도 각 컴파일러에 하나씩 넘깁니다. 어느 쪽이든 그것을 받아들이면 게이트는 실패하고, 예제에 대한 판정은 무효가 됩니다. scripts/compile-gate.ts
- 골든 파일에는 모든 예제의 출력 바이트가 들어 있어서, 백엔드가 조금이라도 바뀌면 리뷰에서 diff로 드러납니다. emit-goldens.test.ts
두 백엔드에서 같은 패스
첫 페이지의 gradient 패스를 백엔드마다 한 번씩 그렸습니다. 두 백엔드의 픽셀 비교는 아직 커밋되어 있지 않습니다.
코드를 쓰는 동안
유니폼 블록은 한 번 선언하고, 필드를 읽는 곳마다 그 선언에 맞춰 타입 검사를 받습니다. 하나만 잘못 써도 문자열이 GPU에 닿기 전에 편집기가 알려 주고, 컴파일러도 같은 코드로 그 파일을 거부합니다.
"use typeshade"
class Uniforms { time: f32 top: vec4 bottom: vec4}
declare const u: uniform<Uniforms>
@fragmentexport 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)}오류 TS8022, 14행 35열: Unknown field "colour" on Uniforms.
reflect()가 복원한 std140 레이아웃입니다. 필드 3개에 48바이트이고, 첫 필드 뒤의 빈 공간은 정렬 때문에 생긴 자리입니다.