feat: Souls - #2796
Conversation
|
Run failed. View the logs →
|
|
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.75, 1.52, 3.19, 5.25, 6.50, 9.92, 18.61, 18.98]
line [0.83, 1.56, 3.56, 5.16, 6.50, 9.96, 18.59, 20.62]
line [0.81, 1.63, 3.38, 5.48, 6.69, 9.90, 18.53, 21.42]
---
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.26, 0.47, 0.55, 0.66, 0.91, 0.96, 1.10, 1.24]
line [0.29, 0.45, 0.53, 0.66, 0.94, 1.02, 1.17, 1.32]
line [0.24, 0.48, 0.69, 0.79, 1.02, 1.03, 1.28, 1.40]
---
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.81, 2.13, 3.46, 6.03, 10.54, 21.78, 45.12, 92.99]
line [0.84, 1.94, 3.89, 5.62, 10.29, 21.65, 46.09, 92.99]
line [0.80, 2.21, 4.36, 6.38, 10.88, 22.56, 46.93, 96.30]
|
Bundle size comparison (
|
| 🟢 Decreased | ➖ Unchanged | 🔴 Increased (max 6.16%) | ❔ Unknown |
|---|---|---|---|
| 0 | 2 | 320 | 0 |
import * as ... in PR vs import * as ... in target (did bundle size increase?):
Click to reveal the results table (118 entries).
| Test | tsdown |
|---|---|
| d_unstruct.ts | 1.65 kB ( |
| d_Void.ts | 759 B ( |
| d_sampler.ts | 767 B ( |
| d_isPtr.ts | 777 B ( |
| d_comparisonSampler.ts | 778 B ( |
| d_isSizeAttrib.ts | 779 B ( |
| d_isWgslArray.ts | 779 B ( |
| d_isAlignAttrib.ts | 780 B ( |
| d_isAtomic.ts | 780 B ( |
| d_isWgslStruct.ts | 780 B ( |
| d_isBuiltinAttrib.ts | 782 B ( |
| d_isDecorated.ts | 783 B ( |
| d_isLocationAttrib.ts | 783 B ( |
| d_isInterpolateAttrib.ts | 786 B ( |
| d_atomic.ts | 804 B ( |
| d_ptrHandle.ts | 876 B ( |
| d_ptrUniform.ts | 877 B ( |
| d_ptrStorage.ts | 881 B ( |
| d_ptrPrivate.ts | 883 B ( |
| d_ptrFn.ts | 884 B ( |
| d_ptrWorkgroup.ts | 885 B ( |
| d_textureExternal.ts | 898 B ( |
| d_textureStorage1d.ts | 1.04 kB ( |
| d_textureStorage2d.ts | 1.04 kB ( |
| d_textureStorage3d.ts | 1.04 kB ( |
| d_textureStorage2dArray.ts | 1.05 kB ( |
| d_struct.ts | 3.71 kB ( |
| d_isDisarray.ts | 1.14 kB ( |
| d_isUnstruct.ts | 1.14 kB ( |
| d_isLooseDecorated.ts | 1.14 kB ( |
| d_isLooseData.ts | 1.18 kB ( |
| d_isWgslData.ts | 1.33 kB ( |
| d_ref.ts | 4.99 kB ( |
| d_isData.ts | 1.83 kB ( |
| d_deepEqual.ts | 2.22 kB ( |
| STATIC_tgpu.ts | 276.20 kB ( |
| tgpu_fn.ts | 276.20 kB ( |
| tgpu_init.ts | 276.21 kB ( |
| tgpu_lazy.ts | 276.21 kB ( |
| tgpu_slot.ts | 276.21 kB ( |
| tgpu_const.ts | 276.21 kB ( |
| tgpu_unroll.ts | 276.21 kB ( |
| tgpu_resolve.ts | 276.21 kB ( |
| tgpu_accessor.ts | 276.21 kB ( |
| tgpu_comptime.ts | 276.21 kB ( |
| tgpu_vertexFn.ts | 276.21 kB ( |
| tgpu_computeFn.ts | 276.21 kB ( |
| tgpu_fragmentFn.ts | 276.21 kB ( |
| tgpu_privateVar.ts | 276.21 kB ( |
| tgpu_vertexLayout.ts | 276.21 kB ( |
| tgpu_workgroupVar.ts | 276.21 kB ( |
| tgpu_initFromDevice.ts | 276.21 kB ( |
| tgpu_bindGroupLayout.ts | 276.22 kB ( |
| tgpu_mutableAccessor.ts | 276.22 kB ( |
| tgpu_resolveWithContext.ts | 276.22 kB ( |
| STATIC_allImports.ts | 301.97 kB ( |
| d_bool.ts | 13.89 kB ( |
| d_f16.ts | 13.89 kB ( |
| d_f32.ts | 13.89 kB ( |
| d_i32.ts | 13.89 kB ( |
| d_u32.ts | 13.89 kB ( |
| d_u16.ts | 13.91 kB ( |
| d_textureDepth2d.ts | 14.33 kB ( |
| d_textureDepthCube.ts | 14.34 kB ( |
| d_texture1d.ts | 14.34 kB ( |
| d_texture2d.ts | 14.34 kB ( |
| d_texture3d.ts | 14.34 kB ( |
| d_textureCube.ts | 14.35 kB ( |
| d_textureDepth2dArray.ts | 14.35 kB ( |
| d_textureDepthCubeArray.ts | 14.36 kB ( |
| d_textureDepthMultisampled2d.ts | 14.36 kB ( |
| d_texture2dArray.ts | 14.36 kB ( |
| d_textureCubeArray.ts | 14.37 kB ( |
| d_textureMultisampled2d.ts | 14.37 kB ( |
| std_discard.ts | 15.18 kB ( |
| std_isBeingTranspiled.ts | 15.28 kB ( |
| std_getTargetShaderLanguage.ts | 15.34 kB ( |
| std_extensionEnabled.ts | 15.40 kB ( |
| std_copy.ts | 15.42 kB ( |
| std_arrayLength.ts | 15.43 kB ( |
| std_range.ts | 15.66 kB ( |
| d_disarrayOf.ts | 15.83 kB ( |
| std_dpdx.ts | 16.14 kB ( |
| std_dpdxCoarse.ts | 16.15 kB ( |
| std_dpdxFine.ts | 16.15 kB ( |
| std_dpdy.ts | 16.15 kB ( |
| std_dpdyCoarse.ts | 16.15 kB ( |
| std_dpdyFine.ts | 16.15 kB ( |
| std_fwidth.ts | 16.15 kB ( |
| std_fwidthCoarse.ts | 16.15 kB ( |
| std_fwidthFine.ts | 16.15 kB ( |
| std_atomicLoad.ts | 16.94 kB ( |
| std_atomicStore.ts | 16.95 kB ( |
| std_textureBarrier.ts | 16.95 kB ( |
| std_atomicAdd.ts | 16.96 kB ( |
| std_atomicAnd.ts | 16.96 kB ( |
| std_atomicMax.ts | 16.96 kB ( |
| std_atomicMin.ts | 16.96 kB ( |
| std_atomicOr.ts | 16.96 kB ( |
| std_atomicSub.ts | 16.96 kB ( |
| std_atomicXor.ts | 16.96 kB ( |
| std_storageBarrier.ts | 16.96 kB ( |
| std_workgroupBarrier.ts | 16.96 kB ( |
| d_vec2b.ts | 20.34 kB ( |
| d_vec2f.ts | 20.34 kB ( |
| d_vec2h.ts | 20.34 kB ( |
| d_vec2i.ts | 20.34 kB ( |
| d_vec2u.ts | 20.34 kB ( |
| d_vec3b.ts | 20.34 kB ( |
| d_vec3f.ts | 20.34 kB ( |
| d_vec3h.ts | 20.34 kB ( |
| d_vec3i.ts | 20.34 kB ( |
| d_vec3u.ts | 20.34 kB ( |
| d_vec4b.ts | 20.34 kB ( |
| d_vec4f.ts | 20.34 kB ( |
| d_vec4h.ts | 20.34 kB ( |
| d_vec4i.ts | 20.34 kB ( |
| d_vec4u.ts | 20.34 kB ( |
import { ... } in PR vs import * as ... in PR (is the library tree-Shakeable?):
| Test | tsdown |
|---|---|
| tgpu_init.ts | 267.11 kB ( |
| tgpu_initFromDevice.ts | 266.58 kB ( |
| tgpu_resolve.ts | 168.15 kB ( |
| tgpu_resolveWithContext.ts | 168.08 kB ( |
| tgpu_bindGroupLayout.ts | 73.79 kB ( |
| tgpu_mutableAccessor.ts | 68.51 kB ( |
| tgpu_accessor.ts | 68.51 kB ( |
| tgpu_privateVar.ts | 67.07 kB ( |
| tgpu_workgroupVar.ts | 67.07 kB ( |
| tgpu_const.ts | 66.62 kB ( |
| tgpu_lazy.ts | 66.42 kB ( |
| tgpu_fragmentFn.ts | 38.92 kB ( |
| tgpu_fn.ts | 38.86 kB ( |
| tgpu_vertexFn.ts | 38.73 kB ( |
| tgpu_computeFn.ts | 38.44 kB ( |
| tgpu_vertexLayout.ts | 27.57 kB ( |
| tgpu_comptime.ts | 15.17 kB ( |
| tgpu_unroll.ts | 1.75 kB ( |
| tgpu_slot.ts | 1.70 kB ( |
If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.
| import { version } from 'typegpu/package.json'; | ||
|
|
||
| export const $internal = Symbol(`typegpu:${version}:$internal`); | ||
| /** A plain record of all definitional state of a resource, surviving a device boundary */ |
There was a problem hiding this comment.
What's a "device boundary"?
There was a problem hiding this comment.
My weird mental identity for runtime, will change, forgot that GPUDevice is indeed a device
| flags: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, | ||
| usages: [], | ||
| raw: undefined, | ||
| label: undefined, |
There was a problem hiding this comment.
Is this label ever updated?
5da4068 to
72c75a4
Compare
There was a problem hiding this comment.
Pull request overview
This PR lays groundwork for an upcoming transfer protocol by consolidating per-resource definitional state into a [$soul] record and shifting “device-object creation” responsibilities into [$internal].materialize() implementations.
Changes:
- Introduces
[$soul]on many resource types to centralize definitional state. - Replaces several
[$internal] = true/ ad-hoc unwrap patterns with[$internal].materialize()for device-owning resources. - Updates pipeline, buffer/texture/sampler/query-set, slot/accessor, and bind group layout implementations to read state from souls (or to populate souls during materialization).
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/typegpu/src/tgpuBindGroupLayout.ts | Adds souls for bind group layouts / bind groups and moves index/state into [$soul]. |
| packages/typegpu/src/shared/symbols.ts | Adds the $soul symbol. |
| packages/typegpu/src/shared/soul.ts | Introduces base TgpuSoul and TgpuDeviceOwningSoul interfaces. |
| packages/typegpu/src/core/vertexLayout/vertexLayout.ts | Adds vertex layout soul and routes stepMode through it. |
| packages/typegpu/src/core/texture/texture.ts | Adds texture soul and replaces internal unwrap with materialize() + soul-backed state. |
| packages/typegpu/src/core/slot/slotTypes.ts | Adds soul types for slots/accessors/mutable-accessors. |
| packages/typegpu/src/core/slot/slot.ts | Stores slot default value in a soul and exposes via getter. |
| packages/typegpu/src/core/slot/accessor.ts | Stores accessor schema/default in a soul; updates base ctor and getters. |
| packages/typegpu/src/core/sampler/sampler.ts | Adds sampler soul and swaps sampler internal creation to materialize(). |
| packages/typegpu/src/core/root/rootTypes.ts | Adds souls for root + guarded compute pipeline types. |
| packages/typegpu/src/core/root/init.ts | Updates unwrap logic to prefer [$internal].materialize() and adds root/guarded-pipeline souls. |
| packages/typegpu/src/core/querySet/querySet.ts | Adds query set soul; moves query set creation behind materialize(). |
| packages/typegpu/src/core/pipeline/renderPipeline.ts | Adds render pipeline soul and materialization path capturing priors/memo info. |
| packages/typegpu/src/core/pipeline/priors.ts | Adds helper to list non-transferable priors. |
| packages/typegpu/src/core/pipeline/computePipeline.ts | Adds compute pipeline soul and materialization path capturing priors/memo info. |
| packages/typegpu/src/core/constant/tgpuConstant.ts | Adds const soul and stores value/dataType there (and exports DeepReadonly). |
| packages/typegpu/src/core/buffer/bufferBinding.ts | Adds buffer-binding soul and exposes bound buffer via getter. |
| packages/typegpu/src/core/buffer/buffer.ts | Adds buffer soul and centralizes GPUBuffer creation behind [$internal].materialize(). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
ℹ️ No critical issues — minor suggestions inline.
Reviewed changes
This run reviewed the first Pullfrog pass over the PR; there were no prior Pullfrog reviews.
- Added
[$soul]plain records to every resource, centralizing definitional state intended to survive a device boundary. - Moved device-owned GPU objects into
[$soul].rawand introduced[$internal].materialize()for lazy creation of buffers, textures, samplers, query sets, and pipelines. - Refactored
TgpuRoot.unwrapto dispatch device-owning resources through the genericmaterialize()path instead of per-type branches. - Added
packages/typegpu/src/shared/soul.tsandpackages/typegpu/src/core/pipeline/priors.tsto define the soul shape and transferable-prior filtering.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
72c75a4 to
9dc5d3d
Compare
There was a problem hiding this comment.
ℹ️ No critical issues — one prior documentation suggestion remains open.
Reviewed changes
This run re-reviewed the delta since the prior Pullfrog pass at 72c75a4c.
- Updated
TgpuSouldoc comments to describe state as surviving "transfer between runtimes" instead of a "device boundary". - Wired resource naming into souls:
setNamenow populatessoul.label, andgetNamefalls back to it, enabling transferred souls to carry their names. - Added a small
soulOfhelper inpackages/typegpu/src/shared/meta.ts. - Relocated the
TgpuRootImplclass doc comment inpackages/typegpu/src/core/root/init.ts.
ℹ️ Soul doc comment still misrepresents local GPU references
The prior inline concern about packages/typegpu/src/shared/soul.ts remains: the comment still says souls hold "everything that survives transfer between runtimes" and contain "own data properties only", while TgpuDeviceOwningSoul stores device and raw GPU objects that are local runtime references and do not survive transfer. Consider clarifying which fields are local references versus serialized definitional state.
Kimi K2 (free via Pullfrog for OSS) | 𝕏


Groundwork for the transfer protocol (PR on top of this one). To move a resource between runtimes we need its complete definitional state as a plain serializable record, and previously that state was scattered across private fields, closures and getters per resource. This PR gathers it into one place without changing any behavior.
[$soul]- a plain record of everything that survives a runtime boundary (own data properties only, no methods, no prototype, no symbol keys)[$internal]changed fromtrueto an object exposingmaterialize(), which fills the soul'srawwith the device object for resources that own one (buffer, texture, query set, pipelines, ...)