feat: tgpu.comptime, tgpu.rawCodeSnippet and this allowed in TypeGPU shader functions#1917
feat: tgpu.comptime, tgpu.rawCodeSnippet and this allowed in TypeGPU shader functions#1917
this allowed in TypeGPU shader functions#1917Conversation
|
pkg.pr.new packages benchmark commit |
this allowed in TypeGPUthis allowed in TypeGPU shader functions
aleksanderkatan
left a comment
There was a problem hiding this comment.
Great changes! 💻🕑
Please add one sentence about each comptime and rawCodeSnippet to the docs (maybe utils.mdx?) so that people know they exist
| get value(): InferGPU<TDataType> { | ||
| return this.$; | ||
| } |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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:
externalsis now an arrow function instead of a getter to properly capturethiscontext - 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.extensionEnabledto use the newcomptimeAPI
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.
aleksanderkatan
left a comment
There was a problem hiding this comment.
I'm now maintaining this PR so I have to withdraw my 'request changes', oh well
| // 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( |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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.
Co-authored-by: Konrad Reczko <[email protected]>
Co-authored-by: Konrad Reczko <[email protected]>
Changes:
externalsis now an arrow function instead of a getter, so that it can capture thethisvalue from the outer scope.thisis treated like any other identifier, except for when generating the metadata object in unplugin. We cannot use shorthand syntax forthistgpu['~unstable'].comptimeis 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'].rawCodeSnippetlets 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)