react-native-wgpu 0.2.10 → 0.3.0

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 (248) hide show
  1. package/README.md +155 -69
  2. package/android/CMakeLists.txt +4 -5
  3. package/android/build.gradle +7 -18
  4. package/android/src/main/java/com/webgpu/WebGPUViewPackage.java +34 -10
  5. package/apple/MetalView.mm +0 -19
  6. package/apple/WebGPUModule.h +1 -9
  7. package/apple/WebGPUModule.mm +0 -3
  8. package/apple/WebGPUView.h +0 -3
  9. package/apple/WebGPUView.mm +0 -2
  10. package/cpp/WGPULogger.h +10 -0
  11. package/cpp/dawn/dawn_proc_table.h +1 -1
  12. package/cpp/dawn/webgpu.h +4855 -0
  13. package/cpp/dawn/webgpu_cpp.h +10168 -0
  14. package/cpp/dawn/wire/client/webgpu.h +354 -0
  15. package/cpp/dawn/wire/client/webgpu_cpp.h +10343 -0
  16. package/cpp/dawn/wire/client/webgpu_cpp_print.h +2715 -0
  17. package/cpp/jsi/RNFJSIConverter.h +17 -59
  18. package/cpp/rnwgpu/RNWebGPUManager.cpp +1 -9
  19. package/cpp/rnwgpu/api/GPU.cpp +51 -26
  20. package/cpp/rnwgpu/api/GPU.h +5 -18
  21. package/cpp/rnwgpu/api/GPUAdapter.cpp +75 -54
  22. package/cpp/rnwgpu/api/GPUAdapter.h +6 -6
  23. package/cpp/rnwgpu/api/GPUAdapterInfo.h +0 -1
  24. package/cpp/rnwgpu/api/GPUBindGroup.h +1 -3
  25. package/cpp/rnwgpu/api/GPUBindGroupLayout.h +1 -3
  26. package/cpp/rnwgpu/api/GPUBuffer.cpp +35 -32
  27. package/cpp/rnwgpu/api/GPUBuffer.h +9 -7
  28. package/cpp/rnwgpu/api/GPUCanvasContext.cpp +5 -1
  29. package/cpp/rnwgpu/api/GPUCanvasContext.h +0 -2
  30. package/cpp/rnwgpu/api/GPUCommandBuffer.h +1 -3
  31. package/cpp/rnwgpu/api/GPUCommandEncoder.h +1 -3
  32. package/cpp/rnwgpu/api/GPUCompilationInfo.h +0 -2
  33. package/cpp/rnwgpu/api/GPUCompilationMessage.h +1 -3
  34. package/cpp/rnwgpu/api/GPUComputePassEncoder.h +1 -3
  35. package/cpp/rnwgpu/api/GPUComputePipeline.h +1 -3
  36. package/cpp/rnwgpu/api/GPUDevice.cpp +183 -128
  37. package/cpp/rnwgpu/api/GPUDevice.h +22 -21
  38. package/cpp/rnwgpu/api/GPUDeviceLostInfo.h +1 -3
  39. package/cpp/rnwgpu/api/GPUExternalTexture.h +1 -3
  40. package/cpp/rnwgpu/api/GPUPipelineLayout.h +1 -3
  41. package/cpp/rnwgpu/api/GPUQuerySet.h +1 -3
  42. package/cpp/rnwgpu/api/GPUQueue.cpp +19 -8
  43. package/cpp/rnwgpu/api/GPUQueue.h +7 -6
  44. package/cpp/rnwgpu/api/GPURenderBundle.h +1 -3
  45. package/cpp/rnwgpu/api/GPURenderBundleEncoder.h +1 -3
  46. package/cpp/rnwgpu/api/GPURenderPassEncoder.h +1 -3
  47. package/cpp/rnwgpu/api/GPURenderPipeline.h +1 -3
  48. package/cpp/rnwgpu/api/GPUSampler.h +1 -3
  49. package/cpp/rnwgpu/api/GPUShaderModule.cpp +42 -28
  50. package/cpp/rnwgpu/api/GPUShaderModule.h +6 -6
  51. package/cpp/rnwgpu/api/GPUSupportedLimits.h +1 -3
  52. package/cpp/rnwgpu/api/GPUTexture.h +1 -3
  53. package/cpp/rnwgpu/api/GPUTextureView.h +1 -3
  54. package/cpp/rnwgpu/api/RNWebGPU.h +1 -7
  55. package/cpp/rnwgpu/async/AsyncDispatcher.h +28 -0
  56. package/cpp/rnwgpu/async/AsyncRunner.cpp +215 -0
  57. package/cpp/rnwgpu/async/AsyncRunner.h +53 -0
  58. package/cpp/rnwgpu/async/AsyncTaskHandle.cpp +181 -0
  59. package/cpp/rnwgpu/async/AsyncTaskHandle.h +55 -0
  60. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.cpp +23 -0
  61. package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.h +22 -0
  62. package/cpp/webgpu/webgpu.h +5 -4827
  63. package/cpp/webgpu/webgpu_cpp.h +5 -10140
  64. package/cpp/{dawn/native/WebGPUBackend.h → webgpu/webgpu_cpp_print.h} +4 -20
  65. package/lib/commonjs/Canvas.js +6 -66
  66. package/lib/commonjs/Canvas.js.map +1 -1
  67. package/lib/commonjs/hooks.js +6 -42
  68. package/lib/commonjs/hooks.js.map +1 -1
  69. package/lib/module/Canvas.js +7 -67
  70. package/lib/module/Canvas.js.map +1 -1
  71. package/lib/module/hooks.js +5 -40
  72. package/lib/module/hooks.js.map +1 -1
  73. package/lib/typescript/lib/commonjs/hooks.d.ts +1 -5
  74. package/lib/typescript/lib/commonjs/hooks.d.ts.map +1 -1
  75. package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
  76. package/lib/typescript/lib/module/hooks.d.ts +1 -5
  77. package/lib/typescript/lib/module/hooks.d.ts.map +1 -1
  78. package/lib/typescript/src/Canvas.d.ts +0 -1
  79. package/lib/typescript/src/Canvas.d.ts.map +1 -1
  80. package/lib/typescript/src/hooks.d.ts +2 -7
  81. package/lib/typescript/src/hooks.d.ts.map +1 -1
  82. package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
  83. package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
  84. package/libs/android/x86/libwebgpu_dawn.so +0 -0
  85. package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
  86. package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +5 -35
  87. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
  88. package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  89. package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  90. package/package.json +4 -3
  91. package/react-native-wgpu.podspec +12 -16
  92. package/src/Canvas.tsx +8 -69
  93. package/src/hooks.tsx +14 -48
  94. package/android/cpp/platform/ThreadUtils.cpp +0 -41
  95. package/android/src/oldarch/com/webgpu/NativeWebGPUModuleSpec.java +0 -23
  96. package/android/src/oldarch/com/webgpu/WebGPUViewManagerSpec.java +0 -12
  97. package/apple/WebGPUViewManager.mm +0 -24
  98. package/apple/platform/ThreadUtils.cpp +0 -34
  99. package/cpp/dawn/dawn_proc.h +0 -50
  100. package/cpp/dawn/dawn_thread_dispatch_proc.h +0 -47
  101. package/cpp/dawn/native/D3D11Backend.h +0 -77
  102. package/cpp/dawn/native/D3D12Backend.h +0 -68
  103. package/cpp/dawn/native/D3DBackend.h +0 -56
  104. package/cpp/dawn/native/MetalBackend.h +0 -56
  105. package/cpp/dawn/platform/DawnPlatform.h +0 -167
  106. package/cpp/dawn/platform/dawn_platform_export.h +0 -49
  107. package/cpp/platform/ThreadUtils.h +0 -30
  108. package/cpp/rnwgpu/api/AsyncRunner.h +0 -30
  109. package/cpp/threading/CallInvokerDispatcher.h +0 -37
  110. package/cpp/threading/Dispatcher.cpp +0 -55
  111. package/cpp/threading/Dispatcher.h +0 -93
  112. package/cpp/threading/ThreadPool.cpp +0 -88
  113. package/cpp/threading/ThreadPool.h +0 -53
  114. package/cpp/webgpu/webgpu_glfw.h +0 -88
  115. package/lib/typescript/src/__tests__/Alpha.spec.d.ts +0 -2
  116. package/lib/typescript/src/__tests__/Alpha.spec.d.ts.map +0 -1
  117. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts +0 -2
  118. package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts.map +0 -1
  119. package/lib/typescript/src/__tests__/Buffer.spec.d.ts +0 -2
  120. package/lib/typescript/src/__tests__/Buffer.spec.d.ts.map +0 -1
  121. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts +0 -2
  122. package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts.map +0 -1
  123. package/lib/typescript/src/__tests__/Constants.spec.d.ts +0 -2
  124. package/lib/typescript/src/__tests__/Constants.spec.d.ts.map +0 -1
  125. package/lib/typescript/src/__tests__/Device.spec.d.ts +0 -2
  126. package/lib/typescript/src/__tests__/Device.spec.d.ts.map +0 -1
  127. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts +0 -2
  128. package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts.map +0 -1
  129. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts +0 -2
  130. package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts.map +0 -1
  131. package/lib/typescript/src/__tests__/GPU.spec.d.ts +0 -2
  132. package/lib/typescript/src/__tests__/GPU.spec.d.ts.map +0 -1
  133. package/lib/typescript/src/__tests__/ImageData.spec.d.ts +0 -2
  134. package/lib/typescript/src/__tests__/ImageData.spec.d.ts.map +0 -1
  135. package/lib/typescript/src/__tests__/Shaders.spec.d.ts +0 -2
  136. package/lib/typescript/src/__tests__/Shaders.spec.d.ts.map +0 -1
  137. package/lib/typescript/src/__tests__/Texture.spec.d.ts +0 -2
  138. package/lib/typescript/src/__tests__/Texture.spec.d.ts.map +0 -1
  139. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts +0 -3
  140. package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts.map +0 -1
  141. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts +0 -29
  142. package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts.map +0 -1
  143. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts +0 -5
  144. package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts.map +0 -1
  145. package/lib/typescript/src/__tests__/components/cube.d.ts +0 -7
  146. package/lib/typescript/src/__tests__/components/cube.d.ts.map +0 -1
  147. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts +0 -22
  148. package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts.map +0 -1
  149. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts +0 -12
  150. package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts.map +0 -1
  151. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts +0 -7
  152. package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts.map +0 -1
  153. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts +0 -6
  154. package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts.map +0 -1
  155. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts +0 -6
  156. package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts.map +0 -1
  157. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts +0 -10
  158. package/lib/typescript/src/__tests__/components/meshes/utils.d.ts.map +0 -1
  159. package/lib/typescript/src/__tests__/components/triangle.d.ts +0 -3
  160. package/lib/typescript/src/__tests__/components/triangle.d.ts.map +0 -1
  161. package/lib/typescript/src/__tests__/config.d.ts +0 -3
  162. package/lib/typescript/src/__tests__/config.d.ts.map +0 -1
  163. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts +0 -2
  164. package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts.map +0 -1
  165. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts +0 -2
  166. package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts.map +0 -1
  167. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts +0 -2
  168. package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts.map +0 -1
  169. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts +0 -2
  170. package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts.map +0 -1
  171. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts +0 -2
  172. package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts.map +0 -1
  173. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts +0 -2
  174. package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts.map +0 -1
  175. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts +0 -2
  176. package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts.map +0 -1
  177. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts +0 -2
  178. package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts.map +0 -1
  179. package/lib/typescript/src/__tests__/globalSetup.d.ts +0 -3
  180. package/lib/typescript/src/__tests__/globalSetup.d.ts.map +0 -1
  181. package/lib/typescript/src/__tests__/globalTeardown.d.ts +0 -3
  182. package/lib/typescript/src/__tests__/globalTeardown.d.ts.map +0 -1
  183. package/lib/typescript/src/__tests__/setup.d.ts +0 -63
  184. package/lib/typescript/src/__tests__/setup.d.ts.map +0 -1
  185. package/libs/apple/arm64_iphoneos/libwebgpu_dawn.a +0 -0
  186. package/libs/apple/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
  187. package/libs/apple/arm64_xros/libwebgpu_dawn.a +0 -0
  188. package/libs/apple/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
  189. package/libs/apple/iphonesimulator/libwebgpu_dawn.a +0 -0
  190. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
  191. package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64-simulator/libwebgpu_dawn.a +0 -0
  192. package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
  193. package/libs/apple/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  194. package/libs/dawn.json +0 -4670
  195. package/src/__tests__/Alpha.spec.ts +0 -28
  196. package/src/__tests__/ArrayBuffer.spec.ts +0 -76
  197. package/src/__tests__/Buffer.spec.ts +0 -357
  198. package/src/__tests__/ComputeShader.spec.ts +0 -375
  199. package/src/__tests__/Constants.spec.ts +0 -89
  200. package/src/__tests__/Device.spec.ts +0 -84
  201. package/src/__tests__/ErrorScope.spec.ts +0 -92
  202. package/src/__tests__/ExternalTexture.spec.ts +0 -284
  203. package/src/__tests__/GPU.spec.ts +0 -272
  204. package/src/__tests__/ImageData.spec.ts +0 -26
  205. package/src/__tests__/Shaders.spec.ts +0 -232
  206. package/src/__tests__/Texture.spec.ts +0 -197
  207. package/src/__tests__/assets/Di-3d.png +0 -0
  208. package/src/__tests__/components/Wireframe/Shaders.ts +0 -138
  209. package/src/__tests__/components/Wireframe/models.ts +0 -113
  210. package/src/__tests__/components/Wireframe/utils.ts +0 -22
  211. package/src/__tests__/components/cube.ts +0 -51
  212. package/src/__tests__/components/meshes/mesh.ts +0 -96
  213. package/src/__tests__/components/meshes/sphere.ts +0 -103
  214. package/src/__tests__/components/meshes/stanfordDragon.ts +0 -44
  215. package/src/__tests__/components/meshes/stanfordDragonData.ts +0 -5
  216. package/src/__tests__/components/meshes/teapot.ts +0 -13
  217. package/src/__tests__/components/meshes/utils.ts +0 -235
  218. package/src/__tests__/components/triangle.ts +0 -17
  219. package/src/__tests__/config.ts +0 -2
  220. package/src/__tests__/demos/ABuffer.spec.ts +0 -890
  221. package/src/__tests__/demos/Blur.spec.ts +0 -398
  222. package/src/__tests__/demos/Cube.spec.ts +0 -929
  223. package/src/__tests__/demos/FractalCube.spec.ts +0 -240
  224. package/src/__tests__/demos/OcclusionQuery.spec.ts +0 -376
  225. package/src/__tests__/demos/RenderBundles.spec.ts +0 -580
  226. package/src/__tests__/demos/Triangle.spec.ts +0 -266
  227. package/src/__tests__/demos/Wireframe.spec.ts +0 -188
  228. package/src/__tests__/globalSetup.ts +0 -45
  229. package/src/__tests__/globalTeardown.ts +0 -11
  230. package/src/__tests__/setup.ts +0 -423
  231. package/src/__tests__/snapshots/abuffer.png +0 -0
  232. package/src/__tests__/snapshots/asteroid.png +0 -0
  233. package/src/__tests__/snapshots/blur.png +0 -0
  234. package/src/__tests__/snapshots/buffer.png +0 -0
  235. package/src/__tests__/snapshots/constant-triangle.png +0 -0
  236. package/src/__tests__/snapshots/cube.png +0 -0
  237. package/src/__tests__/snapshots/f.png +0 -0
  238. package/src/__tests__/snapshots/f2.png +0 -0
  239. package/src/__tests__/snapshots/fractal-cubes.png +0 -0
  240. package/src/__tests__/snapshots/instanced-cubes.png +0 -0
  241. package/src/__tests__/snapshots/occlusion-query.png +0 -0
  242. package/src/__tests__/snapshots/ref.png +0 -0
  243. package/src/__tests__/snapshots/semi-opaque-cyan.png +0 -0
  244. package/src/__tests__/snapshots/texture.png +0 -0
  245. package/src/__tests__/snapshots/textured-cube.png +0 -0
  246. package/src/__tests__/snapshots/triangle-msaa.png +0 -0
  247. package/src/__tests__/snapshots/triangle.png +0 -0
  248. package/src/__tests__/snapshots/two-cube.png +0 -0
@@ -1,375 +0,0 @@
1
- /* eslint-disable prefer-destructuring */
2
- import { client } from "./setup";
3
-
4
- const multiplyMatrices = (m1: number[], m2: number[]) => {
5
- const rows1 = m1[0],
6
- cols1 = m1[1];
7
- const cols2 = m2[1];
8
- const result: number[] = new Array(2 + rows1 * cols2);
9
- result[0] = rows1;
10
- result[1] = cols2;
11
-
12
- for (let i = 0; i < rows1; i++) {
13
- for (let j = 0; j < cols2; j++) {
14
- let sum = 0;
15
- for (let k = 0; k < cols1; k++) {
16
- sum += m1[2 + i * cols1 + k] * m2[2 + k * cols2 + j];
17
- }
18
- result[2 + i * cols2 + j] = sum;
19
- }
20
- }
21
- return result;
22
- };
23
-
24
- describe("Computer Shader", () => {
25
- it("matrix multiplication", async () => {
26
- // First Matrix
27
- const rows = 16;
28
- const columns = 16;
29
- const m1: number[] = new Array(rows * columns + 2);
30
- m1[0] = rows;
31
- m1[1] = columns;
32
- for (let i = 2; i < m1.length; i++) {
33
- m1[i] = Math.random();
34
- }
35
-
36
- // Second Matrix
37
- const m2: number[] = new Array(rows * columns + 2);
38
- m2[0] = rows;
39
- m2[1] = columns;
40
- for (let i = 2; i < m2.length; i++) {
41
- m2[i] = Math.random();
42
- }
43
-
44
- const result = await client.eval(
45
- ({ device, firstMatrixRaw, secondMatrixRaw, rows1, columns1 }) => {
46
- const firstMatrix = new Float32Array(firstMatrixRaw);
47
- const secondMatrix = new Float32Array(secondMatrixRaw);
48
- const gpuBufferFirstMatrix = device.createBuffer({
49
- mappedAtCreation: true,
50
- size: firstMatrix.byteLength,
51
- usage: GPUBufferUsage.STORAGE,
52
- });
53
- const arrayBufferFirstMatrix = gpuBufferFirstMatrix.getMappedRange();
54
- new Float32Array(arrayBufferFirstMatrix).set(firstMatrix);
55
- gpuBufferFirstMatrix.unmap();
56
-
57
- const gpuBufferSecondMatrix = device.createBuffer({
58
- mappedAtCreation: true,
59
- size: secondMatrix.byteLength,
60
- usage: GPUBufferUsage.STORAGE,
61
- });
62
- const arrayBufferSecondMatrix = gpuBufferSecondMatrix.getMappedRange();
63
- new Float32Array(arrayBufferSecondMatrix).set(secondMatrix);
64
- gpuBufferSecondMatrix.unmap();
65
-
66
- // Result Matrix
67
- const resultMatrixBufferSize =
68
- Float32Array.BYTES_PER_ELEMENT *
69
- (2 + firstMatrix[0] * secondMatrix[1]);
70
- const resultMatrixBuffer = device.createBuffer({
71
- size: resultMatrixBufferSize,
72
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
73
- });
74
-
75
- // Compute shader code
76
- const shaderModule = device.createShaderModule({
77
- code: `
78
- struct Matrix {
79
- size : vec2<f32>,
80
- numbers: array<f32>,
81
- }
82
-
83
- @group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
84
- @group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
85
- @group(0) @binding(2) var<storage, read_write> resultMatrix : Matrix;
86
-
87
- @compute @workgroup_size(8, 8)
88
- fn main(@builtin(global_invocation_id) global_id : vec3<u32>) {
89
- // Guard against out-of-bounds work group sizes
90
- if (global_id.x >= u32(firstMatrix.size.x) || global_id.y >= u32(secondMatrix.size.y)) {
91
- return;
92
- }
93
-
94
- resultMatrix.size = vec2(firstMatrix.size.x, secondMatrix.size.y);
95
-
96
- let resultCell = vec2(global_id.x, global_id.y);
97
- var result = 0.0;
98
- for (var i = 0u; i < u32(firstMatrix.size.y); i = i + 1u) {
99
- let a = i + resultCell.x * u32(firstMatrix.size.y);
100
- let b = resultCell.y + i * u32(secondMatrix.size.y);
101
- result = result + firstMatrix.numbers[a] * secondMatrix.numbers[b];
102
- }
103
-
104
- let index = resultCell.y + resultCell.x * u32(secondMatrix.size.y);
105
- resultMatrix.numbers[index] = result;
106
- }
107
- `,
108
- });
109
-
110
- // Pipeline setup
111
- const computePipeline = device.createComputePipeline({
112
- layout: "auto",
113
- compute: {
114
- module: shaderModule,
115
- entryPoint: "main",
116
- },
117
- });
118
-
119
- // Bind group
120
- const bindGroup = device.createBindGroup({
121
- layout: computePipeline.getBindGroupLayout(0 /* index */),
122
- entries: [
123
- {
124
- binding: 0,
125
- resource: {
126
- buffer: gpuBufferFirstMatrix,
127
- },
128
- },
129
- {
130
- binding: 1,
131
- resource: {
132
- buffer: gpuBufferSecondMatrix,
133
- },
134
- },
135
- {
136
- binding: 2,
137
- resource: {
138
- buffer: resultMatrixBuffer,
139
- },
140
- },
141
- ],
142
- });
143
-
144
- // Commands submission
145
- const commandEncoder = device.createCommandEncoder();
146
-
147
- const passEncoder = commandEncoder.beginComputePass();
148
- passEncoder.setPipeline(computePipeline);
149
- passEncoder.setBindGroup(0, bindGroup);
150
- const workgroupCountX = Math.ceil(rows1 / 8);
151
- const workgroupCountY = Math.ceil(columns1 / 8);
152
- passEncoder.dispatchWorkgroups(workgroupCountX, workgroupCountY);
153
- passEncoder.end();
154
-
155
- // Get a GPU buffer for reading in an unmapped state.
156
- const gpuReadBuffer = device.createBuffer({
157
- size: resultMatrixBufferSize,
158
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
159
- });
160
-
161
- // Encode commands for copying buffer to buffer.
162
- commandEncoder.copyBufferToBuffer(
163
- resultMatrixBuffer /* source buffer */,
164
- 0 /* source offset */,
165
- gpuReadBuffer /* destination buffer */,
166
- 0 /* destination offset */,
167
- resultMatrixBufferSize /* size */,
168
- );
169
-
170
- // Submit GPU commands.
171
- const gpuCommands = commandEncoder.finish();
172
- device.queue.submit([gpuCommands]);
173
-
174
- // Read buffer.
175
- return gpuReadBuffer.mapAsync(GPUMapMode.READ).then(() => {
176
- const arrayBuffer = gpuReadBuffer.getMappedRange();
177
- const uint8Array = new Float32Array(arrayBuffer);
178
- // At this point, uint8Array contains the pixel data of the rendered image
179
- // You can process it further, save it, or send it somewhere else
180
- const r = Array.from(uint8Array);
181
- gpuReadBuffer.unmap();
182
- return r;
183
- });
184
- },
185
- {
186
- firstMatrixRaw: m1,
187
- secondMatrixRaw: m2,
188
- rows1: rows,
189
- columns1: columns,
190
- },
191
- );
192
- expect(result.length).toBe(16 * 16 + 2);
193
- expect(result.some((x) => x !== 0)).toBe(true);
194
- const referenceResult = multiplyMatrices(m1, m2);
195
- for (let i = 0; i < result.length; i++) {
196
- expect(result[i]).toBeCloseTo(referenceResult[i], 5); // Using 5 decimal places for floating-point comparison
197
- }
198
- });
199
- it("async matrix multiplication", async () => {
200
- // First Matrix
201
- const rows = 16;
202
- const columns = 16;
203
- const m1: number[] = new Array(rows * columns + 2);
204
- m1[0] = rows;
205
- m1[1] = columns;
206
- for (let i = 2; i < m1.length; i++) {
207
- m1[i] = Math.random();
208
- }
209
-
210
- // Second Matrix
211
- const m2: number[] = new Array(rows * columns + 2);
212
- m2[0] = rows;
213
- m2[1] = columns;
214
- for (let i = 2; i < m2.length; i++) {
215
- m2[i] = Math.random();
216
- }
217
-
218
- const result = await client.eval(
219
- ({ device, firstMatrixRaw, secondMatrixRaw, rows1, columns1 }) => {
220
- const firstMatrix = new Float32Array(firstMatrixRaw);
221
- const secondMatrix = new Float32Array(secondMatrixRaw);
222
- const gpuBufferFirstMatrix = device.createBuffer({
223
- mappedAtCreation: true,
224
- size: firstMatrix.byteLength,
225
- usage: GPUBufferUsage.STORAGE,
226
- });
227
- const arrayBufferFirstMatrix = gpuBufferFirstMatrix.getMappedRange();
228
- new Float32Array(arrayBufferFirstMatrix).set(firstMatrix);
229
- gpuBufferFirstMatrix.unmap();
230
-
231
- const gpuBufferSecondMatrix = device.createBuffer({
232
- mappedAtCreation: true,
233
- size: secondMatrix.byteLength,
234
- usage: GPUBufferUsage.STORAGE,
235
- });
236
- const arrayBufferSecondMatrix = gpuBufferSecondMatrix.getMappedRange();
237
- new Float32Array(arrayBufferSecondMatrix).set(secondMatrix);
238
- gpuBufferSecondMatrix.unmap();
239
-
240
- // Result Matrix
241
- const resultMatrixBufferSize =
242
- Float32Array.BYTES_PER_ELEMENT *
243
- (2 + firstMatrix[0] * secondMatrix[1]);
244
- const resultMatrixBuffer = device.createBuffer({
245
- size: resultMatrixBufferSize,
246
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
247
- });
248
-
249
- // Compute shader code
250
- const shaderModule = device.createShaderModule({
251
- code: `
252
- struct Matrix {
253
- size : vec2<f32>,
254
- numbers: array<f32>,
255
- }
256
-
257
- @group(0) @binding(0) var<storage, read> firstMatrix : Matrix;
258
- @group(0) @binding(1) var<storage, read> secondMatrix : Matrix;
259
- @group(0) @binding(2) var<storage, read_write> resultMatrix : Matrix;
260
-
261
- @compute @workgroup_size(8, 8)
262
- fn main(@builtin(global_invocation_id) global_id : vec3<u32>) {
263
- // Guard against out-of-bounds work group sizes
264
- if (global_id.x >= u32(firstMatrix.size.x) || global_id.y >= u32(secondMatrix.size.y)) {
265
- return;
266
- }
267
-
268
- resultMatrix.size = vec2(firstMatrix.size.x, secondMatrix.size.y);
269
-
270
- let resultCell = vec2(global_id.x, global_id.y);
271
- var result = 0.0;
272
- for (var i = 0u; i < u32(firstMatrix.size.y); i = i + 1u) {
273
- let a = i + resultCell.x * u32(firstMatrix.size.y);
274
- let b = resultCell.y + i * u32(secondMatrix.size.y);
275
- result = result + firstMatrix.numbers[a] * secondMatrix.numbers[b];
276
- }
277
-
278
- let index = resultCell.y + resultCell.x * u32(secondMatrix.size.y);
279
- resultMatrix.numbers[index] = result;
280
- }
281
- `,
282
- });
283
-
284
- // Pipeline setup
285
- return device
286
- .createComputePipelineAsync({
287
- layout: "auto",
288
- compute: {
289
- module: shaderModule,
290
- entryPoint: "main",
291
- },
292
- })
293
- .then((computePipeline) => {
294
- // Bind group
295
- const bindGroup = device.createBindGroup({
296
- layout: computePipeline.getBindGroupLayout(0 /* index */),
297
- entries: [
298
- {
299
- binding: 0,
300
- resource: {
301
- buffer: gpuBufferFirstMatrix,
302
- },
303
- },
304
- {
305
- binding: 1,
306
- resource: {
307
- buffer: gpuBufferSecondMatrix,
308
- },
309
- },
310
- {
311
- binding: 2,
312
- resource: {
313
- buffer: resultMatrixBuffer,
314
- },
315
- },
316
- ],
317
- });
318
-
319
- // Commands submission
320
- const commandEncoder = device.createCommandEncoder();
321
-
322
- const passEncoder = commandEncoder.beginComputePass();
323
- passEncoder.setPipeline(computePipeline);
324
- passEncoder.setBindGroup(0, bindGroup);
325
- const workgroupCountX = Math.ceil(rows1 / 8);
326
- const workgroupCountY = Math.ceil(columns1 / 8);
327
- passEncoder.dispatchWorkgroups(workgroupCountX, workgroupCountY);
328
- passEncoder.end();
329
-
330
- // Get a GPU buffer for reading in an unmapped state.
331
- const gpuReadBuffer = device.createBuffer({
332
- size: resultMatrixBufferSize,
333
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
334
- });
335
-
336
- // Encode commands for copying buffer to buffer.
337
- commandEncoder.copyBufferToBuffer(
338
- resultMatrixBuffer /* source buffer */,
339
- 0 /* source offset */,
340
- gpuReadBuffer /* destination buffer */,
341
- 0 /* destination offset */,
342
- resultMatrixBufferSize /* size */,
343
- );
344
-
345
- // Submit GPU commands.
346
- const gpuCommands = commandEncoder.finish();
347
- device.queue.submit([gpuCommands]);
348
-
349
- // Read buffer.
350
- return gpuReadBuffer.mapAsync(GPUMapMode.READ).then(() => {
351
- const arrayBuffer = gpuReadBuffer.getMappedRange();
352
- const uint8Array = new Float32Array(arrayBuffer);
353
- // At this point, uint8Array contains the pixel data of the rendered image
354
- // You can process it further, save it, or send it somewhere else
355
- const r = Array.from(uint8Array);
356
- gpuReadBuffer.unmap();
357
- return r;
358
- });
359
- });
360
- },
361
- {
362
- firstMatrixRaw: m1,
363
- secondMatrixRaw: m2,
364
- rows1: rows,
365
- columns1: columns,
366
- },
367
- );
368
- expect(result.length).toBe(16 * 16 + 2);
369
- expect(result.some((x) => x !== 0)).toBe(true);
370
- const referenceResult = multiplyMatrices(m1, m2);
371
- for (let i = 0; i < result.length; i++) {
372
- expect(result[i]).toBeCloseTo(referenceResult[i], 5); // Using 5 decimal places for floating-point comparison
373
- }
374
- });
375
- });
@@ -1,89 +0,0 @@
1
- import { client } from "./setup";
2
-
3
- describe("WebGPUConstants", () => {
4
- it("GPUBufferUsage", async () => {
5
- const result = await client.eval(() => {
6
- return GPUBufferUsage;
7
- });
8
- expect(result).toEqual({
9
- MAP_READ: 1,
10
- MAP_WRITE: 2,
11
- COPY_SRC: 4,
12
- COPY_DST: 8,
13
- INDEX: 16,
14
- VERTEX: 32,
15
- UNIFORM: 64,
16
- STORAGE: 128,
17
- INDIRECT: 256,
18
- QUERY_RESOLVE: 512,
19
- });
20
- });
21
- it("GPUColorWrite", async () => {
22
- const result = await client.eval(() => {
23
- return GPUColorWrite;
24
- });
25
- expect(result).toEqual({
26
- RED: 1,
27
- GREEN: 2,
28
- BLUE: 4,
29
- ALPHA: 8,
30
- ALL: 15,
31
- });
32
- });
33
- it("GPUMapMode", async () => {
34
- const result = await client.eval(() => {
35
- return GPUMapMode;
36
- });
37
- expect(result).toEqual({
38
- READ: 1,
39
- WRITE: 2,
40
- });
41
- });
42
- it("GPUShaderStage", async () => {
43
- const result = await client.eval(() => {
44
- return GPUShaderStage;
45
- });
46
- expect(result).toEqual({
47
- VERTEX: 1,
48
- FRAGMENT: 2,
49
- COMPUTE: 4,
50
- });
51
- });
52
- it("GPUTextureUsage", async () => {
53
- const result = await client.eval(() => {
54
- return GPUTextureUsage;
55
- });
56
- expect(result).toEqual({
57
- COPY_SRC: 1,
58
- COPY_DST: 2,
59
- TEXTURE_BINDING: 4,
60
- STORAGE_BINDING: 8,
61
- RENDER_ATTACHMENT: 16,
62
- });
63
- });
64
- it("GPUAdapter", async () => {
65
- const result = await client.eval(({ device, gpu }) => {
66
- return [
67
- gpu instanceof GPU,
68
- device instanceof GPUDevice,
69
- device instanceof GPUAdapter,
70
- ];
71
- });
72
- expect(result).toEqual([true, true, false]);
73
- });
74
- it("instanceof", async () => {
75
- const result = await client.eval(
76
- ({ device, shaders: { triangleVertWGSL } }) => {
77
- const buffer = device.createBuffer({
78
- size: 16,
79
- usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
80
- });
81
- const module = device.createShaderModule({
82
- code: triangleVertWGSL,
83
- });
84
- return [buffer instanceof GPUBuffer, module instanceof GPUShaderModule];
85
- },
86
- );
87
- expect(result).toEqual([true, true]);
88
- });
89
- });
@@ -1,84 +0,0 @@
1
- import { client } from "./setup";
2
-
3
- describe("Device", () => {
4
- it("request device (1)", async () => {
5
- const result = await client.eval(({ gpu }) =>
6
- gpu
7
- .requestAdapter()
8
- .then((adapter) =>
9
- adapter!.requestDevice().then((device) => device !== null),
10
- ),
11
- );
12
- expect(result).toBe(true);
13
- });
14
-
15
- it("request device (2)", async () => {
16
- const result = await client.eval(({ gpu }) =>
17
- gpu
18
- .requestAdapter()
19
- .then((adapter) =>
20
- adapter!.requestDevice(undefined).then((device) => device.label),
21
- ),
22
- );
23
- expect(result).toBe("");
24
- });
25
- it("request device (3)", async () => {
26
- const result = await client.eval(({ gpu }) =>
27
- gpu
28
- .requestAdapter()
29
- .then((adapter) =>
30
- adapter!
31
- .requestDevice({ label: "MyGPU" })
32
- .then((device) => device.label),
33
- ),
34
- );
35
- expect(result).toBe("MyGPU");
36
- });
37
- it("destroy device (3)", async () => {
38
- const result = await client.eval(({ gpu }) =>
39
- gpu.requestAdapter().then((adapter) =>
40
- adapter!.requestDevice({ label: "MyGPU" }).then((device) => {
41
- device.destroy();
42
- return device.lost.then((r) => ({
43
- reason: r.reason,
44
- message: r.message,
45
- }));
46
- }),
47
- ),
48
- );
49
- expect(["unknown", "destroyed"].includes(result.reason)).toBe(true);
50
- });
51
-
52
- it("times out device.lost if the device has not been destroyed", async () => {
53
- const isDeviceLost = await client.eval(({ device }) => {
54
- const timeout = new Promise((resolve) => {
55
- setTimeout(() => {
56
- resolve(false);
57
- }, 50);
58
- });
59
-
60
- return Promise.race([device.lost.then(() => true), timeout]);
61
- });
62
-
63
- expect(isDeviceLost).toBeFalsy();
64
- });
65
-
66
- it("resolves an awaited device.lost when device.destroy is called", async () => {
67
- const result = await client.eval(({ gpu }) =>
68
- gpu.requestAdapter().then((adapter) =>
69
- adapter!.requestDevice({ label: "myGPU2" }).then((device) => {
70
- setTimeout(() => {
71
- device.destroy();
72
- }, 50);
73
-
74
- return device.lost.then((r) => ({
75
- reason: r.reason,
76
- message: r.message,
77
- }));
78
- }),
79
- ),
80
- );
81
-
82
- expect(["unknown", "destroyed"].includes(result.reason)).toBeTruthy();
83
- });
84
- });
@@ -1,92 +0,0 @@
1
- import { client } from "./setup";
2
-
3
- describe("Error Scope", () => {
4
- it("should capture validation error when creating sampler with invalid maxAnisotropy", async () => {
5
- const result = await client.eval(({ device }) => {
6
- device.pushErrorScope("validation");
7
- device.createSampler({
8
- maxAnisotropy: 0, // Invalid, maxAnisotropy must be at least 1.
9
- });
10
- return device.popErrorScope().then((error) => {
11
- if (error) {
12
- return {
13
- hasError: true,
14
- message: error.message,
15
- messageLength: error.message.length,
16
- messageNotEmpty: error.message.length > 0,
17
- };
18
- } else {
19
- return {
20
- hasError: false,
21
- message: "",
22
- messageLength: 0,
23
- messageNotEmpty: false,
24
- };
25
- }
26
- });
27
- });
28
-
29
- expect(result.hasError).toBe(true);
30
- expect(result.messageNotEmpty).toBe(true);
31
- expect(result.messageLength).toBeGreaterThan(0);
32
- });
33
- it("should capture and return error messages from popErrorScope", async () => {
34
- const result = await client.eval(({ device }) => {
35
- // Invalid WGSL shader with syntax error (missing closing parenthesis)
36
- const invalidShaderWGSL = `@fragment
37
- fn main() -> @location(0) vec4f {
38
- return vec4(1.0, 0.0, 0.0, 1.0;
39
- }`;
40
- device.pushErrorScope("validation");
41
- // This should generate a validation error due to syntax error
42
- device.createShaderModule({
43
- code: invalidShaderWGSL,
44
- });
45
- return device.popErrorScope().then((error) => {
46
- if (error) {
47
- return {
48
- hasError: true,
49
- message: error.message,
50
- messageLength: error.message.length,
51
- messageNotEmpty: error.message.length > 0,
52
- messageContainsExpected:
53
- error.message.includes("expected") ||
54
- error.message.includes("error") ||
55
- error.message.includes("parsing"),
56
- };
57
- } else {
58
- return {
59
- hasError: false,
60
- message: "",
61
- messageLength: 0,
62
- messageNotEmpty: false,
63
- messageContainsExpected: false,
64
- };
65
- }
66
- });
67
- });
68
- expect(result.hasError).toBe(true);
69
- expect(result.messageNotEmpty).toBe(true);
70
- expect(result.messageLength).toBeGreaterThan(0);
71
- // The error message should contain some indication that it's a parsing error
72
- expect(result.messageContainsExpected).toBe(true);
73
- });
74
-
75
- it("should return null when no error occurs", async () => {
76
- const result = await client.eval(({ device, shaders: { redFragWGSL } }) => {
77
- device.pushErrorScope("validation");
78
- // This should not generate any errors
79
- device.createShaderModule({
80
- code: redFragWGSL,
81
- });
82
- return device.popErrorScope().then((error) => {
83
- return {
84
- hasError: error !== null,
85
- error: error,
86
- };
87
- });
88
- });
89
- expect(result.hasError).toBe(false);
90
- expect(result.error).toBe(null);
91
- });
92
- });