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.
- package/README.md +155 -69
- package/android/CMakeLists.txt +4 -5
- package/android/build.gradle +7 -18
- package/android/src/main/java/com/webgpu/WebGPUViewPackage.java +34 -10
- package/apple/MetalView.mm +0 -19
- package/apple/WebGPUModule.h +1 -9
- package/apple/WebGPUModule.mm +0 -3
- package/apple/WebGPUView.h +0 -3
- package/apple/WebGPUView.mm +0 -2
- package/cpp/WGPULogger.h +10 -0
- package/cpp/dawn/dawn_proc_table.h +1 -1
- package/cpp/dawn/webgpu.h +4855 -0
- package/cpp/dawn/webgpu_cpp.h +10168 -0
- package/cpp/dawn/wire/client/webgpu.h +354 -0
- package/cpp/dawn/wire/client/webgpu_cpp.h +10343 -0
- package/cpp/dawn/wire/client/webgpu_cpp_print.h +2715 -0
- package/cpp/jsi/RNFJSIConverter.h +17 -59
- package/cpp/rnwgpu/RNWebGPUManager.cpp +1 -9
- package/cpp/rnwgpu/api/GPU.cpp +51 -26
- package/cpp/rnwgpu/api/GPU.h +5 -18
- package/cpp/rnwgpu/api/GPUAdapter.cpp +75 -54
- package/cpp/rnwgpu/api/GPUAdapter.h +6 -6
- package/cpp/rnwgpu/api/GPUAdapterInfo.h +0 -1
- package/cpp/rnwgpu/api/GPUBindGroup.h +1 -3
- package/cpp/rnwgpu/api/GPUBindGroupLayout.h +1 -3
- package/cpp/rnwgpu/api/GPUBuffer.cpp +35 -32
- package/cpp/rnwgpu/api/GPUBuffer.h +9 -7
- package/cpp/rnwgpu/api/GPUCanvasContext.cpp +5 -1
- package/cpp/rnwgpu/api/GPUCanvasContext.h +0 -2
- package/cpp/rnwgpu/api/GPUCommandBuffer.h +1 -3
- package/cpp/rnwgpu/api/GPUCommandEncoder.h +1 -3
- package/cpp/rnwgpu/api/GPUCompilationInfo.h +0 -2
- package/cpp/rnwgpu/api/GPUCompilationMessage.h +1 -3
- package/cpp/rnwgpu/api/GPUComputePassEncoder.h +1 -3
- package/cpp/rnwgpu/api/GPUComputePipeline.h +1 -3
- package/cpp/rnwgpu/api/GPUDevice.cpp +183 -128
- package/cpp/rnwgpu/api/GPUDevice.h +22 -21
- package/cpp/rnwgpu/api/GPUDeviceLostInfo.h +1 -3
- package/cpp/rnwgpu/api/GPUExternalTexture.h +1 -3
- package/cpp/rnwgpu/api/GPUPipelineLayout.h +1 -3
- package/cpp/rnwgpu/api/GPUQuerySet.h +1 -3
- package/cpp/rnwgpu/api/GPUQueue.cpp +19 -8
- package/cpp/rnwgpu/api/GPUQueue.h +7 -6
- package/cpp/rnwgpu/api/GPURenderBundle.h +1 -3
- package/cpp/rnwgpu/api/GPURenderBundleEncoder.h +1 -3
- package/cpp/rnwgpu/api/GPURenderPassEncoder.h +1 -3
- package/cpp/rnwgpu/api/GPURenderPipeline.h +1 -3
- package/cpp/rnwgpu/api/GPUSampler.h +1 -3
- package/cpp/rnwgpu/api/GPUShaderModule.cpp +42 -28
- package/cpp/rnwgpu/api/GPUShaderModule.h +6 -6
- package/cpp/rnwgpu/api/GPUSupportedLimits.h +1 -3
- package/cpp/rnwgpu/api/GPUTexture.h +1 -3
- package/cpp/rnwgpu/api/GPUTextureView.h +1 -3
- package/cpp/rnwgpu/api/RNWebGPU.h +1 -7
- package/cpp/rnwgpu/async/AsyncDispatcher.h +28 -0
- package/cpp/rnwgpu/async/AsyncRunner.cpp +215 -0
- package/cpp/rnwgpu/async/AsyncRunner.h +53 -0
- package/cpp/rnwgpu/async/AsyncTaskHandle.cpp +181 -0
- package/cpp/rnwgpu/async/AsyncTaskHandle.h +55 -0
- package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.cpp +23 -0
- package/cpp/rnwgpu/async/JSIMicrotaskDispatcher.h +22 -0
- package/cpp/webgpu/webgpu.h +5 -4827
- package/cpp/webgpu/webgpu_cpp.h +5 -10140
- package/cpp/{dawn/native/WebGPUBackend.h → webgpu/webgpu_cpp_print.h} +4 -20
- package/lib/commonjs/Canvas.js +6 -66
- package/lib/commonjs/Canvas.js.map +1 -1
- package/lib/commonjs/hooks.js +6 -42
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/module/Canvas.js +7 -67
- package/lib/module/Canvas.js.map +1 -1
- package/lib/module/hooks.js +5 -40
- package/lib/module/hooks.js.map +1 -1
- package/lib/typescript/lib/commonjs/hooks.d.ts +1 -5
- package/lib/typescript/lib/commonjs/hooks.d.ts.map +1 -1
- package/lib/typescript/lib/module/Canvas.d.ts.map +1 -1
- package/lib/typescript/lib/module/hooks.d.ts +1 -5
- package/lib/typescript/lib/module/hooks.d.ts.map +1 -1
- package/lib/typescript/src/Canvas.d.ts +0 -1
- package/lib/typescript/src/Canvas.d.ts.map +1 -1
- package/lib/typescript/src/hooks.d.ts +2 -7
- package/lib/typescript/src/hooks.d.ts.map +1 -1
- package/libs/android/arm64-v8a/libwebgpu_dawn.so +0 -0
- package/libs/android/armeabi-v7a/libwebgpu_dawn.so +0 -0
- package/libs/android/x86/libwebgpu_dawn.so +0 -0
- package/libs/android/x86_64/libwebgpu_dawn.so +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/Info.plist +5 -35
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
- package/package.json +4 -3
- package/react-native-wgpu.podspec +12 -16
- package/src/Canvas.tsx +8 -69
- package/src/hooks.tsx +14 -48
- package/android/cpp/platform/ThreadUtils.cpp +0 -41
- package/android/src/oldarch/com/webgpu/NativeWebGPUModuleSpec.java +0 -23
- package/android/src/oldarch/com/webgpu/WebGPUViewManagerSpec.java +0 -12
- package/apple/WebGPUViewManager.mm +0 -24
- package/apple/platform/ThreadUtils.cpp +0 -34
- package/cpp/dawn/dawn_proc.h +0 -50
- package/cpp/dawn/dawn_thread_dispatch_proc.h +0 -47
- package/cpp/dawn/native/D3D11Backend.h +0 -77
- package/cpp/dawn/native/D3D12Backend.h +0 -68
- package/cpp/dawn/native/D3DBackend.h +0 -56
- package/cpp/dawn/native/MetalBackend.h +0 -56
- package/cpp/dawn/platform/DawnPlatform.h +0 -167
- package/cpp/dawn/platform/dawn_platform_export.h +0 -49
- package/cpp/platform/ThreadUtils.h +0 -30
- package/cpp/rnwgpu/api/AsyncRunner.h +0 -30
- package/cpp/threading/CallInvokerDispatcher.h +0 -37
- package/cpp/threading/Dispatcher.cpp +0 -55
- package/cpp/threading/Dispatcher.h +0 -93
- package/cpp/threading/ThreadPool.cpp +0 -88
- package/cpp/threading/ThreadPool.h +0 -53
- package/cpp/webgpu/webgpu_glfw.h +0 -88
- package/lib/typescript/src/__tests__/Alpha.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/Alpha.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/ArrayBuffer.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/Buffer.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/Buffer.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/ComputeShader.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/Constants.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/Constants.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/Device.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/Device.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/ErrorScope.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/ExternalTexture.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/GPU.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/GPU.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/ImageData.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/ImageData.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/Shaders.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/Shaders.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/Texture.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/Texture.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts +0 -3
- package/lib/typescript/src/__tests__/components/Wireframe/Shaders.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts +0 -29
- package/lib/typescript/src/__tests__/components/Wireframe/models.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts +0 -5
- package/lib/typescript/src/__tests__/components/Wireframe/utils.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/cube.d.ts +0 -7
- package/lib/typescript/src/__tests__/components/cube.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts +0 -22
- package/lib/typescript/src/__tests__/components/meshes/mesh.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts +0 -12
- package/lib/typescript/src/__tests__/components/meshes/sphere.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts +0 -7
- package/lib/typescript/src/__tests__/components/meshes/stanfordDragon.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts +0 -6
- package/lib/typescript/src/__tests__/components/meshes/stanfordDragonData.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts +0 -6
- package/lib/typescript/src/__tests__/components/meshes/teapot.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/meshes/utils.d.ts +0 -10
- package/lib/typescript/src/__tests__/components/meshes/utils.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/components/triangle.d.ts +0 -3
- package/lib/typescript/src/__tests__/components/triangle.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/config.d.ts +0 -3
- package/lib/typescript/src/__tests__/config.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/demos/ABuffer.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/demos/Blur.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/demos/Cube.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/demos/FractalCube.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/demos/OcclusionQuery.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/demos/RenderBundles.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/demos/Triangle.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts +0 -2
- package/lib/typescript/src/__tests__/demos/Wireframe.spec.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/globalSetup.d.ts +0 -3
- package/lib/typescript/src/__tests__/globalSetup.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/globalTeardown.d.ts +0 -3
- package/lib/typescript/src/__tests__/globalTeardown.d.ts.map +0 -1
- package/lib/typescript/src/__tests__/setup.d.ts +0 -63
- package/lib/typescript/src/__tests__/setup.d.ts.map +0 -1
- package/libs/apple/arm64_iphoneos/libwebgpu_dawn.a +0 -0
- package/libs/apple/arm64_iphonesimulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/arm64_xros/libwebgpu_dawn.a +0 -0
- package/libs/apple/arm64_xrsimulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/iphonesimulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64/libwebgpu_dawn.a +0 -0
- package/libs/apple/libwebgpu_dawn.xcframework/xros-arm64-simulator/libwebgpu_dawn.a +0 -0
- package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
- package/libs/apple/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
- package/libs/dawn.json +0 -4670
- package/src/__tests__/Alpha.spec.ts +0 -28
- package/src/__tests__/ArrayBuffer.spec.ts +0 -76
- package/src/__tests__/Buffer.spec.ts +0 -357
- package/src/__tests__/ComputeShader.spec.ts +0 -375
- package/src/__tests__/Constants.spec.ts +0 -89
- package/src/__tests__/Device.spec.ts +0 -84
- package/src/__tests__/ErrorScope.spec.ts +0 -92
- package/src/__tests__/ExternalTexture.spec.ts +0 -284
- package/src/__tests__/GPU.spec.ts +0 -272
- package/src/__tests__/ImageData.spec.ts +0 -26
- package/src/__tests__/Shaders.spec.ts +0 -232
- package/src/__tests__/Texture.spec.ts +0 -197
- package/src/__tests__/assets/Di-3d.png +0 -0
- package/src/__tests__/components/Wireframe/Shaders.ts +0 -138
- package/src/__tests__/components/Wireframe/models.ts +0 -113
- package/src/__tests__/components/Wireframe/utils.ts +0 -22
- package/src/__tests__/components/cube.ts +0 -51
- package/src/__tests__/components/meshes/mesh.ts +0 -96
- package/src/__tests__/components/meshes/sphere.ts +0 -103
- package/src/__tests__/components/meshes/stanfordDragon.ts +0 -44
- package/src/__tests__/components/meshes/stanfordDragonData.ts +0 -5
- package/src/__tests__/components/meshes/teapot.ts +0 -13
- package/src/__tests__/components/meshes/utils.ts +0 -235
- package/src/__tests__/components/triangle.ts +0 -17
- package/src/__tests__/config.ts +0 -2
- package/src/__tests__/demos/ABuffer.spec.ts +0 -890
- package/src/__tests__/demos/Blur.spec.ts +0 -398
- package/src/__tests__/demos/Cube.spec.ts +0 -929
- package/src/__tests__/demos/FractalCube.spec.ts +0 -240
- package/src/__tests__/demos/OcclusionQuery.spec.ts +0 -376
- package/src/__tests__/demos/RenderBundles.spec.ts +0 -580
- package/src/__tests__/demos/Triangle.spec.ts +0 -266
- package/src/__tests__/demos/Wireframe.spec.ts +0 -188
- package/src/__tests__/globalSetup.ts +0 -45
- package/src/__tests__/globalTeardown.ts +0 -11
- package/src/__tests__/setup.ts +0 -423
- package/src/__tests__/snapshots/abuffer.png +0 -0
- package/src/__tests__/snapshots/asteroid.png +0 -0
- package/src/__tests__/snapshots/blur.png +0 -0
- package/src/__tests__/snapshots/buffer.png +0 -0
- package/src/__tests__/snapshots/constant-triangle.png +0 -0
- package/src/__tests__/snapshots/cube.png +0 -0
- package/src/__tests__/snapshots/f.png +0 -0
- package/src/__tests__/snapshots/f2.png +0 -0
- package/src/__tests__/snapshots/fractal-cubes.png +0 -0
- package/src/__tests__/snapshots/instanced-cubes.png +0 -0
- package/src/__tests__/snapshots/occlusion-query.png +0 -0
- package/src/__tests__/snapshots/ref.png +0 -0
- package/src/__tests__/snapshots/semi-opaque-cyan.png +0 -0
- package/src/__tests__/snapshots/texture.png +0 -0
- package/src/__tests__/snapshots/textured-cube.png +0 -0
- package/src/__tests__/snapshots/triangle-msaa.png +0 -0
- package/src/__tests__/snapshots/triangle.png +0 -0
- 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
|
-
});
|