Four clean layers
Trident decides what to show, C kernels compute, Glint IR shades, and the backend draws. No layer does another layer's job.
- Trident scene what to show
- C compute generic transforms
- Glint IR render-only program
- Backend device output
2027 · MerTek technology
Core system / System overview
One scene, from a watch face to a headset
Thalassa is MTK's renderer and scene engine, written in C. A Trident program declares one scene, and Thalassa draws it within each device's screen, memory and graphics limits. Every graphics backend is checked against the same software reference image.
Worked example
A water utility sends a two-person crew to isolate a leaking valve at Pump Station 7. The crew lead wears a watch and carries a rugged tablet. The control room follows on a workstation, and a trainee walks the same station in a headset. All four must show the pump, its valve and a red keep-out zone around the open valve.
The program declares the scene once, as typed rows: entities, placements, geometry, materials, draws and a camera. Entity 11 is the pump, 12 is its valve and 13 is the keep-out zone. t.gfx.encodeScene turns the rows into one canonical scene document. A tap on the tablet and a highlight in the headset name the same valve.
chest stationScene() {
f64[4] steel = [0.55, 0.6, 0.65, 1.0]
f64[4] valveBlue = [0.15, 0.35, 0.9, 1.0]
f64[4] warningRed = [0.9, 0.12, 0.1, 1.0]
chest scene = emptyDeclaration()
scene.entities = [t.gfx.entity(11, 0), t.gfx.entity(12, 11), t.gfx.entity(13, 0)]
scene.transforms = [t.gfx.transform(11, at(0.0, 0.0, 0.4), null),
t.gfx.transform(12, at(0.5, 0.0, 0.25), null),
t.gfx.transform(13, at(0.6, 0.0, 0.6), null)]
scene.geometries = [t.gfx.geometry(1, quad())]
scene.materials = [t.gfx.material(11, solid(steel)),
t.gfx.material(12, solid(valveBlue)), t.gfx.material(13, solid(warningRed))]
chest state = drawState()
scene.draws = [t.gfx.draw(13, 13, 1, 13, state),
t.gfx.draw(11, 11, 1, 11, state), t.gfx.draw(12, 12, 1, 12, state)]
scene.cameras = [planCamera()]
text? selected = "plan"
scene.selectedCamera = selected
return t.gfx.encodeScene(scene)
}Each device gets a mesh level from its screen size, and the program owns the ladder. The watch face is 396 by 484 pixels, so it takes level 3. The tablet takes level 1, and the workstation and headset take level 0. A lower rung removes triangles; it never changes the valve, its color or its ID.
# The larger screen side picks the mesh level. The ladder is policy.
i32 meshLevelFor(f64 width, f64 height) {
f64[] minPx = [1600.0, 1000.0, 600.0, 0.0]
i32[] levels = [0, 1, 2, 3]
return t.media.targetMeshLevel(width, height, minPx, levels)
}
i32[] deviceLevels() {
i32 watch = meshLevelFor(396.0, 484.0) # 3
i32 tablet = meshLevelFor(1280.0, 800.0) # 1
i32 workstation = meshLevelFor(2560.0, 1440.0) # 0
i32 headset = meshLevelFor(1832.0, 1920.0) # 0
return [watch, tablet, workstation, headset]
}Before any frame, Thalassa runs capability admission. It reads each need from the render program itself and checks it against the backend's measured features and limits. The workstation also asks for temporal reconstruction at the 1.5x upscale rung. That request must name every resource it reads, and a missing one refuses by name.
chest temporalRequest() {
chest config = t.recon.configNew("rtGI", 7)
config = t.recon.declareTier(config, "temporal")
config = t.recon.declareRatio(config, "1.5x")
config = t.recon.declareHistorySource(config, "colorHistory")
config = t.recon.declareDepthSources(config, "sceneDepth", "prevDepth")
config = t.recon.declareOnResize(config, "rescale")
config = t.recon.declareOracleReadout(config, "rmse:0.014")
return t.recon.resolveRequest(config)
}
text admission() {
chest resolved = temporalRequest()
bool ok = resolved.ok
text? reason = resolved.reason
if (ok || reason == null) { return "admitted" }
text named = reason
return "refused: " + named # "no declared velocity source"
}Thalassa compiles the scene into a Reef render program. Every shader in it is checked Glint IR. The backends lower that IR to WGSL for WebGPU, HLSL for Direct3D 11, SPIR-V for Vulkan and MSL for Metal. The Soft renderer runs the same IR on the CPU, and each backend's pixels are compared with its pixels.
# One frame on the Soft renderer, and the digests it names.
text frameReport(chest result) {
u32 status = result.status
chest? maybeFacts = result.facts
if (status != 0 || maybeFacts == null) { return "no frame" }
chest facts = maybeFacts
sha256 programId = facts.programDigest
sha256 shaderId = facts.moduleDigest
u64 generation = facts.sceneGeneration
return "generation " + text(generation) + ", program " + text(programId) +
", shader " + text(shaderId)
}
text main(text[] argv) {
chest job = t.chest.decode(t.buffer.hexDecode(argv[1]))
return frameReport(t.render.offline.unretainedSingleFrame(job))
}Input reaches the program the same way on every device. The host turns a key press, a tap or a controller button into one ordered, typed event per call. The program folds that event into its next state, and the next frame draws the change on all four screens.
const chest keys = {
u32 space = 44 # USB HID usage
u32 down = 1 # key phase
}
chest event(chest input) {
u64 generation = input.generation
chest S = input.state
chest e = input.event
text kind = e.kind
if (kind == "inputKey") {
u32 phase = e.phase
u32 usage = e.usage
u32 downPhase = keys.down
u32 spaceKey = keys.space
if (phase == downPhase && usage == spaceKey) {
S.valveIsolated = true
}
}
return completed(generation, S)
}The watch drew the station at mesh level 3, the tablet at level 1, and the workstation and headset at level 0. The valve kept entity 12 and the same blue, inside the same red zone, on all four. Admission refused the first reconstruction request by name, "no declared velocity source", before a single frame drew.
System diagram
The scene keeps stable object IDs and safety colors. Capability policy removes detail that a smaller device cannot support.
Inside the system
Follow the data, decisions, and access boundaries. Each diagram explains a concept used by applications.
Trident decides what to show, C kernels compute, Glint IR shades, and the backend draws. No layer does another layer's job.
One retained scene becomes one verified Reef program that every backend executes.
One checked module runs on the Soft renderer and lowers to WGSL, HLSL, SPIR-V and MSL.
A backend's pixels pass when they stay within the tolerance declared for the capture against the Soft renderer's pixels.
A missing feature refuses by name. A measured limit can only select a lower rung the scene declared.
A raw device sample becomes one ordered, typed event before the program sees it.
Key parts
These are the main boundaries, inputs, outputs, and failure rules. The examples show a specific use of each part.
The program states the scene as typed rows, and t.gfx.encodeScene turns them into one canonical scene document with its own digest. Every device renders from that document. Device facts never enter it.
The valve is entity 12, a child of the pump, with a blue solid material on every device.
Thalassa reads each need from the render program's own graph and checks it against the backend's measured facts before allocating anything. A missing feature refuses by name; a varying limit can only select a lower rung the scene declared.
A backend that cannot sample a texture by level range refuses the program at admission instead of reading the wrong level.
The Soft renderer runs checked Glint IR on the CPU with fixed evaluation order and no driver math. Each backend is compared with it under a tolerance declared per captured resource before the run. Integer lanes must match exactly.
A capture declared at one code value per color channel fails on a device that rounds a gradient two codes off.
Code
Each example is short and complete enough to read on its own. Hover a dotted word for its definition.
A scene carries every camera it offers, each with an id. The tablet shows the plan camera; the workstation shows this one. The field of view is in radians and the clip planes are in meters.
chest valveCamera(dvec3 eye, dvec3 valve) {
chest camera = t.camera.perspective(eye, valve, (0.0, 1.0, 0.0),
1.2, 1.78, 0.05, 200.0, null)
text? cameraId = "valve"
camera.id = cameraId
return camera
}
The binding table is a plain value the program owns. The keyboard, the headset controller and any menu button resolve to named actions. An unbound input resolves to null.
chest[] stationBindings() {
chest[] bindings = []
bindings = t.input.action.declare(bindings, "station7", "isolateValve",
"keyboard", "space", 0)
bindings = t.input.action.declare(bindings, "station7", "acknowledge",
"gamepad", "south", -1)
bindings = t.input.action.declare(bindings, "station7", "openMenu",
"", "menu", -1)
return bindings
}
text actionOf(chest? answer) {
if (answer == null) { return "none" }
chest row = answer
text action = row.action
return action
}
A UI surface states the appearance it paints under. Thalassa resolves its look theme for that appearance. A theme missing a role refuses at its first commit, not on the night shift.
chest statusPanel() {
return t.gfx.uiSurface({
id = 1,
logicalWidth = 1280,
logicalHeight = 800,
placement = "screen",
appearance = "dark",
placementMap = t.draft.parse(
"dmat2x3 viewportFromLogical = (1,0,0,1,0,0), f64 depth = 0.5")
})
}
A scene clock belongs to one scene instance and advances in whole ticks. Halving its rate slows the headset's walk-through without touching the session clock the crew's devices run on.
chest slowWalkthrough(u64 walkthrough) {
t.scene.clock.setRate(walkthrough, 1//2)
chest reading = t.scene.clock.reading(walkthrough)
u64 tick = reading.tick
duration sceneTime = reading.time
t.log.info("tick " + text(tick) + " at " + text(sceneTime))
return reading
}
void holdForQuestion(u64 walkthrough) {
t.scene.clock.pause(walkthrough)
}
The ring is one fragment module. fwidth keeps the edge at least one pixel wide at any zoom, so the watch and the wall display draw the same crisp boundary.
uniform<vec4,slot=0> zone # center x, center y, radius, edge width
uniform<vec4,slot=1> warning
vec4 fragment(vec4 world) {
const vec4 zoneValue = zone
const vec4 paint = warning
const vec2 p = world.xy
const f32 d = length(p - zoneValue.xy) - zoneValue.z
const f32 w = max(zoneValue.w, fwidth(d))
const f32 ring = 1.0 - smoothstep(0.0, w, abs(d))
return vec4(paint.x, paint.y, paint.z, paint.w * ring)
}
Uses
Review questions
Which devices must show the same scene, and at what screen sizes
Which objects and colors must survive on the smallest device
Which lower rungs each scene may fall to, and which features must refuse