Buffer

Edit

A 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.newBufferCreate a new Buffer.
lovr.graphics.getBufferGet a temporary Buffer.

Metadata

Buffer:getFormatGet the format of the Buffer.
Buffer:getLengthGet the length of the Buffer.
Buffer:getSizeGet the size of the Buffer, in bytes.
Buffer:getStrideGet the stride of the Buffer, in bytes.
Buffer:isTemporaryCheck if the Buffer is temporary.

Transfers

Buffer:clearClear data in the Buffer.
Buffer:getDataGet the data in the Buffer.
Buffer:getPointerGet a writable pointer to the Buffer's memory.
Buffer:mapDataGet a writable pointer to the Buffer's memory.
Buffer:newReadbackRead back the contents of the Buffer asynchronously.
Buffer:setDataChange the data in the Buffer.

See also