@flighthq/render-wgpu 0.3.0-next.906.07cea63 → 0.3.1-next.209.43ef1bc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/contract.d.ts +7 -1
  2. package/dist/contract.d.ts.map +1 -1
  3. package/dist/contract.js +7 -1
  4. package/dist/contract.js.map +1 -1
  5. package/dist/enableWgpuTextureResolverGuards.d.ts +4 -0
  6. package/dist/enableWgpuTextureResolverGuards.d.ts.map +1 -0
  7. package/dist/enableWgpuTextureResolverGuards.js +8 -0
  8. package/dist/enableWgpuTextureResolverGuards.js.map +1 -0
  9. package/dist/explainWgpuTextureResolution.d.ts +3 -0
  10. package/dist/explainWgpuTextureResolution.d.ts.map +1 -0
  11. package/dist/explainWgpuTextureResolution.js +14 -0
  12. package/dist/explainWgpuTextureResolution.js.map +1 -0
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/wgpuBackground.js +2 -2
  18. package/dist/wgpuBackground.js.map +1 -1
  19. package/dist/wgpuCompressedTexture.d.ts +2 -2
  20. package/dist/wgpuCompressedTexture.d.ts.map +1 -1
  21. package/dist/wgpuCompressedTexture.js +40 -12
  22. package/dist/wgpuCompressedTexture.js.map +1 -1
  23. package/dist/wgpuDraw.d.ts +6 -4
  24. package/dist/wgpuDraw.d.ts.map +1 -1
  25. package/dist/wgpuDraw.js +139 -67
  26. package/dist/wgpuDraw.js.map +1 -1
  27. package/dist/wgpuExternalImageSource.d.ts +3 -0
  28. package/dist/wgpuExternalImageSource.d.ts.map +1 -0
  29. package/dist/wgpuExternalImageSource.js +51 -0
  30. package/dist/wgpuExternalImageSource.js.map +1 -0
  31. package/dist/wgpuExternalTexture.d.ts +4 -0
  32. package/dist/wgpuExternalTexture.d.ts.map +1 -0
  33. package/dist/wgpuExternalTexture.js +62 -0
  34. package/dist/wgpuExternalTexture.js.map +1 -0
  35. package/dist/wgpuMaterialRegistry.d.ts.map +1 -1
  36. package/dist/wgpuMaterialRegistry.js +10 -9
  37. package/dist/wgpuMaterialRegistry.js.map +1 -1
  38. package/dist/wgpuMipmap.d.ts.map +1 -1
  39. package/dist/wgpuMipmap.js +11 -9
  40. package/dist/wgpuMipmap.js.map +1 -1
  41. package/dist/wgpuRenderState.d.ts +11 -2
  42. package/dist/wgpuRenderState.d.ts.map +1 -1
  43. package/dist/wgpuRenderState.js +217 -30
  44. package/dist/wgpuRenderState.js.map +1 -1
  45. package/dist/wgpuRenderTarget.d.ts.map +1 -1
  46. package/dist/wgpuRenderTarget.js +2 -0
  47. package/dist/wgpuRenderTarget.js.map +1 -1
  48. package/dist/wgpuRenderTexture.d.ts +15 -0
  49. package/dist/wgpuRenderTexture.d.ts.map +1 -0
  50. package/dist/wgpuRenderTexture.js +130 -0
  51. package/dist/wgpuRenderTexture.js.map +1 -0
  52. package/dist/wgpuRenderTexturePool.d.ts +7 -0
  53. package/dist/wgpuRenderTexturePool.d.ts.map +1 -0
  54. package/dist/wgpuRenderTexturePool.js +86 -0
  55. package/dist/wgpuRenderTexturePool.js.map +1 -0
  56. package/dist/wgpuShader.d.ts.map +1 -1
  57. package/dist/wgpuShader.js +5 -1
  58. package/dist/wgpuShader.js.map +1 -1
  59. package/dist/wgpuSurface.d.ts +2 -2
  60. package/dist/wgpuSurface.d.ts.map +1 -1
  61. package/dist/wgpuSurface.js +61 -13
  62. package/dist/wgpuSurface.js.map +1 -1
  63. package/dist/wgpuTestHelper.d.ts +1 -0
  64. package/dist/wgpuTestHelper.d.ts.map +1 -1
  65. package/dist/wgpuTestHelper.js +15 -1
  66. package/dist/wgpuTestHelper.js.map +1 -1
  67. package/dist/wgpuTextureResolver.d.ts +9 -0
  68. package/dist/wgpuTextureResolver.d.ts.map +1 -0
  69. package/dist/wgpuTextureResolver.js +67 -0
  70. package/dist/wgpuTextureResolver.js.map +1 -0
  71. package/dist/wgpuTextureUpload.d.ts +2 -2
  72. package/dist/wgpuTextureUpload.d.ts.map +1 -1
  73. package/dist/wgpuTextureUpload.js +5 -10
  74. package/dist/wgpuTextureUpload.js.map +1 -1
  75. package/package.json +13 -7
  76. package/src/enableWgpuTextureResolverGuards.test.ts +65 -0
  77. package/src/explainWgpuTextureResolution.test.ts +36 -0
  78. package/src/wgpuCompressedTexture.test.ts +18 -35
  79. package/src/wgpuDraw.test.ts +164 -62
  80. package/src/wgpuExternalImageSource.test.ts +89 -0
  81. package/src/wgpuExternalTexture.test.ts +35 -0
  82. package/src/wgpuMaterialRegistry.test.ts +28 -2
  83. package/src/wgpuMipmap.test.ts +10 -2
  84. package/src/wgpuRenderState.test.ts +143 -11
  85. package/src/wgpuRenderTarget.test.ts +14 -0
  86. package/src/wgpuRenderTexture.test.ts +165 -0
  87. package/src/wgpuRenderTexturePool.test.ts +146 -0
  88. package/src/wgpuShaderBinding.test.ts +6 -6
  89. package/src/wgpuSurface.test.ts +95 -3
  90. package/src/wgpuTextureResolver.test.ts +209 -0
  91. package/src/wgpuTextureUpload.test.ts +28 -13
@@ -0,0 +1,67 @@
1
+ import { getTextureSampleColorSpace, getTextureSource, getTextureSourceKind } from '@flighthq/texture/contract';
2
+ import { BitmapTextureSourceKind, CompressedImageTextureSourceKind, ImageTextureSourceKind, RenderRegistry, RenderTargetTextureSourceKind, } from '@flighthq/types/contract';
3
+ import { bindWgpuBitmapTexture, bindWgpuCompressedImageTexture, bindWgpuImageResourceTexture } from './wgpuDraw';
4
+ import { getWgpuRenderStateRuntime } from './wgpuRenderState';
5
+ import { bindWgpuRenderTexture } from './wgpuRenderTexture';
6
+ export function registerStandardWgpuTextureResolvers(state) {
7
+ registerWgpuBitmapTextureResolver(state);
8
+ registerWgpuImageTextureResolver(state);
9
+ registerWgpuRenderTextureResolver(state);
10
+ }
11
+ export function registerWgpuBitmapTextureResolver(state) {
12
+ registerWgpuTextureResolver(state, BitmapTextureSourceKind, resolveWgpuBitmapTexture);
13
+ }
14
+ export function registerWgpuCompressedImageTextureResolver(state) {
15
+ registerWgpuTextureResolver(state, CompressedImageTextureSourceKind, resolveWgpuCompressedImageTexture);
16
+ }
17
+ export function registerWgpuImageTextureResolver(state) {
18
+ registerWgpuTextureResolver(state, ImageTextureSourceKind, resolveWgpuImageTexture);
19
+ }
20
+ export function registerWgpuRenderTextureResolver(state) {
21
+ registerWgpuTextureResolver(state, RenderTargetTextureSourceKind, resolveWgpuRenderTexture);
22
+ }
23
+ // Registers or replaces one declared source-kind resolver on this render state. Map.set is
24
+ // last-write-wins; passing null removes the key.
25
+ export function registerWgpuTextureResolver(state, sourceKind, resolver) {
26
+ const runtime = getWgpuRenderStateRuntime(state);
27
+ const registry = (runtime.wgpuTextureResolverRegistry ??= new Map());
28
+ if (resolver === null)
29
+ registry.delete(sourceKind);
30
+ else
31
+ registry.set(sourceKind, resolver);
32
+ }
33
+ // Resolves through one keyed lookup using the source's declared kind. Resolution may realize, upload,
34
+ // and cache the GPU entry, but unlike the GL twin it does not bind command-pass state; the draw caller
35
+ // binds the returned entry's group explicitly.
36
+ export function resolveWgpuTexture(state, texture, premultiply = false, workingColorSpace = 'linear') {
37
+ const sourceKind = getTextureSourceKind(texture);
38
+ if (sourceKind === null)
39
+ return null;
40
+ const runtime = getWgpuRenderStateRuntime(state);
41
+ const resolver = runtime.wgpuTextureResolverRegistry?.get(sourceKind);
42
+ if (resolver === undefined) {
43
+ runtime.registryMiss?.(RenderRegistry.TextureResolver, sourceKind);
44
+ return null;
45
+ }
46
+ return resolver(state, texture, premultiply, getTextureSampleColorSpace(texture.colorSpace, workingColorSpace));
47
+ }
48
+ function resolveWgpuBitmapTexture(state, texture, premultiply, colorSpace) {
49
+ const bitmap = getTextureSource(texture);
50
+ return bitmap === null
51
+ ? null
52
+ : bindWgpuBitmapTexture(state, bitmap, texture.sampler.mipmaps, premultiply, colorSpace);
53
+ }
54
+ function resolveWgpuCompressedImageTexture(state, texture, _premultiply, colorSpace) {
55
+ const image = getTextureSource(texture);
56
+ return image === null ? null : bindWgpuCompressedImageTexture(state, image, colorSpace);
57
+ }
58
+ function resolveWgpuImageTexture(state, texture, premultiply, colorSpace) {
59
+ const image = getTextureSource(texture);
60
+ return image === null
61
+ ? null
62
+ : bindWgpuImageResourceTexture(state, image, texture.sampler.mipmaps, premultiply, colorSpace);
63
+ }
64
+ function resolveWgpuRenderTexture(state, texture) {
65
+ return bindWgpuRenderTexture(state, texture);
66
+ }
67
+ //# sourceMappingURL=wgpuTextureResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuTextureResolver.js","sourceRoot":"","sources":["../src/wgpuTextureResolver.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import type { ImageResource } from '@flighthq/types/contract';
1
+ import type { Image } from '@flighthq/types/contract';
2
2
  export declare function uploadWgpuTextureData(device: GPUDevice, texture: GPUTexture, origin: GPUOrigin3D, width: number, height: number, data: Readonly<Uint8ClampedArray<ArrayBuffer>>): void;
3
3
  export declare function uploadWgpuTextureElement(device: GPUDevice, texture: GPUTexture, origin: GPUOrigin3D, width: number, height: number, source: GPUCopyExternalImageSource): void;
4
- export declare function uploadWgpuTextureImageResource(device: GPUDevice, texture: GPUTexture, origin: GPUOrigin3D, image: Readonly<ImageResource>): void;
4
+ export declare function uploadWgpuTextureImageResource(device: GPUDevice, texture: GPUTexture, origin: GPUOrigin3D, image: Readonly<Image>): void;
5
5
  //# sourceMappingURL=wgpuTextureUpload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wgpuTextureUpload.d.ts","sourceRoot":"","sources":["../src/wgpuTextureUpload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAS9D,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,GAC7C,IAAI,CAON;AAID,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,0BAA0B,GACjC,IAAI,CAEN;AAID,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,GAC7B,IAAI,CAaN"}
1
+ {"version":3,"file":"wgpuTextureUpload.d.ts","sourceRoot":"","sources":["../src/wgpuTextureUpload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAWtD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,GAC7C,IAAI,CAON;AAID,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,0BAA0B,GACjC,IAAI,CAEN;AAGD,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GACrB,IAAI,CASN"}
@@ -1,25 +1,20 @@
1
+ import { tryCopyWgpuExternalImageToTexture } from './wgpuExternalImageSource';
1
2
  // Texel-upload primitives for one texture region. Each writes into `texture` at `origin` (the [x, y, z]
2
3
  // where z selects a cube-array layer / cube face). The wgpu mirror of render-gl's glTextureUpload; the
3
4
  // caller owns texture creation and format.
4
5
  // Uploads rgba8 CPU pixels through queue.writeTexture — the portable bedrock upload, reimplemented 1:1 by
5
6
  // a native backend. `bytesPerRow` is width*4: a tightly-packed rgba8unorm (4 bytes/texel) region, which is
6
- // exactly what a Surface's `data` holds.
7
+ // exactly what a Bitmap's `data` holds.
7
8
  export function uploadWgpuTextureData(device, texture, origin, width, height, data) {
8
9
  device.queue.writeTexture({ texture, origin }, data, { bytesPerRow: width * 4, rowsPerImage: height }, [width, height, 1]);
9
10
  }
10
11
  // Uploads a decoded DOM element through queue.copyExternalImageToTexture — the web fast-path (GPU-side
11
12
  // copy, no CPU staging). Absent on non-web hosts.
12
13
  export function uploadWgpuTextureElement(device, texture, origin, width, height, source) {
13
- device.queue.copyExternalImageToTexture({ source }, { texture, origin }, [width, height, 1]);
14
+ tryCopyWgpuExternalImageToTexture(device.queue, { source }, { texture, origin }, width, height);
14
15
  }
15
- // Dispatches an ImageResource to the element fast-path when a decoded `source` is present, else the
16
- // portable `data` path (a generated Surface). Assumes the resource has pixels in at least one form.
16
+ // Uploads a host-backed Image through the decoded-element fast path.
17
17
  export function uploadWgpuTextureImageResource(device, texture, origin, image) {
18
- if (image.source !== null) {
19
- uploadWgpuTextureElement(device, texture, origin, image.width, image.height, image.source);
20
- }
21
- else {
22
- uploadWgpuTextureData(device, texture, origin, image.width, image.height, image.data);
23
- }
18
+ uploadWgpuTextureElement(device, texture, origin, image.width, image.height, image.source);
24
19
  }
25
20
  //# sourceMappingURL=wgpuTextureUpload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wgpuTextureUpload.js","sourceRoot":"","sources":["../src/wgpuTextureUpload.ts"],"names":[],"mappings":"AAEA,wGAAwG;AACxG,uGAAuG;AACvG,2CAA2C;AAE3C,0GAA0G;AAC1G,2GAA2G;AAC3G,yCAAyC;AACzC,MAAM,UAAU,qBAAqB,CACnC,MAAiB,EACjB,OAAmB,EACnB,MAAmB,EACnB,KAAa,EACb,MAAc,EACd,IAA8C;IAE9C,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,EAAE,OAAO,EAAE,MAAM,EAAE,EACnB,IAAsC,EACtC,EAAE,WAAW,EAAE,KAAK,GAAG,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,EAChD,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CACnB,CAAC;AACJ,CAAC;AAED,uGAAuG;AACvG,kDAAkD;AAClD,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,OAAmB,EACnB,MAAmB,EACnB,KAAa,EACb,MAAc,EACd,MAAkC;IAElC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED,oGAAoG;AACpG,oGAAoG;AACpG,MAAM,UAAU,8BAA8B,CAC5C,MAAiB,EACjB,OAAmB,EACnB,MAAmB,EACnB,KAA8B;IAE9B,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC1B,wBAAwB,CACtB,MAAM,EACN,OAAO,EACP,MAAM,EACN,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,MAAoC,CAC3C,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,qBAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAK,CAAC,CAAC;IACzF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"wgpuTextureUpload.js","sourceRoot":"","sources":["../src/wgpuTextureUpload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AAE9E,wGAAwG;AACxG,uGAAuG;AACvG,2CAA2C;AAE3C,0GAA0G;AAC1G,2GAA2G;AAC3G,wCAAwC;AACxC,MAAM,UAAU,qBAAqB,CACnC,MAAiB,EACjB,OAAmB,EACnB,MAAmB,EACnB,KAAa,EACb,MAAc,EACd,IAA8C;IAE9C,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,EAAE,OAAO,EAAE,MAAM,EAAE,EACnB,IAAsC,EACtC,EAAE,WAAW,EAAE,KAAK,GAAG,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,EAChD,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CACnB,CAAC;AACJ,CAAC;AAED,uGAAuG;AACvG,kDAAkD;AAClD,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,OAAmB,EACnB,MAAmB,EACnB,KAAa,EACb,MAAc,EACd,MAAkC;IAElC,iCAAiC,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAClG,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,8BAA8B,CAC5C,MAAiB,EACjB,OAAmB,EACnB,MAAmB,EACnB,KAAsB;IAEtB,wBAAwB,CACtB,MAAM,EACN,OAAO,EACP,MAAM,EACN,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,MAAoC,CAC3C,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "name": "@flighthq/render-wgpu",
3
- "version": "0.3.0-next.906.07cea63",
3
+ "version": "0.3.1-next.209.43ef1bc",
4
+ "author": "Joshua Granick and other contributors",
5
+ "license": "MIT",
4
6
  "repository": {
5
7
  "type": "git",
6
8
  "url": "https://github.com/flighthq/flight.git",
@@ -36,12 +38,16 @@
36
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
37
39
  },
38
40
  "dependencies": {
39
- "@flighthq/color": "0.3.0-next.906.07cea63",
40
- "@flighthq/scene2d": "0.3.0-next.906.07cea63",
41
- "@flighthq/geometry": "0.3.0-next.906.07cea63",
42
- "@flighthq/render": "0.3.0-next.906.07cea63",
43
- "@flighthq/surface": "0.3.0-next.906.07cea63",
44
- "@flighthq/types": "0.3.0-next.906.07cea63"
41
+ "@flighthq/color": "0.3.1-next.209.43ef1bc",
42
+ "@flighthq/entity": "0.3.1-next.209.43ef1bc",
43
+ "@flighthq/scene2d": "0.3.1-next.209.43ef1bc",
44
+ "@flighthq/geometry": "0.3.1-next.209.43ef1bc",
45
+ "@flighthq/log": "0.3.1-next.209.43ef1bc",
46
+ "@flighthq/render": "0.3.1-next.209.43ef1bc",
47
+ "@flighthq/signals": "0.3.1-next.209.43ef1bc",
48
+ "@flighthq/bitmap": "0.3.1-next.209.43ef1bc",
49
+ "@flighthq/texture": "0.3.1-next.209.43ef1bc",
50
+ "@flighthq/types": "0.3.1-next.209.43ef1bc"
45
51
  },
46
52
  "devDependencies": {
47
53
  "@webgpu/types": "*",
@@ -0,0 +1,65 @@
1
+ import { addLogSink, createMemoryLogSink, getMemoryLogSinkEntries, removeLogSink } from '@flighthq/log/contract';
2
+ import { createTexture } from '@flighthq/texture/contract';
3
+ import type { Image } from '@flighthq/types/contract';
4
+
5
+ import {
6
+ areWgpuTextureResolverGuardsEnabled,
7
+ enableWgpuTextureResolverGuards,
8
+ } from './enableWgpuTextureResolverGuards';
9
+ import { createWgpuRenderStateForTest, installWgpuMock } from './wgpuTestHelper';
10
+ import { registerWgpuTextureResolver, resolveWgpuTexture } from './wgpuTextureResolver';
11
+
12
+ beforeAll(() => {
13
+ installWgpuMock();
14
+ });
15
+
16
+ describe('areWgpuTextureResolverGuardsEnabled', () => {
17
+ it('reports whether diagnostics were installed for the state', async () => {
18
+ const state = await createWgpuRenderStateForTest();
19
+ expect(areWgpuTextureResolverGuardsEnabled(state)).toBe(false);
20
+
21
+ enableWgpuTextureResolverGuards(state);
22
+ expect(areWgpuTextureResolverGuardsEnabled(state)).toBe(true);
23
+ });
24
+ });
25
+
26
+ describe('enableWgpuTextureResolverGuards', () => {
27
+ it('is idempotent', async () => {
28
+ const state = await createWgpuRenderStateForTest();
29
+ enableWgpuTextureResolverGuards(state);
30
+ enableWgpuTextureResolverGuards(state);
31
+ expect(areWgpuTextureResolverGuardsEnabled(state)).toBe(true);
32
+ });
33
+
34
+ it('warns once for a missing resolver and stays silent for a registered resolver returning null', async () => {
35
+ const state = await createWgpuRenderStateForTest();
36
+ const missing = textureWithKind('acme.missing.wgpu');
37
+ const registered = textureWithKind('acme.registered.wgpu');
38
+ const sink = createMemoryLogSink(4);
39
+ addLogSink(sink.sink);
40
+ enableWgpuTextureResolverGuards(state);
41
+ registerWgpuTextureResolver(state, 'acme.registered.wgpu', () => null);
42
+ try {
43
+ expect(resolveWgpuTexture(state, missing)).toBeNull();
44
+ expect(resolveWgpuTexture(state, missing)).toBeNull();
45
+ expect(resolveWgpuTexture(state, registered)).toBeNull();
46
+
47
+ const entries = getMemoryLogSinkEntries(sink);
48
+ expect(entries).toHaveLength(1);
49
+ expect(entries[0]?.data).toMatchObject({
50
+ kind: 'acme.missing.wgpu',
51
+ message:
52
+ 'resolveWgpuTexture: texture source kind has no registered resolver — call registerWgpuTextureResolver(state, sourceKind, resolver)',
53
+ });
54
+ } finally {
55
+ removeLogSink(sink.sink);
56
+ }
57
+ });
58
+ });
59
+
60
+ function textureWithKind(kind: string) {
61
+ return createTexture({
62
+ dimension: '2d',
63
+ source: { kind } as Image,
64
+ });
65
+ }
@@ -0,0 +1,36 @@
1
+ import { createEntity } from '@flighthq/entity/contract';
2
+ import { createTexture } from '@flighthq/texture/contract';
3
+ import type { TextureSource } from '@flighthq/types/contract';
4
+
5
+ import { explainWgpuTextureResolution } from './explainWgpuTextureResolution';
6
+ import { createWgpuRenderStateForTest, installWgpuMock } from './wgpuTestHelper';
7
+ import { registerWgpuTextureResolver } from './wgpuTextureResolver';
8
+
9
+ beforeAll(() => {
10
+ installWgpuMock();
11
+ });
12
+
13
+ describe('explainWgpuTextureResolution', () => {
14
+ it('distinguishes missing kinds, missing resolvers, and registered resolvers', async () => {
15
+ const state = await createWgpuRenderStateForTest();
16
+ const texture = createTexture({
17
+ dimension: '2d',
18
+ source: createEntity({ height: 1, kind: 'acme.test', version: 0, width: 1 }) as TextureSource,
19
+ });
20
+
21
+ expect(explainWgpuTextureResolution(state, createTexture())).toEqual({
22
+ kind: null,
23
+ status: 'missing-kind',
24
+ });
25
+ expect(explainWgpuTextureResolution(state, texture)).toEqual({
26
+ kind: 'acme.test',
27
+ status: 'missing-resolver',
28
+ });
29
+
30
+ registerWgpuTextureResolver(state, 'acme.test', () => null);
31
+ expect(explainWgpuTextureResolution(state, texture)).toEqual({
32
+ kind: 'acme.test',
33
+ status: 'registered',
34
+ });
35
+ });
36
+ });
@@ -1,4 +1,5 @@
1
- import type { ImageResource, TextureContainer, WgpuCompressedTextureSupport } from '@flighthq/types/contract';
1
+ import type { CompressedImage, TextureContainer, WgpuCompressedTextureSupport } from '@flighthq/types/contract';
2
+ import { CompressedImageTextureSourceKind } from '@flighthq/types/contract';
2
3
 
3
4
  import {
4
5
  detectWgpuCompressedTextureSupport,
@@ -8,7 +9,7 @@ import {
8
9
  registerWgpuCompressedTextureUpload,
9
10
  uploadWgpuCompressedTextureContainer,
10
11
  } from './wgpuCompressedTexture';
11
- import { bindWgpuImageResourceTexture } from './wgpuDraw';
12
+ import { bindWgpuCompressedImageTexture } from './wgpuDraw';
12
13
  import { getWgpuRenderStateRuntime } from './wgpuRenderState';
13
14
  import { createWgpuRenderStateForTest, installWgpuMock } from './wgpuTestHelper';
14
15
 
@@ -29,6 +30,16 @@ function container(overrides: Partial<TextureContainer> = {}): TextureContainer
29
30
  };
30
31
  }
31
32
 
33
+ function compressedImage(): CompressedImage {
34
+ return {
35
+ compressed: { container: container(), payload: new Uint8Array(8) },
36
+ height: 4,
37
+ kind: CompressedImageTextureSourceKind,
38
+ version: 1,
39
+ width: 4,
40
+ } as unknown as CompressedImage;
41
+ }
42
+
32
43
  describe('detectWgpuCompressedTextureSupport', () => {
33
44
  it('reads the three WebGPU compression features', async () => {
34
45
  const state = await createWgpuRenderStateForTest();
@@ -69,7 +80,7 @@ describe('registerWgpuCompressedTextureDecoder', () => {
69
80
  });
70
81
 
71
82
  describe('registerWgpuCompressedTextureUpload', () => {
72
- it('installs and clears the ImageResource upload seam', async () => {
83
+ it('installs and clears the CompressedImage upload seam', async () => {
73
84
  const state = await createWgpuRenderStateForTest();
74
85
  registerWgpuCompressedTextureUpload(state);
75
86
  expect(getWgpuRenderStateRuntime(state).compressedTextureUpload).toBeTypeOf('function');
@@ -77,23 +88,14 @@ describe('registerWgpuCompressedTextureUpload', () => {
77
88
  expect(getWgpuRenderStateRuntime(state).compressedTextureUpload).toBeNull();
78
89
  });
79
90
 
80
- it('lets the normal image binder consume a compressed-only resource', async () => {
91
+ it('lets the compressed-image binder consume its source', async () => {
81
92
  const state = await createWgpuRenderStateForTest();
82
93
  registerWgpuCompressedTextureUpload(state);
83
94
  registerWgpuCompressedTextureDecoder(state, (_format, width, height) => {
84
95
  return new Uint8ClampedArray(width * height * 4);
85
96
  });
86
- const image = {
87
- alphaType: 'straight',
88
- compressed: { container: container(), payload: new Uint8Array(8) },
89
- data: null,
90
- height: 4,
91
- source: null,
92
- version: 1,
93
- width: 4,
94
- } as unknown as ImageResource;
95
97
  const writeTexture = vi.spyOn(state.device.queue, 'writeTexture');
96
- expect(bindWgpuImageResourceTexture(state, image).view).toBeDefined();
98
+ expect(bindWgpuCompressedImageTexture(state, compressedImage())?.view).toBeDefined();
97
99
  expect(writeTexture).toHaveBeenCalledTimes(1);
98
100
  });
99
101
 
@@ -109,18 +111,9 @@ describe('registerWgpuCompressedTextureUpload', () => {
109
111
  }
110
112
  return rgba;
111
113
  });
112
- const image = {
113
- alphaType: 'straight',
114
- compressed: { container: container(), payload: new Uint8Array(8) },
115
- data: null,
116
- height: 4,
117
- source: null,
118
- version: 1,
119
- width: 4,
120
- } as unknown as ImageResource;
121
114
  const writeTexture = vi.spyOn(state.device.queue, 'writeTexture');
122
115
 
123
- const entry = bindWgpuImageResourceTexture(state, image);
116
+ const entry = bindWgpuCompressedImageTexture(state, compressedImage())!;
124
117
 
125
118
  expect(entry.straightAlpha).toBe(false);
126
119
  expect(Array.from(writeTexture.mock.calls[0][1] as Uint8ClampedArray).slice(0, 4)).toEqual([128, 32, 0, 128]);
@@ -130,17 +123,7 @@ describe('registerWgpuCompressedTextureUpload', () => {
130
123
  const state = await createWgpuRenderStateForTest();
131
124
  (state.device.features as Set<GPUFeatureName>).add('texture-compression-bc');
132
125
  registerWgpuCompressedTextureUpload(state);
133
- const image = {
134
- alphaType: 'straight',
135
- compressed: { container: container(), payload: new Uint8Array(8) },
136
- data: null,
137
- height: 4,
138
- source: null,
139
- version: 1,
140
- width: 4,
141
- } as unknown as ImageResource;
142
-
143
- expect(bindWgpuImageResourceTexture(state, image).straightAlpha).toBe(true);
126
+ expect(bindWgpuCompressedImageTexture(state, compressedImage())?.straightAlpha).toBe(true);
144
127
  });
145
128
  });
146
129