Skip to content

feat: tgpu.comptime, tgpu.rawCodeSnippet and this allowed in TypeGPU shader functions#1917

Merged
reczkok merged 24 commits intomainfrom
feat/comptime-and-raw-code-snippet
Nov 28, 2025
Merged

feat: tgpu.comptime, tgpu.rawCodeSnippet and this allowed in TypeGPU shader functions#1917
reczkok merged 24 commits intomainfrom
feat/comptime-and-raw-code-snippet

Conversation

@iwoplaza
Copy link
Collaborator

@iwoplaza iwoplaza commented Nov 15, 2025

Changes:

  • externals is now an arrow function instead of a getter, so that it can capture the this value from the outer scope.
  • this is treated like any other identifier, except for when generating the metadata object in unplugin. We cannot use shorthand syntax for this
  • tgpu['~unstable'].comptime is a way to create functions that are callable from within shader functions, but only allowed to execute at compile-time. They accept only compile-time known arguments, and throw otherwise.
  • tgpu['~unstable'].rawCodeSnippet lets a JS-implemented function refer to a WGSL expression that TypeGPU doesn't have control over (like in the case of our Three.js integration)

@github-actions
Copy link

github-actions bot commented Nov 20, 2025

pkg.pr.new

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

https://pkg.pr.new/software-mansion/TypeGPU/typegpu@bc159fadbec3a46bfc7b3e64f7151e36eb8c3421
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/noise@bc159fadbec3a46bfc7b3e64f7151e36eb8c3421
https://pkg.pr.new/software-mansion/TypeGPU/unplugin-typegpu@bc159fadbec3a46bfc7b3e64f7151e36eb8c3421

benchmark
view benchmark

commit
view commit

@iwoplaza iwoplaza changed the title feat: tgpu.comptime, tgpu.rawCodeSnippet and this allowed in TypeGPU feat: tgpu.comptime, tgpu.rawCodeSnippet and this allowed in TypeGPU shader functions Nov 20, 2025
Copy link
Contributor

@aleksanderkatan aleksanderkatan left a comment

Choose a reason for hiding this comment

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

Great changes! 💻🕑

Please add one sentence about each comptime and rawCodeSnippet to the docs (maybe utils.mdx?) so that people know they exist

Comment on lines +163 to +165
get value(): InferGPU<TDataType> {
return this.$;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we still plan to deprecate and remove the value in favor of $? If so, maybe we can skip adding the value getter in new resources

@aleksanderkatan aleksanderkatan marked this pull request as draft November 21, 2025 14:03
Copy link

Copilot AI left a comment

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 introduces three major features to TypeGPU: support for this in shader functions, compile-time function execution via tgpu.comptime, and raw WGSL code injection through tgpu.rawCodeSnippet. The key enabler for the this support is changing externals from a getter to an arrow function, allowing it to capture the lexical this value.

Key Changes:

  • Metadata format change: externals is now an arrow function instead of a getter to properly capture this context
  • Added tgpu['~unstable'].comptime() for functions that execute at shader compile-time rather than runtime
  • Added tgpu['~unstable'].rawCodeSnippet() for injecting custom WGSL expressions with full type safety
  • Refactored std.extensionEnabled to use the new comptime API

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/unplugin-typegpu/src/babel.ts Changed externals from getter to arrow function; added special handling for this in object shorthand
packages/unplugin-typegpu/src/rollup-impl.ts Changed externals from getter to arrow function with this handling
packages/unplugin-typegpu/src/common.ts Added comptime to resource constructors list for auto-naming support
packages/tinyest-for-wgsl/src/parsers.ts Added ThisExpression handler to track this usage in externals
packages/typegpu/src/core/function/comptime.ts New implementation of compile-time function execution
packages/typegpu/src/core/rawCodeSnippet/tgpuRawCodeSnippet.ts New implementation for raw WGSL code injection
packages/typegpu/src/core/function/fnCore.ts Added backward compatibility for old metadata format
packages/typegpu/src/shared/meta.ts Extended externals type to support both function and object (for backward compatibility)
packages/typegpu/src/std/extensions.ts Refactored to use comptime instead of custom DualFn implementation
packages/typegpu/src/types.ts Fixed isKnownAtComptime to correctly handle string literals with UnknownData type
packages/typegpu/src/tgsl/wgslGenerator.ts Changed string literal origin from 'runtime' to 'constant'
packages/typegpu/src/index.ts Exported new APIs: comptime, rawCodeSnippet, and their types
apps/typegpu-docs/src/content/docs/fundamentals/utils.mdx Added documentation for comptime and rawCodeSnippet
apps/typegpu-docs/src/examples/algorithms/mnist-inference/index.html Removed unused HTML element
Test files Updated snapshots to reflect externals format change; added comprehensive tests for this, comptime, and rawCodeSnippet

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Copy link
Contributor

@aleksanderkatan aleksanderkatan left a comment

Choose a reason for hiding this comment

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

I'm now maintaining this PR so I have to withdraw my 'request changes', oh well

@aleksanderkatan aleksanderkatan marked this pull request as ready for review November 25, 2025 12:36
Comment on lines +145 to +153
// Passing a record happens prior to version 0.9.0
// TODO: Support for this can be removed down the line
const pluginExternals = typeof pluginData?.externals === 'function'
? pluginData.externals()
: pluginData?.externals;

if (pluginExternals) {
const missing = Object.fromEntries(
Object.entries(pluginData.externals).filter(
Object.entries(pluginExternals).filter(
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to support both? If we have mismatched versions of the library and the plugin there will be issues anyway and if they match there shouldn't be an issue

Copy link
Contributor

Choose a reason for hiding this comment

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

When somebody publishes a typegpu library, the code is already transformed, and provides the externals as a record. Therefore, you would have to bump all such libraries at once (provided that authors actually updated them already).

const myController = new MyController();

expect(tgpu.resolve([myController.myFn])).toMatchInlineSnapshot(`
"@group(0) @binding(0) var<uniform> item_1: u32;
Copy link
Contributor

Choose a reason for hiding this comment

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

No auto naming? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

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

I created a detailed issue for this: #1940

Copy link
Contributor

Choose a reason for hiding this comment

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

What caused this? 🤔

Copy link
Contributor

@aleksanderkatan aleksanderkatan Nov 25, 2025

Choose a reason for hiding this comment

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

I'm pretty sure that .toMatchInlineSnapshot tries to ignore indent and this was a manual stylistic change.
The test still passes if I indent everything, and logging the result shows no unnecessary indentation.

@reczkok reczkok merged commit 7606644 into main Nov 28, 2025
3 checks passed
@reczkok reczkok deleted the feat/comptime-and-raw-code-snippet branch November 28, 2025 21:35
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.

4 participants