MCPcopy
hub / github.com/processing/p5.js / compute

Method compute

src/webgpu/p5.RendererWebGPU.js:4138–4199  ·  view source on GitHub ↗
(shader, x, y = 1, z = 1)

Source from the content-addressed store, hash-verified

4136 }
4137
4138 compute(shader, x, y = 1, z = 1) {
4139 if (shader.shaderType !== 'compute') {
4140 throw new Error('compute() can only be called with a compute shader');
4141 }
4142
4143 this._finishActiveRenderPass();
4144
4145 // Ensure shader is initialized and finalized
4146 if (!shader._compiled) {
4147 shader.init();
4148 }
4149
4150 // Set default uniforms
4151 shader.setDefaultUniforms();
4152 shader.setUniform('uTotalCount', [x, y, z]);
4153
4154 // Calculate optimal workgroup size (8x8x1 = 64 threads per workgroup)
4155 const WORKGROUP_SIZE_X = 8;
4156 const WORKGROUP_SIZE_Y = 8;
4157 const WORKGROUP_SIZE_Z = 1;
4158
4159 // auto spreading: if any dimension is too large or for performance optimization,
4160 // spread total iteration count across dimensions
4161 const totalIterations = x * y * z;
4162 const MAX_THREADS_PER_DIM = 65535 * 8;
4163
4164 let px = x;
4165 let py = y;
4166 let pz = z;
4167
4168 // we spread if we exceed GPU limits OR if it involves a large 1D dispatch
4169 const exceedsLimits = x > MAX_THREADS_PER_DIM || y > MAX_THREADS_PER_DIM || z > MAX_THREADS_PER_DIM;
4170 const isLarge1D = totalIterations > 1024 && y === 1 && z === 1;
4171
4172 if (exceedsLimits || isLarge1D) {
4173 // Always use 2D square spreading (√N × √N).
4174 // Benchmarks showed 2D square equals or outperforms 3D cube at every
4175 // scale tested, with simpler index reconstruction in the shader.
4176 px = Math.ceil(Math.sqrt(totalIterations));
4177 py = Math.ceil(totalIterations / px);
4178 pz = 1;
4179 }
4180
4181 shader.setUniform('uPhysicalCount', [px, py, pz]);
4182
4183 const workgroupCountX = Math.ceil(px / WORKGROUP_SIZE_X);
4184 const workgroupCountY = Math.ceil(py / WORKGROUP_SIZE_Y);
4185 const workgroupCountZ = Math.ceil(pz / WORKGROUP_SIZE_Z);
4186
4187 const commandEncoder = this.device.createCommandEncoder();
4188 const passEncoder = commandEncoder.beginComputePass();
4189 this.setupShaderBindGroups(shader, passEncoder, {
4190 compute: true,
4191 workgroupSize: [WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y, WORKGROUP_SIZE_Z],
4192 });
4193
4194 // Dispatch compute workgroups
4195 passEncoder.dispatchWorkgroups(workgroupCountX, workgroupCountY, workgroupCountZ);

Callers 4

p5.Shader.jsFile · 0.80
webgpu.jsFile · 0.80
renderer3DFunction · 0.80

Calls 7

setupShaderBindGroupsMethod · 0.95
setDefaultUniformsMethod · 0.80
setUniformMethod · 0.80
endMethod · 0.80
finishMethod · 0.80
initMethod · 0.45

Tested by

no test coverage detected