Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 51 additions & 4 deletions modules/experimental/src/gpu-primitives/gpu-command-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ export class GPUCommandGraph<Parameters = void> {
private readonly buffers = new Map<string, GraphBufferHandle>();
private readonly textures = new Map<string, GraphTextureHandle>();
private readonly externalTextures = new Map<string, GraphExternalTextureHandle>();
private readonly tableBufferHandles = new Map<Buffer, GraphBufferHandle>();
private readonly importedBufferHandles = new Map<Buffer, GraphBufferHandle>();
private readonly dynamicBufferHandles = new Set<GraphBufferHandle>();
private readonly nodes: GPUCommandGraphNode<Parameters>[] = [];
private readonly nodeIds = new Set<string>();
private compiled = false;
Expand Down Expand Up @@ -265,7 +266,17 @@ export class GPUCommandGraph<Parameters = void> {
if (defaultBuffer) {
validateImportedBuffer(defaultBuffer, descriptor, this.device);
}
return this.addBuffer(new GraphBufferHandle(this, descriptor, false, defaultBuffer));
const handle = this.addBuffer(new GraphBufferHandle(this, descriptor, false, defaultBuffer));
if (defaultBuffer) {
const physicalBuffer = getCoreBuffer(defaultBuffer);
if (!this.getImportedBufferHandle(physicalBuffer)) {
this.importedBufferHandles.set(physicalBuffer, handle);
}
if (defaultBuffer instanceof DynamicBuffer) {
this.dynamicBufferHandles.add(handle);
}
}
return handle;
}

/**
Expand Down Expand Up @@ -590,13 +601,22 @@ export class GPUCommandGraph<Parameters = void> {
throw new Error(`GPUCommandGraph import "${id}" requires GPUData.format`);
}
const coreBuffer = getCoreBuffer(data.buffer);
let handle = this.tableBufferHandles.get(coreBuffer);
let handle: GraphBufferHandle | undefined;
if (data.buffer instanceof DynamicBuffer) {
for (const dynamicHandle of this.dynamicBufferHandles) {
if (dynamicHandle.defaultBuffer === data.buffer) {
handle = dynamicHandle;
break;
}
}
} else {
handle = this.getImportedBufferHandle(coreBuffer);
}
if (!handle) {
handle = this.importBuffer(
{id, byteLength: coreBuffer.byteLength, usage: coreBuffer.usage},
data.buffer
);
this.tableBufferHandles.set(coreBuffer, handle);
}
return this.createDataView(handle, {
format: data.format,
Expand All @@ -607,6 +627,33 @@ export class GPUCommandGraph<Parameters = void> {
});
}

private getImportedBufferHandle(buffer: Buffer): GraphBufferHandle | undefined {
const cachedHandle = this.importedBufferHandles.get(buffer);
let replacedDynamicBacking = false;
if (cachedHandle?.defaultBuffer) {
if (getCoreBuffer(cachedHandle.defaultBuffer) === buffer) {
return cachedHandle;
}
this.importedBufferHandles.delete(buffer);
replacedDynamicBacking = true;
}
for (const handle of this.dynamicBufferHandles) {
if (handle.defaultBuffer && getCoreBuffer(handle.defaultBuffer) === buffer) {
this.importedBufferHandles.set(buffer, handle);
return handle;
}
}
if (replacedDynamicBacking) {
for (const handle of this.buffers.values()) {
if (handle.defaultBuffer && getCoreBuffer(handle.defaultBuffer) === buffer) {
this.importedBufferHandles.set(buffer, handle);
return handle;
}
}
}
return undefined;
}

private assertBuffer(buffer: GraphBufferHandle): void {
if (buffer.graph !== this || this.buffers.get(buffer.id) !== buffer) {
throw new Error(`Graph buffer "${buffer.id}" does not belong to ${this.id}`);
Expand Down
Loading
Loading