Skip to content

feat: Allow tgpu.resolve to be nested - #2811

Open
iwoplaza wants to merge 1 commit into
mainfrom
fix/nested-tgpu-resolve
Open

feat: Allow tgpu.resolve to be nested#2811
iwoplaza wants to merge 1 commit into
mainfrom
fix/nested-tgpu-resolve

Conversation

@iwoplaza

@iwoplaza iwoplaza commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Nesting resolutions is essential for @typegpu/three (and similar integrations) to work correctly, as nested resolves can happen when a TSL node calls a TypeGPU function, which references a TSL node that calls a TypeGPU function again.

Copilot AI lite review requested due to automatic review settings August 8, 2026 07:13
@github-actions

github-actions Bot commented Aug 8, 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.63, 1.27, 2.66, 3.67, 4.49, 7.13, 13.60, 15.50]
  line [0.65, 1.24, 2.44, 3.87, 4.76, 7.79, 13.66, 15.96]
  line [0.70, 1.29, 2.77, 4.20, 4.75, 7.17, 14.03, 14.95]
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.20, 0.39, 0.46, 0.61, 0.82, 0.81, 1.03, 1.11]
  line [0.20, 0.35, 0.53, 0.60, 0.85, 0.82, 0.98, 1.05]
  line [0.19, 0.37, 0.47, 0.55, 0.77, 0.77, 1.01, 1.04]
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.61, 1.51, 2.78, 4.44, 7.91, 15.93, 34.48, 70.07]
  line [0.65, 1.53, 2.83, 4.16, 7.37, 15.83, 35.13, 71.51]
  line [0.63, 1.60, 2.83, 4.21, 7.93, 16.63, 35.31, 75.52]
Loading

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

Enables tgpu.resolve (and related context-providing mechanisms) to be invoked from within other resolution-driven code paths by making resolution context providers properly nestable, and adds tests to validate nested resolution scenarios.

Changes:

  • Updated provideCtx to support nested contexts by restoring the previous context on exit.
  • Added test coverage for nested tgpu.resolve usage, including a shared namespace scenario.
  • Exposed ResolvableObject as a public type export to support the new tests and user typing.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
packages/typegpu/tests/resolve.test.ts Adds new tests asserting nested tgpu.resolve behavior and shared-namespace name generation.
packages/typegpu/src/indexNamedExports.ts Exports ResolvableObject from the public barrel for external typing.
packages/typegpu/src/execMode.ts Changes provideCtx to behave like a stack (save/restore previous context) to allow nesting.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/typegpu/tests/resolve.test.ts Outdated
Comment thread packages/typegpu/src/execMode.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.

Important

Removing the only use of invariant in provideCtx leaves an unused import that fails the test:style lint gate. Drop the import before this merges.

Reviewed changes — Allow tgpu.resolve to be nested by making provideCtx restore the previous resolution context instead of resetting it to undefined, and dropping the "Cannot nest context providers" invariant. Resolves inside an outer resolve (e.g. via tgpu.comptime) now run with their own context and hand control back cleanly afterward. Exports ResolvableObject as a public type so comptime helpers can type a shared-namespace resource.

The context-stacking logic itself looks correct: the same-context short-circuit is preserved, provideCtx callers (resolutionCtx.ts top-level resolve, tgpuSimulate.ts) are unaffected since they never nest a different context, and the new tests genuinely exercise nesting (they would have thrown the old invariant). The one blocking issue is the now-unused invariant import, which oxlint --max-warnings=0 reports as a hard failure.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu/src/execMode.ts
@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from 88e9dd2 to 9d86c96 Compare August 8, 2026 15:00
@pullfrog

pullfrog Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Run failed. View the logs →

Pullfrog  | Rerun failed job ➔View workflow run | via Pullfrog | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from 9d86c96 to 40d03ff Compare August 8, 2026 15:06
@github-actions

github-actions Bot commented Aug 8, 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@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/tgpu-gen@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/tinyest-for-wgsl@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/typegpu@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/cli@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/color@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/gl@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/noise@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/radiance-cascades@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/react@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/sdf@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/three@d706555d86e482b0dfa7a64246fe95e5ddca5771
https://pkg.pr.new/software-mansion/TypeGPU/unplugin-typegpu@d706555d86e482b0dfa7a64246fe95e5ddca5771

benchmark
view benchmark

commit
view commit

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

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

🟢 Decreased (max -0.02%) ➖ Unchanged 🔴 Increased (max 0.03%) ❔ Unknown
21 136 165 0

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

Test tsdown
tgpu_init.ts 267.80 kB ($${\color{green}-3.3\%}$$)
tgpu_initFromDevice.ts 267.27 kB ($${\color{green}-3.5\%}$$)
tgpu_resolve.ts 168.37 kB ($${\color{green}-39.2\%}$$)
tgpu_resolveWithContext.ts 168.30 kB ($${\color{green}-39.2\%}$$)
tgpu_bindGroupLayout.ts 73.79 kB ($${\color{green}-73.4\%}$$)
tgpu_mutableAccessor.ts 68.52 kB ($${\color{green}-75.3\%}$$)
tgpu_accessor.ts 68.51 kB ($${\color{green}-75.3\%}$$)
tgpu_privateVar.ts 67.20 kB ($${\color{green}-75.7\%}$$)
tgpu_workgroupVar.ts 67.20 kB ($${\color{green}-75.7\%}$$)
tgpu_const.ts 66.62 kB ($${\color{green}-75.9\%}$$)
tgpu_lazy.ts 66.42 kB ($${\color{green}-76.0\%}$$)
tgpu_fragmentFn.ts 38.92 kB ($${\color{green}-85.9\%}$$)
tgpu_fn.ts 38.86 kB ($${\color{green}-86.0\%}$$)
tgpu_vertexFn.ts 38.73 kB ($${\color{green}-86.0\%}$$)
tgpu_computeFn.ts 38.44 kB ($${\color{green}-86.1\%}$$)
tgpu_vertexLayout.ts 27.57 kB ($${\color{green}-90.0\%}$$)
tgpu_comptime.ts 15.18 kB ($${\color{green}-94.5\%}$$)
tgpu_unroll.ts 1.75 kB ($${\color{green}-99.4\%}$$)
tgpu_slot.ts 1.70 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.

@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from 40d03ff to c074033 Compare August 8, 2026 19:09

@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 — delta on top of the prior Pullfrog review (40d03ffc074033):

  • Removed the now-unused import { invariant } from './errors.ts' from execMode.ts. This addresses the prior review's only blocking finding (unused import failing the test:style oxlint --max-warnings=0 gate); the thread is resolved and oxlint reports 0 warnings/errors on all three changed files.
  • Reworked the first tgpu resolve - nesting test to use tgpu.resolveWithContext([getPi2]).declarations.length (renaming the comptime helper to getDeclarationsOfGetPi2) instead of tgpu.resolve([getPi2]).length, updating the snapshot from + 79f to + 2f. The new assertion (pi const + getPi2 fn = 2 declarations) is more meaningful than a brittle resolved-code string-length count, and I confirmed both nesting tests pass.

The context-stacking change itself remains sound: the same-context short-circuit is preserved, nesting restores the prior context (true LIFO, no cross-context state pollution), and the tests genuinely exercise nesting — they would have thrown the old "Cannot nest context providers" invariant.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from c074033 to b7aa8c4 Compare August 8, 2026 19:17
@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from b7aa8c4 to df0fe67 Compare August 9, 2026 07:40
@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from df0fe67 to 8b446b4 Compare August 9, 2026 18:03
it('should allow for nested use with a shared namespace', () => {
const namespace = tgpu['~unstable'].namespace();

const getGeneratedName = tgpu.comptime((resource: ResolvableObject) => {

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.

neat trick!

@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from 8b446b4 to 5817871 Compare August 10, 2026 10:06
@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from 5817871 to a0244d2 Compare August 10, 2026 10:15

@cieplypolar cieplypolar 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.

Cool tests :shipit:

@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from a0244d2 to a897929 Compare August 11, 2026 09:16
Base automatically changed from fix/simpler-generator-lifetime to main August 11, 2026 09:25
@iwoplaza
iwoplaza force-pushed the fix/nested-tgpu-resolve branch from a897929 to d706555 Compare August 11, 2026 09:25
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.

5 participants