Part of #776 — SOLID architecture debt umbrella.
Phase: P0 · Finding: C3
Problem
world-runtime (highest tier) imports the concrete Vulkan backend and performs an unsafe downcast of the opaque RHI pointer, then issues 27 raw c.vk* calls (vkCmdDispatch, vkCmdPipelineBarrier, vkWaitForFences, …). The RHI abstraction is bypassed entirely for GPU meshing. Same pattern in lpv_backend.zig ( candidly documented as intentional).
Evidence
modules/world-runtime/src/gpu_mesher.zig:9-11,89:
const graphics = @import("engine-graphics");
const VulkanContext = graphics.VulkanContext;
...
const vk_ctx: *VulkanContext = @ptrCast(@alignCast(rhi.ptr));
// then: c.vkCmdDispatch(cmd, CHUNK_Y, 1, 1); etc.
modules/engine-graphics/src/lpv_backend.zig:6-15 carries the same @ptrCast(@alignCast(rhi.ptr)) downcast.
Fix
- Add a compute facet to
RHI.VTable: createComputePipeline, bindComputePipeline, dispatch, pushConstants, fillBuffer, pipelineBarrier.
- Implement the facet in the Vulkan backend (port the existing raw calls).
- Rewrite
gpu_mesher.zig and lpv_backend.zig to consume the abstraction.
- Remove both
@ptrCast(@alignCast(rhi.ptr)) downcasts and the engine-graphics import from world-runtime.
Verification
nix develop --command zig build test (includes shader validation)
- If rendering-touching: capture headless screenshot baseline before/after (
-Dskip-present)
- If behavior-preserving refactor: golden-output test must stay green
Constraints
- Small reviewable PR targeting
dev; conventional commit (refactor: / feat:)
- Preserve current behavior unless this issue explicitly changes it
- Keep worker-thread RHI isolation intact (no RHI calls off main thread)
Notes
Must land before C2 — C2's drawSky/drawWater will share this compute/dispatch infrastructure. Capture a headless screenshot baseline before and after (per #776 Key risks). Keep worker-thread RHI isolation intact: compute dispatch stays on the main thread.
Tracking: #776
Part of #776 — SOLID architecture debt umbrella.
Phase: P0 · Finding: C3
Problem
world-runtime(highest tier) imports the concrete Vulkan backend and performs an unsafe downcast of the opaque RHI pointer, then issues 27 rawc.vk*calls (vkCmdDispatch,vkCmdPipelineBarrier,vkWaitForFences, …). The RHI abstraction is bypassed entirely for GPU meshing. Same pattern inlpv_backend.zig( candidly documented as intentional).Evidence
modules/world-runtime/src/gpu_mesher.zig:9-11,89:modules/engine-graphics/src/lpv_backend.zig:6-15carries the same@ptrCast(@alignCast(rhi.ptr))downcast.Fix
RHI.VTable:createComputePipeline,bindComputePipeline,dispatch,pushConstants,fillBuffer,pipelineBarrier.gpu_mesher.zigandlpv_backend.zigto consume the abstraction.@ptrCast(@alignCast(rhi.ptr))downcasts and theengine-graphicsimport fromworld-runtime.Verification
nix develop --command zig build test(includes shader validation)-Dskip-present)Constraints
dev; conventional commit (refactor:/feat:)Notes
Must land before C2 — C2's
drawSky/drawWaterwill share this compute/dispatch infrastructure. Capture a headless screenshot baseline before and after (per #776 Key risks). Keep worker-thread RHI isolation intact: compute dispatch stays on the main thread.Tracking: #776