2026-10-26 shader-surface: SULD, SUST, SUATOM and SURED in the Maxwell translator¶
Branch claude/shader-surface-2026-10-26-cloud2 (Linux cloud session; nothing here was compiled by Metal). Owner area: gfx/src/shader/ and the shader text tests.
What changed¶
- The surface family no longer ends in the "no image binding in the translator contract" refusal.
src/shader/surface.inc(included bymaxwell_translate.c) translates: - SULD: dimensions 1D, BUFFER, 1D_ARRAY, 2D, 2D_ARRAY, 3D; raw
.Dsizes U8 S8 U16 S16 32 64 128; formatted.Pwith a channel mask; byte addressing.BA; clamp modes IGN, TRAP, CLAMP, ZERO; immediate and bindless (.B) handles. - SUST: the same dimensions, sizes, masks and clamps; a partial
.Pmask is a read-modify-write. - SUATOM / SURED: ADD, MIN, MAX, AND, OR, XOR on 32-bit signed/unsigned images, through MSL 3.1 texture atomics.
- Unsupported by Metal, each a translator error naming the instruction and the reason: INC, DEC (wrapping), EXCH, CAS (MSL 3.1 has no texture exchange / compare-exchange), 64-bit and floating-point atomics. Also refused: more than 8 images, one image used with two dimensions, a key that contradicts a shader-forced integer kind, other opcodes in 0xea/0xeb.
- Binding contract (documented in
docs/architecture/gfx.mdsection 11): image slot i is[[texture(64 + i)]], access qualifier from use, component type fromShaderKey.image_int_mask / image_uint_maskor forced by raw/atomic access, handle at c2 + 4 * index or from a user buffer when bindless,needs_msl31for atomics. NewShaderInfofields:nimg,img[],needs_msl31; newShaderKeyfields:image_int_mask,image_uint_mask.
Decisions¶
- The instruction field layout is the translator's own decode (listed at the top of
surface.inc), reconstructed from memory of the public Maxwell decoders. It is pinned by hand-assembled tests but NOT checked against a shader binary from a game: the first Mac corpus run (NAPPLE_SHADER_CORPUS) is the real check. If a field is off, onlyemit_surfacedecode lines change. - TRAP behaves as IGN (a GPU cannot trap). Bounds checks are explicit; Metal's own out-of-range behaviour is not relied on.
.BAassumes the texel size equals the access size. A raw.Daccess without.BAreturns the first channel(s) of a texel, not packed texel bits.- Atomics promote an image to an integer kind on first use; an image already used as float is refused rather than silently retyped.
- Stretch: 1D-array surfaces are covered. TLD4/TLD4S edge cases were reviewed: the existing translation already handles array, depth, constant and AOFFI offsets; per-texel offsets (PTP) stay refused (Metal needs constant gather offsets) and were not changed.
Status¶
| Item | Status |
|---|---|
| Translation text of every SULD/SUST/SUATOM/SURED variant above | tested (sh gfx/tests/t_xlate_linux.sh: ok) |
| MSL compiles (Metal) | unbuilt: MSL_COMPILES / MSL_COMPILES31 in t_xlate.m run on the Mac only |
Binding glue in mtl_shader.m / mtl_replay.m |
not done (not mine); exact calls listed in gfx.md section 11 and the integrator file |
| Encoding against real shaders | proposed |
Files¶
gfx/src/shader/surface.inc (new), maxwell.h, maxwell_translate.c (include, dispatch, argument list), gfx/tests/t_surface.inc, t_surface_asm.inc (new), t_xlate.m, docs/architecture/gfx.md (section 11 appended), docs/guides/add-maxwell-shader-op.md (one sentence).