not sure
This commit is contained in:
parent
560398fefb
commit
80ed37298b
73 changed files with 3619 additions and 1295 deletions
|
|
@ -14,14 +14,16 @@ export class AgentGenerationPipeline {
|
|||
|
||||
private readonly bindGroupLayout: GPUBindGroupLayout;
|
||||
private readonly uniforms: GPUBuffer;
|
||||
private readonly bindGroup: GPUBindGroup;
|
||||
private readonly bindGroupsByActiveBuffer = new WeakMap<
|
||||
GPUBuffer,
|
||||
WeakMap<GPUBuffer, GPUBindGroup>
|
||||
>();
|
||||
|
||||
private readonly resizePipeline: GPUComputePipeline;
|
||||
private readonly compactionPipeline: GPUComputePipeline;
|
||||
private readonly compactedAgentsCopyPipeline: GPUComputePipeline;
|
||||
|
||||
public readonly agentsBuffer: GPUBuffer;
|
||||
private readonly compactedAgentsBuffer: GPUBuffer;
|
||||
private activeAgentsBuffer: GPUBuffer;
|
||||
private inactiveAgentsBuffer: GPUBuffer;
|
||||
private readonly countersBuffer: GPUBuffer;
|
||||
private readonly countersStagingBuffer: GPUBuffer;
|
||||
private readonly counterClearValues = new Uint32Array(
|
||||
|
|
@ -69,15 +71,8 @@ export class AgentGenerationPipeline {
|
|||
],
|
||||
});
|
||||
|
||||
this.agentsBuffer = this.device.createBuffer({
|
||||
size: this.maxAgentCount * AGENT_SIZE_IN_BYTES,
|
||||
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
||||
});
|
||||
|
||||
this.compactedAgentsBuffer = this.device.createBuffer({
|
||||
size: this.maxAgentCount * AGENT_SIZE_IN_BYTES,
|
||||
usage: GPUBufferUsage.STORAGE,
|
||||
});
|
||||
this.activeAgentsBuffer = this.createAgentsBuffer();
|
||||
this.inactiveAgentsBuffer = this.createAgentsBuffer();
|
||||
|
||||
this.countersBuffer = this.device.createBuffer({
|
||||
size: AgentGenerationPipeline.COUNTER_COUNT * Uint32Array.BYTES_PER_ELEMENT,
|
||||
|
|
@ -94,36 +89,6 @@ export class AgentGenerationPipeline {
|
|||
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
||||
});
|
||||
|
||||
this.bindGroup = this.device.createBindGroup({
|
||||
layout: this.bindGroupLayout,
|
||||
entries: [
|
||||
{
|
||||
binding: 0,
|
||||
resource: {
|
||||
buffer: this.uniforms,
|
||||
},
|
||||
},
|
||||
{
|
||||
binding: 1,
|
||||
resource: {
|
||||
buffer: this.agentsBuffer,
|
||||
},
|
||||
},
|
||||
{
|
||||
binding: 2,
|
||||
resource: {
|
||||
buffer: this.countersBuffer,
|
||||
},
|
||||
},
|
||||
{
|
||||
binding: 3,
|
||||
resource: {
|
||||
buffer: this.compactedAgentsBuffer,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.resizePipeline = device.createComputePipeline({
|
||||
layout: device.createPipelineLayout({
|
||||
bindGroupLayouts: [emptyBindGroupLayout, this.bindGroupLayout],
|
||||
|
|
@ -145,15 +110,16 @@ export class AgentGenerationPipeline {
|
|||
entryPoint: 'main',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.compactedAgentsCopyPipeline = device.createComputePipeline({
|
||||
layout: device.createPipelineLayout({
|
||||
bindGroupLayouts: [emptyBindGroupLayout, this.bindGroupLayout],
|
||||
}),
|
||||
compute: {
|
||||
module: compactionModule,
|
||||
entryPoint: 'copyCompactedAgents',
|
||||
},
|
||||
public get agentsBuffer(): GPUBuffer {
|
||||
return this.activeAgentsBuffer;
|
||||
}
|
||||
|
||||
private createAgentsBuffer(): GPUBuffer {
|
||||
return this.device.createBuffer({
|
||||
size: this.maxAgentCount * AGENT_SIZE_IN_BYTES,
|
||||
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -163,6 +129,10 @@ export class AgentGenerationPipeline {
|
|||
? this.maxAgentCountUpperLimit
|
||||
: Number.POSITIVE_INFINITY,
|
||||
Math.floor(this.device.limits.maxBufferSize / AGENT_SIZE_IN_BYTES) - 1,
|
||||
Math.floor(
|
||||
((this.device.limits as GPUSupportedLimits).maxStorageBufferBindingSize ??
|
||||
this.device.limits.maxBufferSize) / AGENT_SIZE_IN_BYTES
|
||||
) - 1,
|
||||
this.device.limits.maxComputeWorkgroupsPerDimension *
|
||||
AgentGenerationPipeline.WORKGROUP_SIZE
|
||||
);
|
||||
|
|
@ -170,7 +140,7 @@ export class AgentGenerationPipeline {
|
|||
|
||||
public writeAgents(agentOffset: number, data: Float32Array): void {
|
||||
this.device.queue.writeBuffer(
|
||||
this.agentsBuffer,
|
||||
this.activeAgentsBuffer,
|
||||
agentOffset * AGENT_SIZE_IN_BYTES,
|
||||
data
|
||||
);
|
||||
|
|
@ -190,7 +160,7 @@ export class AgentGenerationPipeline {
|
|||
const commandEncoder = this.device.createCommandEncoder();
|
||||
const passEncoder = commandEncoder.beginComputePass();
|
||||
passEncoder.setPipeline(this.resizePipeline);
|
||||
passEncoder.setBindGroup(1, this.bindGroup);
|
||||
passEncoder.setBindGroup(1, this.getBindGroup());
|
||||
passEncoder.dispatchWorkgroups(
|
||||
getWorkgroupCount(agentCount, AgentGenerationPipeline.WORKGROUP_SIZE)
|
||||
);
|
||||
|
|
@ -204,8 +174,6 @@ export class AgentGenerationPipeline {
|
|||
return 0;
|
||||
}
|
||||
|
||||
this.counterClearValues.fill(0);
|
||||
this.agentCountUniformValues.fill(0);
|
||||
this.agentCountUniformValues[0] = agentCount;
|
||||
this.device.queue.writeBuffer(this.countersBuffer, 0, this.counterClearValues);
|
||||
this.device.queue.writeBuffer(this.uniforms, 0, this.agentCountUniformValues);
|
||||
|
|
@ -213,20 +181,12 @@ export class AgentGenerationPipeline {
|
|||
const commandEncoder = this.device.createCommandEncoder();
|
||||
const passEncoder = commandEncoder.beginComputePass();
|
||||
passEncoder.setPipeline(this.compactionPipeline);
|
||||
passEncoder.setBindGroup(1, this.bindGroup);
|
||||
passEncoder.setBindGroup(1, this.getBindGroup());
|
||||
passEncoder.dispatchWorkgroups(
|
||||
getWorkgroupCount(agentCount, AgentGenerationPipeline.WORKGROUP_SIZE)
|
||||
);
|
||||
passEncoder.end();
|
||||
|
||||
const copyPassEncoder = commandEncoder.beginComputePass();
|
||||
copyPassEncoder.setPipeline(this.compactedAgentsCopyPipeline);
|
||||
copyPassEncoder.setBindGroup(1, this.bindGroup);
|
||||
copyPassEncoder.dispatchWorkgroups(
|
||||
getWorkgroupCount(agentCount, AgentGenerationPipeline.WORKGROUP_SIZE)
|
||||
);
|
||||
copyPassEncoder.end();
|
||||
|
||||
commandEncoder.copyBufferToBuffer(
|
||||
this.countersBuffer,
|
||||
0,
|
||||
|
|
@ -239,18 +199,74 @@ export class AgentGenerationPipeline {
|
|||
|
||||
await this.countersStagingBuffer.mapAsync(GPUMapMode.READ);
|
||||
const compactedCount = new Uint32Array(
|
||||
this.countersStagingBuffer.getMappedRange().slice(0, Uint32Array.BYTES_PER_ELEMENT)
|
||||
this.countersStagingBuffer.getMappedRange(),
|
||||
0,
|
||||
1
|
||||
)[0];
|
||||
this.countersStagingBuffer.unmap();
|
||||
this.swapAgentBuffers();
|
||||
|
||||
return compactedCount;
|
||||
}
|
||||
|
||||
private getBindGroup(): GPUBindGroup {
|
||||
let inactiveCache = this.bindGroupsByActiveBuffer.get(this.activeAgentsBuffer);
|
||||
if (!inactiveCache) {
|
||||
inactiveCache = new WeakMap<GPUBuffer, GPUBindGroup>();
|
||||
this.bindGroupsByActiveBuffer.set(this.activeAgentsBuffer, inactiveCache);
|
||||
}
|
||||
|
||||
const cached = inactiveCache.get(this.inactiveAgentsBuffer);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const bindGroup = this.device.createBindGroup({
|
||||
layout: this.bindGroupLayout,
|
||||
entries: [
|
||||
{
|
||||
binding: 0,
|
||||
resource: {
|
||||
buffer: this.uniforms,
|
||||
},
|
||||
},
|
||||
{
|
||||
binding: 1,
|
||||
resource: {
|
||||
buffer: this.activeAgentsBuffer,
|
||||
},
|
||||
},
|
||||
{
|
||||
binding: 2,
|
||||
resource: {
|
||||
buffer: this.countersBuffer,
|
||||
},
|
||||
},
|
||||
{
|
||||
binding: 3,
|
||||
resource: {
|
||||
buffer: this.inactiveAgentsBuffer,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
inactiveCache.set(this.inactiveAgentsBuffer, bindGroup);
|
||||
return bindGroup;
|
||||
}
|
||||
|
||||
private swapAgentBuffers(): void {
|
||||
[this.activeAgentsBuffer, this.inactiveAgentsBuffer] = [
|
||||
this.inactiveAgentsBuffer,
|
||||
this.activeAgentsBuffer,
|
||||
];
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.uniforms.destroy();
|
||||
this.countersBuffer.destroy();
|
||||
this.countersStagingBuffer.destroy();
|
||||
this.compactedAgentsBuffer.destroy();
|
||||
this.agentsBuffer.destroy();
|
||||
this.inactiveAgentsBuffer.destroy();
|
||||
this.activeAgentsBuffer.destroy();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue