react-native-wgpu 0.1.5 → 0.1.7

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 (168) hide show
  1. package/README.md +43 -42
  2. package/android/cpp/AndroidPlatformContext.h +2 -1
  3. package/cpp/jsi/RNFJSIConverter.h +10 -0
  4. package/cpp/rnwgpu/SurfaceRegistry.h +1 -2
  5. package/cpp/rnwgpu/api/Canvas.h +3 -3
  6. package/cpp/rnwgpu/api/GPUBuffer.h +1 -1
  7. package/ios/WebGPUView.mm +14 -1
  8. package/lib/commonjs/Canvas.js.map +1 -1
  9. package/lib/commonjs/utils.js +2 -2
  10. package/lib/commonjs/utils.js.map +1 -1
  11. package/lib/module/Canvas.js.map +1 -1
  12. package/lib/module/utils.js +2 -2
  13. package/lib/module/utils.js.map +1 -1
  14. package/lib/typescript/lib/commonjs/utils.d.ts +1 -1
  15. package/lib/typescript/lib/commonjs/utils.d.ts.map +1 -1
  16. package/lib/typescript/lib/module/utils.d.ts +1 -1
  17. package/lib/typescript/lib/module/utils.d.ts.map +1 -1
  18. package/lib/typescript/src/Canvas.d.ts +3 -2
  19. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  20. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts +2 -0
  21. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts.map +1 -0
  22. package/lib/typescript/src/__tests__/Buffer.spec.d.ts +2 -0
  23. package/lib/typescript/src/__tests__/Buffer.spec.d.ts.map +1 -0
  24. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts +2 -0
  25. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts.map +1 -0
  26. package/lib/typescript/src/__tests__/Constants.spec.d.ts +2 -0
  27. package/lib/typescript/src/__tests__/Constants.spec.d.ts.map +1 -0
  28. package/lib/typescript/src/__tests__/Device.spec.d.ts +2 -0
  29. package/lib/typescript/src/__tests__/Device.spec.d.ts.map +1 -0
  30. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts +2 -0
  31. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts.map +1 -0
  32. package/lib/typescript/src/__tests__/GPU.spec.d.ts +2 -0
  33. package/lib/typescript/src/__tests__/GPU.spec.d.ts.map +1 -0
  34. package/lib/typescript/src/__tests__/ImageData.spec.d.ts +2 -0
  35. package/lib/typescript/src/__tests__/ImageData.spec.d.ts.map +1 -0
  36. package/lib/typescript/src/__tests__/Shaders.spec.d.ts +2 -0
  37. package/lib/typescript/src/__tests__/Shaders.spec.d.ts.map +1 -0
  38. package/lib/typescript/src/__tests__/Texture.spec.d.ts +2 -0
  39. package/lib/typescript/src/__tests__/Texture.spec.d.ts.map +1 -0
  40. package/lib/typescript/src/__tests__/components/DrawingContext.d.ts +12 -0
  41. package/lib/typescript/src/__tests__/components/DrawingContext.d.ts.map +1 -0
  42. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts +3 -0
  43. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts.map +1 -0
  44. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts +29 -0
  45. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts.map +1 -0
  46. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts +5 -0
  47. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts.map +1 -0
  48. package/lib/typescript/src/__tests__/components/cube.d.ts +7 -0
  49. package/lib/typescript/src/__tests__/components/cube.d.ts.map +1 -0
  50. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts +22 -0
  51. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts.map +1 -0
  52. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts +12 -0
  53. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts.map +1 -0
  54. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts +7 -0
  55. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts.map +1 -0
  56. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts +6 -0
  57. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts.map +1 -0
  58. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts +6 -0
  59. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts.map +1 -0
  60. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts +10 -0
  61. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts.map +1 -0
  62. package/lib/typescript/src/__tests__/components/triangle.d.ts +3 -0
  63. package/lib/typescript/src/__tests__/components/triangle.d.ts.map +1 -0
  64. package/lib/typescript/src/__tests__/config.d.ts +3 -0
  65. package/lib/typescript/src/__tests__/config.d.ts.map +1 -0
  66. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts +2 -0
  67. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts.map +1 -0
  68. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts +2 -0
  69. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts.map +1 -0
  70. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts +2 -0
  71. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts.map +1 -0
  72. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts +2 -0
  73. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts.map +1 -0
  74. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts +2 -0
  75. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts.map +1 -0
  76. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts +2 -0
  77. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts.map +1 -0
  78. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts +2 -0
  79. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts.map +1 -0
  80. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts +2 -0
  81. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts.map +1 -0
  82. package/lib/typescript/src/__tests__/globalSetup.d.ts +10 -0
  83. package/lib/typescript/src/__tests__/globalSetup.d.ts.map +1 -0
  84. package/lib/typescript/src/__tests__/globalTeardown.d.ts +3 -0
  85. package/lib/typescript/src/__tests__/globalTeardown.d.ts.map +1 -0
  86. package/lib/typescript/src/__tests__/setup.d.ts +62 -0
  87. package/lib/typescript/src/__tests__/setup.d.ts.map +1 -0
  88. package/lib/typescript/src/utils.d.ts +2 -1
  89. package/lib/typescript/src/utils.d.ts.map +1 -1
  90. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  91. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  92. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  93. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  94. package/libs/{ios/libwebgpu_dawn.xcframework/ios-arm64 → apple/arm64_iphoneos}/libwebgpu_dawn.a +0 -0
  95. package/libs/{ios → apple}/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
  96. package/libs/{ios → apple}/arm64_xros/libwebgpu_dawn.a +0 -0
  97. package/libs/{ios → apple}/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
  98. package/libs/{ios → apple}/libwebgpu_dawn.a +0 -0
  99. package/libs/{ios/arm64_iphoneos → apple/libwebgpu_dawn.xcframework/ios-arm64}/libwebgpu_dawn.a +0 -0
  100. package/libs/{ios → apple}/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  101. package/libs/apple/libwebgpu_dawn_macosx.xcframework/Info.plist +28 -0
  102. package/libs/apple/libwebgpu_dawn_macosx.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  103. package/libs/{ios/libwebgpu_dawn_visionos.xcframework/xros-arm64_x86_64-simulator → apple}/libwebgpu_dawn_visionos.a +0 -0
  104. package/libs/{ios → apple}/libwebgpu_dawn_visionos.xcframework/Info.plist +2 -2
  105. package/libs/{ios/arm64_xros/libwebgpu_dawn_visionos.a → apple/libwebgpu_dawn_visionos.xcframework/xros-arm64/libwebgpu_dawn.a} +0 -0
  106. package/libs/{ios → apple/libwebgpu_dawn_visionos.xcframework/xros-arm64_x86_64-simulator}/libwebgpu_dawn_visionos.a +0 -0
  107. package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
  108. package/libs/{ios → apple}/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  109. package/libs/{ios → apple}/x86_64_xrsimulator/libwebgpu_dawn.a +0 -0
  110. package/package.json +23 -22
  111. package/react-native-wgpu.podspec +2 -2
  112. package/src/Canvas.tsx +4 -2
  113. package/src/__tests__/ArrayBuffer.spec.ts +76 -0
  114. package/src/__tests__/Buffer.spec.ts +357 -0
  115. package/src/__tests__/ComputeShader.spec.ts +375 -0
  116. package/src/__tests__/Constants.spec.ts +91 -0
  117. package/src/__tests__/Device.spec.ts +35 -0
  118. package/src/__tests__/ExternalTexture.spec.ts +284 -0
  119. package/src/__tests__/GPU.spec.ts +229 -0
  120. package/src/__tests__/ImageData.spec.ts +26 -0
  121. package/src/__tests__/Shaders.spec.ts +232 -0
  122. package/src/__tests__/Texture.spec.ts +191 -0
  123. package/src/__tests__/assets/Di-3d.png +0 -0
  124. package/src/__tests__/components/DrawingContext.ts +11 -0
  125. package/src/__tests__/components/Wireframe/Shaders.ts +138 -0
  126. package/src/__tests__/components/Wireframe/models.ts +113 -0
  127. package/src/__tests__/components/Wireframe/utils.ts +22 -0
  128. package/src/__tests__/components/cube.ts +51 -0
  129. package/src/__tests__/components/meshes/mesh.ts +96 -0
  130. package/src/__tests__/components/meshes/sphere.ts +103 -0
  131. package/src/__tests__/components/meshes/stanfordDragon.ts +44 -0
  132. package/src/__tests__/components/meshes/stanfordDragonData.ts +5 -0
  133. package/src/__tests__/components/meshes/teapot.ts +13 -0
  134. package/src/__tests__/components/meshes/utils.ts +235 -0
  135. package/src/__tests__/components/triangle.ts +17 -0
  136. package/src/__tests__/config.ts +2 -0
  137. package/src/__tests__/demos/ABuffer.spec.ts +885 -0
  138. package/src/__tests__/demos/Blur.spec.ts +397 -0
  139. package/src/__tests__/demos/Cube.spec.ts +925 -0
  140. package/src/__tests__/demos/FractalCube.spec.ts +239 -0
  141. package/src/__tests__/demos/OcclusionQuery.spec.ts +376 -0
  142. package/src/__tests__/demos/RenderBundles.spec.ts +579 -0
  143. package/src/__tests__/demos/Triangle.spec.ts +248 -0
  144. package/src/__tests__/demos/Wireframe.spec.ts +190 -0
  145. package/src/__tests__/globalSetup.ts +54 -0
  146. package/src/__tests__/globalTeardown.ts +11 -0
  147. package/src/__tests__/setup.ts +409 -0
  148. package/src/__tests__/snapshots/abuffer.png +0 -0
  149. package/src/__tests__/snapshots/asteroid.png +0 -0
  150. package/src/__tests__/snapshots/blur.png +0 -0
  151. package/src/__tests__/snapshots/buffer.png +0 -0
  152. package/src/__tests__/snapshots/constant-triangle.png +0 -0
  153. package/src/__tests__/snapshots/cube.png +0 -0
  154. package/src/__tests__/snapshots/f.png +0 -0
  155. package/src/__tests__/snapshots/f2.png +0 -0
  156. package/src/__tests__/snapshots/fractal-cubes.png +0 -0
  157. package/src/__tests__/snapshots/instanced-cubes.png +0 -0
  158. package/src/__tests__/snapshots/occlusion-query.png +0 -0
  159. package/src/__tests__/snapshots/ref.png +0 -0
  160. package/src/__tests__/snapshots/texture.png +0 -0
  161. package/src/__tests__/snapshots/textured-cube.png +0 -0
  162. package/src/__tests__/snapshots/triangle-msaa.png +0 -0
  163. package/src/__tests__/snapshots/triangle.png +0 -0
  164. package/src/__tests__/snapshots/two-cube.png +0 -0
  165. package/src/utils.ts +3 -1
  166. package/android/gradle.properties +0 -5
  167. package/libs/ios/libwebgpu_dawn_visionos.xcframework/xros-arm64/libwebgpu_dawn_visionos.a +0 -0
  168. package/libs/{ios → apple}/libwebgpu_dawn.xcframework/Info.plist +5 -5
@@ -0,0 +1,284 @@
1
+ import { checkImage, client, encodeImage } from "./setup";
2
+
3
+ describe("External Textures", () => {
4
+ it("Simple (1)", async () => {
5
+ const result = await client.eval(
6
+ ({ gpu, device, ctx, urls: { fTexture } }) => {
7
+ const module = device.createShaderModule({
8
+ label: "our hardcoded textured quad shaders",
9
+ code: /* wgsl */ `
10
+ struct OurVertexShaderOutput {
11
+ @builtin(position) position: vec4f,
12
+ @location(0) texcoord: vec2f,
13
+ };
14
+
15
+ @vertex fn vs(
16
+ @builtin(vertex_index) vertexIndex : u32
17
+ ) -> OurVertexShaderOutput {
18
+ let pos = array(
19
+ // 1st triangle
20
+ vec2f( 0.0, 0.0), // center
21
+ vec2f( 1.0, 0.0), // right, center
22
+ vec2f( 0.0, 1.0), // center, top
23
+
24
+ // 2st triangle
25
+ vec2f( 0.0, 1.0), // center, top
26
+ vec2f( 1.0, 0.0), // right, center
27
+ vec2f( 1.0, 1.0), // right, top
28
+ );
29
+
30
+ var vsOutput: OurVertexShaderOutput;
31
+ let xy = pos[vertexIndex];
32
+ vsOutput.position = vec4f(xy, 0.0, 1.0);
33
+ vsOutput.texcoord = xy;
34
+ return vsOutput;
35
+ }
36
+
37
+ @group(0) @binding(0) var ourSampler: sampler;
38
+ @group(0) @binding(1) var ourTexture: texture_2d<f32>;
39
+
40
+ @fragment fn fs(fsInput: OurVertexShaderOutput) -> @location(0) vec4f {
41
+ return textureSample(ourTexture, ourSampler, fsInput.texcoord);
42
+ }
43
+ `,
44
+ });
45
+
46
+ const presentationFormat = gpu.getPreferredCanvasFormat();
47
+ const pipeline = device.createRenderPipeline({
48
+ label: "hardcoded textured quad pipeline",
49
+ layout: "auto",
50
+ vertex: {
51
+ module,
52
+ },
53
+ fragment: {
54
+ module,
55
+ targets: [{ format: presentationFormat }],
56
+ },
57
+ });
58
+
59
+ return fetch(fTexture).then((res) => {
60
+ return res.blob().then((blob) => {
61
+ return createImageBitmap(blob, {
62
+ colorSpaceConversion: "none",
63
+ }).then((source) => {
64
+ const texture = device.createTexture({
65
+ label: fTexture,
66
+ format: "rgba8unorm",
67
+ size: [source.width, source.height],
68
+ usage:
69
+ GPUTextureUsage.TEXTURE_BINDING |
70
+ GPUTextureUsage.COPY_DST |
71
+ GPUTextureUsage.RENDER_ATTACHMENT,
72
+ });
73
+ device.queue.copyExternalImageToTexture(
74
+ { source, flipY: true },
75
+ { texture },
76
+ { width: source.width, height: source.height },
77
+ );
78
+ const bindGroups: GPUBindGroup[] = [];
79
+ for (let i = 0; i < 8; ++i) {
80
+ const sampler = device.createSampler({
81
+ addressModeU: i & 1 ? "repeat" : "clamp-to-edge",
82
+ addressModeV: i & 2 ? "repeat" : "clamp-to-edge",
83
+ magFilter: i & 4 ? "linear" : "nearest",
84
+ });
85
+
86
+ const bindGroup = device.createBindGroup({
87
+ layout: pipeline.getBindGroupLayout(0),
88
+ entries: [
89
+ { binding: 0, resource: sampler },
90
+ { binding: 1, resource: texture.createView() },
91
+ ],
92
+ });
93
+ bindGroups.push(bindGroup);
94
+ }
95
+
96
+ const renderPassDescriptor: GPURenderPassDescriptor = {
97
+ label: "our basic canvas renderPass",
98
+ colorAttachments: [
99
+ {
100
+ view: ctx.getCurrentTexture().createView(), // Assigned later
101
+ clearValue: [0.3, 0.3, 0.3, 1],
102
+ loadOp: "clear",
103
+ storeOp: "store",
104
+ },
105
+ ],
106
+ };
107
+
108
+ const settings = {
109
+ addressModeU: "repeat",
110
+ addressModeV: "repeat",
111
+ magFilter: "linear",
112
+ };
113
+
114
+ function render() {
115
+ const ndx =
116
+ (settings.addressModeU === "repeat" ? 1 : 0) +
117
+ (settings.addressModeV === "repeat" ? 2 : 0) +
118
+ (settings.magFilter === "linear" ? 4 : 0);
119
+ const bindGroup = bindGroups[ndx];
120
+
121
+ const encoder = device.createCommandEncoder({
122
+ label: "render quad encoder",
123
+ });
124
+ const pass = encoder.beginRenderPass(renderPassDescriptor);
125
+ pass.setPipeline(pipeline);
126
+ pass.setBindGroup(0, bindGroup);
127
+ pass.draw(6); // call our vertex shader 6 times
128
+ pass.end();
129
+
130
+ const commandBuffer = encoder.finish();
131
+ device.queue.submit([commandBuffer]);
132
+ }
133
+ render();
134
+ return ctx.getImageData();
135
+ });
136
+ });
137
+ });
138
+ },
139
+ {},
140
+ );
141
+ const image = encodeImage(result);
142
+ checkImage(image, "snapshots/f.png");
143
+ });
144
+ it("Simple (2)", async () => {
145
+ const result = await client.eval(
146
+ ({ gpu, device, ctx, urls: { fTexture } }) => {
147
+ const module = device.createShaderModule({
148
+ label: "our hardcoded textured quad shaders",
149
+ code: /* wgsl */ `
150
+ struct OurVertexShaderOutput {
151
+ @builtin(position) position: vec4f,
152
+ @location(0) texcoord: vec2f,
153
+ };
154
+
155
+ @vertex fn vs(
156
+ @builtin(vertex_index) vertexIndex : u32
157
+ ) -> OurVertexShaderOutput {
158
+ let pos = array(
159
+ // 1st triangle
160
+ vec2f( 0.0, 0.0), // center
161
+ vec2f( 1.0, 0.0), // right, center
162
+ vec2f( 0.0, 1.0), // center, top
163
+
164
+ // 2st triangle
165
+ vec2f( 0.0, 1.0), // center, top
166
+ vec2f( 1.0, 0.0), // right, center
167
+ vec2f( 1.0, 1.0), // right, top
168
+ );
169
+
170
+ var vsOutput: OurVertexShaderOutput;
171
+ let xy = pos[vertexIndex];
172
+ vsOutput.position = vec4f(xy, 0.0, 1.0);
173
+ vsOutput.texcoord = xy;
174
+ return vsOutput;
175
+ }
176
+
177
+ @group(0) @binding(0) var ourSampler: sampler;
178
+ @group(0) @binding(1) var ourTexture: texture_2d<f32>;
179
+
180
+ @fragment fn fs(fsInput: OurVertexShaderOutput) -> @location(0) vec4f {
181
+ return textureSample(ourTexture, ourSampler, fsInput.texcoord);
182
+ }
183
+ `,
184
+ });
185
+
186
+ const presentationFormat = gpu.getPreferredCanvasFormat();
187
+ const pipeline = device.createRenderPipeline({
188
+ label: "hardcoded textured quad pipeline",
189
+ layout: "auto",
190
+ vertex: {
191
+ module,
192
+ },
193
+ fragment: {
194
+ module,
195
+ targets: [{ format: presentationFormat }],
196
+ },
197
+ });
198
+
199
+ return fetch(fTexture).then((res) => {
200
+ return res.blob().then((blob) => {
201
+ return createImageBitmap(blob, {
202
+ colorSpaceConversion: "none",
203
+ }).then((source) => {
204
+ const texture = device.createTexture({
205
+ label: fTexture,
206
+ format: "rgba8unorm",
207
+ size: [source.width, source.height],
208
+ usage:
209
+ GPUTextureUsage.TEXTURE_BINDING |
210
+ GPUTextureUsage.COPY_DST |
211
+ GPUTextureUsage.RENDER_ATTACHMENT,
212
+ });
213
+ device.queue.copyExternalImageToTexture(
214
+ { source },
215
+ { texture },
216
+ { width: source.width, height: source.height },
217
+ );
218
+ const bindGroups: GPUBindGroup[] = [];
219
+ for (let i = 0; i < 8; ++i) {
220
+ const sampler = device.createSampler({
221
+ addressModeU: i & 1 ? "repeat" : "clamp-to-edge",
222
+ addressModeV: i & 2 ? "repeat" : "clamp-to-edge",
223
+ magFilter: i & 4 ? "linear" : "nearest",
224
+ });
225
+
226
+ const bindGroup = device.createBindGroup({
227
+ layout: pipeline.getBindGroupLayout(0),
228
+ entries: [
229
+ { binding: 0, resource: sampler },
230
+ { binding: 1, resource: texture.createView() },
231
+ ],
232
+ });
233
+ bindGroups.push(bindGroup);
234
+ }
235
+
236
+ const renderPassDescriptor: GPURenderPassDescriptor = {
237
+ label: "our basic canvas renderPass",
238
+ colorAttachments: [
239
+ {
240
+ view: ctx.getCurrentTexture().createView(), // Assigned later
241
+ clearValue: [0.3, 0.3, 0.3, 1],
242
+ loadOp: "clear",
243
+ storeOp: "store",
244
+ },
245
+ ],
246
+ };
247
+
248
+ const settings = {
249
+ addressModeU: "repeat",
250
+ addressModeV: "repeat",
251
+ magFilter: "linear",
252
+ };
253
+
254
+ function render() {
255
+ const ndx =
256
+ (settings.addressModeU === "repeat" ? 1 : 0) +
257
+ (settings.addressModeV === "repeat" ? 2 : 0) +
258
+ (settings.magFilter === "linear" ? 4 : 0);
259
+ const bindGroup = bindGroups[ndx];
260
+
261
+ const encoder = device.createCommandEncoder({
262
+ label: "render quad encoder",
263
+ });
264
+ const pass = encoder.beginRenderPass(renderPassDescriptor);
265
+ pass.setPipeline(pipeline);
266
+ pass.setBindGroup(0, bindGroup);
267
+ pass.draw(6); // call our vertex shader 6 times
268
+ pass.end();
269
+
270
+ const commandBuffer = encoder.finish();
271
+ device.queue.submit([commandBuffer]);
272
+ }
273
+ render();
274
+ return ctx.getImageData();
275
+ });
276
+ });
277
+ });
278
+ },
279
+ {},
280
+ );
281
+ const image = encodeImage(result);
282
+ checkImage(image, "snapshots/f2.png");
283
+ });
284
+ });
@@ -0,0 +1,229 @@
1
+ import { client } from "./setup";
2
+
3
+ describe("Adapter", () => {
4
+ it("executes a simple function", async () => {
5
+ const result = await client.eval(() => 1 + 1);
6
+ expect(result).toBe(2);
7
+ });
8
+ it("executes a simple function from context", async () => {
9
+ const result = await client.eval(({ a, b, c }) => a + b + c, {
10
+ a: 1,
11
+ b: 2,
12
+ c: 3,
13
+ });
14
+ expect(result).toBe(6);
15
+ });
16
+ it("execute a simple async function (1)", async () => {
17
+ const result = await client.eval(
18
+ () =>
19
+ new Promise<number>((resolve) => setTimeout(() => resolve(1 + 1), 100)),
20
+ );
21
+ expect(result).toBe(2);
22
+ });
23
+ it("requestAdapter (1)", async () => {
24
+ const result = await client.eval(({ gpu }) => {
25
+ return gpu.requestAdapter().then((adapter) => adapter != null);
26
+ });
27
+ expect(result).toBe(true);
28
+ });
29
+ it("requestAdapter (2)", async () => {
30
+ const result = await client.eval(({ gpu }) => {
31
+ return gpu.requestAdapter(undefined).then((adapter) => adapter != null);
32
+ });
33
+ expect(result).toBe(true);
34
+ });
35
+ it("requestAdapter (3)", async () => {
36
+ const result = await client.eval(({ gpu }) => {
37
+ return gpu.requestAdapter(undefined).then((adapter) => adapter != null);
38
+ });
39
+ expect(result).toBe(true);
40
+ });
41
+ it("requestAdapter (4)", async () => {
42
+ const result = await client.eval(({ gpu }) => {
43
+ return gpu.requestAdapter({}).then((adapter) => adapter != null);
44
+ });
45
+ expect(result).toBe(true);
46
+ });
47
+ it("requestAdapter (5)", async () => {
48
+ const result = await client.eval(({ gpu }) => {
49
+ return gpu
50
+ .requestAdapter({ powerPreference: "low-power" })
51
+ .then((adapter) => adapter != null);
52
+ });
53
+ expect(result).toBe(true);
54
+ });
55
+ it("isFallback", async () => {
56
+ const result = await client.eval(({ adapter }) => {
57
+ return adapter.isFallbackAdapter;
58
+ });
59
+ expect(result).toBe(false);
60
+ });
61
+ it("features", async () => {
62
+ const result = await client.eval(({ adapter }) => {
63
+ return Array.from(adapter.features);
64
+ });
65
+ expect(result.includes("depth-clip-control")).toBe(true);
66
+ expect(result.includes("rg11b10ufloat-renderable")).toBe(true);
67
+ expect(result.includes("texture-compression-etc2")).toBe(true);
68
+ });
69
+ // it("requiredLimits", async () => {
70
+ // const result = await client.eval(({ adapter }) => {
71
+ // return adapter
72
+ // .requestDevice({
73
+ // requiredLimits: {
74
+ // maxBufferSize: 1024 * 1024 * 4,
75
+ // },
76
+ // })
77
+ // .then((device) => device.limits.maxBufferSize);
78
+ // });
79
+ // expect(result).toBe(1024 * 1024 * 4);
80
+ // });
81
+ // TODO: re-enable
82
+ // it("timestamp", async () => {
83
+ // const result = await client.eval(({ adapter }) => {
84
+ // return adapter.features.has("timestamp-query");
85
+ // });
86
+ // expect(result).toBe(true);
87
+ // });
88
+ // it("request device with timestamp queries", async () => {
89
+ // const result = await client.eval(({ adapter }) => {
90
+ // return adapter
91
+ // .requestDevice({
92
+ // requiredFeatures: ["timestamp-query"],
93
+ // })
94
+ // .then((device) => device.features.has("timestamp-query"));
95
+ // });
96
+ // expect(result).toBe(true);
97
+ // });
98
+ it("limits", async () => {
99
+ const result = await client.eval(({ adapter }) => {
100
+ const {
101
+ maxTextureDimension1D,
102
+ maxTextureDimension2D,
103
+ maxTextureDimension3D,
104
+ maxTextureArrayLayers,
105
+ maxBindGroups,
106
+ maxBindGroupsPlusVertexBuffers,
107
+ maxBindingsPerBindGroup,
108
+ maxDynamicUniformBuffersPerPipelineLayout,
109
+ maxDynamicStorageBuffersPerPipelineLayout,
110
+ maxSampledTexturesPerShaderStage,
111
+ maxSamplersPerShaderStage,
112
+ maxStorageBuffersPerShaderStage,
113
+ maxStorageTexturesPerShaderStage,
114
+ maxUniformBuffersPerShaderStage,
115
+ maxUniformBufferBindingSize,
116
+ maxStorageBufferBindingSize,
117
+ minUniformBufferOffsetAlignment,
118
+ minStorageBufferOffsetAlignment,
119
+ maxVertexBuffers,
120
+ maxBufferSize,
121
+ maxVertexAttributes,
122
+ maxVertexBufferArrayStride,
123
+ maxInterStageShaderComponents,
124
+ maxInterStageShaderVariables,
125
+ maxColorAttachments,
126
+ maxColorAttachmentBytesPerSample,
127
+ maxComputeWorkgroupStorageSize,
128
+ maxComputeInvocationsPerWorkgroup,
129
+ maxComputeWorkgroupSizeX,
130
+ maxComputeWorkgroupSizeY,
131
+ maxComputeWorkgroupSizeZ,
132
+ maxComputeWorkgroupsPerDimension,
133
+ } = adapter.limits;
134
+ return {
135
+ __brand: adapter.limits.__brand,
136
+ maxTextureDimension1D,
137
+ maxTextureDimension2D,
138
+ maxTextureDimension3D,
139
+ maxTextureArrayLayers,
140
+ maxBindGroups,
141
+ maxBindGroupsPlusVertexBuffers,
142
+ maxBindingsPerBindGroup,
143
+ maxDynamicUniformBuffersPerPipelineLayout,
144
+ maxDynamicStorageBuffersPerPipelineLayout,
145
+ maxSampledTexturesPerShaderStage,
146
+ maxSamplersPerShaderStage,
147
+ maxStorageBuffersPerShaderStage,
148
+ maxStorageTexturesPerShaderStage,
149
+ maxUniformBuffersPerShaderStage,
150
+ maxUniformBufferBindingSize,
151
+ maxStorageBufferBindingSize,
152
+ minUniformBufferOffsetAlignment,
153
+ minStorageBufferOffsetAlignment,
154
+ maxVertexBuffers,
155
+ maxBufferSize,
156
+ maxVertexAttributes,
157
+ maxVertexBufferArrayStride,
158
+ maxInterStageShaderComponents,
159
+ maxInterStageShaderVariables,
160
+ maxColorAttachments,
161
+ maxColorAttachmentBytesPerSample,
162
+ maxComputeWorkgroupStorageSize,
163
+ maxComputeInvocationsPerWorkgroup,
164
+ maxComputeWorkgroupSizeX,
165
+ maxComputeWorkgroupSizeY,
166
+ maxComputeWorkgroupSizeZ,
167
+ maxComputeWorkgroupsPerDimension,
168
+ };
169
+ });
170
+ if (result.__brand) {
171
+ expect(result.__brand).toBe("GPUSupportedLimits");
172
+ }
173
+ expect(result.maxBindGroups).toBeGreaterThan(0);
174
+ expect(result.maxBindGroupsPlusVertexBuffers).toBeGreaterThan(
175
+ result.maxBindGroups,
176
+ );
177
+ expect(result.maxBindingsPerBindGroup).toBeGreaterThan(0);
178
+ expect(result.maxBufferSize).toBeGreaterThan(0);
179
+ expect(result.maxColorAttachmentBytesPerSample).toBeGreaterThan(0);
180
+ expect(result.maxColorAttachments).toBeGreaterThan(0);
181
+ expect(result.maxComputeInvocationsPerWorkgroup).toBeGreaterThan(0);
182
+ expect(result.maxComputeWorkgroupSizeX).toBeGreaterThan(0);
183
+ expect(result.maxComputeWorkgroupSizeY).toBeGreaterThan(0);
184
+ expect(result.maxComputeWorkgroupSizeZ).toBeGreaterThan(0);
185
+ expect(result.maxComputeWorkgroupStorageSize).toBeGreaterThan(0);
186
+ expect(result.maxComputeWorkgroupsPerDimension).toBeGreaterThan(0);
187
+
188
+ // For alignment values, check if they're powers of 2
189
+ expect(Math.log2(result.minStorageBufferOffsetAlignment) % 1).toBe(0);
190
+ expect(Math.log2(result.minUniformBufferOffsetAlignment) % 1).toBe(0);
191
+
192
+ // For maximum dimensions, you might want to set a reasonable lower bound
193
+ expect(result.maxTextureDimension1D).toBeGreaterThanOrEqual(2048);
194
+ expect(result.maxTextureDimension2D).toBeGreaterThanOrEqual(2048);
195
+ expect(result.maxTextureDimension3D).toBeGreaterThanOrEqual(256);
196
+ });
197
+ // it("adapter info", async () => {
198
+ // const result = await client.eval(({ adapter }) => {
199
+ // return {
200
+ // __brand: adapter.info.__brand,
201
+ // description: adapter.info.description,
202
+ // architecture: adapter.info.architecture,
203
+ // device: adapter.info.device,
204
+ // vendor: adapter.info.vendor,
205
+ // };
206
+ // });
207
+ // expect(result.description).toBeTruthy();
208
+ // expect(result.architecture).toBeTruthy();
209
+ // expect(result.device).toBeTruthy();
210
+ // expect(result.vendor).toBeTruthy();
211
+ // });
212
+ it("getPreferredCanvasFormat", async () => {
213
+ const result = await client.eval(({ gpu }) => {
214
+ return gpu.getPreferredCanvasFormat();
215
+ });
216
+ expect(result).toBe(client.OS === "android" ? "rgba8unorm" : "bgra8unorm");
217
+ });
218
+ it("wgslLanguageFeatures", async () => {
219
+ const result = await client.eval(({ gpu }) => {
220
+ return Array.from(gpu.wgslLanguageFeatures);
221
+ });
222
+ expect(result.includes("readonly_and_readwrite_storage_textures")).toBe(
223
+ true,
224
+ );
225
+ expect(result.includes("packed_4x8_integer_dot_product")).toBe(true);
226
+ expect(result.includes("unrestricted_pointer_parameters")).toBe(true);
227
+ expect(result.includes("pointer_composite_access")).toBe(true);
228
+ });
229
+ });
@@ -0,0 +1,26 @@
1
+ import path from "path";
2
+
3
+ import { checkImage, client, encodeImage, decodeImage } from "./setup";
4
+
5
+ describe("Image Bitmap", () => {
6
+ it("createImageBitmap (1)", async () => {
7
+ const bitmap = await decodeImage(
8
+ path.join(__dirname, "./assets/Di-3d.png"),
9
+ );
10
+ const image = encodeImage(bitmap);
11
+ checkImage(image, "snapshots/ref.png");
12
+ });
13
+ it("createImageBitmap (2)", async () => {
14
+ const bitmap = await decodeImage(
15
+ path.join(__dirname, "./assets/Di-3d.png"),
16
+ );
17
+ const result = await client.eval(
18
+ ({ bitmap: bmp }) => {
19
+ return bmp;
20
+ },
21
+ { bitmap },
22
+ );
23
+ const image = encodeImage(result);
24
+ checkImage(image, "snapshots/ref.png");
25
+ });
26
+ });