Skip to content
Merged
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
3 changes: 1 addition & 2 deletions apps/typegpu-docs/src/content/docs/fundamentals/roots.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ To unwrap a `TgpuVertexLayout` make sure to explicitly mark each of its attribut

## Destroying resources

Calling `root.destroy()` will destroy all resources created with it.
It will also destroy the underlying WebGPU device, if it wasn't originally passed in via the `initFromDevice` function.
Calling `root.destroy()` will call `device.destroy()` to let the browser know that it can free up all the resources. However, if an existing device is passed in via `tgpu.initFromDevice()`, this method does nothing.

```ts
root.destroy(); // <- frees up all the resources
Expand Down
18 changes: 1 addition & 17 deletions packages/typegpu/src/core/root/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,6 @@ class WithFragmentImpl implements WithFragment {
}
}

interface Disposable {
destroy(): void;
}

/**
* Holds all data that is necessary to facilitate CPU and GPU communication.
* Programs that share a root can interact via GPU buffers.
Expand All @@ -261,8 +257,6 @@ class TgpuRootImpl extends WithBindingImpl
implements TgpuRoot, ExperimentalTgpuRoot {
'~unstable': Omit<ExperimentalTgpuRoot, keyof TgpuRoot>;

private _disposables: Disposable[] = [];

private _unwrappedBindGroupLayouts = new WeakMemo(
(key: TgpuBindGroupLayout) => key.unwrap(this),
);
Expand Down Expand Up @@ -307,9 +301,7 @@ class TgpuRootImpl extends WithBindingImpl
typeSchema: TData,
initialOrBuffer?: Infer<TData> | GPUBuffer,
): TgpuBuffer<TData> {
const buffer = INTERNAL_createBuffer(this, typeSchema, initialOrBuffer);
this._disposables.push(buffer);
return buffer;
return INTERNAL_createBuffer(this, typeSchema, initialOrBuffer);
}

createUniform<TData extends AnyWgslData>(
Expand All @@ -319,7 +311,6 @@ class TgpuRootImpl extends WithBindingImpl
const buffer = INTERNAL_createBuffer(this, typeSchema, initialOrBuffer)
// biome-ignore lint/suspicious/noExplicitAny: i'm sure it's fine
.$usage('uniform' as any);
this._disposables.push(buffer);

return new TgpuBufferShorthandImpl('uniform', buffer);
}
Expand All @@ -331,7 +322,6 @@ class TgpuRootImpl extends WithBindingImpl
const buffer = INTERNAL_createBuffer(this, typeSchema, initialOrBuffer)
// biome-ignore lint/suspicious/noExplicitAny: i'm sure it's fine
.$usage('storage' as any);
this._disposables.push(buffer);

return new TgpuBufferShorthandImpl('mutable', buffer);
}
Expand All @@ -343,7 +333,6 @@ class TgpuRootImpl extends WithBindingImpl
const buffer = INTERNAL_createBuffer(this, typeSchema, initialOrBuffer)
// biome-ignore lint/suspicious/noExplicitAny: i'm sure it's fine
.$usage('storage' as any);
this._disposables.push(buffer);

return new TgpuBufferShorthandImpl('readonly', buffer);
}
Expand All @@ -369,10 +358,6 @@ class TgpuRootImpl extends WithBindingImpl
}

destroy() {
for (const disposable of this._disposables) {
disposable.destroy();
}

clearTextureUtilsCache(this.device);

if (this._ownDevice) {
Expand Down Expand Up @@ -413,7 +398,6 @@ class TgpuRootImpl extends WithBindingImpl
>
> {
const texture = INTERNAL_createTexture(props, this);
this._disposables.push(texture);
// biome-ignore lint/suspicious/noExplicitAny: <too much type wrangling>
return texture as any;
}
Expand Down
9 changes: 5 additions & 4 deletions packages/typegpu/tests/root.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('TgpuRoot', () => {
});

describe('.destroy', () => {
it('should call .destroy on all buffers created with it', ({ root }) => {
it('should call .destroy on the device it created', ({ root }) => {
const buffer1 = root.createBuffer(d.f32);
const buffer2 = root.createBuffer(d.i32);
const buffer3 = root.createBuffer(d.u32);
Expand All @@ -71,9 +71,10 @@ describe('TgpuRoot', () => {

root.destroy();

expect(buffer1DestroySpy).toHaveBeenCalledOnce();
expect(buffer2DestroySpy).toHaveBeenCalledOnce();
expect(buffer3DestroySpy).toHaveBeenCalledOnce();
expect(root.device.destroy).toHaveBeenCalledOnce();
expect(buffer1DestroySpy).not.toHaveBeenCalled();
expect(buffer2DestroySpy).not.toHaveBeenCalled();
expect(buffer3DestroySpy).not.toHaveBeenCalled();
});
});

Expand Down