feat: Introduce Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs - #2764
feat: Introduce Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs#2764reczkok wants to merge 8 commits into
Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs#2764Conversation
1100e5e to
657340d
Compare
…to it in call order
657340d to
2a31791
Compare
|
pkg.pr.new packages benchmark commit |
Resolution Time Benchmark---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.77, 1.53, 3.53, 5.68, 6.39, 10.22, 18.58, 20.84]
line [0.79, 1.65, 3.11, 4.98, 6.32, 9.62, 18.51, 19.44]
line [0.80, 1.59, 3.37, 5.77, 6.39, 10.62, 17.91, 21.15]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.27, 0.47, 0.61, 0.67, 0.88, 0.92, 1.13, 1.25]
line [0.27, 0.43, 0.57, 0.73, 0.95, 1.03, 1.21, 1.35]
line [0.27, 0.45, 0.60, 0.75, 1.07, 1.05, 1.27, 1.36]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.72, 1.78, 3.55, 5.64, 10.31, 21.76, 45.72, 94.53]
line [0.80, 1.74, 3.07, 5.45, 10.05, 21.51, 46.58, 92.97]
line [0.79, 1.74, 3.45, 5.48, 10.66, 22.81, 46.86, 95.90]
|
Bundle size comparison (
|
| 🟢 Decreased | ➖ Unchanged | 🔴 Increased (max 1.41%) | ❔ Unknown |
|---|---|---|---|
| 0 | 301 | 21 | 0 |
import * as ... in PR vs import * as ... in target (did bundle size increase?):
| Test | tsdown |
|---|---|
| STATIC_tgpu.ts | 271.17 kB ( |
| tgpu_fn.ts | 271.17 kB ( |
| tgpu_init.ts | 271.17 kB ( |
| tgpu_lazy.ts | 271.17 kB ( |
| tgpu_slot.ts | 271.17 kB ( |
| tgpu_const.ts | 271.17 kB ( |
| tgpu_unroll.ts | 271.18 kB ( |
| tgpu_resolve.ts | 271.18 kB ( |
| tgpu_accessor.ts | 271.18 kB ( |
| tgpu_comptime.ts | 271.18 kB ( |
| tgpu_vertexFn.ts | 271.18 kB ( |
| tgpu_computeFn.ts | 271.18 kB ( |
| tgpu_fragmentFn.ts | 271.18 kB ( |
| tgpu_privateVar.ts | 271.18 kB ( |
| tgpu_vertexLayout.ts | 271.18 kB ( |
| tgpu_workgroupVar.ts | 271.18 kB ( |
| tgpu_initFromDevice.ts | 271.18 kB ( |
| tgpu_bindGroupLayout.ts | 271.18 kB ( |
| tgpu_mutableAccessor.ts | 271.18 kB ( |
| tgpu_resolveWithContext.ts | 271.19 kB ( |
| STATIC_allImports.ts | 296.93 kB ( |
import { ... } in PR vs import * as ... in PR (is the library tree-Shakeable?):
| Test | tsdown |
|---|---|
| tgpu_init.ts | 262.66 kB ( |
| tgpu_initFromDevice.ts | 262.15 kB ( |
| tgpu_resolve.ts | 164.72 kB ( |
| tgpu_resolveWithContext.ts | 164.65 kB ( |
| tgpu_bindGroupLayout.ts | 68.97 kB ( |
| tgpu_mutableAccessor.ts | 65.97 kB ( |
| tgpu_accessor.ts | 65.96 kB ( |
| tgpu_privateVar.ts | 65.31 kB ( |
| tgpu_workgroupVar.ts | 65.30 kB ( |
| tgpu_const.ts | 64.55 kB ( |
| tgpu_fn.ts | 38.14 kB ( |
| tgpu_fragmentFn.ts | 38.14 kB ( |
| tgpu_vertexFn.ts | 37.96 kB ( |
| tgpu_computeFn.ts | 37.66 kB ( |
| tgpu_vertexLayout.ts | 26.79 kB ( |
| tgpu_comptime.ts | 14.48 kB ( |
| tgpu_unroll.ts | 1.66 kB ( |
| tgpu_slot.ts | 1.54 kB ( |
| tgpu_lazy.ts | 1.19 kB ( |
If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.
Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs
There was a problem hiding this comment.
Pull request overview
This PR replaces the old callback-based experimental pass APIs with typed command encoder/pass abstractions (TgpuCommandEncoder, TgpuRenderPass, TgpuComputePass) to support batching, better state management, and deferred log/timestamp processing across submissions.
Changes:
- Introduces typed command encoders/passes and render bundle encoders, and rewires pipelines to target typed passes/encoders (or adopted raw WebGPU objects).
- Centralizes draw/dispatch state tracking (deduplication, “raw access disables dedup”, executeBundles reset behavior), and defers shader-log draining + timestamp resolve to encoder submission.
- Updates tests and docs to the new APIs; upgrades
@webgpu/typescatalog version.
Reviewed changes
Copilot reviewed 33 out of 34 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pnpm-workspace.yaml | Bumps @webgpu/types catalog version. |
| pnpm-lock.yaml | Lockfile updates for @webgpu/types@0.1.71. |
| packages/typegpu/tests/tgsl/shellless.test.ts | Adds regression test for mixed void/value return type detection. |
| packages/typegpu/tests/root.test.ts | Migrates render-pass tests to createCommandEncoder/typed pass flow. |
| packages/typegpu/tests/renderPipeline.test.ts | Updates error messaging + adds new behavior tests for pass defaults and bundle-pass binding. |
| packages/typegpu/tests/guardedComputePipeline.test.ts | Adds batching safety tests for guarded dispatch sizing. |
| packages/typegpu/tests/computePipeline.test.ts | Adds tests for log draining, timestamp deferral, and raw-encoder warnings. |
| packages/typegpu/tests/commandEncoder.test.ts | New comprehensive test suite for typed command encoder/pass state behavior. |
| packages/typegpu/src/unwrapper.ts | Extends unwrap overloads to include typed command encoder and passes. |
| packages/typegpu/src/tgsl/wgslGenerator.ts | Reports void return types consistently for bare return; to enable mixed-return detection. |
| packages/typegpu/src/tgsl/consoleLog/types.ts | Clarifies log-count limit semantics across encoder-batched workloads. |
| packages/typegpu/src/shared/warnOnce.ts | Adds shared warnOnce helper for deduplicated warnings. |
| packages/typegpu/src/indexNamedExports.ts | Exposes new command encoder/pass-related types from the public entrypoint. |
| packages/typegpu/src/core/texture/texture.ts | Tracks view format/aspect in internals for attachment-default inference. |
| packages/typegpu/src/core/root/rootTypes.ts | Replaces old callback-based pass APIs with typed encoder/pass API definitions. |
| packages/typegpu/src/core/root/init.ts | Implements createCommandEncoder/createRenderBundleEncoder; updates unwrap logic; adds guarded-dispatch tracking hooks. |
| packages/typegpu/src/core/pipeline/typeGuards.ts | Adds TypeGPU command/pass guards and strengthens raw WebGPU encoder/pass detection. |
| packages/typegpu/src/core/pipeline/timeable.ts | Defers timestamp resolution/callback invocation to encoder submission; dedupes resolve + warns on repeated timed executions. |
| packages/typegpu/src/core/pipeline/renderPipeline.ts | Refactors draw execution to use typed passes/encoders and shared draw-state machinery. |
| packages/typegpu/src/core/pipeline/drawState.ts | New shared render/compute state tracking + log/timestamp deferral + raw-surface warnings. |
| packages/typegpu/src/core/pipeline/connectAttachmentToShader.ts | Treats void fragment outputs as “no color attachments”. |
| packages/typegpu/src/core/pipeline/computePipeline.ts | Refactors dispatch execution to use typed passes/encoders and shared draw-state machinery. |
| packages/typegpu/src/core/pipeline/applyPipelineState.ts | Removes old “apply pipeline state” helper (superseded by drawState.ts). |
| packages/typegpu/src/core/commandEncoder/renderPass.ts | New typed render pass + render bundle encoder implementations, including attachment normalization/defaults. |
| packages/typegpu/src/core/commandEncoder/computePass.ts | New typed compute pass implementation. |
| packages/typegpu/src/core/commandEncoder/commandEncoder.ts | New typed command encoder implementation with submit/finish hooks. |
| packages/typegpu/src/core/commandEncoder/attachments.ts | Shared attachment types + unwrapping helpers for typed pass descriptors. |
| packages/typegpu-testing-utility/src/extendedIt.ts | Adjusts test harness to mock createRenderBundleEncoder and expose bundle encoder fixture earlier. |
| packages/typegpu-gl/src/tgpuRootWebGL.ts | Updates WebGL fallback surface for the renamed bundle encoder API (but currently misses createCommandEncoder). |
| apps/typegpu-docs/src/examples/rendering/simple-shadow/index.ts | Migrates example to typed command encoder/passes. |
| apps/typegpu-docs/src/examples/rendering/render-bundles/index.ts | Migrates bundle recording and per-frame render pass to new APIs. |
| apps/typegpu-docs/src/examples/rendering/render-bundles-with/index.ts | Migrates example to typed command encoder submission. |
| apps/typegpu-docs/src/content/docs/apis/pipelines.mdx | Rewrites docs section to describe command encoders/passes and new execution modes. |
| apps/typegpu-docs/src/content/docs/advanced/timestamp-queries.mdx | Documents performance callbacks behavior with typed command encoders vs shared passes. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| createRenderBundleEncoder(): never { | ||
| throw new WebGLFallbackUnsupportedError('createRenderBundleEncoder'); | ||
| } |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — introduces TgpuCommandEncoder, TgpuRenderPass, TgpuComputePass, and TgpuRenderBundleEncoder as typed wrappers around WebGPU's encoder/pass primitives, replacing the old callback-based beginRenderPass/beginRenderBundleEncoder APIs. Refactors pipeline dispatch to use the new typed passes, consolidates draw state management into drawState.ts, moves attachment types into attachments.ts, and adds a warnOnce utility for deduplicated warnings.
- Typed command encoder and passes —
createCommandEncoder,beginRenderPass,beginComputePassonExperimentalTgpuRoot;TgpuCommandEncoder,TgpuRenderPass,TgpuComputePass,TgpuRenderBundleEncodernew public types - Pipeline dispatch refactor — both render and compute pipelines redirect through
#execute→emitRenderDraw/emitComputeDispatch;#withPriorshelper consolidateswith()chain mutation - Draw state and deduplication —
RenderDrawState/ComputeDrawStateclasses with version counters; state re-applied on the raw pass only when changed or afterunwrapping - Attachment defaults —
beginRenderPassderivesloadOp/storeOp/depthClearValuedefaults from texture format and view aspect;ColorAttachment/DepthStencilAttachmentmoved from render pipeline toattachments.ts - Timestamp resolution — deferred to the encoder's
beforeFinishhook viaqueueTimestampResolve; callbacks fire once per submission; repeated timed executions within one encoder warn warnOnceutility —WeakMap<object, Set<string>>deduplicates warnings per key; used for attachments, timestamps, logs, and guarded dispatch size mismatchesTgpuGuardedComputePipeline— tracks batched dispatch sizes per encoder/pass; rejects differently-sized dispatches in one submission@webgpu/typesbump — 0.1.69 → 0.1.71- Old API removal —
beginRenderPass/beginRenderBundleEncodercallbacks,RenderPass/RenderBundleEncoderPasstypes,applyPipelineState.ts,_lastAppliedRender/_lastAppliedComputeweak maps
DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

Why is this PR?
In short apart from introducing typed variants of the pass/encoder APIs they also give us more freedom and control for future extensions and clean up the pipeline APIs (moves the complexity elsewhere tbh). This will allow/already achieves:
I also rewrote the beginRenderBundleEncoder API to match the new conventions since it followed the old render pass callback based API (which also is removed as part of this PR). This is a breaking change ❗ but I think fair game since it's unstable. Keeping it around would be inconsistent imo
I will integrate the
warnOncefeature into #2747 once its merged