virtual ~buffer_too_small() throw() { }
};
+enum BufferUsage
+{
+ STATIC,
+ STREAMING
+};
+
/**
Stores data in GPU memory.
then be modified either synchronously with the data() and sub_data() functions,
or asynchronously by memory-mapping the buffer.
+Buffers can have a static or streaming usage pattern. Streaming buffers can be
+memory mapped for less update overhead, but memory space is more limited. If
+the buffer is updated only rarely, static is recommended.
+
Applications normally don't need to deal with Buffers directly. They're
managed by other classes such as Mesh and ProgramData.
*/
private:
std::size_t size = 0;
+ BufferUsage usage = STATIC;
+ bool mapped = false;
public:
- /** Sets the storage size and allocates memory for the buffer. Size cannot
- be changed once set. */
- void storage(std::size_t);
+ /** Sets storage size and usage pattern and allocates memory for the buffer.
+ Size and usage cannot be changed once set. */
+ void storage(std::size_t, BufferUsage);
/** Replaces contents of the entire buffer. Allocated storage must exist.
The data must have size matching the defined storage. */
void sub_data(std::size_t, std::size_t, const void *);
std::size_t get_size() const { return size; }
+ BufferUsage get_usage() const { return usage; }
void require_size(std::size_t) const;
void Mesh::resize_buffers() const
{
if(dirty&VERTEX_BUFFER)
- vbuf->storage(vertices.get_required_buffer_size());
+ vbuf->storage(vertices.get_required_buffer_size(), STATIC);
if((dirty&INDEX_BUFFER) && !batches.empty())
- ibuf->storage(batches.front().get_required_buffer_size());
+ ibuf->storage(batches.front().get_required_buffer_size(), STATIC);
dirty = 0;
}
const Mesh *mesh = object.get_mesh();
mesh->get_vertices().refresh();
if(instance_buffer->get_size()==0)
- instance_buffer->storage(instance_data.get_required_buffer_size());
+ instance_buffer->storage(instance_data.get_required_buffer_size(), STREAMING);
instance_data.refresh();
Renderer::Push push(renderer);