Engineering change orders
The microZeus devlog, kept the way a drawing office keeps revisions: numbered, dated, and tagged with the sheets they touch.
Subscribe — RSS feedECO-0062mzVolk mzVolk: the audit’s cleanup pass
The parity audit reaches its tail (v0.83 → v0.85): vkGetImageMemoryRequirements reports honest memoryTypeBits, a handful of trivially-missing entry points are filled in so nothing dlsyms to null, and vkQueueSubmit now skips command buffers that were never successfully recorded instead of executing garbage. Unglamorous by design — the last few findings on a 24-item list, closed so the number goes to zero.
ECO-0061mzVolk mzVolk: layered images, addressed correctly
The AP3 audit group turns to array textures (v0.81 → v0.82): vkGetImageSubresourceLayout now honors the requested array layer, depth/stencil aspect, and depth, and vkCmdCopyImage honors array layers when copying. Layered images — cube faces, texture arrays, the 2D-array textures the driver already samples — can now be laid out and copied by the exact subresource an app names, not just layer zero.
ECO-0060mzVolk mzVolk reaches for Vulkan 1.1
With the 1.0 honest list long empty and the parity audit winding down, mzVolk starts climbing to Vulkan 1.1 (v0.79 → v0.80): the promoted, pNext-extensible entrypoints 1.1 apps expect — vkGetPhysicalDeviceFormatProperties2, vkGetPhysicalDeviceImageFormatProperties2, vkGetDeviceQueue2, vkEnumerateInstanceVersion, and the memory pair vkGetImage/BufferMemoryRequirements2 with vkBindImage/BufferMemory2. A software driver that finished 1.0 to the letter now has somewhere new to go.
ECO-0059mzOS2zui3d zui3d on the desktop: the stack, made visible
The visual payoff. zui3d’s UI is now a window on a desktop microZeus wrote. Each frame renders through the headless mzVolk swapchain; after zui_EndFrame, mzzui_demo reads the rendered image (mzvolk_image_pixels) and hands it to an mz surface, and the persistent mzwm compositor composites it as a real client window — verified live as "window[1/1] 'zui3d' 640×480 *focused*". That closes the last gap from ECO-0057: the whole microZeus GFX stack runs on mzOS2 end to end — mz protocol, a persistent compositor with pluggable shells, and mzWin/mzVolk/mzVKI/zui3d — a software-Vulkan UI toolkit, presented natively, no X11, no Wayland. The drawing set draws itself, on the screen of its own OS.
ECO-0058mzVolk mzVolk: descriptor sets, to the letter
Two descriptor-set audit items (v0.77 → v0.78): maxBoundDescriptorSets now reports the driver’s real four-slot capacity rather than a placeholder, and vkUpdateDescriptorSets honors VkCopyDescriptorSet — copying bindings between sets, not just writing them. Applications that query limits before allocating, or that update descriptors by copy, now get the behaviour the spec promises.
ECO-0057mzOS2zui3dmzVKImzVolkmzWin The whole stack, on its own OS
The tagline, made literal. zui3d — the UI toolkit at the top of the stack — runs on mzOS2. /bin/mzzui_demo initializes through mzVKI on a headless mzVolk swapchain, loads its SPIR-V from /system/gfx, renders three frames of its public API — Text and Button widgets — and shuts down clean while the boot stays green, so kmain launches it again. That completes GFX port #50: all four microZeus graphics libraries — mzWin windowing over the mz protocol, mzVolk software Vulkan, mzVKI device setup, and zui3d — now build and run on the operating system microZeus wrote, statically, no ICD, no host anything. The whole stack, hand-drawn, on its own OS. Honest remainder: zui3d’s optional instanced-pipeline shaders don’t load yet, and presenting its finished frame to the mzwm compositor rather than rendering it headless is the next step. But the stack is up.
ECO-0056mzVolk mzVolk: descriptor and sampler state, pinned down
Two more audit items on the binding path (v0.75 → v0.76): vkCreateSampler now captures its full create-info state instead of a subset, and descriptor sets are routed by pipelineBindPoint — graphics bindings and compute bindings no longer step on each other when a command buffer uses both. Small, exact fixes of the kind a parity audit exists to surface: the difference between "usually works" and "works".
ECO-0055mzOS2mzVolkzui3d The last unknown: zui3d’s render path, proven
zui3d renders through a real Vulkan swapchain and presents each frame — so the question was whether that path could run with no native window on mzOS2. It can. mzVolk gained mzvolk_create_headless_surface, and /bin/mzvolk_swap builds a 2-image headless swapchain, clears the acquired image on the queue, presents it, then reads the presented image back and forwards its pixels to a window over the mz protocol. Verified: a 240×150 swapchain, corner pixel 0xff33bf59 — exactly the requested clear colour RGB(0.20, 0.75, 0.35). zui3d also gained its mzOS port hooks (ZUI_MZOS: headless surface, fixed asset path). The mechanism zui3d’s zui_Init/EndFrame needs is proven; wiring zui3d itself onto the bridge is the only step left to the whole stack rendering on its own OS.
ECO-0054mzVolk mzVolk: the long tail of the API
Two more audit items fill in commands real engines reach for occasionally (v0.73 → v0.74): the dynamic-state setters vkCmdSetLineWidth, vkCmdSetDepthBias, and vkCmdSetDepthBounds, and vkCmdCopyQueryPoolResults to write query outcomes into a buffer. Neither is glamorous, but a driver that only implements the common path is a driver that fails the moment an app steps off it — the audit exists to keep that from happening.
ECO-0053mzOS2mzVolk The stack renders: mzVolk pixels in a window on mzOS2
End to end, for real. On mzOS2, /bin/mzvolk_render drives raw vk* through mzVolk — create a device and graphics queue, allocate a host-visible R8G8B8A8 image, record vkCmdClearColorImage under a layout barrier, submit and wait, map the result respecting its row pitch, and present it to a window over the mz protocol, where mzwm composites it as an ordinary client surface. The proof is a single pixel: the presented corner reads 0xff1f8cd9, exactly the requested clear colour RGB(0.12, 0.55, 0.85). A software Vulkan driver microZeus wrote cleared an image and put the right pixels on screen, through a compositor microZeus wrote, on an operating system microZeus wrote. No GPU in the building.
ECO-0052mzOS2mzVKI mzVKI climbs onto mzOS2
The layer above the driver follows it up. mzVKI — the thin Vulkan wrapper — is ported over mzVolk on mzOS2, running in x86_64 userspace on a portable libm, with a boot probe of its own. mzVKI is the single point of contact the rest of the stack speaks through, so with it and mzWin both now on the OS, zui3d is the only rung left before the whole graphics stack runs on the operating system microZeus wrote. The build’s fetch list already names it.
ECO-0051mzVolk mzVolk: honest capabilities
The audit’s capability group (v0.70 → v0.72) makes the driver stop over-promising. Format properties now advertise the real sampled, linear, storage, and texel support instead of claiming every feature bit; image-format queries report honest sample counts and reject usages the driver cannot back; and vkBindImageMemory refuses overflowing binds outright. An application that asks "can you do this?" now gets the true answer — the same honesty the known-limitations list was built on, pushed down into the API itself.
ECO-0050mzOS2mzVolk First light: mzVolk runs on mzOS2
The dashed line goes solid. mzVolk — the software Vulkan driver — is ported onto mzOS2 and runs freestanding: no host OS, no GPU, vk* calls executing on the microZeus kernel with a boot-time probe exercising the pipeline. This is GFX Phase 4, and it is the whole point of the drawing set arriving at once — an operating system microZeus wrote, running a Vulkan implementation microZeus wrote. It is interpreter-only for now (mzJIT is stubbed on this target; the native path is a later phase), and the sheet says so — but the stack is on its own OS. Sheet 1 has been redrawn: the planned edge is now real.
ECO-0049mzOS2mzWin mzOS2: the ecosystem lands on the compositor
Not a shim this time — the real thing. microZeus’s own mzWin windowing library gains an mzOS backend and runs as a client on the mzwm compositor, speaking the mz protocol instead of X11 or Win32. A second client family joins too: mzmac, a Cocoa-flavored shim beside the Win32-flavored mzwin. The direction of travel is what matters — mzWin is the layer zui3d sits on, so an ecosystem library rendering through mzOS2’s own display server is the last rung before the UI stack itself does.
ECO-0048mzVolk mzVolk: render-pass clears, correctly
Two more parity-audit fixes tighten the render pass (v0.68 → v0.69): vkCmdBeginRenderPass now honors each attachment’s loadOp — clear, load, or don’t-care, per attachment — and the clears it performs respect renderArea instead of blanketing the whole framebuffer. A render pass that clears one attachment while preserving another, into a sub-rectangle of the target, now does exactly that.
ECO-0047mzOS2 mzOS2: the compositor grows a client API
One check after the mzwm seed, the windowing stack becomes usable. The compositor now stacks multiple windows with z-order and focus, and each can wear its own OS personality at once — a win-themed frame beside a mac-themed one beside a linux one. Programs reach it through mzwin, a Win32-flavored client shim (MZW_CreateWindow and friends) that speaks the mz protocol so an application never has to: the demo client opens a "Notepad" window and paints into it without touching a single IPC message. mzOS2 now runs a windowed app on its own display server.
ECO-0046mzOS2 mzOS2: a windowing stack of its own
The pieces come together into a display server. mzwm — the mz system compositor — owns the framebuffer (ECO-0040) and composites client windows shared cross-process over the kernel IPC protocol (ECO-0041): one compositor, many clients, real buffer sharing. Pluggable shell personalities (win/mac/lnx) restyle the window frames and titles the compositor draws. This is GFX Phase 3, and the shape of it matters — mzOS2 is no longer only a kernel that boots, it is growing the graphical layer the rest of the drawing set is meant to sit on.
ECO-0045mzVolk mzVolk: per-draw state, the rest of the way
The per-draw parity work from ECO-0043 finishes the binding surface: descriptor sets (v0.65) and vertex/index buffers (v0.66) are now snapshotted into each draw call too. Every piece of state a command buffer can rebind between draws — pipeline, push constants, viewport/scissor, descriptor sets, and vertex/index buffers — is captured at record time and replayed exactly, so a single command buffer that changes any of them mid-stream renders each draw against the state it was actually recorded with.
ECO-0044mzOS2 mzOS2: native virtio-blk, dual-path ARM boot
ARM and ARM64 gain a kernel-native virtio-blk block driver, closing a long-running boot-parity thread. Disk I/O now takes whichever path exists: the resident mzBIOS services when booting through the firmware stack, or the native driver directly when there is no resident BIOS — a direct QEMU -kernel boot. Getting there meant putting zero-init data back in .bss (kernel 1.3MB → 443KB, so it fits the FAT /boot partition), keeping the guarded kernel section out of the physical allocator, and a green mzBIOS ISO boot. mzBIOS stays the primary path; the native driver is the fallback that makes the OS bootable on its own.
ECO-0043mzVolk mzVolk: per-draw state, honored
A Vulkan API parity audit turned up 24 findings; the first batch fixes a shared root cause in the command-buffer replay path (v0.62 → v0.64). Pipeline binding, push constants, and static pipeline-baked viewport/scissor are now each snapshotted into the draw call and applied per draw — so a command buffer that binds a different pipeline, pushes new constants, or changes viewport between draws renders every one correctly, instead of replaying them all with the last state set. The honest list stays empty; correctness is its own kind of feature.
ECO-0042mzVolkmzJIT mzVolk: the honest list is empty
The last item comes off the list. Multisampling lands end-to-end (v0.58 → v0.59) — a supersample pass with vkCmdResolveImage as the resolve primitive — joined by polygon fill/line/point modes (v0.57), and on the shader side mzJIT v0.43 lowers OpFunctionCall by inlining so glslang-emitted shaders, which use real function calls, JIT-compile like the rest. From v0.4 to v0.60, a pure-C software Vulkan driver went from "no depth test yet" to a known-limitations section with nothing left in it. The list was never hidden, and now it is simply done.
ECO-0041mzOS2 mzOS2: an IPC layer takes shape
The mz protocol gets its transport: cross-process shared memory as the foundation, then a control channel of named ports and message channels on top. This is the plumbing a windowing system and a display server need to talk to clients — laid down deliberately now that mzOS2 has a framebuffer to put behind it.
ECO-0040mzOS2 mzOS2: pixels on screen via ramfb
The graphics-stack-on-mzOS2 work reaches a display: arm64 brings up a framebuffer through ramfb, the foundation for GFX Phase 3, with the presentation format nailed down (BGRA8 matches XRGB8888 as ramfb/DRM expect). This is the same pixel format mzVolk presents into — the dashed "mz stack on mzOS2" edge in the schematic now has a screen to draw on.
ECO-0039mzOS2 mzOS2: the primitives a graphics stack needs
Userspace grows teeth: mmap, mprotect, and munmap syscalls with a working JIT primitive — allocate memory, write code, flip it executable — and per-thread FP/SIMD context save/restore with userspace floating point enabled on arm64. Read alongside the new MZ_GFX build skeleton in the same tree, the direction is unmistakable: these are exactly the primitives mzJIT and mzVolk need to run on mzOS2. The schematic’s dashed edge is being drawn in.
ECO-0038mzVolkmzJIT mzVolk: storage images and the far plane
Five more releases (v0.47 → v0.51): clipping extends to the full frustum — the far plane joins the near plane — buffer views bring uniform texel buffer descriptors (with Lod-less OpImageFetch in mzJIT v0.39), vkCmdNextSubpass adds data-only multi-subpass semantics, and storage images land: imageLoad and imageStore through STORAGE_IMAGE descriptors, compute writing pixels directly. Capped with a perf win: pre-shading vertices once for threaded indexed draws, worth +132% on the mesh benchmark at eight threads.
ECO-0037mzOS2 mzOS2: concurrent scheduling, on by default
Application processors now schedule threads concurrently as the default configuration — the payoff of a patient root-cause chase through the ARM scheduler: an irq_handler that clobbered the interrupted SVC context’s LR_svc, an idle thread identified by pointer instead of tid, icache maintenance after code writes, and Inner-Shareable TLB operations. Every core works, all the time, no flag required.
ECO-0036mzVolkmzJIT mzVolk: cube maps, indirect draws, gl_FragDepth
Five releases in one run (v0.42 → v0.46): cube map sampling end-to-end and 2D array textures with layered sampling (mzJIT v0.38), non-float32 vertex input formats, indirect draws — vkCmdDrawIndirect, vkCmdDrawIndexedIndirect, and vkCmdDispatchIndirect pulling their parameters from GPU-visible buffers — secondary command buffers via vkCmdExecuteCommands, and gl_FragDepth so shaders can override interpolated depth. The API surface is starting to look uncomfortably complete for a driver with no hardware under it.
ECO-0035mzVolkmzJIT mzVolk: spec constants and integer completeness
Specialization constants work end-to-end (v0.40 → v0.41, mzJIT v0.36 → v0.37): VkSpecializationInfo at pipeline creation resolves OpSpecConstant* by SpecId, so one SPIR-V binary can compile into many specialized pipelines — the way real engines actually ship shaders. And the integer story is now complete: division, modulo, shifts, bitwise ops, and int↔uint bitcasts across the interpreter and JIT backends.
ECO-0034mzVolkmzJIT mzVolk: shared memory, atomics in the JIT, more formats
Compute grows up (v0.37 → v0.39, mzJIT v0.33 → v0.35): workgroup shared memory with OpControlBarrier via phased dispatch — threads run each barrier-delimited phase to completion before the next begins — and the atomics + OpSwitch lowerings land in the JIT backends, closing the fail-closed gap from ECO-0033. On the graphics side, sampled textures move beyond 4-byte RGBA: R8, RG8, R16F, and RGBA16F formats decode natively.
ECO-0033mzVolkmzJIT mzVolk: multiple render targets
Fragment shaders can now write more than one color attachment — subpass color attachments beyond the first rasterize (v0.36.0), opening the door to deferred-style rendering on a CPU driver. The supporting run (v0.34.2 → v0.35.1): a post-transform vertex cache for indexed draws, atomics and OpSwitch in the mzJIT interpreter with the JIT failing closed until its lowering lands, a small-triangle stress bench — and two negative perf results recorded in the backlog instead of deleted. Experiments that fail are still data.
ECO-0032mzVolkmzJIT mzVolk: textures, the completeness pass
Texturing goes from working to correct (v0.33.1 → v0.34.1, mzJIT v0.29 → v0.31): texelFetch and textureSize land via OpImageFetch and OpImageQuerySizeLod, sRGB textures decode properly instead of sampling raw bytes, and sampler LOD range and bias are wired through the whole stack. Also caught by the test suite: an x86 lane bug where slot-resident function locals read zeros.
ECO-0031mzVolkmzJIT mzVolk: stencil and fragment discard
Two more rasterizer capabilities in one run (v0.32.0 → v0.33.0): full stencil support — D32_S8 depth/stencil backing, the complete test and op set, every clear path, and dynamic state via vkCmdSetStencilCompareMask/WriteMask/Reference — and fragment discard end-to-end, with OpKill landing in mzJIT v0.28 so discard works in both interpreted and JIT-compiled shaders.
ECO-0030mzVolk mzVolk: lines, points, and honest fragments
Four releases (v0.30.0 → v0.31.1) keep filling in the API: vkCmdCopyImage, vkCmdUpdateBuffer and vkCmdFillBuffer, vkGetImageSubresourceLayout, line and point topologies (width/size 1), and dynamic descriptor offsets. One entry in the honest tradition: a commit titled "gl_FragCoord was silently broken" — found, fixed, and pinned by the pixel-regression suite instead of quietly patched.
ECO-0029mzVolk mzVolk: blending, completed
Three point releases (v0.29.1 → v0.29.3) close out output-merger correctness: colorWriteMask is honored, the full blend factor and blend op matrix is implemented with vkCmdSetBlendConstants, and the clear commands land — vkCmdClearColorImage, vkCmdClearDepthStencilImage, vkCmdClearAttachments. A pixel-regression manifest now pins the whole test suite. The backlog of remaining Vulkan feature gaps was audited and published in-repo — the honest list stays honest.
ECO-0028mzVolkmzJIT mzVolk: the aarch64 perf pass
Apple-silicon rasterization gets its own SIMD treatment (v0.28.1 → v0.28.2): NEON attribute interpolation and pixel packing in the scanline loop, and a batched fragment entry point in mzJIT v0.27 — one call into JIT-compiled code shades a whole run of fragments, measured at 69% less per-fragment cost in isolation. The x86_64 SSE lanes now have a proper arm64 counterpart.
ECO-0027mzVolkmzJIT mzVolk: staging copies, mip chains, query pools
Three releases (v0.26 → v0.28) make the texture path production-shaped: staging copies via vkCmdCopyBuffer and vkCmdCopyBufferToImage — the upload path real apps actually use — and full mip chains with textureLod sampling end-to-end, backed by OpImageSampleExplicitLod in mzJIT v0.26. Then more API surface: query pools and events join the synchronization toolbox.
ECO-0026mzJITmzVolk mzJIT: buffer layouts, decoded properly
Three releases (v0.23 → v0.25) close out layout correctness: std140 and std430 buffer layout decorations are honored, decorated buffer offsets get real JIT lowering — mixed layouts stay JIT-compiled instead of dropping to the interpreter — and push-constant member offsets work across both execution paths. Shaders now read buffers where the compiler actually put the data.
ECO-0025mzVolkmzJIT mzVolk: full sampler address modes
The texture story rounds out (mzVolk v0.25.0, mzJIT v0.22.0): sampler address modes are honored per axis — independent U/V modes, mirrored repeat, and clamp to border join repeat and clamp to edge. Texture sampling now behaves like the spec says it should at the edges, not just in the middle.
ECO-0024mzVolkmzJIT mzVolk: parallel rasterization
v0.24.0 splits the framebuffer into row bands rasterized across worker threads (MZV_THREADS), each band shading through its own cloned shader executor — mzJIT grew spirv_executor_copy_bindings so per-thread executors share compiled code without sharing state. The software rasterizer now scales with cores, not just SIMD lanes.
ECO-0023mzVolkmzJIT mzVolk: compute pipelines land
The second-to-last big honest-list item falls: vkCreateComputePipelines and vkCmdDispatch execute compute shaders on the CPU (v0.21 → v0.23), with storage-buffer writes, gl_GlobalInvocationID, dynamic-indexed SSBO arrays (out[gid] = f(gid) works), and workgroup local sizes honored from OpExecutionMode LocalSize. mzJIT carried the shader side across interpreter and JIT. Only multisampling remains on the list.
ECO-0022mzVolkmzJIT mzVolk: textures land
Samplers and combined image sampler descriptors arrive in mzVolk (v0.19 → v0.20.2), with OpImageSampleImplicitLod executing across mzJIT’s interpreter and JIT backends — then a perf pass killed dead sampled-image loads and memoized sampling binding lookups for +8% textured fps. Alongside: multi-binding vertex input with per-instance attribute rates, and OpPhi support, so optimizer-compiled shaders (glslc -O) now JIT instead of falling back.
ECO-0021mzVKI mzVKI: Metal surfaces and MoltenVK portability
mzVKI_CreateSurfaceMetal lands (VK_EXT_metal_surface), with VK_KHR_portability_enumeration set at instance creation and VK_KHR_portability_subset enabled at device creation when available. On Apple platforms the Metal surface extension set is selected automatically — the thin wrapper stays thin while MoltenVK becomes a first-class path.
ECO-0020mzOS2 mzOS2: the evening audit sweep
Seven numbered findings (#28–#34) worked through in one sitting: fd get/put refcounting with an open-leak fix, per-process locks for the fd table and thread list, ELF header/phdr/segment bounds checks, a cap on .ko section sizes to stop integer overflow, ext4 directory-name validation, and a framebuffer ioctl that wrote to an unvalidated user pointer. Kernel attack surface shrinks one finding at a time.
ECO-0019mzOS2 mzOS2: threads on all four architectures
The follow-through on ECO-0018, one hour later: multi-threaded userspace is complete on i386, x86_64, arm, and arm64 — the libc thread path now rides clone(CLONE_VM) on every architecture the kernel boots. The parity discipline holds: no feature is done until all four sheets say so.
ECO-0018mzOS2 mzOS2: userspace goes multi-threaded
thread_create lands in userspace, built over clone(CLONE_VM) on x86_64 — threads share an address space while the kernel tracks them per-process, with a new per-process lock guarding the fd table and thread list against concurrent create/exit. The other architectures follow the same path fork/clone parity took.
ECO-0017mzVolk mzVolk: thread safety and loud failures
The robustness section of the honest list gets its turn (v0.17.0 → v0.18.0): fixed-size tables now fail loudly instead of silently corrupting, a lifetime audit tightened object ownership, and queue execution is serialized behind a global mutex — concurrent vkQueueSubmit is safe. The README was rewritten to current reality, now with published numbers: ≈2400 fps for a gradient quad and ≈620 fps for a per-fragment UBO shader at 640×480 on an arm64 MacBook, with Rosetta x86_64 passing every shader test JIT-active.
ECO-0016mzVolkmzJIT mzVolk: strips, fans, and instanced draws
Two more limitations struck from the honest list: topology is no longer fixed to triangle lists (strips and fans rasterize), and instanceCount is no longer ignored — instanced draws execute with gl_InstanceIndex flowing through mzJIT as a builtin input. Underneath, mzJIT v0.15.0 reached backend parity: x86_64 matrix multiplication, full extended-instruction coverage on i386, and 3-operand extended instructions on arm32.
ECO-0015mzVolk mzVolk: IOSurface presentation on macOS
The macOS present path graduates from CGImage/CFData to an IOSurface pool (v0.14.0 → v0.15.1), alongside a fix for the x86_64 SIMD tail calling into a deleted fragment-shader path and Release-by-default builds without -ffast-math.
ECO-0014mzOS2 mzOS2: manifest-verified module loading
The dynamic driver path now verifies .ko integrity against a manifest before load — modules that do not match do not run. Combined with the bounds-checked loader, on-disk drivers are now both validated and verified before the kernel trusts a byte of them.
ECO-0013mzOS2 mzOS2: userspace parity on all four architectures
arm64 climbed the userspace ladder in four milestones: a paged kernel on the real long-descriptor MMU, EL0 entry with SVC dispatch, init running at EL0 with working syscalls, and finally fork()/clone() — full userspace parity with i386, x86_64, and arm. Alongside it: /proc introspection (cpuinfo, processes, stat), ext4 bounds hardening from superblock geometry down to directory entries, and an audit pass over fork, the scheduler, and address-space teardown.
ECO-0012mzJITmzVolk mzJIT: loops, uniforms, and a 70% aarch64 speedup
Six releases (v0.8.0 → v0.13.0): integer ops ride the float lanes so loops JIT-compile; control flow lowers on every backend — arm32, x86_64 (Rosetta-verified), i386; access-chain component loads/stores reach the JIT correctly; descriptor-backed uniform buffer loads; uniform-resident mat4 transforms on all paths; and aarch64 direct-binding loads/stores that resolve I/O at compile time, worth ~+70% FPS in the uniform-buffer benchmark.
ECO-0011mzVolk mzVolk: the honest list gets shorter
Ten releases (v0.4.0 → v0.13.1) cleared the entire rasterizer section of the known-limitations list, item by item: depth testing, blending, scissor test and face culling, perspective-correct interpolation, indexed draws with pipeline-driven vertex input, descriptor sets with a uniform-buffer path, synchronization honesty plus properties2, and — quoting the commit — "the last honest-list rasterizer item": near-plane clipping. Then a perf pass: per-triangle binding resolution, inline fragment dispatch, and a 1:1 blit fast path.
ECO-0010mzJITmzVolk mzJIT: aarch64 NEON backend and real control flow
Five releases in one sweep (v0.3.0 → v0.7.0): a real NEON JIT backend for aarch64 with safe executable-memory handling, multi-block control flow with branches across the IR builder, interpreter, and aarch64 backend, comparisons/select/logical ops, the full GLSL.std.450 extended-instruction map, and an IR builder that now fails closed on unsupported SPIR-V.
ECO-0009mzVolk mzVolk lands on macOS
Full build and WSI support on macOS arm64: VK_MVK_macos_surface entry points, presentation via a CGImage-backed NSView, and the ICD manifest learning about .dylib. Every platform in the support table now builds and presents.
ECO-0008mzOS2 mzOS2: the fourth architecture boots
arm64 runs the full kernel lifecycle, completing the four-architecture set. Alongside it: the full dynamic driver path — on-disk .ko modules relocated at runtime — SMP per-CPU-state fixes, and a module loader hardened with bounds checks on every on-disk offset and size before any of it is trusted.
ECO-0007 microz.us erected
The drawing set goes public. microz.us now documents the full mz stack — from mzBIOS at power-on to zui3d putting pixels on screen — while the repositories themselves finish their private alpha. Watch this log for change orders as sheets open up.
ECO-0006mzVolkmzJIT mzVolk: SSE fragment lanes land on x86_64
The scanline rasterizer now shades four pixel lanes at a time through JIT-compiled fragment shaders on x86_64. A pass-through detector skips shader invocation entirely for trivially-interpolating fragment shaders. Scalar loop remains the fallback on other architectures.
ECO-0005mzJIT mzJIT: helper-call lowering for arm32
arm32 gains partial JIT support — operations without a native lowering are compiled to helper calls instead of dropping the whole shader back to the interpreter. aarch64 native backend is drafted and planned next.
ECO-0004mzOS2 mzOS2: macOS cross-compilation without PATH surgery
x86 targets now cross-compile from macOS using Homebrew LLVM with explicit per-architecture target triples, linked with lld. The build finds keg-only LLVM on its own; -m32 ambiguity (which means 32-bit ARM on Apple toolchains) is resolved by the explicit triple.
ECO-0003zui3d zui3d: text layer with cursors and scroll
TextLayer joins the layer hierarchy: bitmap fonts with multi-line support, cursor handling, and scrolling. The omega_layout test exercises it end-to-end with zero dynamic allocation, and frames capture to PPM for pixel verification.
ECO-0002mzDTBmzOS2 mzDTB: freestanding parser proven in-kernel
The DTB parser library now runs libc-free in bare-metal environments. mzOS2 uses it to extract memory@ nodes at boot; gen_dtb output is wired into the CMake build so MZ_MEM and MZ_MEM_BASE flow straight into the generated tree.
ECO-0001mzBoot mzBoot: complete disk toolchain, zero external tools
partmz, mk.fat.fs, mk.ext4.fs, and mzbootup together prepare a bootable GPT disk image — partitioning, filesystems, and bootloader install — without parted, mkfs, or grub-install. Boot menu reads an external mzboot.cfg with timeout, default entry, kernel, initrd, and args.