]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a usage parameter to Buffer
authorMikko Rasa <tdb@tdb.fi>
Wed, 17 Nov 2021 12:48:58 +0000 (14:48 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 17 Nov 2021 13:07:00 +0000 (15:07 +0200)
It has no real meaning on OpenGL but is needed on Vulkan

source/backends/opengl/texture2d_backend.cpp
source/core/buffer.cpp
source/core/buffer.h
source/core/mesh.cpp
source/render/instancearray.cpp
source/render/programdata.cpp

index 2f396df4180978ec52821ec59247ed5a76293be4..45ba78cc8f6f10c1e4e8d3b7d372b82b148843f0 100644 (file)
@@ -167,7 +167,7 @@ bool OpenGLTexture2D::AsyncLoader::process()
        }
        else if(phase==1)
        {
-               pixel_buffer.storage(n_bytes);
+               pixel_buffer.storage(n_bytes, STREAMING);
                mapped_address = reinterpret_cast<char *>(pixel_buffer.map());
        }
        else if(phase==2)
index 240fcd72754b67babe7a28b9ee2fe42a80f1fe4b..15a37397bcb18bdf094b5e5a5cef1a7d31b38c31 100644 (file)
@@ -8,7 +8,7 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
-void Buffer::storage(size_t sz)
+void Buffer::storage(size_t sz, BufferUsage u)
 {
        if(size>0)
        {
@@ -20,6 +20,7 @@ void Buffer::storage(size_t sz)
                throw invalid_argument("Buffer::storage");
 
        size = sz;
+       usage = u;
 
        allocate();
 }
index b642738e0e96ef370a5e748701be071998e2de54..a12b3373e601664bddf75d60bb930d56bbe26833 100644 (file)
@@ -15,6 +15,12 @@ public:
        virtual ~buffer_too_small() throw() { }
 };
 
+enum BufferUsage
+{
+       STATIC,
+       STREAMING
+};
+
 /**
 Stores data in GPU memory.
 
@@ -22,6 +28,10 @@ Memory must be allocated for the buffer by calling storage().  Contents can
 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.
 */
@@ -31,11 +41,13 @@ class Buffer: public BufferBackend
 
 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. */
@@ -46,6 +58,7 @@ public:
        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;
 
index 208126ef26c477ed5adf8ca61f357400ca44ee73..360d588f97659d9a3e2d395fa876029a4d84a337 100644 (file)
@@ -211,9 +211,9 @@ void Mesh::draw(Renderer &renderer, const VertexSetup *vs, unsigned count) 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;
 }
 
index 4a24ac456b6439935d28c063cf94fb4143b109aa..eec72f98dc18144c777f8ae61bb5eb3d18677db0 100644 (file)
@@ -105,7 +105,7 @@ void InstanceArray::render(Renderer &renderer, Tag tag) const
        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);
index a908284b3abae9de3e8f177b8165daf084ff6eba..fc9b30a99e14b5011eba96d426f555a5467012f1 100644 (file)
@@ -656,7 +656,7 @@ vector<ProgramData::ProgramBlock>::const_iterator ProgramData::prepare_program(c
 #endif
                                }
 
-                               buffer->storage(required_size);
+                               buffer->storage(required_size, STREAMING);
                        }
                }
        }