(
texture: BrowserGpuTexture
)
| 500 | }); |
| 501 | |
| 502 | const computeRedCentroidFromTexture = async ( |
| 503 | texture: BrowserGpuTexture |
| 504 | ): Promise<BrowserTextureCentroid> => { |
| 505 | const pixelCount = width * height; |
| 506 | const compareWorkgroupCount = Math.ceil(pixelCount / centroidWorkgroupSize); |
| 507 | const partialByteLength = compareWorkgroupCount * 4 * Uint32Array.BYTES_PER_ELEMENT; |
| 508 | const partialA = device!.createBuffer({ |
| 509 | size: partialByteLength, |
| 510 | usage: bufferUsageStorage | bufferUsageCopySrc, |
| 511 | }); |
| 512 | const partialB = device!.createBuffer({ |
| 513 | size: partialByteLength, |
| 514 | usage: bufferUsageStorage | bufferUsageCopySrc, |
| 515 | }); |
| 516 | const readbackBuffer = device!.createBuffer({ |
| 517 | size: 4 * Uint32Array.BYTES_PER_ELEMENT, |
| 518 | usage: bufferUsageMapRead | bufferUsageCopyDst, |
| 519 | }); |
| 520 | const paramsBuffers: BrowserGpuBuffer[] = []; |
| 521 | |
| 522 | try { |
| 523 | const commandEncoder = device!.createCommandEncoder(); |
| 524 | const compareParams = createAndWriteUniformBuffer(new Uint32Array([width, height, 0, 0])); |
| 525 | paramsBuffers.push(compareParams); |
| 526 | const compareBindGroup = device!.createBindGroup({ |
| 527 | layout: centroidComparePipeline.getBindGroupLayout(0), |
| 528 | entries: [ |
| 529 | { binding: 0, resource: texture.createView() }, |
| 530 | { binding: 1, resource: { buffer: partialA } }, |
| 531 | { binding: 2, resource: { buffer: compareParams } }, |
| 532 | ], |
| 533 | }); |
| 534 | |
| 535 | const comparePass = commandEncoder.beginComputePass(); |
| 536 | comparePass.setPipeline(centroidComparePipeline); |
| 537 | comparePass.setBindGroup(0, compareBindGroup); |
| 538 | comparePass.dispatchWorkgroups(compareWorkgroupCount); |
| 539 | comparePass.end(); |
| 540 | |
| 541 | let inputBuffer = partialA; |
| 542 | let outputBuffer = partialB; |
| 543 | let inputCount = compareWorkgroupCount; |
| 544 | while (inputCount > 1) { |
| 545 | const outputCount = Math.ceil(inputCount / centroidWorkgroupSize); |
| 546 | const reduceParams = createAndWriteUniformBuffer(new Uint32Array([inputCount, 0, 0, 0])); |
| 547 | paramsBuffers.push(reduceParams); |
| 548 | const reduceBindGroup = device!.createBindGroup({ |
| 549 | layout: centroidReducePipeline.getBindGroupLayout(0), |
| 550 | entries: [ |
| 551 | { binding: 0, resource: { buffer: inputBuffer } }, |
| 552 | { binding: 1, resource: { buffer: outputBuffer } }, |
| 553 | { binding: 2, resource: { buffer: reduceParams } }, |
| 554 | ], |
| 555 | }); |
| 556 | const reducePass = commandEncoder.beginComputePass(); |
| 557 | reducePass.setPipeline(centroidReducePipeline); |
| 558 | reducePass.setBindGroup(0, reduceBindGroup); |
| 559 | reducePass.dispatchWorkgroups(outputCount); |
no test coverage detected