Repository navigation
Step 5: the quoted shaders written as MSL (gpu.METAL), compiled and checked - #840
Merged
Merged
Conversation
A third dialect beside Vulkan's and OpenGL's GLSL, from the same trees: emit_msl, emit_vertex_msl and emit_screen_vertex_msl. The expressions and statements are the GLSL emitter's, with a CALL_MSL column in the call table (sample/read for the texture calls, rsqrt, atan2, the prelude's ae_mod and ae_mat3) and struct literals as aggregates. Around them: - Vulkan's conventions: clip z 0..1, the screen's y down, each vertex shader's position y negated as it returns it, so a Metal renderer draws with the Vulkan renderer's matrices and the frame comes out the same way. - Nothing global: each block a struct in a buffer, each texture with its sampler (ae_smp_<name>), each storage buffer a pointer; the entry's first lines name each capture as a reference into its block, so the body reads it where it uses it, as the GLSL does. A helper reading in place is handed what it reads by name, and so is each helper calling it; a helper whose own name would hide one is refused (MSL only). - std140 by hand: each block struct member by member at ae3d.gpu's offsets, padded between (vec3 a packed_float3, scalar arrays float4 arrays read through their lanes, an element struct with a maker for its literals), every offset and size a static_assert. - Varyings at [[user(locnK)]] (an int [[flat]]), attributes at the table's [[attribute(n)]] (a mat4 four float4s), colour outputs four lanes wide. - Bindings: set N's block at buffer(N), storage buffers at 8 + k, textures and samplers at their capture order. Nothing the GLSL dialects write changes (the dialect is set only while MSL is written; names MSL keeps are escaped then alone). tests/test_gpu_msl holds each rule, the offsets to the GLSL block's, and the GLSL and OpenGL's names unchanged by writing MSL; negative controls for each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…--check Every quoted shader's stages written as MSL beside their GLSL, 41 files, which --check compares byte for byte as it does the GLSL (95 generated files now). The GLSL, ae3d.vkscene and ae3d.vkspirv are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/mslc.m compiles MSL through the device (newLibraryWithSource), behind pragmas making every clang warning an error but four groups that say nothing about a shader (C++98 compatibility, padding, Metal 4's deprecated vertex/fragment keywords, unused parameters). The runtime compiler reports diagnostics only when a source fails, hence the pragmas. scripts/msl_check.sh builds it and runs it over src/ae3d/metal, and runs `xcrun metal -Werror` too where Xcode's Metal Toolchain is installed (it is a separate download, not on the M6). ./ci.sh runs it on macOS after the generator's check; each block struct's static_asserts make this a check of the MSL's std140 layout as well. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Section 9 item 5 and section 11's "What it buys MSL": the dialect's rules, how it is held (--check, msl_check, test_gpu_msl, MoltenVK's own MSL of the same SPIR-V: interfaces equal, 506 offsets asserted on its structs), and three ways to a Metal path (#312), smallest first, with a recommendation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
./ci.sh's leaks run counted the six shaders the suite made and never gave back (843 allocations under them). Each is freed now: 0 leaks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 5 of docs/aether_quote_design.md section 9: MSL from the quoted shaders' trees. No Metal renderer yet. Section 11 sets no narrower first step, and #312 (the Metal backend) waits on the Vulkan performance pass. So this PR does the part that is clearly in scope: the MSL, compiled and checked. Section 11 now lists the Metal-path options for Nic.
No aether change was needed. Quote's trees carry everything the dialect reads, so this builds on the pinned 0.834.0 and needs no release.
Commits
ae3d.gpu: the quoted shaders written as MSL (
gpu.METAL).emit_msl,emit_vertex_mslandemit_screen_vertex_mslreuse the GLSL emitter's expressions and statements, with aCALL_MSLcolumn in the call table. The rules:packed_float3andfloat4arrays, and every offset and size is astatic_assert.[[user(locnK)]], attributes at the table's[[attribute(n)]], and colour outputs are four lanes wide.[[buffer(N)]], storage buffers at 8 + k, and textures/samplers follow capture order.tests/test_gpu_msl(no GPU) checks this.generate_shaders. Writes all 41 MSL files to
src/ae3d/metal, and--checkbyte-compares them. The GLSL, vkscene and SPIR-V are unchanged.msl_check.
tools/mslc.muses Metal's own compiler through the device, with every warning an error except four noise groups.scripts/msl_check.shruns it, and./ci.shruns that on macOS.xcrun metalalso runs where Xcode's Metal Toolchain is installed; it is a separate download and is not on the M6.docs. Section 9 item 5 and section 11 "What it buys MSL": the rules, how they are held, and three ways to a Metal path, with a recommendation.
Verification (M6, Aether 0.834.0, glslang 16.6.0)
generate_shaders --check: 95 generated files are current (53 GLSL, vkscene, 41 MSL), and the SPIR-V (892,276 B) is what glslang 16.6.0 makes. The GLSL and SPIR-V are unchanged by this PR.scripts/msl_check.sh: all 41 files compile clean with every warning an error.Against MoltenVK's own MSL of the same SPIR-V (SPIRV-Cross, logged with
MVK_CONFIG_DEBUG=1fromtest_backend_parity):This checks interfaces and layouts, not arithmetic.
tests/test_gpu_msl: 33 checks pass, with 0 leaks.Negative controls. Each of these fails as it should:
.metal(--check);static_assert);float3(--check+ 13 asserts + test);The existing bar:
./ci.sh: green at e262954 (8 hardware skips); the run at bd52d7c failed only the leaks check on test_gpu_msl, fixed by e262954;PR CI: 10/10 green. macos-2 timed out at 25 min on its first run, with every suite up to then ok (Step 6, the scene: per-camera and per-world blocks, the scene's shaders quoted #838 changed ae3d.gpu too and its macos-2 took 14 min). It passed on a rerun in 8m37s.
For Nic
Metal path: pick one of three.
Recommended: 1, then 3 after Metal backend #312's groundwork.
Binding model. It uses discrete arguments, not the argument buffers section 11 first mentioned.
xcrun metalwas not run. It needs the Metal Toolchain download (xcodebuild -downloadComponent MetalToolchain). The device compiler, with stricter flags, stands in.scene_rq_vk.fragis still hand-written. It has no MSL.🤖 Generated with Claude Code