Roots
Roots are responsible for resource allocation and management. Whether you’d like to wrap an existing WebGPU buffer with a typed shell or create a brand new buffer, roots are the place to start.
You can create a root using the tgpu.init
function.
It requests a GPU device with default requirements. An optional parameter
can be passed in with special requirements for the GPU device. If you already have a device that you want to use,
you can pass it into tgpu.initFromDevice
instead.
To retrieve the device that is associated with a root, you can use the root.device
property.
Creating resources
Every root.create*
function creates a typed resource.
Function | Description |
---|---|
root.createBuffer | Creates a typed buffer with a given data-type and, optionally, an initial value. More information in the next chapter. |
Unwrapping resources
There are times where a typed resource needs to be used by a vanilla WebGPU API. To retrieve the raw
untyped value of a typed resource, use the root.unwrap
function.
Function | Description |
---|---|
root.unwrap(resource: TgpuBuffer<AnyTgpuData>) | Returns a GPUBuffer . |
root.unwrap(resource: TgpuBindGroupLayout) | Returns a GPUBindGroupLayout . |
root.unwrap(resource: TgpuBindGroup) | Returns a GPUBindGroup . |
Destroying resources
Calling root.destroy()
will destroy all resources created with it.
Best practices
Treat roots as their own separate universes, meaning resources created from the same root can interact with each other, while resources created by seperate roots can have a hard time interacting. This usually means creating just one root at the start of the program is the safest bet, but there are exceptions.
If you do not own the GPU device
If you cannot control the lifetime of the GPU device you are to use for computing/rendering, but are instead given the device in a lifecycle hook (e.g., react-native-wgpu), you can create a new root each time, as long as you recreate every resource as well.
If you pass the GPU device everywhere
It is common practice to pass a GPUDevice
to classes or functions for them to allocate their required resources. At first glance, this poses a problem when trying to
incorporate TypeGPU, since we would need to pass a root around instead of a device for all functionality that wants to move towards a typed API. We can create a global mapping
between devices and roots to solve this.
You can copy and paste the utility below that implements a basic global cache for roots.
If you reuse the same getOrInitRoot
function across code that has to create resources, the root will be shared
across them.