feat: Require explicit resize option (preparation for future changes) - #2840
Conversation
|
pkg.pr.new packages benchmark commit |
ba5b769 to
7e930f9
Compare
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.52, 1.12, 2.43, 3.38, 3.99, 6.22, 11.17, 13.07]
line [0.60, 1.10, 2.30, 3.36, 4.16, 5.84, 11.55, 12.39]
line [0.54, 1.03, 2.06, 3.46, 4.30, 6.27, 11.65, 13.79]
---
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.18, 0.37, 0.48, 0.58, 0.76, 0.69, 0.82, 1.04]
line [0.19, 0.33, 0.42, 0.46, 0.70, 0.73, 0.84, 0.89]
line [0.20, 0.35, 0.43, 0.53, 0.69, 0.71, 0.82, 1.00]
---
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.57, 2.24, 3.95, 6.42, 14.32, 31.13, 65.52]
line [0.52, 1.29, 2.23, 3.87, 6.77, 14.34, 29.36, 64.78]
line [0.60, 1.29, 2.86, 3.51, 7.05, 14.46, 30.44, 63.78]
|
Bundle size comparison (
|
| 🟢 Decreased | ➖ Unchanged | 🔴 Increased (max 0.12%) | ❔ Unknown |
|---|---|---|---|
| 0 | 303 | 21 | 0 |
import { ... } in PR vs import * as ... in PR (is the library tree-Shakeable?):
| Test | tsdown |
|---|---|
| tgpu_init.ts | 271.29 kB ( |
| tgpu_initFromDevice.ts | 270.75 kB ( |
| tgpu_resolve.ts | 171.58 kB ( |
| tgpu_resolveWithContext.ts | 171.52 kB ( |
| tgpu_bindGroupLayout.ts | 73.94 kB ( |
| tgpu_mutableAccessor.ts | 68.66 kB ( |
| tgpu_accessor.ts | 68.66 kB ( |
| tgpu_privateVar.ts | 67.35 kB ( |
| tgpu_workgroupVar.ts | 67.35 kB ( |
| tgpu_const.ts | 66.77 kB ( |
| tgpu_lazy.ts | 66.56 kB ( |
| tgpu_fragmentFn.ts | 38.92 kB ( |
| tgpu_fn.ts | 38.87 kB ( |
| tgpu_vertexFn.ts | 38.74 kB ( |
| tgpu_computeFn.ts | 38.44 kB ( |
| tgpu_vertexLayout.ts | 27.57 kB ( |
| tgpu_comptime.ts | 15.18 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.
There was a problem hiding this comment.
Pull request overview
This PR updates the texture.write(...) image-source API to require explicit resize intent (via an options object) and prepares consumers for the stricter behavior planned in #2641, while updating tests, docs, and examples accordingly.
Changes:
- Add
TextureWriteOptions/fit: 'stretch'support and make mismatched image writes throw unless explicit stretching is requested. - Require
'render'usage for image-source writes and add coverage for the new error cases. - Update docs-site examples and MDX API docs to use
$usage('render')and{ fit: 'stretch' }.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/typegpu/tests/texture.test.ts | Updates/extends tests for new render-usage requirement and explicit resize behavior. |
| packages/typegpu/src/indexNamedExports.ts | Re-exports new public types (TextureWriteFit, TextureWriteOptions). |
| packages/typegpu/src/core/texture/texture.ts | Implements new write(..., options?) overload + explicit resize behavior and render-usage enforcement. |
| apps/typegpu-docs/src/examples/tests/texture-test/index.ts | Updates example calls to pass { fit: 'stretch' }. |
| apps/typegpu-docs/src/examples/simulation/gravity/helpers.ts | Updates texture writes to pass { fit: 'stretch' }. |
| apps/typegpu-docs/src/examples/algorithms/genetic-racing/index.ts | Updates texture write call to pass { fit: 'stretch' }. |
| apps/typegpu-docs/src/content/docs/apis/textures.mdx | Updates API docs to reflect new options and render-usage requirement. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
ℹ️ Minor suggestions — one design question and a small doc nit, both non-blocking.
Reviewed changes
- Texture write API:
TgpuTexture.writefor image sources now takes an optionalTextureWriteOptions(fit?: 'stretch') and throws when the source dimensions don't match the texture unlessfit: 'stretch'is passed. - Render-usage gate: image-source writes now require
'render'usage — enforced for every image write, including size-matched ones that don't resample. - Exports:
TextureWriteFitandTextureWriteOptionsadded toindexNamedExports.ts. - Tests: the old "handles resizing" test was split into three — missing-render throw (size-matched,
'sampled'only), missing-fitthrow (32x32 into 64x64), and thefit: 'stretch'resample path. - Docs/examples:
textures.mdx,genetic-racing,simulation/gravity/helpers, andtests/texture-testupdated to passfit: 'stretch'.
I traced every other image-write call site in the repo (3d-fish, blur, image-tuning, os-awards cubemap/model, liquid-glass, background-segmentation write(video)) — all are safe because they size the texture to the source and already declare 'render' usage.
ℹ️ 'render' gate is broader than the "explicit resize" promise
The gate fires for every image write, including size-matched writes that only perform a copyExternalImageToTexture (which needs COPY_DST, not RENDER_ATTACHMENT). So a $usage('sampled')-only texture that previously accepted a matching-size image now throws — a runtime regression beyond the "explicit resize option" scope implied by the title. This may be intended forward-compatibility for #2641, but worth a deliberate confirmation; if not, the gate could be scoped to the resampling path only.
ℹ️ Nitpicks
textures.mdxline 251 (Mipmaps example) still callstexture.write(imageBitmap)on a fixed[256, 256]texture with an arbitrary-sized bitmap, while the section above now documents that mismatched writes throw. That texture already has'render'usage, so add{ fit: 'stretch' }there too to keep the sample valid under the new rules.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found. The incremental changes address the prior review's feedback cleanly.
Reviewed changes
- Mipmap doc nit fixed:
textures.mdxMipmaps example now passes{ fit: 'stretch' }, so the sample is valid under the new mismatch rules. jelly-sliderfixture corrected: the test mockcreateImageBitmapsize changed from the default 2×2 to 512×256 (matching the atlas layer size innumbers.ts),expectedCallsdropped 6→4, and the inline snapshot was updated to drop the two resample shaders (vs_main/fs_mainVertexOutputpair). This is the right fix — under the new mismatch-throw rule the old 2×2 mock would have thrown, and since the example's real writes are size-matched, no resample shaders are generated anymore. Verified: the test passes and the fullindividual-example-testssuite (59 tests) is green.
The prior render-gate design question was confirmed as deliberate prep for #2641 and its thread is resolved.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
95c7eec to
7f16e99
Compare

This PR exists so #2641 does not introduce breaking changes