Files
sx/examples/issue-0026.sx
agra a1647eab9b metal: pause step 3b pending sx-side fixes (filed 0024-0030)
Step 3b code is wired across UIRenderer + GlyphCache + UIPipeline +
chess game (gpu_mode = .metal on iOS, MetalGPU bound via the GPU
protocol). macOS GL chess, iOS-sim GLES chess, and iOS-sim Metal
triangle (63-metal-clear.sx) all still render.

iOS-sim Metal chess crashes inside replaceRegion uploading the 1MB
font atlas. Bisecting that crash exposed several sx-language issues
where mid-bisect tracers (NSLog inside if/else branch bodies) didn't
produce output, blocking further investigation.

Filing each finding as examples/issue-NNNN.sx rather than working
around piecemeal:

Bugs:
- 0024 NSLog/foreign-call inside if/else body not producing output
- 0025 C-ABI param coercion incomplete for composites >16B
       (combined direct-call abiCoerceParamType TODO + call_indirect
        path that doesn't apply C-ABI coercion at all)
- 0026 replaceRegion 1MB upload crash (likely downstream of 0025)

Features needed for step 4 + cleanup:
- 0027 Obj-C block bridge (^{...}) for animateWithDuration:
- 0028 Optional protocol box (?GPU = null) replaces T = ---; has_T: bool
- 0029 destroy_texture/buffer/shader on GPU protocol
- 0030 extern cross-file globals

Library-side: renderer.sx + glyph_cache.sx + pipeline.sx gain a
`gpu: GPU = ---; has_gpu: bool` field pair + branches that route every
GL touchpoint through the protocol when has_gpu. glyph_cache.init
saves/restores those fields around its memset. pipeline.set_gpu()
propagates to renderer + font. Renderer's MSL shader source added as
UI_MSL_SRC using packed_float2/packed_float4 to keep the 12-float
interleaved vertex layout tight (48 bytes).

metal.sx: dual-phase init (init(null, 0, 0) for eager device+queue,
re-init with the layer once UIKit installs the SxMetalView).
setStorageMode:.shared on every texture descriptor to ensure CPU-
writable atlas pixels on Apple Silicon iOS-sim.

Regression suite: 68 passing, 0 failed. WASM chess build currently
broken under step 3b state (silent compiler crash); documented in
CHECKPOINT.md, likely fallout from one of the filed issues (probably
0028 — the verbose protocol-box pattern). Step 3b resumes after
0024-0030 land.
2026-05-17 21:17:17 +03:00

69 lines
3.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// issue-0026: Chess game on iOS-sim with `plat.gpu_mode = .metal` crashes
// inside `[MTLTexture replaceRegion:mipmapLevel:withBytes:bytesPerRow:]`
// when uploading the 1024×1024 R8 font atlas. The 1×1 RGBA8 white tex
// through the SAME code path (metal_update_texture_region_ios in
// library/modules/gpu/metal.sx) works.
//
// Blocked on issue-0024 (NSLog inside if/else not firing — or unified-log
// buffer loss on crash; investigation pending) — without a trustworthy
// tracer we can't reliably bisect which arg arrives wrong. Most likely
// cause: this is downstream of issue-0025's ABI gaps (MTLRegion is 48
// bytes and goes through `xx objc_msgSend` cast, which is the
// call_indirect path that issue-0025 part B covers).
//
// ── Reproduction recipe ───────────────────────────────────────────────────
//
// cd /Users/agra/projects/game
// /Users/agra/projects/sx/zig-out/bin/sx build --target ios-sim main.sx \
// --bundle sx-out/ios/SxChess.app --bundle-id co.swipelab.sxchess \
// -F ~/Library/Frameworks
// cp -R assets sx-out/ios/SxChess.app/
// codesign --force --sign - --timestamp=none sx-out/ios/SxChess.app
// xcrun simctl install booted sx-out/ios/SxChess.app
// xcrun simctl launch --terminate-running-process booted co.swipelab.sxchess
// sleep 4 && xcrun simctl io booted screenshot /tmp/sx-chess.png
//
// Expected (after fix): chess board renders via Metal.
// Observed: app launches, returns immediately to home screen, no screen
// touched. The simpler examples/63-metal-clear.sx demo still renders the
// colored triangle on the same sim, so the Metal pipeline itself works
// for small uploads.
//
// ── Candidate root causes (in priority order) ─────────────────────────────
//
// 1. issue-0025 fallout (most likely): MTLRegion (48 B by value) passed
// via the *MTLRegion workaround. The call_indirect path (issue-0025
// part B) doesn't ABI-coerce, so the pointer-shaped declaration may
// not actually pass the address in the right register slot for that
// call site shape (6 args, including the indirect aggregate).
//
// 2. iOS-sim Metal-driver limitation: `setStorageMode:.shared` may not be
// honored for r8 textures of this size; default may be `.private`
// which precludes CPU-side replaceRegion. Workaround would be to
// upload via `MTLBuffer` + `MTLBlitCommandEncoder` (newBufferWithBytes
// + copyFromBuffer:sourceOffset:sourceBytesPerRow:...:toTexture:...).
//
// 3. sx-side `xx` cast bug: bytes_per_row : u64 = xx (u32_expr) may
// truncate or sign-extend incorrectly. Less likely (the math comes
// out to 1024, which fits in any width).
//
// ── How to resolve ────────────────────────────────────────────────────────
//
// After issues 0024 + 0025 are landed:
// 1. Re-add the trace NSLog markers ("[metal] U1..U5" in
// metal_update_texture_region_ios) — now they should actually print.
// 2. Re-build + relaunch chess on iOS-sim.
// 3. If U5 fires after U4 (no crash inside msg_replace), the bug was
// ABI-related; declare success and rename this file to
// examples/NN-metal-large-region-upload.sx (next free NN).
// 4. If U4 → crash persists, fall back to the MTLBuffer + blit
// encoder path in metal.sx's create_texture (when pixels != null,
// allocate a temporary MTLBuffer with newBufferWithBytes:length:options:
// then run a one-shot command buffer with a MTLBlitCommandEncoder
// copying the buffer into the texture). This is the Apple-recommended
// approach for large texture initial-uploads.
#import "modules/std.sx";
main :: () -> s32 { 0; }