Last updated: 2026-06-12

Decode Planning

Graph

All API Sections

Shape-static ZINC_RT IR graph builder.

Graphs contain logical buffers and opcode nodes before any tier lowers them into packets, shaders, or pure Zig calls.

6 exports 7 methods src/zinc_rt/ir/graph.zig

6 exports shown

constant

BufferId

#
pub const BufferId = u32

Dense index identifying a logical buffer inside a Graph.

Buffer ids are assigned sequentially by `Graph.addBuffer` starting at 0.

src/zinc_rt/ir/graph.zig:10

constant

NodeId

#
pub const NodeId = u32

Dense index identifying a node (opcode invocation) inside a Graph.

Node ids are assigned in insertion order by `Graph.addNode`.

src/zinc_rt/ir/graph.zig:14

constant

max_bindings

#
pub const max_bindings = 8

Maximum number of input or output buffers a single node may bind.

Picked to keep `BindingList` inline-storable without heap allocation.

src/zinc_rt/ir/graph.zig:18

struct

BindingList

#
pub const BindingList = struct

Fixed-capacity list of buffer ids bound to one side of a node.

Stores up to `max_bindings` entries inline so a `Node` stays POD and trivially copyable through the planner.

src/zinc_rt/ir/graph.zig:23

Methods

2

method

BindingList.init

#
pub fn init(values: []const BufferId) !BindingList

Build a binding list from a slice of buffer ids.

Parameters
values
Buffer ids to copy; must contain at most `max_bindings`.
Returns

A fully populated `BindingList`.

Notes

Returns `error.TooManyBindings` when `values.len > max_bindings`.

src/zinc_rt/ir/graph.zig:31

method

BindingList.slice

#
pub fn slice(self: *const BindingList) []const BufferId

View the populated prefix of the binding list as a slice.

Returns

The first `self.len` buffer ids, in insertion order.

src/zinc_rt/ir/graph.zig:43

struct

Node

#
pub const Node = struct

Single opcode invocation in the graph.

Each node references its inputs and outputs by `BufferId`; the opcode itself decides the semantics of those bindings (see `op.Info`).

src/zinc_rt/ir/graph.zig:51

struct

Graph

#
pub const Graph = struct

Shape-static ZINC_RT IR graph.

A graph is a flat list of opcode nodes plus a buffer count; lowering passes turn this representation into T-CPU packets, PM4 indirect buffers, or Metal/Vulkan dispatches without mutating the graph itself.

src/zinc_rt/ir/graph.zig:61

Methods

5

method

Graph.init

#
pub fn init(allocator: std.mem.Allocator) Graph

Create an empty graph backed by `allocator`.

tracked as a plain counter and require no per-buffer heap allocation.

Parameters
allocator
Retained for growing the node array; buffer ids are
Returns

A zero-buffer, zero-node graph ready for `addBuffer`/`addNode`.

src/zinc_rt/ir/graph.zig:70

method

Graph.deinit

#
pub fn deinit(self: *Graph) void

Release the node array and poison the graph value.

Notes

Buffer ids are integers and require no per-buffer release.

src/zinc_rt/ir/graph.zig:76

method

Graph.addBuffer

#
pub fn addBuffer(self: *Graph) BufferId

Reserve a new logical buffer and return its id.

Returns

The freshly allocated `BufferId`, equal to the previous buffer count.

src/zinc_rt/ir/graph.zig:83

method

Graph.addNode

#
pub fn addNode( self: *Graph, opcode: op.Opcode, inputs: []const BufferId, outputs: []const BufferId, ) !NodeId

Append an opcode node with the given input and output bindings.

Parameters
opcode
Opcode this node executes.
inputs
Buffer ids consumed by the node, in opcode-defined order.
outputs
Buffer ids produced by the node, in opcode-defined order.
Returns

The `NodeId` of the newly appended node.

Notes

Fails with `error.TooManyBindings` when either slice exceeds `max_bindings`.

src/zinc_rt/ir/graph.zig:95

method

Graph.verify

#
pub fn verify(self: *const Graph) !void

Structural sanity check: graph is non-empty, all bindings resolve, and every non-barrier/stream_out node produces at least one output.

`error.UnknownOutputBuffer`, or `error.NodeWithoutOutput` on failure.

Returns

`error.EmptyGraph`, `error.UnknownInputBuffer`,

src/zinc_rt/ir/graph.zig:114