/** Native buffer and storage-image compute. Kernels execute on a real WebGPU device. */ export type ComputeBindingKind = "storage" | "read-only-storage" | "uniform" | "storage-image" | "sampled-texture"; /** Tight native rows; r8uint uses one exact uint32 and rg11b10ufloat three float32 values per texel. */ export interface ComputeImage { format: "r8uint" | "r32uint" | "r32float" | "r16float" | "rg16float" | "rg11b10ufloat" | "rgba16float" | "rgba32float" | "rgba8unorm"; width: number; height: number; /** Layer-major tight rows. Omitted fields retain the original 2D wire format. */ layers?: number; dimension?: "2d" | "2d-array" | "cube" | "3d"; access: "read-only" | "write-only" | "read-write"; /** Sampled snapshots are mip-major, then layer-major tight rows. Each gets * a separate sampler binding after all payload bindings, in payload order. */ mipLevelCount?: number; sampler?: { addressModeU: "clamp-to-edge" | "repeat" | "mirror-repeat"; addressModeV: "clamp-to-edge" | "repeat" | "mirror-repeat"; addressModeW: "clamp-to-edge" | "repeat" | "mirror-repeat"; magFilter: "nearest" | "linear"; minFilter: "nearest" | "linear"; mipmapFilter: "nearest" | "linear"; lodMinClamp: number; lodMaxClamp: number; }; } export interface ComputeStep { entryPoint?: string; groups?: [number, number, number]; indirect?: { buffer: number; offset: number }; constants?: Record; bindingTypes?: ComputeBindingKind[]; } export interface ComputeJob { language: "wgsl" | "glsl"; source: string; entryPoint: string; groups: [number, number, number]; kinds: ComputeBindingKind[]; steps: ComputeStep[] | null; images?: Record; /** Native allocation lifetime tokens, never WASM addresses. Null entries are transient. */ owners?: (string | null)[]; /** Native API arguments at byte offset zero, snapshotted after COMMAND visibility. * This is an INDIRECT-only allocation, never an extra shader binding. */ nativeIndirect?: { owner: string; arguments: [number, number, number] }; } export interface ComputeRelease { releaseOwners: string[] } /** Effective limits of the device used by this broker, capped by transport budgets. * Keep the word order stable for the shared-memory capability reply. */ export const COMPUTE_CAPABILITY_FIELDS = [ "storageBuffers", "storageBufferBytes", "storageBufferAlignment", "workgroups", "workgroupSizeX", "workgroupSizeY", "workgroupSizeZ", "uniformBufferBytes", ] as const; export type ComputeCapabilities = Record; export interface ComputeCapabilitiesRequest { capabilities: true; control: SharedArrayBuffer; error: SharedArrayBuffer; data: SharedArrayBuffer; } export interface ComputeRequest { job: ComputeJob; sizes: number[]; /** Control[0]: 0 pending, 1 committed, -1 error, 2 abandoned. */ control: SharedArrayBuffer; error: SharedArrayBuffer; data: SharedArrayBuffer; } export const COMPUTE_LIMITS = { sourceBytes: 1024 * 1024, buffers: 32, bufferBytes: 64 * 1024 * 1024, totalBytes: 256 * 1024 * 1024, steps: 64, errorBytes: 4096, } as const;