Skip to content

feat: Introduce Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs - #2764

Merged
reczkok merged 10 commits into
mainfrom
feat/tgpu-encoder-pass
Aug 6, 2026
Merged

feat: Introduce Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs#2764
reczkok merged 10 commits into
mainfrom
feat/tgpu-encoder-pass

Conversation

@reczkok

@reczkok reczkok commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

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:

  • much cleaner Immediate implementation
  • smooth transition to Souls
  • using logs/timestamps in batched workloads (tbh both those features are debug only but why not)

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

The warnOnce feature is now integrated with the logger from #2747.

@reczkok
reczkok force-pushed the feat/tgpu-encoder-pass branch 2 times, most recently from 657340d to 2a31791 Compare July 27, 2026 23:25
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/eslint-plugin-typegpu@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/tgpu-gen@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/tinyest-for-wgsl@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/typegpu@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/cli@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/color@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/gl@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/noise@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/radiance-cascades@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/react@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/sdf@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/three@f691efbf67ae4680209c1f4f61a2792e7d324712
https://pkg.pr.new/software-mansion/TypeGPU/unplugin-typegpu@f691efbf67ae4680209c1f4f61a2792e7d324712

benchmark
view benchmark

commit
view commit

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

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.92, 1.87, 3.99, 6.57, 7.01, 11.16, 23.16, 25.68]
  line [0.93, 1.91, 4.08, 6.84, 7.00, 12.01, 22.42, 22.52]
  line [1.02, 2.11, 4.67, 6.56, 7.73, 11.34, 21.99, 23.23]
Loading
---
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.32, 0.46, 0.64, 0.80, 1.08, 1.10, 1.37, 1.49]
  line [0.35, 0.55, 0.71, 0.81, 1.08, 1.18, 1.40, 1.54]
  line [0.30, 0.54, 0.71, 0.82, 1.17, 1.23, 1.50, 1.65]
Loading
---
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.87, 2.02, 4.51, 7.47, 12.89, 25.05, 53.71, 107.75]
  line [0.79, 2.12, 3.46, 8.45, 13.28, 25.16, 53.64, 111.08]
  line [0.93, 1.98, 4.09, 7.55, 13.28, 27.25, 56.01, 116.79]
Loading

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased ➖ Unchanged 🔴 Increased (max 1.37%) ❔ Unknown
0 37 285 0

import * as ... in PR vs import * as ... in target (did bundle size increase?):

Click to reveal the results table (183 entries).
Test tsdown
STATIC_tgpu.ts 273.24 kB ($${\color{red}+1.4\%}$$)
tgpu_fn.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_init.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_lazy.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_slot.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_const.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_unroll.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_resolve.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_accessor.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_comptime.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_vertexFn.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_computeFn.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_fragmentFn.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_privateVar.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_vertexLayout.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_workgroupVar.ts 273.25 kB ($${\color{red}+1.4\%}$$)
tgpu_initFromDevice.ts 273.26 kB ($${\color{red}+1.4\%}$$)
tgpu_bindGroupLayout.ts 273.26 kB ($${\color{red}+1.4\%}$$)
tgpu_mutableAccessor.ts 273.26 kB ($${\color{red}+1.4\%}$$)
tgpu_resolveWithContext.ts 273.26 kB ($${\color{red}+1.4\%}$$)
STATIC_allImports.ts 299.01 kB ($${\color{red}+1.3\%}$$)
d_bool.ts 13.79 kB ($${\color{red}+1.2\%}$$)
d_f16.ts 13.79 kB ($${\color{red}+1.2\%}$$)
d_f32.ts 13.79 kB ($${\color{red}+1.2\%}$$)
d_i32.ts 13.79 kB ($${\color{red}+1.2\%}$$)
d_u32.ts 13.79 kB ($${\color{red}+1.2\%}$$)
d_u16.ts 13.81 kB ($${\color{red}+1.2\%}$$)
d_textureDepth2d.ts 14.23 kB ($${\color{red}+1.2\%}$$)
d_textureDepthCube.ts 14.24 kB ($${\color{red}+1.2\%}$$)
d_texture1d.ts 14.24 kB ($${\color{red}+1.2\%}$$)
d_texture2d.ts 14.24 kB ($${\color{red}+1.2\%}$$)
d_texture3d.ts 14.24 kB ($${\color{red}+1.2\%}$$)
d_textureCube.ts 14.25 kB ($${\color{red}+1.2\%}$$)
d_textureDepth2dArray.ts 14.25 kB ($${\color{red}+1.2\%}$$)
d_textureDepthCubeArray.ts 14.26 kB ($${\color{red}+1.2\%}$$)
d_textureDepthMultisampled2d.ts 14.26 kB ($${\color{red}+1.2\%}$$)
d_texture2dArray.ts 14.26 kB ($${\color{red}+1.2\%}$$)
d_textureCubeArray.ts 14.27 kB ($${\color{red}+1.2\%}$$)
d_textureMultisampled2d.ts 14.27 kB ($${\color{red}+1.2\%}$$)
std_discard.ts 15.08 kB ($${\color{red}+1.1\%}$$)
std_isBeingTranspiled.ts 15.18 kB ($${\color{red}+1.1\%}$$)
std_getTargetShaderLanguage.ts 15.25 kB ($${\color{red}+1.1\%}$$)
std_extensionEnabled.ts 15.30 kB ($${\color{red}+1.1\%}$$)
std_copy.ts 15.32 kB ($${\color{red}+1.1\%}$$)
std_arrayLength.ts 15.33 kB ($${\color{red}+1.1\%}$$)
std_range.ts 15.56 kB ($${\color{red}+1.1\%}$$)
d_disarrayOf.ts 15.74 kB ($${\color{red}+1.1\%}$$)
std_dpdx.ts 16.04 kB ($${\color{red}+1.1\%}$$)
std_dpdxCoarse.ts 16.05 kB ($${\color{red}+1.1\%}$$)
std_dpdxFine.ts 16.05 kB ($${\color{red}+1.1\%}$$)
std_dpdy.ts 16.05 kB ($${\color{red}+1.1\%}$$)
std_dpdyCoarse.ts 16.05 kB ($${\color{red}+1.1\%}$$)
std_dpdyFine.ts 16.05 kB ($${\color{red}+1.1\%}$$)
std_fwidth.ts 16.05 kB ($${\color{red}+1.1\%}$$)
std_fwidthCoarse.ts 16.05 kB ($${\color{red}+1.1\%}$$)
std_fwidthFine.ts 16.05 kB ($${\color{red}+1.1\%}$$)
std_atomicLoad.ts 16.84 kB ($${\color{red}+1.0\%}$$)
std_atomicStore.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_textureBarrier.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_atomicAdd.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_atomicAnd.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_atomicMax.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_atomicMin.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_atomicOr.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_atomicSub.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_atomicXor.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_storageBarrier.ts 16.85 kB ($${\color{red}+1.0\%}$$)
std_workgroupBarrier.ts 16.85 kB ($${\color{red}+1.0\%}$$)
d_vec2b.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec2f.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec2h.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec2i.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec2u.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec3b.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec3f.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec3h.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec3i.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec3u.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec4b.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec4f.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec4h.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec4i.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_vec4u.ts 20.23 kB ($${\color{red}+0.8\%}$$)
d_formatToWGSLType.ts 21.73 kB ($${\color{red}+0.8\%}$$)
d_uint8.ts 21.73 kB ($${\color{red}+0.8\%}$$)
d_float16.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_float16x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_float16x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_float32.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_float32x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_float32x3.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_float32x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint16.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint16x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint16x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint32.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint32x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint32x3.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint32x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint8.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint8x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_sint8x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_snorm16.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_snorm16x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_snorm16x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_snorm8.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_snorm8x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_snorm8x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_uint16.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_uint16x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_uint16x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_uint32.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_uint32x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_uint32x3.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_uint32x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_uint8x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_uint8x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_unorm10_10_10_2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_unorm16.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_unorm16x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_unorm16x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_unorm8.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_unorm8x2.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_unorm8x4.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_unorm8x4_bgra.ts 21.74 kB ($${\color{red}+0.8\%}$$)
d_packedFormats.ts 21.75 kB ($${\color{red}+0.8\%}$$)
d_isPackedData.ts 21.80 kB ($${\color{red}+0.8\%}$$)
d_alignmentOf.ts 22.68 kB ($${\color{red}+0.7\%}$$)
std_subgroupAdd.ts 25.18 kB ($${\color{red}+0.7\%}$$)
std_subgroupAll.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupAnd.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupAny.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupBallot.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupBroadcast.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupBroadcastFirst.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupElect.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupExclusiveAdd.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupExclusiveMul.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupInclusiveAdd.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupInclusiveMul.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupMax.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupMin.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupMul.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupOr.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupShuffle.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupShuffleDown.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupShuffleUp.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupShuffleXor.ts 25.19 kB ($${\color{red}+0.7\%}$$)
std_subgroupXor.ts 25.19 kB ($${\color{red}+0.7\%}$$)
d_isBuiltin.ts 25.41 kB ($${\color{red}+0.7\%}$$)
d_sizeOf.ts 25.46 kB ($${\color{red}+0.7\%}$$)
d_isContiguous.ts 25.47 kB ($${\color{red}+0.7\%}$$)
d_getLongestContiguousPrefix.ts 25.48 kB ($${\color{red}+0.7\%}$$)
std_textureDimensions.ts 26.79 kB ($${\color{red}+0.6\%}$$)
std_textureGather.ts 26.79 kB ($${\color{red}+0.6\%}$$)
std_textureLoad.ts 26.80 kB ($${\color{red}+0.6\%}$$)
std_textureSample.ts 26.80 kB ($${\color{red}+0.6\%}$$)
std_textureSampleBaseClampToEdge.ts 26.80 kB ($${\color{red}+0.6\%}$$)
std_textureSampleBias.ts 26.80 kB ($${\color{red}+0.6\%}$$)
std_textureSampleCompare.ts 26.80 kB ($${\color{red}+0.6\%}$$)
std_textureSampleCompareLevel.ts 26.80 kB ($${\color{red}+0.6\%}$$)
std_textureSampleGrad.ts 26.80 kB ($${\color{red}+0.6\%}$$)
std_textureSampleLevel.ts 26.80 kB ($${\color{red}+0.6\%}$$)
std_textureStore.ts 26.80 kB ($${\color{red}+0.6\%}$$)
d_arrayOf.ts 26.90 kB ($${\color{red}+0.6\%}$$)
d_size.ts 27.15 kB ($${\color{red}+0.6\%}$$)
d_align.ts 27.15 kB ($${\color{red}+0.6\%}$$)
d_location.ts 27.15 kB ($${\color{red}+0.6\%}$$)
d_interpolate.ts 27.15 kB ($${\color{red}+0.6\%}$$)
d_invariant.ts 27.52 kB ($${\color{red}+0.6\%}$$)
std_identity2.ts 27.85 kB ($${\color{red}+0.6\%}$$)
std_identity3.ts 27.85 kB ($${\color{red}+0.6\%}$$)
std_rotationX4.ts 27.85 kB ($${\color{red}+0.6\%}$$)
std_rotationY4.ts 27.85 kB ($${\color{red}+0.6\%}$$)
std_rotationZ4.ts 27.85 kB ($${\color{red}+0.6\%}$$)
std_scaling4.ts 27.85 kB ($${\color{red}+0.6\%}$$)
std_translation4.ts 27.85 kB ($${\color{red}+0.6\%}$$)
std_identity4.ts 27.85 kB ($${\color{red}+0.6\%}$$)
d_mat4x4f.ts 27.85 kB ($${\color{red}+0.6\%}$$)
d_mat2x2f.ts 27.85 kB ($${\color{red}+0.6\%}$$)
d_mat3x3f.ts 27.85 kB ($${\color{red}+0.6\%}$$)
d_matToArray.ts 27.98 kB ($${\color{red}+0.6\%}$$)
d_builtin.ts 29.36 kB ($${\color{red}+0.6\%}$$)

import { ... } in PR vs import * as ... in PR (is the library tree-Shakeable?):

Test tsdown
tgpu_init.ts 264.49 kB ($${\color{green}-3.2\%}$$)
tgpu_initFromDevice.ts 263.96 kB ($${\color{green}-3.4\%}$$)
tgpu_resolve.ts 167.56 kB ($${\color{green}-38.7\%}$$)
tgpu_resolveWithContext.ts 167.49 kB ($${\color{green}-38.7\%}$$)
tgpu_bindGroupLayout.ts 71.83 kB ($${\color{green}-73.7\%}$$)
tgpu_mutableAccessor.ts 68.22 kB ($${\color{green}-75.0\%}$$)
tgpu_accessor.ts 68.22 kB ($${\color{green}-75.0\%}$$)
tgpu_privateVar.ts 66.96 kB ($${\color{green}-75.5\%}$$)
tgpu_workgroupVar.ts 66.96 kB ($${\color{green}-75.5\%}$$)
tgpu_const.ts 66.44 kB ($${\color{green}-75.7\%}$$)
tgpu_lazy.ts 66.32 kB ($${\color{green}-75.7\%}$$)
tgpu_fn.ts 38.75 kB ($${\color{green}-85.8\%}$$)
tgpu_fragmentFn.ts 38.75 kB ($${\color{green}-85.8\%}$$)
tgpu_vertexFn.ts 38.57 kB ($${\color{green}-85.9\%}$$)
tgpu_computeFn.ts 38.27 kB ($${\color{green}-86.0\%}$$)
tgpu_vertexLayout.ts 27.39 kB ($${\color{green}-90.0\%}$$)
tgpu_comptime.ts 15.07 kB ($${\color{green}-94.5\%}$$)
tgpu_unroll.ts 1.66 kB ($${\color{green}-99.4\%}$$)
tgpu_slot.ts 1.54 kB ($${\color{green}-99.4\%}$$)

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

@reczkok reczkok changed the title feat: Introduce Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs feat: Introduce Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs Jul 27, 2026
@reczkok
reczkok marked this pull request as ready for review July 28, 2026 14:53
Copilot AI review requested due to automatic review settings July 28, 2026 14:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/types catalog 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.

Comment thread packages/typegpu-gl/src/tgpuRootWebGL.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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 passescreateCommandEncoder, beginRenderPass, beginComputePass on ExperimentalTgpuRoot; TgpuCommandEncoder, TgpuRenderPass, TgpuComputePass, TgpuRenderBundleEncoder new public types
  • Pipeline dispatch refactor — both render and compute pipelines redirect through #executeemitRenderDraw/emitComputeDispatch; #withPriors helper consolidates with() chain mutation
  • Draw state and deduplicationRenderDrawState/ComputeDrawState classes with version counters; state re-applied on the raw pass only when changed or after unwrapping
  • Attachment defaultsbeginRenderPass derives loadOp/storeOp/depthClearValue defaults from texture format and view aspect; ColorAttachment/DepthStencilAttachment moved from render pipeline to attachments.ts
  • Timestamp resolution — deferred to the encoder's beforeFinish hook via queueTimestampResolve; callbacks fire once per submission; repeated timed executions within one encoder warn
  • warnOnce utilityWeakMap<object, Set<string>> deduplicates warnings per key; used for attachments, timestamps, logs, and guarded dispatch size mismatches
  • TgpuGuardedComputePipeline — tracks batched dispatch sizes per encoder/pass; rejects differently-sized dispatches in one submission
  • @webgpu/types bump — 0.1.69 → 0.1.71
  • Old API removalbeginRenderPass/beginRenderBundleEncoder callbacks, RenderPass/RenderBundleEncoderPass types, applyPipelineState.ts, _lastAppliedRender/_lastAppliedCompute weak maps

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@iwoplaza iwoplaza linked an issue Jul 29, 2026 that may be closed by this pull request
3 tasks

@iwoplaza iwoplaza left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome changes! 👏

Comment thread packages/typegpu/src/core/commandEncoder/commandEncoder.ts Outdated
Comment thread packages/typegpu/tests/computePipeline.test.ts Outdated
Comment thread packages/typegpu/tests/computePipeline.test.ts Outdated
@reczkok
reczkok force-pushed the feat/tgpu-encoder-pass branch 2 times, most recently from 8870379 to b1d046f Compare August 3, 2026 15:35
pullfrog[bot]

This comment was marked as outdated.

@reczkok
reczkok force-pushed the feat/tgpu-encoder-pass branch from b1d046f to 9a541a7 Compare August 3, 2026 15:39

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — commit 9a541a71 integrates the standalone warnOnce utility into TgpuLogger, switches all call sites to use logger.warnOnce('suspicious', ...), and adds the missing createCommandEncoder surface to the WebGL fallback.

  • warnOnce in TgpuLoggershared/warnOnce.ts deleted; TgpuLogger gains warnOnce(type, key, tag, ...args) with the same dedup semantics plus warning-type gating (silenced in production)
  • Per-root dedup for finish() — key changed from the encoder instance to root, so the "use submit()" warning fires at most once per root
  • WebGL fallbackTgpuRootWebGL now has createCommandEncoder() that throws WebGLFallbackUnsupportedError
  • Test hardeningvi.spyOnusing in two compute pipeline tests; new test for per-root warning dedup across encoders; new warnOnce unit tests for the logger (once-per-key-and-tag, disabled-type behavior)

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏

@aleksanderkatan aleksanderkatan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great changes! I think the new API is intuitive.

I didn't manage to review the entire thing.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make passes and encoders namable:

Image

stacked PR❓

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will open an issue, not a priority for me now

Comment thread apps/typegpu-docs/src/content/docs/apis/pipelines.mdx Outdated
Comment thread apps/typegpu-docs/src/content/docs/apis/pipelines.mdx
Comment thread packages/typegpu/src/core/root/init.ts Outdated
import type { TgpuUniform } from '../buffer/bufferBinding.ts';
import type { ExperimentalTgpuRoot } from '../root/rootTypes.ts';
import {
INTERNAL_beginComputePass,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which functions exactly should be prefixed with "INTERNAL_"? For example, why is INTERNAL_adoptRenderCommands named like that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INTERNAL_adoptRenderCommands is named that because it's called from renderPipeline.ts's .with(rawPass) which is an internal api and not user facing. Seems consistent to me

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or at least consistently inconsistent with existing convention across repo

Comment thread packages/typegpu/src/core/commandEncoder/computePass.ts Outdated
Comment thread packages/typegpu/src/core/pipeline/drawState.ts Outdated
Comment thread packages/typegpu/src/core/commandEncoder/renderPass.ts Outdated
Comment thread packages/typegpu/src/core/commandEncoder/renderPass.ts Outdated
Comment thread packages/typegpu/src/core/commandEncoder/renderPass.ts Outdated
Comment thread packages/typegpu/tests/commandEncoder.test.ts Outdated

expect(renderPassEncoder.setPipeline).toBeCalledTimes(3);
});

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this intended behavior?

  it('re-applies pipeline state? ', ({ root, renderPassEncoder }) => {
    const group = root.createBindGroup(layout, {
      foo: root.createBuffer(d.f32).$usage('uniform'),
    });

    const first = root
      .createRenderPipeline({ vertex: mainVertex, fragment: mainFragment })
      .with(group);

    const encoder = root.createCommandEncoder();
    const pass = encoder.beginRenderPass({ colorAttachments: [] });
    first.with(pass).draw(3);
    first.with(pass).draw(3);
    first.with(pass).draw(3);
    pass.end();
    encoder.submit();

    expect(renderPassEncoder.setPipeline).toBeCalledTimes(3);
  });

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's fine for now, we can add dedupe mechanism in the future

Comment thread packages/typegpu/tests/commandEncoder.test.ts Outdated
plain.with(pass).draw(3);
pass.end();
encoder.submit();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the behavior of bindGroups and stencilReferences inconsistent

pass.setBindGroup(passGroup);
pipeline.with(pass).draw(3);
pass.end();
encoder.submit();

expect(renderPassEncoder.setBindGroup).toBeCalledTimes(1);
expect(renderPassEncoder.setBindGroup).toBeCalledWith(0, root.unwrap(pipelineGroup));

I don't think that pass.setStencilReference(7); should be called.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made lazy

Comment thread packages/typegpu/tests/computePipeline.test.ts Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — commit 8de9da9c builds on the typed encoder/pass API by integrating buffers with command encoders, adding typed indirect draw/dispatch support, simplifying the guarded compute pipeline contract, and updating docs/examples.

  • Buffer encoder integrationTgpuBuffer.clear(encoder?) and TgpuBuffer.copyFrom(src, encoder?) now record into an optional TgpuCommandEncoder instead of always submitting immediately; tests verify the command is deferred until encoder.submit()
  • Typed indirect dispatches and drawsdispatchWorkgroupsIndirect, drawIndirect, and drawIndexedIndirect accept TgpuBuffer<...> & IndirectFlag plus a PrimitiveOffsetInfo or numeric offset; a shared resolveIndirectOffset helper validates alignment, buffer bounds, and contiguous-byte padding in pipelineUtils.ts
  • Guarded pipeline simplificationTgpuGuardedComputePipeline.with() now only accepts bind groups and dispatches immediately on each dispatchThreads() call; the previous batched-size tracking for encoders/passes was removed, matching the documented limitation
  • Genetic-racing example rewrite — switched from guarded pipelines to regular compute pipelines batched into typed compute passes, avoiding the guarded-pipeline overhead while using the new encoder APIs
  • Docs and examples — updated buffers.mdx, pipelines.mdx, and timestamp-queries.mdx with the new encoder examples; migrated render-bundles, render-bundles-with, and simple-shadow examples to the typed command encoder/pass flow
  • WebGL fallback — renamed the unsupported-method stubs from the old callback API to createCommandEncoder/createRenderBundleEncoder
  • Test hardening — replaced toBeCalled* with toHaveBeenCalled* across the new command-encoder tests and added using for console.warn spies; buffer tests cover the new encoder variants

Validation run: pnpm vitest run --project=!browser packages/typegpu/tests/{buffer,commandEncoder,computePipeline,renderPipeline,guardedComputePipeline,root}.test.ts (199 tests passed) and pnpm --filter typegpu test:types both pass.

Pullfrog  | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — the latest push (8de9da9c3f1f2d16) is a rebase onto a newer main. The PR-specific typed encoder/pass changes are unchanged from the prior review.

I re-ran the targeted test suite on the new head and verified the same behavior:

  • pnpm vitest run --project=!browser packages/typegpu/tests/{buffer,commandEncoder,computePipeline,renderPipeline,guardedComputePipeline,root}.test.ts199 tests passed
  • pnpm --filter typegpu test:typespasses

No new PR-specific concerns.

Pullfrog  | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

@reczkok
reczkok force-pushed the feat/tgpu-encoder-pass branch from 3f1f2d1 to f691efb Compare August 6, 2026 10:40

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — commit f691efbf adds encoder-integrated clear/copyFrom on buffers, typed indirect draw/dispatch support on render and compute passes/pipelines, removes guarded-pipeline pass/encoder batching, and migrates the genetic-racing example and docs to the new APIs.

  • Buffer encoder integrationTgpuBuffer.clear(encoder?) and copyFrom(src, encoder?) can record into a TgpuCommandEncoder instead of submitting immediately; tests verify deferred submission.
  • Typed indirect commandsdispatchWorkgroupsIndirect, drawIndirect, and drawIndexedIndirect accept TgpuBuffer<...> & IndirectFlag plus PrimitiveOffsetInfo/numeric offsets; resolveIndirectOffset centralizes alignment, bounds, and padding validation.
  • Guarded pipeline simplificationTgpuGuardedComputePipeline.with() only accepts bind groups; batched size tracking removed, so dispatchThreads always submits on its own.
  • Stencil reference state — render-pass stencil reference is now tracked in RenderDrawState and applied lazily/deduplicated at draw time.
  • Docs/examplesbuffers.mdx and pipelines.mdx updated with encoder examples; genetic-racing switched from guarded pipelines to regular compute pipelines batched into typed passes.
  • Test hardeningtoBeCalled* replaced with toHaveBeenCalled* across command-encoder tests; using for console.warn spies; new buffer and stencil-reference tests.

Validation run:

  • pnpm vitest run --project=!browser packages/typegpu/tests/{buffer,commandEncoder,computePipeline,renderPipeline,guardedComputePipeline,root}.test.ts199 tests passed
  • pnpm --filter typegpu test:typespasses
  • pnpm test:types (root, including docs) — passes

Pullfrog  | Fix it ➔View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

@reczkok
reczkok merged commit 0bf6981 into main Aug 6, 2026
8 of 9 checks passed
@reczkok
reczkok deleted the feat/tgpu-encoder-pass branch August 6, 2026 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

explore: Improve ergonomics of drawing multiple meshes onto the same texture

5 participants