The render hardware interface

A backend-abstract GPU service

The render hardware interface is Platform's GPU service: a backend-abstract API for creating GPU resources and submitting draw work, with Metal behind it today. It is raster- and draw-focused, the surface Kinogaki UI's 2-D canvas is built on, and it holds Metal entirely behind the interface so the rest of the stack talks to the RHI alone.

#include "kinogaki/platform/Rhi.h"
using namespace kinogaki::platform::rhi;

auto device   = Device::create(Backend::Metal);     // or Device::createHeadless()
auto buffer   = device->newBuffer(vertices, bytes);
auto texture  = device->newRenderTexture(w, h, PixelFormat::RGBA8Unorm);
auto shader   = device->newShader(mslSource);
auto pipeline = device->newPipeline({shader, /* vertex layout, blend … */});

The resource set

The interface covers exactly what a 2-D drawer and a viewport need:

Pipelining, the right way

Responsiveness depends on letting the CPU run ahead of the GPU each frame. The RHI commits work and keeps going during interaction, and blocks at just two boundaries: an explicit readback and present.

This pattern removed a per-frame CPU↔GPU stall that used to make panning lag: the CPU blocks only at the two boundaries that need it. The per-region offscreen buffers in the UI toolkit are RHI render textures used exactly this way: render a panel once, then re-composite its texture.

Headless = testable

Device::createHeadless() gives a windowless GPU device, so rendering is covered by automated tests: render an offscreen triangle, read it back, assert on the pixels, all on a headless machine. That is why the drawing stack ships with real GPU tests that verify exact pixels. The RHI stays separate from any compute-focused render engine: a tracer creates its own device abstraction sharing the same MTLDevice, so two abstractions ride one piece of hardware. The other cross-cutting infrastructure Platform carries is the buses.