react-native-wgpu 0.1.4 → 0.1.6

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 (167) 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/libwebgpu_dawn.xcframework/xros-arm64 → 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/apple/libwebgpu_dawn.xcframework/Info.plist +44 -0
  100. package/libs/{ios/arm64_iphoneos → apple/libwebgpu_dawn.xcframework/ios-arm64}/libwebgpu_dawn.a +0 -0
  101. package/libs/{ios → apple}/libwebgpu_dawn.xcframework/ios-arm64_x86_64-simulator/libwebgpu_dawn.a +0 -0
  102. package/libs/apple/libwebgpu_dawn_macosx.xcframework/Info.plist +28 -0
  103. package/libs/apple/libwebgpu_dawn_macosx.xcframework/macos-arm64_x86_64/libwebgpu_dawn.a +0 -0
  104. package/libs/{ios/libwebgpu_dawn.xcframework/xros-arm64_x86_64-simulator → apple}/libwebgpu_dawn_visionos.a +0 -0
  105. package/libs/{ios/libwebgpu_dawn.xcframework → apple/libwebgpu_dawn_visionos.xcframework}/Info.plist +0 -31
  106. package/libs/{ios/arm64_xros → apple/libwebgpu_dawn_visionos.xcframework/xros-arm64}/libwebgpu_dawn.a +0 -0
  107. package/libs/{ios → apple/libwebgpu_dawn_visionos.xcframework/xros-arm64_x86_64-simulator}/libwebgpu_dawn_visionos.a +0 -0
  108. package/libs/apple/universal_macosx/libwebgpu_dawn.a +0 -0
  109. package/libs/{ios → apple}/x86_64_iphonesimulator/libwebgpu_dawn.a +0 -0
  110. package/libs/{ios → apple}/x86_64_xrsimulator/libwebgpu_dawn.a +0 -0
  111. package/package.json +24 -24
  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/react-native-wgpu.podspec +0 -53
@@ -0,0 +1,397 @@
1
+ import { checkImage, client, encodeImage } from "../setup";
2
+
3
+ const blur = /*wgsl*/ `struct Params {
4
+ filterDim : i32,
5
+ blockDim : u32,
6
+ }
7
+
8
+ @group(0) @binding(0) var samp : sampler;
9
+ @group(0) @binding(1) var<uniform> params : Params;
10
+ @group(1) @binding(1) var inputTex : texture_2d<f32>;
11
+ @group(1) @binding(2) var outputTex : texture_storage_2d<rgba8unorm, write>;
12
+
13
+ struct Flip {
14
+ value : u32,
15
+ }
16
+ @group(1) @binding(3) var<uniform> flip : Flip;
17
+
18
+ // This shader blurs the input texture in one direction, depending on whether
19
+ // |flip.value| is 0 or 1.
20
+ // It does so by running (128 / 4) threads per workgroup to load 128
21
+ // texels into 4 rows of shared memory. Each thread loads a
22
+ // 4 x 4 block of texels to take advantage of the texture sampling
23
+ // hardware.
24
+ // Then, each thread computes the blur result by averaging the adjacent texel values
25
+ // in shared memory.
26
+ // Because we're operating on a subset of the texture, we cannot compute all of the
27
+ // results since not all of the neighbors are available in shared memory.
28
+ // Specifically, with 128 x 128 tiles, we can only compute and write out
29
+ // square blocks of size 128 - (filterSize - 1). We compute the number of blocks
30
+ // needed in Javascript and dispatch that amount.
31
+
32
+ var<workgroup> tile : array<array<vec3f, 128>, 4>;
33
+
34
+ @compute @workgroup_size(32, 1, 1)
35
+ fn main(
36
+ @builtin(workgroup_id) WorkGroupID : vec3u,
37
+ @builtin(local_invocation_id) LocalInvocationID : vec3u
38
+ ) {
39
+ let filterOffset = (params.filterDim - 1) / 2;
40
+ let dims = vec2i(textureDimensions(inputTex, 0));
41
+ let baseIndex = vec2i(WorkGroupID.xy * vec2(params.blockDim, 4) +
42
+ LocalInvocationID.xy * vec2(4, 1))
43
+ - vec2(filterOffset, 0);
44
+
45
+ for (var r = 0; r < 4; r++) {
46
+ for (var c = 0; c < 4; c++) {
47
+ var loadIndex = baseIndex + vec2(c, r);
48
+ if (flip.value != 0u) {
49
+ loadIndex = loadIndex.yx;
50
+ }
51
+
52
+ tile[r][4 * LocalInvocationID.x + u32(c)] = textureSampleLevel(
53
+ inputTex,
54
+ samp,
55
+ (vec2f(loadIndex) + vec2f(0.25, 0.25)) / vec2f(dims),
56
+ 0.0
57
+ ).rgb;
58
+ }
59
+ }
60
+
61
+ workgroupBarrier();
62
+
63
+ for (var r = 0; r < 4; r++) {
64
+ for (var c = 0; c < 4; c++) {
65
+ var writeIndex = baseIndex + vec2(c, r);
66
+ if (flip.value != 0) {
67
+ writeIndex = writeIndex.yx;
68
+ }
69
+
70
+ let center = i32(4 * LocalInvocationID.x) + c;
71
+ if (center >= filterOffset &&
72
+ center < 128 - filterOffset &&
73
+ all(writeIndex < dims)) {
74
+ var acc = vec3(0.0, 0.0, 0.0);
75
+ for (var f = 0; f < params.filterDim; f++) {
76
+ var i = center + f - filterOffset;
77
+ acc = acc + (1.0 / f32(params.filterDim)) * tile[r][i];
78
+ }
79
+ textureStore(outputTex, writeIndex, vec4(acc, 1.0));
80
+ }
81
+ }
82
+ }
83
+ }
84
+ `;
85
+
86
+ const fullscreenTexturedQuad = /*wgsl*/ `@group(0) @binding(0) var mySampler : sampler;
87
+ @group(0) @binding(1) var myTexture : texture_2d<f32>;
88
+
89
+ struct VertexOutput {
90
+ @builtin(position) Position : vec4f,
91
+ @location(0) fragUV : vec2f,
92
+ }
93
+
94
+ @vertex
95
+ fn vert_main(@builtin(vertex_index) VertexIndex : u32) -> VertexOutput {
96
+ const pos = array(
97
+ vec2( 1.0, 1.0),
98
+ vec2( 1.0, -1.0),
99
+ vec2(-1.0, -1.0),
100
+ vec2( 1.0, 1.0),
101
+ vec2(-1.0, -1.0),
102
+ vec2(-1.0, 1.0),
103
+ );
104
+
105
+ const uv = array(
106
+ vec2(1.0, 0.0),
107
+ vec2(1.0, 1.0),
108
+ vec2(0.0, 1.0),
109
+ vec2(1.0, 0.0),
110
+ vec2(0.0, 1.0),
111
+ vec2(0.0, 0.0),
112
+ );
113
+
114
+ var output : VertexOutput;
115
+ output.Position = vec4(pos[VertexIndex], 0.0, 1.0);
116
+ output.fragUV = uv[VertexIndex];
117
+ return output;
118
+ }
119
+
120
+ @fragment
121
+ fn frag_main(@location(0) fragUV : vec2f) -> @location(0) vec4f {
122
+ return textureSample(myTexture, mySampler, fragUV);
123
+ }
124
+ `;
125
+
126
+ describe("Blur", () => {
127
+ it("draw scene", async () => {
128
+ const result = await client.eval(
129
+ ({
130
+ ctx,
131
+ device,
132
+ gpu,
133
+ assets: { di3D: imageBitmap },
134
+ fullscreenTexturedQuadWGSL,
135
+ blurWGSL,
136
+ }) => {
137
+ const tileDim = 128;
138
+ const batch = [4, 4];
139
+ const presentationFormat = gpu.getPreferredCanvasFormat();
140
+ const blurPipeline = device.createComputePipeline({
141
+ layout: "auto",
142
+ compute: {
143
+ module: device.createShaderModule({
144
+ code: blurWGSL,
145
+ }),
146
+ },
147
+ });
148
+
149
+ const fullscreenQuadPipeline = device.createRenderPipeline({
150
+ layout: "auto",
151
+ vertex: {
152
+ module: device.createShaderModule({
153
+ code: fullscreenTexturedQuadWGSL,
154
+ }),
155
+ },
156
+ fragment: {
157
+ module: device.createShaderModule({
158
+ code: fullscreenTexturedQuadWGSL,
159
+ }),
160
+ targets: [
161
+ {
162
+ format: presentationFormat,
163
+ },
164
+ ],
165
+ },
166
+ primitive: {
167
+ topology: "triangle-list",
168
+ },
169
+ });
170
+
171
+ const sampler = device.createSampler({
172
+ magFilter: "linear",
173
+ minFilter: "linear",
174
+ });
175
+
176
+ const [srcWidth, srcHeight] = [imageBitmap.width, imageBitmap.height];
177
+ const imageTexture = device.createTexture({
178
+ size: [srcWidth, srcHeight, 1],
179
+ format: "rgba8unorm",
180
+ usage:
181
+ GPUTextureUsage.TEXTURE_BINDING |
182
+ GPUTextureUsage.COPY_DST |
183
+ GPUTextureUsage.RENDER_ATTACHMENT,
184
+ });
185
+ device.queue.copyExternalImageToTexture(
186
+ { source: imageBitmap },
187
+ { texture: imageTexture },
188
+ [imageBitmap.width, imageBitmap.height],
189
+ );
190
+ const textures = [0, 1].map(() => {
191
+ return device.createTexture({
192
+ size: {
193
+ width: srcWidth,
194
+ height: srcHeight,
195
+ },
196
+ format: "rgba8unorm",
197
+ usage:
198
+ GPUTextureUsage.COPY_DST |
199
+ GPUTextureUsage.STORAGE_BINDING |
200
+ GPUTextureUsage.TEXTURE_BINDING,
201
+ });
202
+ });
203
+
204
+ const buffer0 = (() => {
205
+ const buffer = device.createBuffer({
206
+ size: 4,
207
+ mappedAtCreation: true,
208
+ usage: GPUBufferUsage.UNIFORM,
209
+ });
210
+ new Uint32Array(buffer.getMappedRange())[0] = 0;
211
+ buffer.unmap();
212
+ return buffer;
213
+ })();
214
+
215
+ const buffer1 = (() => {
216
+ const buffer = device.createBuffer({
217
+ size: 4,
218
+ mappedAtCreation: true,
219
+ usage: GPUBufferUsage.UNIFORM,
220
+ });
221
+ new Uint32Array(buffer.getMappedRange())[0] = 1;
222
+ buffer.unmap();
223
+ return buffer;
224
+ })();
225
+
226
+ const blurParamsBuffer = device.createBuffer({
227
+ size: 8,
228
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.UNIFORM,
229
+ });
230
+
231
+ const computeConstants = device.createBindGroup({
232
+ layout: blurPipeline.getBindGroupLayout(0),
233
+ entries: [
234
+ {
235
+ binding: 0,
236
+ resource: sampler,
237
+ },
238
+ {
239
+ binding: 1,
240
+ resource: {
241
+ buffer: blurParamsBuffer,
242
+ },
243
+ },
244
+ ],
245
+ });
246
+
247
+ const computeBindGroup0 = device.createBindGroup({
248
+ layout: blurPipeline.getBindGroupLayout(1),
249
+ entries: [
250
+ {
251
+ binding: 1,
252
+ resource: imageTexture.createView(),
253
+ },
254
+ {
255
+ binding: 2,
256
+ resource: textures[0].createView(),
257
+ },
258
+ {
259
+ binding: 3,
260
+ resource: {
261
+ buffer: buffer0,
262
+ },
263
+ },
264
+ ],
265
+ });
266
+
267
+ const computeBindGroup1 = device.createBindGroup({
268
+ layout: blurPipeline.getBindGroupLayout(1),
269
+ entries: [
270
+ {
271
+ binding: 1,
272
+ resource: textures[0].createView(),
273
+ },
274
+ {
275
+ binding: 2,
276
+ resource: textures[1].createView(),
277
+ },
278
+ {
279
+ binding: 3,
280
+ resource: {
281
+ buffer: buffer1,
282
+ },
283
+ },
284
+ ],
285
+ });
286
+
287
+ const computeBindGroup2 = device.createBindGroup({
288
+ layout: blurPipeline.getBindGroupLayout(1),
289
+ entries: [
290
+ {
291
+ binding: 1,
292
+ resource: textures[1].createView(),
293
+ },
294
+ {
295
+ binding: 2,
296
+ resource: textures[0].createView(),
297
+ },
298
+ {
299
+ binding: 3,
300
+ resource: {
301
+ buffer: buffer0,
302
+ },
303
+ },
304
+ ],
305
+ });
306
+
307
+ const showResultBindGroup = device.createBindGroup({
308
+ layout: fullscreenQuadPipeline.getBindGroupLayout(0),
309
+ entries: [
310
+ {
311
+ binding: 0,
312
+ resource: sampler,
313
+ },
314
+ {
315
+ binding: 1,
316
+ resource: textures[1].createView(),
317
+ },
318
+ ],
319
+ });
320
+
321
+ const settings = {
322
+ filterSize: 15,
323
+ iterations: 2,
324
+ };
325
+
326
+ let blockDim: number;
327
+ const updateSettings = () => {
328
+ blockDim = tileDim - (settings.filterSize - 1);
329
+ device.queue.writeBuffer(
330
+ blurParamsBuffer,
331
+ 0,
332
+ new Uint32Array([settings.filterSize, blockDim]),
333
+ );
334
+ };
335
+ updateSettings();
336
+
337
+ function frame() {
338
+ const commandEncoder = device.createCommandEncoder();
339
+
340
+ const computePass = commandEncoder.beginComputePass();
341
+ computePass.setPipeline(blurPipeline);
342
+ computePass.setBindGroup(0, computeConstants);
343
+
344
+ computePass.setBindGroup(1, computeBindGroup0);
345
+ computePass.dispatchWorkgroups(
346
+ Math.ceil(srcWidth / blockDim),
347
+ Math.ceil(srcHeight / batch[1]),
348
+ );
349
+
350
+ computePass.setBindGroup(1, computeBindGroup1);
351
+ computePass.dispatchWorkgroups(
352
+ Math.ceil(srcHeight / blockDim),
353
+ Math.ceil(srcWidth / batch[1]),
354
+ );
355
+
356
+ for (let i = 0; i < settings.iterations - 1; ++i) {
357
+ computePass.setBindGroup(1, computeBindGroup2);
358
+ computePass.dispatchWorkgroups(
359
+ Math.ceil(srcWidth / blockDim),
360
+ Math.ceil(srcHeight / batch[1]),
361
+ );
362
+
363
+ computePass.setBindGroup(1, computeBindGroup1);
364
+ computePass.dispatchWorkgroups(
365
+ Math.ceil(srcHeight / blockDim),
366
+ Math.ceil(srcWidth / batch[1]),
367
+ );
368
+ }
369
+
370
+ computePass.end();
371
+
372
+ const passEncoder = commandEncoder.beginRenderPass({
373
+ colorAttachments: [
374
+ {
375
+ view: ctx.getCurrentTexture().createView(),
376
+ clearValue: [0, 0, 0, 1],
377
+ loadOp: "clear",
378
+ storeOp: "store",
379
+ },
380
+ ],
381
+ });
382
+
383
+ passEncoder.setPipeline(fullscreenQuadPipeline);
384
+ passEncoder.setBindGroup(0, showResultBindGroup);
385
+ passEncoder.draw(6);
386
+ passEncoder.end();
387
+ device.queue.submit([commandEncoder.finish()]);
388
+ }
389
+ frame();
390
+ return ctx.getImageData();
391
+ },
392
+ { blurWGSL: blur, fullscreenTexturedQuadWGSL: fullscreenTexturedQuad },
393
+ );
394
+ const image = encodeImage(result);
395
+ checkImage(image, "snapshots/blur.png");
396
+ });
397
+ });