From df6cb2161d2d72e596d69d38eb69fac1d13da42f Mon Sep 17 00:00:00 2001 From: swipelab Date: Thu, 4 Jun 2026 18:21:35 +0300 Subject: [PATCH] P0.2: draw a colored quad on the iOS Simulator, driven by sx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prove the render path end-to-end: bring up UIKit + Metal (already scaffolded), clear to a solid blue, and draw one centered orange quad via the GPU protocol's clear+quad path — an MSL pass-through pipeline plus a 6-vertex (2-triangle) NDC buffer, created lazily once the MTLDevice exists. Geometry is NDC [-0.5, 0.5]² so the quad is the central 50%x50% of the drawable regardless of device resolution, keeping the screenshot golden unambiguous. Background (0.10, 0.20, 0.55), quad (1.0, 0.6, 0.0). goldens/p0_quad.png is the first screenshot golden, captured from the booted iOS 26.0 simulator after install + launch. --- goldens/p0_quad.png | Bin 0 -> 75921 bytes main.sx | 74 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 goldens/p0_quad.png diff --git a/goldens/p0_quad.png b/goldens/p0_quad.png new file mode 100644 index 0000000000000000000000000000000000000000..bbe5863d323493d228d17eb36d8ce13caa5db173 GIT binary patch literal 75921 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

23VNG1j5@Hm`u8*X~gGbig27 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 ZvheG9$AU6|Dm1>6$1MKH|K0ie{{{T2^pOAn literal 0 HcmV?d00001 diff --git a/main.sx b/main.sx index 0535515..62ac332 100644 --- a/main.sx +++ b/main.sx @@ -22,6 +22,60 @@ g_viewport_h : f32 = 600.0; g_uikit_plat : *UIKitPlatform = null; g_metal_gpu : *MetalGPU = null; +// ── Render-path proof (P0.2) ───────────────────────────────────────────── +// Clear to a solid blue, then draw one centered orange quad covering the +// central 50%×50% of the drawable. Geometry is in NDC ([-0.5, 0.5]²) so the +// quad stays screen-size independent across simulator devices, which keeps +// the screenshot golden unambiguous. This is the GPU protocol's +// clear+quad path: an MSL pipeline state plus a 6-vertex (2-triangle) +// buffer, created lazily once the MTLDevice exists. +g_quad_shader : ShaderHandle = 0; +g_quad_vbuf : BufferHandle = 0; + +BG_CLEAR :: ClearColor.{ r = 0.10, g = 0.20, b = 0.55, a = 1.0 }; + +// Vertex layout matches QUAD_MSL's `Vertex`: packed_float2 pos + +// packed_float4 color = 24 bytes. `packed_*` avoids the 16-byte alignment +// padding a plain `float4` would force. 6 vertices = 2 triangles. +QUAD_VERTS : [36]f32 = .[ + -0.5, 0.5, 1.0, 0.6, 0.0, 1.0, + 0.5, 0.5, 1.0, 0.6, 0.0, 1.0, + -0.5, -0.5, 1.0, 0.6, 0.0, 1.0, + 0.5, 0.5, 1.0, 0.6, 0.0, 1.0, + 0.5, -0.5, 1.0, 0.6, 0.0, 1.0, + -0.5, -0.5, 1.0, 0.6, 0.0, 1.0, +]; + +// Pass-through shader: the vertex stage emits NDC positions directly (no +// projection), the fragment stage returns the interpolated vertex color. +// Entry-point names vmain / fmain are what MetalGPU.create_shader looks up. +QUAD_MSL :: #string MSL +#include +using namespace metal; + +struct Vertex { + packed_float2 pos; + packed_float4 color; +}; + +struct RasterizerData { + float4 position [[position]]; + float4 color; +}; + +vertex RasterizerData vmain(uint vid [[vertex_id]], + constant Vertex* vertices [[buffer(0)]]) { + RasterizerData out; + out.position = float4(vertices[vid].pos, 0.0, 1.0); + out.color = float4(vertices[vid].color); + return out; +} + +fragment float4 fmain(RasterizerData in [[stage_in]]) { + return in.color; +} +MSL; + frame :: () { fc := g_plat.begin_frame(); g_viewport_w = fc.viewport_w; @@ -49,12 +103,26 @@ frame :: () { } else if g_metal_gpu.pixel_w != g_uikit_plat.pixel_w or g_metal_gpu.pixel_h != g_uikit_plat.pixel_h { g_metal_gpu.resize(g_uikit_plat.pixel_w, g_uikit_plat.pixel_h); } - clear : ClearColor = .{ r = 0.12, g = 0.12, b = 0.15, a = 1.0 }; - if !g_metal_gpu.begin_frame(clear) { return; } + // Compile the quad pipeline + upload its vertices once. The MTLDevice + // was created eagerly in main(), so both only need a valid device. + if g_quad_shader == 0 { + g_quad_shader = g_metal_gpu.create_shader(QUAD_MSL, ""); + if g_quad_shader == 0 { return; } + } + if g_quad_vbuf == 0 { + g_quad_vbuf = g_metal_gpu.create_buffer(size_of([36]f32)); + if g_quad_vbuf == 0 { return; } + g_metal_gpu.update_buffer(g_quad_vbuf, xx @QUAD_VERTS, size_of([36]f32)); + } + + if !g_metal_gpu.begin_frame(BG_CLEAR) { return; } + g_metal_gpu.set_shader(g_quad_shader); + g_metal_gpu.set_vertex_buffer(g_quad_vbuf); + g_metal_gpu.draw_triangles(0, 6); g_metal_gpu.end_frame(fc.target_present_time); } else { glViewport(0, 0, fc.pixel_w, fc.pixel_h); - glClearColor(0.12, 0.12, 0.15, 1.0); + glClearColor(0.10, 0.20, 0.55, 1.0); glClear(GL_COLOR_BUFFER_BIT); } g_plat.end_frame();