Skip to content

Commit 15d2eda

Browse files
MarkKropfclaude
andcommitted
Update iteration log with iteration 12 (full-screen terrain fix)
Record black rectangle fix, updated priority queue, and confirmed working status after FBO Bind() no-op workarounds resolved the terrain visibility and screen blinking issues. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1ad1171 commit 15d2eda

1 file changed

Lines changed: 50 additions & 13 deletions

File tree

tools/metal-debug/iteration-log.md

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
# Metal Debug Iteration Log
22

33
## Current Status
4-
- Last iteration: 11
5-
- Commit: (pending)
6-
- Shaders: 89/89(+5 grass), Draw calls: 19idx+11, FPS: 54.3, PSO fails: 2 (cached)
4+
- Last iteration: 12
5+
- Commit: 1ad1171218
6+
- Shaders: 87, Draw calls: 19idx+11, FPS: 54.6, PSO fails: 2 (cached)
77
- Exit: **CLEAN EXIT (code 0)**, Errors: **12**
8-
- Visual: **UNITS + SKY + GRASS PIPELINE READY**all grass infrastructure on Metal
9-
- **Grass rendering fully enabled on Metal**shaders compile, GL_QUADS→Triangles conversion,
10-
GLAD extension bypass, BAR Lua override patching. Test map has no grass data (0/24576 squares).
8+
- Visual: **FULL-SCREEN TERRAIN + UNITS + SKY**no black rectangle, no blinking
9+
- **Terrain covers entire 800x600**previously only top-left ~25% showed ground.
10+
Root cause was Metal FBO Bind() no-op leaking Lua/MiniMap/RmlUi draws to screen.
1111

1212
## Priority Queue
13-
1. Terrain rendering diagnostic — only top-left ~25% of screen shows detailed terrain,
14-
other 3/4 render units/effects but no ground. Viewport/frustum investigation needed.
13+
1. Widget off-screen textures — `gl.RenderToTexture()` stale on Metal (scissor-clipped workaround)
1514
2. Shadow pass verification — shadow shader variants compile, need to verify FBO + shadow map pipeline
1615
3. BumpWater — requires `[[clip_distance]]` across all water-affected shaders. Water=0 anyway.
1716
4. Last 2 PSO failures — both cached, non-crashing. Quick investigation.
1817
5. Info textures (Combiner) — requires FFP builtin removal from Lua info shaders.
1918
6. Tier 5: CI pipeline, macOS app bundle, final audit
2019

21-
## Confirmed Working (Post-Phase 38)
20+
## Confirmed Working (Post-Iteration 12)
21+
- **Full-screen terrain** — terrain covers entire 800x600, no black rectangle or blinking
22+
- **Units + particle effects** — commanders, infantry, battle smoke, construction sparks
23+
- **Atmospheric sky** — ModernSky gradient rendering (Sky-0/Sky-1 shaders)
24+
- **Grass pipeline** — all infrastructure ready, test map has 0 grass data
2225
- **Clean shutdown** — Metal device destroyed, all Kill[] stages complete, exit code 0
23-
- **Game simulation** — forcestart works, gf=0→43 in 300 frames
26+
- **Game simulation** — forcestart works, gf=189 in 600 frames, ~54.6 FPS
2427
- **SIGABRT recovery** — Metal abort() during PSO creation caught + cached via sigsetjmp
2528
- **Vertex output padding** — PadMissingVertexOutputs adds zero-initialized dummy outputs
2629
- **PSO failure caching** — both NSError and SIGABRT failures cached, logged once per shader
27-
- **27 PSOs created OK** — up from ~8 before padding fix
2830
- Viewport: 800x600, drawable matches, contentsScale=1.0
2931
- SPIRV-Cross texture remapping: GL unit → Metal [[texture(N)]] index per shader stage
3032
- Terrain shader: SMFShaderGLSL-Forward-Adv with correct texture bindings
31-
- ROAM patch visibility: 2/24 patches visible at steep camera angle — geometrically correct
32-
- Drawable: 800x600 matches viewport, present works correctly
3333
- Clear(): mid-pass clears properly handled via fullscreen quad
3434
- Screenshots: ReadPixels with Y-flip works correctly
3535
- Loading screen: "Loading..." text renders with fonts
@@ -309,3 +309,40 @@
309309
Far billboard path enters Draw() with 59 blocks but all have empty grassMap data.
310310
Near grass blade VBO created, DrawIndexed(Triangles) path ready.
311311
- Next: Terrain rendering diagnostic (top-left quadrant issue), shadow pass verification.
312+
313+
### Iteration 12 — 2026-03-01 (Black rectangle fix + full-screen terrain) ★ FULL SCREEN
314+
- Run: 20260301_181211
315+
- Commit: 1ad1171218
316+
- Metrics: shaders=87 draws=19idx+11 fps=54.6 pso_fails=2(cached) exit=0 gf=189 errors=12
317+
- Visual: **TERRAIN FILLS ENTIRE 800x600 SCREEN** — no black rectangle, no alternating black
318+
frames. Units with battle smoke, particle effects, atmospheric sky all visible.
319+
- Root cause: **Metal FBO Bind() is a no-op** — three subsystems called FBO::Bind() expecting
320+
rendering to redirect to off-screen textures, but on Metal all draws went to the screen:
321+
1. **LuaOpenGL::RenderToTexture** — Lua widgets called `gl.RenderToTexture()` which set viewport
322+
to texture size (400x300 = half screen) and drew to screen, producing the black rectangle.
323+
2. **MiniMap::UpdateTextureCache**`FBO::IsSupported()` returns true on Metal (line 36-37 of
324+
FBO.cpp), so `renderToTexture=true`, causing minimap to render at reduced viewport to screen.
325+
3. **RmlUi layer compositing**`BeginFrame`/`PushLayer`/`CompositeLayers` used FBO Bind()+Clear()
326+
which cleared the screen each frame, causing alternating black frames ("blinking").
327+
- Failed approaches:
328+
- **Render pass break** (EndRenderPass→BeginRenderPass(FBO)→EndRenderPass→BeginDefaultRenderPass):
329+
Terrain became invisible even with LoadAction::Load for both color and depth. Draw counts normal
330+
(128+) but fragments didn't render. Root cause unclear — possibly Metal Store→Load within same
331+
command buffer doesn't preserve correctly.
332+
- **Clear FBO to transparent** (LoadAction::Clear with 0,0,0,0): Same terrain disappearance.
333+
- Fix: Three targeted workarounds (11 files, 127 insertions, 42 deletions):
334+
1. **LuaOpenGL.cpp**: Scissor-clip RenderToTexture on Metal — set 1x1 scissor rect before Lua
335+
function execution, restore after. Lua code runs (no crash) but draws are invisible.
336+
2. **MiniMap.cpp**: Force `renderToTexture=false` on Metal — uses direct rendering path instead
337+
of broken FBO texture cache.
338+
3. **RmlUi_Renderer_GL3_Recoil.cpp**: Guard all FBO operations with `IsMetalBackend()` checks —
339+
BeginFrame, EndFrame, PushLayer, CompositeLayers, PopLayer all skip FBO paths on Metal.
340+
4. **MTLContext.mm**: Support explicit depth LoadAction in BeginDefaultRenderPass (for future
341+
render pass resume support).
342+
5. **WorldDrawer.cpp**: Viewport restore at start of Draw(), ClearColor alpha 1.0 (was 0.0).
343+
6. **Supporting**: ModernSky CullMode::None, DepthBufferCopy Metal skip, MTLDevice opaque=YES,
344+
SMFRenderState clipPlane2 default, NetCommands sync logging.
345+
- Known limitation: Widget off-screen textures not updated on Metal (stale via scissor workaround).
346+
Widgets that depend on RenderToTexture will have empty/stale textures. Proper fix requires
347+
solving the render pass break terrain issue.
348+
- Next: Widget texture rendering, shadow pass verification.

0 commit comments

Comments
 (0)