Buffer
EditA Buffer is a block of memory on the GPU. It's like a GPU version of a Blob
. Lua code can write data to the buffer which uploads to VRAM, and shaders read buffer data during rendering. Compute shaders can also write to buffers.
The size of a Buffer is the number of bytes of VRAM it occupies. It's set when the Buffer is created and can't be changed afterwards.
Buffers can optionally have a format, which defines the type of data stored in the buffer. The format determines how Lua values are converted into binary. Like the size, it can't change after the buffer is created. Shader:getBufferFormat
returns the format of a variable in a Shader
.
When a Buffer has a format, it also has a length, which is the number of items it holds, and a stride, which is the number of bytes between each item.
Buffer:setData
is used to upload data to the Buffer. Buffer:clear
can also be used to efficiently zero out a Buffer.
Buffer:getData
can be used to download data from the Buffer, but be aware that it stalls the GPU until the download is complete, which is very slow! Buffer:newReadback
will instead download the data in the background, which avoids costly stalls.
Buffers are often used for mesh data. Vertices stored in buffers can be drawn using Pass:mesh
. Mesh
objects can also be used, which wrap Buffers along with some extra metadata.
Buffers can be "bound" to a variable in a Shader using Pass:send
. That means that the next time the shader runs, the data from the Buffer will be used for the stuff in the variable.
It's important to understand that data from a Buffer will only be used at the point when graphics commands are actually submitted. This example records 2 draws, changing the buffer data between each one:
buffer:setData(data1)
pass:mesh(buffer)
buffer:setData(data2)
pass:mesh(buffer)
lovr.graphics.submit(pass)
Both draws will use data2
here! That's because lovr.graphics.submit
is where the draws actually get processed, so they both see the "final" state of the buffer. The data in a Buffer can't be 2 things at once! If you need multiple versions of data, it's best to use a bigger buffer with offsets (or multiple buffers).
Constructors
lovr.graphics.newBuffer | Create a new Buffer. |
lovr.graphics.getBuffer | Get a temporary Buffer. |
Metadata
Buffer:getFormat | Get the format of the Buffer. |
Buffer:getLength | Get the length of the Buffer. |
Buffer:getSize | Get the size of the Buffer, in bytes. |
Buffer:getStride | Get the stride of the Buffer, in bytes. |
Buffer:isTemporary | Check if the Buffer is temporary. |
Transfers
Buffer:clear | Clear data in the Buffer. |
Buffer:getData | Get the data in the Buffer. |
Buffer:getPointer | Get a writable pointer to the Buffer's memory. |
Buffer:mapData | Get a writable pointer to the Buffer's memory. |
Buffer:newReadback | Read back the contents of the Buffer asynchronously. |
Buffer:setData | Change the data in the Buffer. |