metal: GPU protocol + MetalGPU renders MSL triangle on iOS
Phase 8 step 3a of the Metal renderer port:
- New library/modules/gpu/ with types.sx (handles + ClearColor +
TextureFormat enum), api.sx (GPU :: protocol { ... } covering the
lifecycle / per-frame / resource / per-draw surface), and metal.sx
(MetalGPU backend implementing the protocol against CAMetalLayer).
Resource handles are 1-based indices into backend List(*void) tables.
MTL aggregates >16 bytes (MTLRegion, MTLScissorRect) pass via *T to
match arm64 Apple's indirect-by-reference ABI; MTLClearColor + CGSize
go through the HFA path as direct fn-pointer casts on objc_msgSend.
- UIKitPlatform got a gpu_mode: GpuMode toggle + sibling SxMetalView
class registration. In metal mode init skips EAGL context, the
did_finish_launching IMP skips the EAGL drawable-properties dict,
layoutSubviews reads the layer's bounds * dpi_scale into pixel_w/h
instead of allocating a GL renderbuffer, and end_frame is a no-op
(the MetalGPU owns its own present).
- examples/63-metal-clear.sx verifies the pipeline end-to-end on iOS
sim — compiles a pass-through MSL shader (packed_float2/packed_float4
to avoid alignment padding), uploads 3 vertices, draws a colored
triangle on a dark-blue clear.
Compiler fixes (filed-and-fixed in this branch):
- inline if X { return E; } followed by a fall-through final expression
no longer emits two terminators into the same basic block. Verified
by examples/83-inline-if-return-fallthrough.sx.
- Top-level type alias Name :: u32; now resolves correctly as the type
annotation on a global variable (was treated as ptr {}, breaking
comparisons + initializers). Verified by examples/84-global-type-alias.sx.
Issue->feature promotion:
- 16 historical examples/issue-NNNN.sx repros now confirmed-fixed and
renamed to focused feature names (67-82). Each gains a
tests/expected/*.txt + .exit pair so the regression suite covers them.
- 5 stale issue repros deleted (subsumed by broader tests).
Regression suite: 68 passing, 0 failed. macOS chess builds + runs; wasm
chess builds; iOS sim GLES chess still renders the full board; iOS sim
Metal demo renders the triangle.
This commit is contained in:
1
tests/expected/67-impl-for-builtin.exit
Normal file
1
tests/expected/67-impl-for-builtin.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
2
tests/expected/67-impl-for-builtin.txt
Normal file
2
tests/expected/67-impl-for-builtin.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
lerp(0, 10, 0.5) = 5.000000
|
||||
lerp(0, 10, 0.25) = 2.500000
|
||||
1
tests/expected/68-generic-protocol-constraint.exit
Normal file
1
tests/expected/68-generic-protocol-constraint.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
3
tests/expected/68-generic-protocol-constraint.txt
Normal file
3
tests/expected/68-generic-protocol-constraint.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
after set: 100.000000x50.000000
|
||||
mid anim: 150.000000x75.000000
|
||||
end anim: 200.000000x100.000000
|
||||
1
tests/expected/69-optional-all-null.exit
Normal file
1
tests/expected/69-optional-all-null.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
3
tests/expected/69-optional-all-null.txt
Normal file
3
tests/expected/69-optional-all-null.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
r1 = 150.000000
|
||||
r2 = 150.000000
|
||||
r3 = 200.000000
|
||||
1
tests/expected/70-optional-roundtrip.exit
Normal file
1
tests/expected/70-optional-roundtrip.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
10
tests/expected/70-optional-roundtrip.txt
Normal file
10
tests/expected/70-optional-roundtrip.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
=== Direct calls ===
|
||||
d1 = 150.000000
|
||||
d2 = 150.000000
|
||||
d3 = 200.000000
|
||||
d4 = 110.000000
|
||||
=== Protocol dispatch ===
|
||||
r1 = 150.000000
|
||||
r2 = 150.000000
|
||||
r3 = 200.000000
|
||||
r4 = 110.000000
|
||||
1
tests/expected/71-int-cmp-in-float-ternary.exit
Normal file
1
tests/expected/71-int-cmp-in-float-ternary.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
2
tests/expected/71-int-cmp-in-float-ternary.txt
Normal file
2
tests/expected/71-int-cmp-in-float-ternary.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
ok
|
||||
result = 1.000000
|
||||
1
tests/expected/72-protocol-in-wrapper-struct.exit
Normal file
1
tests/expected/72-protocol-in-wrapper-struct.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
4
tests/expected/72-protocol-in-wrapper-struct.txt
Normal file
4
tests/expected/72-protocol-in-wrapper-struct.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
inside add: 42
|
||||
inside add: 99
|
||||
items[0] = 42 (expected 42)
|
||||
items[1] = 99 (expected 99)
|
||||
1
tests/expected/73-protocol-list-from-fn.exit
Normal file
1
tests/expected/73-protocol-list-from-fn.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
7
tests/expected/73-protocol-list-from-fn.txt
Normal file
7
tests/expected/73-protocol-list-from-fn.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
=== Created in main ===
|
||||
first: 42 (expected 42)
|
||||
second: 42 (expected 42)
|
||||
=== Created in add() ===
|
||||
first: 99 (expected 99)
|
||||
second: 99 (expected 99)
|
||||
=== OK ===
|
||||
1
tests/expected/74-protocol-dispatch-via-fn-arg.exit
Normal file
1
tests/expected/74-protocol-dispatch-via-fn-arg.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
8
tests/expected/74-protocol-dispatch-via-fn-arg.txt
Normal file
8
tests/expected/74-protocol-dispatch-via-fn-arg.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
=== Direct 1 ===
|
||||
r1 = 42
|
||||
=== Direct 2 ===
|
||||
r2 = 42
|
||||
=== From function ===
|
||||
dispatch_fn: about to dispatch
|
||||
dispatch_fn: result = 42
|
||||
=== OK ===
|
||||
1
tests/expected/75-push-context-with-arena.exit
Normal file
1
tests/expected/75-push-context-with-arena.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
2
tests/expected/75-push-context-with-arena.txt
Normal file
2
tests/expected/75-push-context-with-arena.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
inside push
|
||||
after push
|
||||
1
tests/expected/76-closure-returning-protocol.exit
Normal file
1
tests/expected/76-closure-returning-protocol.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
2
tests/expected/76-closure-returning-protocol.txt
Normal file
2
tests/expected/76-closure-returning-protocol.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
direct call works
|
||||
closure call works
|
||||
1
tests/expected/77-list-items-assign-big-T.exit
Normal file
1
tests/expected/77-list-items-assign-big-T.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
4
tests/expected/77-list-items-assign-big-T.txt
Normal file
4
tests/expected/77-list-items-assign-big-T.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
size_of BigNode = 40
|
||||
before: sentinel = 3735928559
|
||||
after: sentinel = 3735928559
|
||||
OK
|
||||
1
tests/expected/78-global-compound-assign.exit
Normal file
1
tests/expected/78-global-compound-assign.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
10
tests/expected/78-global-compound-assign.txt
Normal file
10
tests/expected/78-global-compound-assign.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
--- Test 1: += (broken) ---
|
||||
Expected: 1, 2, 3
|
||||
counter=1
|
||||
counter=2
|
||||
counter=3
|
||||
--- Test 2: = x + 1 (works) ---
|
||||
Expected: 2, 3, 4
|
||||
counter=4
|
||||
counter=5
|
||||
counter=6
|
||||
1
tests/expected/79-global-array-init.exit
Normal file
1
tests/expected/79-global-array-init.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
2
tests/expected/79-global-array-init.txt
Normal file
2
tests/expected/79-global-array-init.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
VALS: -2 -1 42 99
|
||||
PASS
|
||||
1
tests/expected/80-dot-shorthand-protocol-field.exit
Normal file
1
tests/expected/80-dot-shorthand-protocol-field.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
3
tests/expected/80-dot-shorthand-protocol-field.txt
Normal file
3
tests/expected/80-dot-shorthand-protocol-field.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
StackA: draw=42
|
||||
StackB: draw=25
|
||||
OK
|
||||
1
tests/expected/81-global-struct-defaults.exit
Normal file
1
tests/expected/81-global-struct-defaults.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
6
tests/expected/81-global-struct-defaults.txt
Normal file
6
tests/expected/81-global-struct-defaults.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
local running=true x=42 name=default
|
||||
g_empty running=true x=42 name=default
|
||||
g_partial running=true x=99 name=default
|
||||
g_override running=false x=42 name=default
|
||||
g_reorder running=false x=7 name=hi
|
||||
g_positional running=false x=13 name=pos
|
||||
1
tests/expected/82-xx-target-in-field-assign.exit
Normal file
1
tests/expected/82-xx-target-in-field-assign.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
2
tests/expected/82-xx-target-in-field-assign.txt
Normal file
2
tests/expected/82-xx-target-in-field-assign.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
dpi=2.000000
|
||||
delta=0.500000 fc.a=1.000000
|
||||
1
tests/expected/83-inline-if-return-fallthrough.exit
Normal file
1
tests/expected/83-inline-if-return-fallthrough.exit
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
1
tests/expected/83-inline-if-return-fallthrough.txt
Normal file
1
tests/expected/83-inline-if-return-fallthrough.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
1
tests/expected/84-global-type-alias.exit
Normal file
1
tests/expected/84-global-type-alias.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
1
tests/expected/84-global-type-alias.txt
Normal file
1
tests/expected/84-global-type-alias.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user