import { trackCollectable } from "./debug.js"; import { objectId } from "./shared.js"; import type { GpuContext } from "./types.js"; /** * Attachment formats a bundle is recorded against — a plain * GPURenderBundleEncoderDescriptor. Use `ctx.format` in `colorFormats` (and * `ctx.depthStencilFormat`) when the bundle targets the canvas. */ export type RenderBundleFormats = GPURenderBundleEncoderDescriptor; /** * Record a reusable render bundle. The callback receives a * GPURenderBundleEncoder supporting setPipeline/setBindGroup/draw calls; * executing the finished bundle replays them with near-zero CPU cost. * * Use `ctx.format`/`ctx.depthStencilFormat` when the bundle targets the canvas. * * ```js * const bundle = gpu.createRenderBundle( * ctx, * { * colorFormats: [ctx.format], * depthStencilFormat: ctx.depthStencilFormat, * }, * (encoder) => { * encoder.setPipeline(pipeline); * // ... * encoder.drawIndexed(count); * }, * ); * // later, inside a matching render pass: * pass.executeBundles([bundle]); * ``` */ export function createRenderBundle( ctx: GpuContext, formats: RenderBundleFormats, record: (encoder: GPURenderBundleEncoder) => void, ): GPURenderBundle { const label = formats.label ?? "pex-gpu bundle"; const encoder = ctx.device.createRenderBundleEncoder({ ...formats, sampleCount: formats.sampleCount ?? 1, label, }); record(encoder); const bundle = encoder.finish({ label }); trackCollectable(ctx.device, "renderBundles", bundle, { id: objectId(bundle), label, bytes: 0, }); return bundle; }