GPUComputePassEncoder: dispatchWorkgroupsIndirect() 方法
GPUComputePassEncoder
接口的 dispatchWorkgroupsIndirect()
方法根据 GPUBuffer
的参数调度一个工作组网格,以执行当前 GPUComputePipeline
(即通过 GPUComputePassEncoder.setPipeline()
设置) 所做的工作。
语法
dispatchWorkgroupsIndirect(indirectBuffer, indirectOffset)
参数
indirectBuffer
-
一个
GPUBuffer
,包含要调度的网格的工作组的 X、Y 和 Z 尺寸。缓冲区必须包含一个紧密排列的三个 32 位无符号整数值块,表示尺寸 (总共 12 字节),顺序与GPUComputePassEncoder.dispatchWorkgroups()
的参数顺序相同。因此,例如jsconst uint32 = new Uint32Array(3); uint32[0] = 25; // The X value uint32[1] = 1; // The Y value uint32[2] = 1; // The Z value // Write values into a GPUBuffer device.queue.writeBuffer(buffer, 0, uint32, 0, uint32.length);
indirectOffset
-
在
indirectBuffer
中,维度数据开始处的偏移量(以字节为单位)。
注意: 传递给 GPUComputePassEncoder.dispatchWorkgroups()
和 dispatchWorkgroupsIndirect()
的 X、Y 和 Z 维度值是每个维度要分派的 workgroup 数量,而不是每个维度要执行的着色器调用次数。这与现代原生 GPU API 的行为一致,但与 OpenCL 的行为不同。这意味着,如果 GPUShaderModule
定义了一个入口点,其 @workgroup_size(4, 4)
,并且工作使用调用 dispatchWorkgroupsIndirect(indirectBuffer);
分派给它,其中 indirectBuffer
指定了 X 和 Y 维度为 8 和 8,则入口点将被调用 1024 次 - 沿 X 和 Y 轴将 4 x 4 的 workgroup 分派 8 次。4 * 4 * 8 * 8 = 1024
。
返回值
无 (Undefined
).
验证
调用 **dispatchWorkgroupsIndirect()
** 时,必须满足以下条件,否则将生成 GPUValidationError
,并且 GPUComputePassEncoder
将变为无效
indirectBuffer
的GPUBuffer.usage
包含GPUBufferUsage.INDIRECT
标志。indirectOffset
+ 由X
、Y
和Z
维度指定的总大小小于或等于indirectBuffer
的GPUBuffer.size
。indirectOffset
是 4 的倍数。
示例
// Set global buffer size
const BUFFER_SIZE = 1000;
// Compute shader; note workgroup size of 64
const shader = `
@group(0) @binding(0)
var<storage, read_write> output: array<f32>;
@compute @workgroup_size(64)
...
`;
// ...
// Create GPUCommandEncoder to encode commands to issue to the GPU
const commandEncoder = device.createCommandEncoder();
// Initiate render pass
const passEncoder = commandEncoder.beginComputePass();
// Issue commands
passEncoder.setPipeline(computePipeline);
passEncoder.setBindGroup(0, bindGroup);
const uint32 = new Uint32Array(3);
// Note workgroupCountX is set based on the global buffer size and the shader workgroup count.
uint32[0] = Math.ceil(BUFFER_SIZE / 64);
uint32[1] = 1;
uint32[2] = 1;
const workgroupDimensions = device.createBuffer({
size: 12,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.INDIRECT,
});
device.queue.writeBuffer(workgroupDimensions, 0, uint32, 0, uint32.length);
passEncoder.dispatchWorkgroupsIndirect(workgroupDimensions, 0);
// End the render pass
passEncoder.end();
// Copy output buffer to staging buffer
commandEncoder.copyBufferToBuffer(
output,
0, // Source offset
stagingBuffer,
0, // Destination offset
BUFFER_SIZE,
);
// End frame by passing array of command buffers to command queue for execution
device.queue.submit([commandEncoder.finish()]);
// ...
规范
规范 |
---|
WebGPU # dom-gpucomputepassencoder-dispatchworkgroupsindirect |
浏览器兼容性
BCD 表格仅在浏览器中加载