Buffers
Memory on the GPU can be allocated and managed through buffers. That way, WGSL shaders can be provided with an additional context, or retrieve the results of parallel computation back to JS. When creating a buffer, a schema for the contained values has to be provided, which allows for:
- Calculating the required size of the buffer,
- Automatic conversion to-and-from a binary representation,
- Type-safe APIs for writing and reading.
As an example, let’s create a buffer for storing particles.
This buffer can then be used and/or updated by a WGSL shader.
Creating a buffer
To create a buffer, you will need to define its schema by composing data types imported from typegpu/data
. Every WGSL data-type can be represented as JS schemas, including
structs and arrays. They will be explored in more detail in a following chapter.
Usage flags
To be able to use these buffers in WGSL shaders, we have to declare their usage upfront with .$usage(...)
.
You can also add all flags in a single $usage()
.
Additional flags
It is also possible to add any of the GPUBufferUsage
flags to a typed buffer object, using the .$addFlags
method.
Though it shouldn’t be necessary in most scenarios as majority of the flags are handled automatically by the library
or indirectly through the .$usage
method.
Flags can only be added this way if the typed buffer was not created with an existing GPU buffer. If it was, then all flags need to be provided to the existing buffer when constructing it.
Initial value
You can also pass an initial value to the root.createBuffer
function.
When the buffer is created, it will be mapped at creation, and the initial value will be written to the buffer.
Using an existing buffer
You can also create a buffer using an existing WebGPU buffer. This is useful when you have existing logic but want to introduce type-safe data operations.
Writing to a buffer
To write data to a buffer, you can use the .write(value)
method. The typed schema enables auto-complete as well as static validation of this
method’s arguments.
There’s also an option to copy value from another typed buffer using the .copyFrom(buffer)
method,
as long as both buffers have a matching data schema.
Reading from a buffer
To read data from a buffer, you can use the .read()
method.
It returns a promise that resolves to the data read from the buffer.