@multiplekex/shallot 0.2.5 → 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/package.json +1 -1
- package/src/core/component.ts +1 -1
- package/src/core/index.ts +1 -13
- package/src/core/math.ts +186 -0
- package/src/core/state.ts +1 -1
- package/src/core/xml.ts +56 -41
- package/src/extras/orbit/index.ts +1 -1
- package/src/extras/text/index.ts +10 -65
- package/src/extras/{water.ts → water/index.ts} +59 -4
- package/src/standard/raster/batch.ts +149 -0
- package/src/standard/raster/forward.ts +832 -0
- package/src/standard/raster/index.ts +146 -472
- package/src/standard/raster/shadow.ts +408 -0
- package/src/standard/raytracing/bvh/blas.ts +335 -87
- package/src/standard/raytracing/bvh/radix.ts +225 -228
- package/src/standard/raytracing/bvh/refit.ts +711 -0
- package/src/standard/raytracing/bvh/structs.ts +0 -55
- package/src/standard/raytracing/bvh/tlas.ts +153 -141
- package/src/standard/raytracing/bvh/traverse.ts +72 -64
- package/src/standard/raytracing/index.ts +233 -204
- package/src/standard/raytracing/instance.ts +30 -18
- package/src/standard/raytracing/ray.ts +1 -1
- package/src/standard/raytracing/shaders.ts +23 -40
- package/src/standard/render/camera.ts +10 -28
- package/src/standard/render/data.ts +1 -1
- package/src/standard/render/index.ts +68 -12
- package/src/standard/render/light.ts +2 -2
- package/src/standard/render/mesh.ts +404 -0
- package/src/standard/render/overlay.ts +5 -2
- package/src/standard/render/postprocess.ts +263 -267
- package/src/standard/render/surface/index.ts +81 -12
- package/src/standard/render/surface/shaders.ts +265 -11
- package/src/standard/render/surface/structs.ts +10 -0
- package/src/standard/tween/tween.ts +44 -115
- package/src/standard/render/mesh/box.ts +0 -20
- package/src/standard/render/mesh/index.ts +0 -315
- package/src/standard/render/mesh/plane.ts +0 -11
- package/src/standard/render/mesh/sphere.ts +0 -40
- package/src/standard/render/mesh/unified.ts +0 -96
- package/src/standard/render/surface/compile.ts +0 -65
- package/src/standard/render/surface/noise.ts +0 -58
|
@@ -195,77 +195,81 @@ interface PrefixPass {
|
|
|
195
195
|
dispatch: [number, number];
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
static async create(device: GPUDevice, data: GPUBuffer, count: number): Promise<PrefixSum> {
|
|
202
|
-
const passes: PrefixPass[] = [];
|
|
203
|
-
const module = device.createShaderModule({ code: prefixSumShader });
|
|
204
|
-
await PrefixSum.build(device, module, data, count, passes);
|
|
205
|
-
return new PrefixSum(passes);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
private static async build(
|
|
209
|
-
device: GPUDevice,
|
|
210
|
-
module: GPUShaderModule,
|
|
211
|
-
data: GPUBuffer,
|
|
212
|
-
count: number,
|
|
213
|
-
passes: PrefixPass[]
|
|
214
|
-
): Promise<void> {
|
|
215
|
-
const wgCount = Math.ceil(count / ITEMS_PER_WG);
|
|
216
|
-
const dispatch = dispatchSize(device, wgCount);
|
|
217
|
-
|
|
218
|
-
const blockSums = device.createBuffer({
|
|
219
|
-
size: Math.max(wgCount * 4, 4),
|
|
220
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
const layout = device.createBindGroupLayout({
|
|
224
|
-
entries: [
|
|
225
|
-
{ binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
226
|
-
{ binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
227
|
-
],
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
const bindGroup = device.createBindGroup({
|
|
231
|
-
layout,
|
|
232
|
-
entries: [
|
|
233
|
-
{ binding: 0, resource: { buffer: data } },
|
|
234
|
-
{ binding: 1, resource: { buffer: blockSums } },
|
|
235
|
-
],
|
|
236
|
-
});
|
|
198
|
+
interface PrefixSumState {
|
|
199
|
+
passes: PrefixPass[];
|
|
200
|
+
}
|
|
237
201
|
|
|
238
|
-
|
|
202
|
+
async function buildPrefixPasses(
|
|
203
|
+
device: GPUDevice,
|
|
204
|
+
module: GPUShaderModule,
|
|
205
|
+
data: GPUBuffer,
|
|
206
|
+
count: number,
|
|
207
|
+
passes: PrefixPass[]
|
|
208
|
+
): Promise<void> {
|
|
209
|
+
const wgCount = Math.ceil(count / ITEMS_PER_WG);
|
|
210
|
+
const dispatch = dispatchSize(device, wgCount);
|
|
211
|
+
|
|
212
|
+
const blockSums = device.createBuffer({
|
|
213
|
+
size: Math.max(wgCount * 4, 4),
|
|
214
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
const layout = device.createBindGroupLayout({
|
|
218
|
+
entries: [
|
|
219
|
+
{ binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
220
|
+
{ binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
221
|
+
],
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const bindGroup = device.createBindGroup({
|
|
225
|
+
layout,
|
|
226
|
+
entries: [
|
|
227
|
+
{ binding: 0, resource: { buffer: data } },
|
|
228
|
+
{ binding: 1, resource: { buffer: blockSums } },
|
|
229
|
+
],
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [layout] });
|
|
233
|
+
|
|
234
|
+
passes.push({
|
|
235
|
+
pipeline: await device.createComputePipelineAsync({
|
|
236
|
+
layout: pipelineLayout,
|
|
237
|
+
compute: { module, entryPoint: "scan", constants: { COUNT: count } },
|
|
238
|
+
}),
|
|
239
|
+
bindGroup,
|
|
240
|
+
dispatch,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
if (wgCount > 1) {
|
|
244
|
+
await buildPrefixPasses(device, module, blockSums, wgCount, passes);
|
|
239
245
|
|
|
240
246
|
passes.push({
|
|
241
247
|
pipeline: await device.createComputePipelineAsync({
|
|
242
248
|
layout: pipelineLayout,
|
|
243
|
-
compute: { module, entryPoint: "
|
|
249
|
+
compute: { module, entryPoint: "addBlocks", constants: { COUNT: count } },
|
|
244
250
|
}),
|
|
245
251
|
bindGroup,
|
|
246
252
|
dispatch,
|
|
247
253
|
});
|
|
248
|
-
|
|
249
|
-
if (wgCount > 1) {
|
|
250
|
-
await PrefixSum.build(device, module, blockSums, wgCount, passes);
|
|
251
|
-
|
|
252
|
-
passes.push({
|
|
253
|
-
pipeline: await device.createComputePipelineAsync({
|
|
254
|
-
layout: pipelineLayout,
|
|
255
|
-
compute: { module, entryPoint: "addBlocks", constants: { COUNT: count } },
|
|
256
|
-
}),
|
|
257
|
-
bindGroup,
|
|
258
|
-
dispatch,
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
254
|
}
|
|
255
|
+
}
|
|
262
256
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
257
|
+
async function createPrefixSum(
|
|
258
|
+
device: GPUDevice,
|
|
259
|
+
data: GPUBuffer,
|
|
260
|
+
count: number
|
|
261
|
+
): Promise<PrefixSumState> {
|
|
262
|
+
const passes: PrefixPass[] = [];
|
|
263
|
+
const module = device.createShaderModule({ code: prefixSumShader });
|
|
264
|
+
await buildPrefixPasses(device, module, data, count, passes);
|
|
265
|
+
return { passes };
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function dispatchPrefixSum(state: PrefixSumState, pass: GPUComputePassEncoder): void {
|
|
269
|
+
for (const p of state.passes) {
|
|
270
|
+
pass.setPipeline(p.pipeline);
|
|
271
|
+
pass.setBindGroup(0, p.bindGroup);
|
|
272
|
+
pass.dispatchWorkgroups(p.dispatch[0], p.dispatch[1], 1);
|
|
269
273
|
}
|
|
270
274
|
}
|
|
271
275
|
|
|
@@ -274,189 +278,182 @@ interface RadixPass {
|
|
|
274
278
|
reorder: { pipeline: GPUComputePipeline; bindGroup: GPUBindGroup };
|
|
275
279
|
}
|
|
276
280
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
) {}
|
|
283
|
-
|
|
284
|
-
static async create(
|
|
285
|
-
device: GPUDevice,
|
|
286
|
-
keys: GPUBuffer,
|
|
287
|
-
values: GPUBuffer,
|
|
288
|
-
count: number
|
|
289
|
-
): Promise<RadixSort> {
|
|
290
|
-
const wgCount = Math.ceil(count / WG_SIZE);
|
|
291
|
-
const workgroups = dispatchSize(device, wgCount);
|
|
292
|
-
|
|
293
|
-
const tmpKeys = device.createBuffer({
|
|
294
|
-
size: count * 4,
|
|
295
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
296
|
-
});
|
|
297
|
-
const tmpVals = device.createBuffer({
|
|
298
|
-
size: count * 4,
|
|
299
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
300
|
-
});
|
|
301
|
-
const localSums = device.createBuffer({
|
|
302
|
-
size: count * 4,
|
|
303
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
304
|
-
});
|
|
305
|
-
const blockSums = device.createBuffer({
|
|
306
|
-
size: 4 * wgCount * 4,
|
|
307
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
const prefixSum = await PrefixSum.create(device, blockSums, 4 * wgCount);
|
|
311
|
-
|
|
312
|
-
const blockSumModule = device.createShaderModule({ code: blockSumShader });
|
|
313
|
-
const reorderModule = device.createShaderModule({ code: reorderShader });
|
|
314
|
-
|
|
315
|
-
const blockSumLayout = device.createBindGroupLayout({
|
|
316
|
-
entries: [
|
|
317
|
-
{
|
|
318
|
-
binding: 0,
|
|
319
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
320
|
-
buffer: { type: "read-only-storage" },
|
|
321
|
-
},
|
|
322
|
-
{ binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
323
|
-
{ binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
324
|
-
],
|
|
325
|
-
});
|
|
281
|
+
interface RadixSortState {
|
|
282
|
+
passes: RadixPass[];
|
|
283
|
+
prefixSum: PrefixSumState;
|
|
284
|
+
workgroups: [number, number];
|
|
285
|
+
}
|
|
326
286
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
buffer: { type: "read-only-storage" },
|
|
333
|
-
},
|
|
334
|
-
{ binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
335
|
-
{
|
|
336
|
-
binding: 2,
|
|
337
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
338
|
-
buffer: { type: "read-only-storage" },
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
binding: 3,
|
|
342
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
343
|
-
buffer: { type: "read-only-storage" },
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
binding: 4,
|
|
347
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
348
|
-
buffer: { type: "read-only-storage" },
|
|
349
|
-
},
|
|
350
|
-
{ binding: 5, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
351
|
-
],
|
|
352
|
-
});
|
|
287
|
+
export interface RadixSortConfig {
|
|
288
|
+
keys: GPUBuffer;
|
|
289
|
+
values: GPUBuffer;
|
|
290
|
+
count: number;
|
|
291
|
+
}
|
|
353
292
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
293
|
+
export async function createRadixSort(
|
|
294
|
+
device: GPUDevice,
|
|
295
|
+
config: RadixSortConfig
|
|
296
|
+
): Promise<RadixSortState> {
|
|
297
|
+
const { keys, values, count } = config;
|
|
298
|
+
const wgCount = Math.ceil(count / WG_SIZE);
|
|
299
|
+
const workgroups = dispatchSize(device, wgCount);
|
|
300
|
+
|
|
301
|
+
const tmpKeys = device.createBuffer({
|
|
302
|
+
size: count * 4,
|
|
303
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
304
|
+
});
|
|
305
|
+
const tmpVals = device.createBuffer({
|
|
306
|
+
size: count * 4,
|
|
307
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
308
|
+
});
|
|
309
|
+
const localSums = device.createBuffer({
|
|
310
|
+
size: count * 4,
|
|
311
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
312
|
+
});
|
|
313
|
+
const blockSums = device.createBuffer({
|
|
314
|
+
size: 4 * wgCount * 4,
|
|
315
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
const prefixSum = await createPrefixSum(device, blockSums, 4 * wgCount);
|
|
319
|
+
|
|
320
|
+
const blockSumModule = device.createShaderModule({ code: blockSumShader });
|
|
321
|
+
const reorderModule = device.createShaderModule({ code: reorderShader });
|
|
322
|
+
|
|
323
|
+
const blockSumLayout = device.createBindGroupLayout({
|
|
324
|
+
entries: [
|
|
325
|
+
{
|
|
326
|
+
binding: 0,
|
|
327
|
+
visibility: GPUShaderStage.COMPUTE,
|
|
328
|
+
buffer: { type: "read-only-storage" },
|
|
329
|
+
},
|
|
330
|
+
{ binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
331
|
+
{ binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
332
|
+
],
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const reorderLayout = device.createBindGroupLayout({
|
|
336
|
+
entries: [
|
|
337
|
+
{
|
|
338
|
+
binding: 0,
|
|
339
|
+
visibility: GPUShaderStage.COMPUTE,
|
|
340
|
+
buffer: { type: "read-only-storage" },
|
|
341
|
+
},
|
|
342
|
+
{ binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
343
|
+
{
|
|
344
|
+
binding: 2,
|
|
345
|
+
visibility: GPUShaderStage.COMPUTE,
|
|
346
|
+
buffer: { type: "read-only-storage" },
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
binding: 3,
|
|
350
|
+
visibility: GPUShaderStage.COMPUTE,
|
|
351
|
+
buffer: { type: "read-only-storage" },
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
binding: 4,
|
|
355
|
+
visibility: GPUShaderStage.COMPUTE,
|
|
356
|
+
buffer: { type: "read-only-storage" },
|
|
357
|
+
},
|
|
358
|
+
{ binding: 5, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } },
|
|
359
|
+
],
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
const pipelinePromises: Promise<{
|
|
363
|
+
blockSum: GPUComputePipeline;
|
|
364
|
+
reorder: GPUComputePipeline;
|
|
365
|
+
}>[] = [];
|
|
366
|
+
|
|
367
|
+
for (let bit = 0; bit < 32; bit += 2) {
|
|
368
|
+
pipelinePromises.push(
|
|
369
|
+
(async () => {
|
|
370
|
+
const [blockSumPipeline, reorderPipeline] = await Promise.all([
|
|
371
|
+
device.createComputePipelineAsync({
|
|
372
|
+
layout: device.createPipelineLayout({
|
|
373
|
+
bindGroupLayouts: [blockSumLayout],
|
|
382
374
|
}),
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
const pipelines = await Promise.all(pipelinePromises);
|
|
390
|
-
const passes: RadixPass[] = [];
|
|
391
|
-
|
|
392
|
-
for (let i = 0; i < 16; i++) {
|
|
393
|
-
const bit = i * 2;
|
|
394
|
-
const even = bit % 4 === 0;
|
|
395
|
-
const inK = even ? keys : tmpKeys;
|
|
396
|
-
const inV = even ? values : tmpVals;
|
|
397
|
-
const outK = even ? tmpKeys : keys;
|
|
398
|
-
const outV = even ? tmpVals : values;
|
|
399
|
-
|
|
400
|
-
passes.push({
|
|
401
|
-
blockSum: {
|
|
402
|
-
pipeline: pipelines[i].blockSum,
|
|
403
|
-
bindGroup: device.createBindGroup({
|
|
404
|
-
layout: blockSumLayout,
|
|
405
|
-
entries: [
|
|
406
|
-
{ binding: 0, resource: { buffer: inK } },
|
|
407
|
-
{ binding: 1, resource: { buffer: localSums } },
|
|
408
|
-
{ binding: 2, resource: { buffer: blockSums } },
|
|
409
|
-
],
|
|
375
|
+
compute: {
|
|
376
|
+
module: blockSumModule,
|
|
377
|
+
entryPoint: "main",
|
|
378
|
+
constants: { WG_COUNT: wgCount, BIT: bit, COUNT: count },
|
|
379
|
+
},
|
|
410
380
|
}),
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
{
|
|
419
|
-
|
|
420
|
-
{ binding: 3, resource: { buffer: blockSums } },
|
|
421
|
-
{ binding: 4, resource: { buffer: inV } },
|
|
422
|
-
{ binding: 5, resource: { buffer: outV } },
|
|
423
|
-
],
|
|
381
|
+
device.createComputePipelineAsync({
|
|
382
|
+
layout: device.createPipelineLayout({
|
|
383
|
+
bindGroupLayouts: [reorderLayout],
|
|
384
|
+
}),
|
|
385
|
+
compute: {
|
|
386
|
+
module: reorderModule,
|
|
387
|
+
entryPoint: "main",
|
|
388
|
+
constants: { WG_COUNT: wgCount, BIT: bit, COUNT: count },
|
|
389
|
+
},
|
|
424
390
|
}),
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
return new RadixSort(passes, prefixSum, workgroups);
|
|
391
|
+
]);
|
|
392
|
+
return { blockSum: blockSumPipeline, reorder: reorderPipeline };
|
|
393
|
+
})()
|
|
394
|
+
);
|
|
430
395
|
}
|
|
431
396
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
for (const p of this.passes) {
|
|
435
|
-
pass.setPipeline(p.blockSum.pipeline);
|
|
436
|
-
pass.setBindGroup(0, p.blockSum.bindGroup);
|
|
437
|
-
pass.dispatchWorkgroups(x, y, 1);
|
|
397
|
+
const pipelines = await Promise.all(pipelinePromises);
|
|
398
|
+
const passes: RadixPass[] = [];
|
|
438
399
|
|
|
439
|
-
|
|
400
|
+
for (let i = 0; i < 16; i++) {
|
|
401
|
+
const bit = i * 2;
|
|
402
|
+
const even = bit % 4 === 0;
|
|
403
|
+
const inK = even ? keys : tmpKeys;
|
|
404
|
+
const inV = even ? values : tmpVals;
|
|
405
|
+
const outK = even ? tmpKeys : keys;
|
|
406
|
+
const outV = even ? tmpVals : values;
|
|
440
407
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
408
|
+
passes.push({
|
|
409
|
+
blockSum: {
|
|
410
|
+
pipeline: pipelines[i].blockSum,
|
|
411
|
+
bindGroup: device.createBindGroup({
|
|
412
|
+
layout: blockSumLayout,
|
|
413
|
+
entries: [
|
|
414
|
+
{ binding: 0, resource: { buffer: inK } },
|
|
415
|
+
{ binding: 1, resource: { buffer: localSums } },
|
|
416
|
+
{ binding: 2, resource: { buffer: blockSums } },
|
|
417
|
+
],
|
|
418
|
+
}),
|
|
419
|
+
},
|
|
420
|
+
reorder: {
|
|
421
|
+
pipeline: pipelines[i].reorder,
|
|
422
|
+
bindGroup: device.createBindGroup({
|
|
423
|
+
layout: reorderLayout,
|
|
424
|
+
entries: [
|
|
425
|
+
{ binding: 0, resource: { buffer: inK } },
|
|
426
|
+
{ binding: 1, resource: { buffer: outK } },
|
|
427
|
+
{ binding: 2, resource: { buffer: localSums } },
|
|
428
|
+
{ binding: 3, resource: { buffer: blockSums } },
|
|
429
|
+
{ binding: 4, resource: { buffer: inV } },
|
|
430
|
+
{ binding: 5, resource: { buffer: outV } },
|
|
431
|
+
],
|
|
432
|
+
}),
|
|
433
|
+
},
|
|
434
|
+
});
|
|
445
435
|
}
|
|
446
|
-
}
|
|
447
436
|
|
|
448
|
-
|
|
449
|
-
keys: GPUBuffer;
|
|
450
|
-
values: GPUBuffer;
|
|
451
|
-
count: number;
|
|
437
|
+
return { passes, prefixSum, workgroups };
|
|
452
438
|
}
|
|
453
439
|
|
|
454
|
-
export function
|
|
455
|
-
|
|
440
|
+
export function dispatchRadixSort(state: RadixSortState, pass: GPUComputePassEncoder): void {
|
|
441
|
+
const [x, y] = state.workgroups;
|
|
442
|
+
for (const p of state.passes) {
|
|
443
|
+
pass.setPipeline(p.blockSum.pipeline);
|
|
444
|
+
pass.setBindGroup(0, p.blockSum.bindGroup);
|
|
445
|
+
pass.dispatchWorkgroups(x, y, 1);
|
|
446
|
+
|
|
447
|
+
dispatchPrefixSum(state.prefixSum, pass);
|
|
448
|
+
|
|
449
|
+
pass.setPipeline(p.reorder.pipeline);
|
|
450
|
+
pass.setBindGroup(0, p.reorder.bindGroup);
|
|
451
|
+
pass.dispatchWorkgroups(x, y, 1);
|
|
452
|
+
}
|
|
456
453
|
}
|
|
457
454
|
|
|
458
455
|
export function createRadixSortNode(config: RadixSortConfig): ComputeNode {
|
|
459
|
-
let sort:
|
|
456
|
+
let sort: RadixSortState | null = null;
|
|
460
457
|
|
|
461
458
|
return {
|
|
462
459
|
id: "radix-sort",
|
|
@@ -469,7 +466,7 @@ export function createRadixSortNode(config: RadixSortConfig): ComputeNode {
|
|
|
469
466
|
|
|
470
467
|
execute(ctx: ExecutionContext) {
|
|
471
468
|
const pass = ctx.encoder.beginComputePass();
|
|
472
|
-
sort
|
|
469
|
+
dispatchRadixSort(sort!, pass);
|
|
473
470
|
pass.end();
|
|
474
471
|
},
|
|
475
472
|
};
|