Skip to content

ci: compiled shaders are built in CI and checked against their HLSL - #405

Merged
foxnne merged 5 commits into
mainfrom
ci/shaders
Oct 16, 2026
Merged

foxnne merged 5 commits into
mainfrom
ci/shaders

Conversation

@foxnne

@foxnne foxnne commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Compiles the SPIR-V and DXIL that fizzy's native backend embeds (Vulkan, D3D12) from their HLSL in CI, and fails when what is committed is not what the HLSL compiles to, uploading the fresh files as an artifact to commit.

Why. Nothing noticed when an HLSL changed and its compiled files did not: Windows and Linux quietly drew the previous glass after #227 (fixed by hand in #242), and again since #373, whose shader changes are in the HLSL but not in the DXIL or SPIR-V. Its first run here found worse: main's glass HLSL has not compiled since #373 (float3(x) from one scalar is Metal and GLSL, not HLSL). Fixed here ((float3)x).

The toolchain is SDL_shadercross at 1ff05bec, with the DirectXShaderCompiler release it pins itself (Microsoft's prebuilt v1.9.2602, by SHA-256), built as shadercross's own CI builds it: only SPIRV-Cross and shadercross, a few minutes, cached by the pin. With it the backend's default shaders, unchanged since they were compiled, reproduce byte for byte, SPIR-V and DXIL: the committed files were made with this compiler. (An earlier run built shadercross's vendored DXC from source instead, half an hour: its SPIR-V matched, its DXIL differed in DXC's version string.)

The glass SPIR-V and DXIL are compiled again from #373's HLSL (with the fix above). The DXIL's interface (input and output signatures, pipeline state, feature flags) is identical to the old one's, so the backend's pipeline for it is unchanged.

First step of making the glass one source. Next, in its own PR: the glass written once, in HLSL, its Metal and WebGL GLSL generated from it by SPIRV-Cross and checked by this same job, so the forms cannot drift apart as they did here.

Not seen on Windows or Linux yet: the new glass on D3D12 and Vulkan wants a look on those machines. zig build and zig build check-web pass on macOS.

🤖 Generated with Claude Code

@foxnne foxnne changed the title ci: SPIR-V and DXIL compiled from their HLSL in CI, checked against what is committed ci: compiled shaders are built in CI and checked against their HLSL Oct 14, 2026
foxnne and others added 4 commits October 14, 2026 12:19
`float3(x)` from one scalar is Metal and GLSL, not HLSL: `(float3)x`. The workflow goes on past a shader that does not compile, uploads what did, and says where a stale one differs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Compiled by this workflow (shadercross 1ff05bec, DXC v1.9.2602), the toolchain the backend's default shaders reproduce with byte for byte. The DXIL's interface (signatures, pipeline state, flags) is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@foxnne
foxnne marked this pull request as ready for review October 16, 2026 15:41
@foxnne
foxnne merged commit c45686c into main Oct 16, 2026
14 checks passed
@foxnne
foxnne deleted the ci/shaders branch October 16, 2026 15:41
foxnne added a commit that referenced this pull request Oct 16, 2026
#405 landed on main; the workflow keeps this branch's version, which is #405's with the compile script.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
foxnne added a commit that referenced this pull request Oct 16, 2026
**Stacked on #405** (its commits show here until it merges).

The glass written once, in HLSL; its Metal and WebGL GLSL generated from
it and checked by #405's job, instead of three programs kept in step by
hand. Keeping them in step is where the shader bugs came from: #373's
`float3(x)` was valid Metal and GLSL and broke the HLSL, and the
compiled forms went stale twice.

## What changes

- **`scripts/compile-shaders.sh`**: every `X.hlsl` with compiled forms
committed beside it, to each of them. SPIR-V, DXIL and Metal by
shadercross (the Metal SDL_GPU takes, as the backend's own default
shaders already shipped). GLSL ES 3.00 for WebGL2 by spirv-cross from
the SPIR-V, with NaN checks relaxed (HLSL's `min`/`max` otherwise come
out wrapped in `isnan` tests at every pixel), float precision high, and
the names the web binds (`vColor`, `vTextureCoord`, `uSampler`, `uTex1`,
`uData`). The workflow runs it and compares every form.
- **The glass loads the generated Metal and GLSL** (`LiquidField`); the
hand-written `liquid_glass.metal` and `liquid_glass.glsl` are gone. The
HLSL is the one source and carries the explanations the GLSL had.
- **The web compiles a complete generated source as it is**
(`web/web.js`, a `#version` line), on WebGL2 only: on WebGL1 the program
fails and the glass falls back to its meshes (generated loops are not
WebGL1's constant-bounded ones).
- `program_example`'s committed Metal, hand-written to show the
interface, is now generated like the rest (same interface).

## Verified

- **CI's compile check**: the backend's default shaders reproduce byte
for byte in all three of SPIR-V, DXIL and Metal with this toolchain.
- **macOS**: the same in-app About dialog captured through the agent
with the hand-written Metal (#405's build) and the generated one (this
build): plain glass differs by a mean of 0.18 of 255, at most 2 (the
dither); elsewhere only edges, where the dialog's contents sat a
fraction of a pixel apart between the two captures.
- **Web (Chromium, WebGL2)**: the generated GLSL compiles and links
against the web's own vertex shader, and `uData`, `uSampler`, `uTex1`
and `uMatrix` all resolve; this build's menus draw their glass through
it, no program failed, and it looks as main's did.
- `zig build`, `zig build test` (91/91 steps), `zig build
test-integration` (53/53 steps), `zig build check-web`.
- Not seen: Windows (D3D12) and Linux (Vulkan), as for #405; Firefox and
Safari on the web.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant