]> git.tdb.fi Git - libs/gl.git/commitdiff
Split UniformBlock into two classes
authorMikko Rasa <tdb@tdb.fi>
Sat, 10 Apr 2021 20:00:39 +0000 (23:00 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 10 Apr 2021 20:02:36 +0000 (23:02 +0300)
There's basically no overlap between default and buffer-backed blocks,
so no point in having them in the same class.

source/core/uniformblock.cpp
source/core/uniformblock.h
source/render/programdata.cpp
source/render/programdata.h

index 6f63e385a7bbf6dad1791a3c7782dbf3c350abbd..25511d251e2361e56b67285b86b7e8add1f14585 100644 (file)
@@ -14,77 +14,80 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
-UniformBlock::UniformBlock():
-       size(0),
-       buf_range(0)
+DefaultUniformBlock::DefaultUniformBlock()
 {
        static Require _req(ARB_shader_objects);
 }
 
-UniformBlock::UniformBlock(unsigned s):
+void DefaultUniformBlock::attach(const Program::UniformInfo &info, const Uniform &uni)
+{
+       if(info.block->bind_point>=0)
+               throw invalid_argument("DefaultUniformBlock::attach");
+
+       uniforms[info.location] = &uni;
+}
+
+void DefaultUniformBlock::attach(int index, const Uniform &uni)
+{
+       uniforms[index] = &uni;
+}
+
+void DefaultUniformBlock::apply(int index) const
+{
+       if(index>=0)
+               throw invalid_argument("DefaultUniformBlock::apply");
+
+       for(map<int, const Uniform *>::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i)
+               i->second->apply(i->first);
+}
+
+
+BufferBackedUniformBlock::BufferBackedUniformBlock(unsigned s):
        size(s),
+       data(size),
        buf_range(0)
 {
-       static Require _req(ARB_uniform_buffer_object);
+       static Require _req(ARB_shader_objects);
+       static Require _req2(ARB_uniform_buffer_object);
 
        if(!size)
-               throw invalid_argument("UniformBlock::UniformBlock");
-       data.resize(size);
+               throw invalid_argument("BufferBackedUniformBlock::BufferBackedUniformBlock");
 }
 
-UniformBlock::~UniformBlock()
+BufferBackedUniformBlock::~BufferBackedUniformBlock()
 {
        delete buf_range;
 }
 
-unsigned UniformBlock::get_alignment() const
+unsigned BufferBackedUniformBlock::get_alignment() const
 {
        return BufferRange::get_uniform_buffer_alignment();
 }
 
-void UniformBlock::location_changed(Buffer *buf, unsigned off, unsigned) const
+void BufferBackedUniformBlock::location_changed(Buffer *buf, unsigned off, unsigned) const
 {
        delete buf_range;
-       buf_range = new BufferRange(*buf, off, size);
+       buf_range = buf->create_range(off, size);
 }
 
-void UniformBlock::attach(int index, const Uniform &uni)
+void BufferBackedUniformBlock::attach(const Program::UniformInfo &info, const Uniform &uni)
 {
-       if(size)
-               throw invalid_operation("UniformBlock::attach");
+       if(info.block->bind_point<0)
+               throw invalid_argument("BufferBackedUniformBlock::attach");
 
-       uniforms[index] = &uni;
-}
-
-void UniformBlock::attach(const Program::UniformInfo &info, const Uniform &uni)
-{
-       if(size)
-       {
-               uni.store(info, &data[info.offset]);
-               dirty = true;
-       }
-       else
-               uniforms[info.location] = &uni;
+       uni.store(info, &data[info.offset]);
+       dirty = true;
 }
 
-void UniformBlock::apply(int index) const
+void BufferBackedUniformBlock::apply(int index) const
 {
-       if((index>=0) != (size>0))
+       if(index<0)
+               throw invalid_argument("BufferBackedUniformBlock::apply");
+       if(!get_buffer())
                throw invalid_operation("UniformBlock::apply");
 
-       if(size)
-       {
-               if(!get_buffer())
-                       throw invalid_operation("UniformBlock::apply");
-
-               refresh();
-               buf_range->bind_to(UNIFORM_BUFFER, index);
-       }
-       else
-       {
-               for(map<int, const Uniform *>::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i)
-                       i->second->apply(i->first);
-       }
+       refresh();
+       buf_range->bind_to(UNIFORM_BUFFER, index);
 }
 
 } // namespace GL
index c8b8d36a3d8e2deceaf8881d5dbb83ec0ae1f825..5a037edb4b5e53323e32bddf7a1fbf44f4353581 100644 (file)
@@ -19,20 +19,45 @@ struct Color;
 Stores uniforms with a specific layout.  Both named and default uniform blocks
 are supported.
 */
-class UniformBlock: public Bufferable
+class UniformBlock: public NonCopyable
+{
+protected:
+       UniformBlock() { }
+public:
+       virtual ~UniformBlock() { }
+
+       virtual void attach(const Program::UniformInfo &, const Uniform &) = 0;
+       virtual void apply(int) const = 0;
+};
+
+/** Stores uniforms for the default uniform block.  Uniforms are associated
+with locations, as returned by Program::get_uniform_location. */
+class DefaultUniformBlock: public UniformBlock
 {
 private:
        std::map<int, const Uniform *> uniforms;
+
+public:
+       DefaultUniformBlock();
+
+       virtual void attach(const Program::UniformInfo &, const Uniform &);
+       void attach(int, const Uniform &);
+       virtual void apply(int) const;
+};
+
+/** Stores uniforms for a buffer-backed uniform block.  Uniform values are
+stored in a memory block which can be uploaded into a buffer and bound for use
+by a Program. */
+class BufferBackedUniformBlock: public UniformBlock, public Bufferable
+{
+private:
        unsigned size;
        std::vector<char> data;
        mutable BufferRange *buf_range;
 
-       UniformBlock(const UniformBlock &);
-       UniformBlock &operator=(const UniformBlock &);
 public:
-       UniformBlock();
-       UniformBlock(unsigned);
-       ~UniformBlock();
+       BufferBackedUniformBlock(unsigned);
+       virtual ~BufferBackedUniformBlock();
 
 private:
        virtual unsigned get_data_size() const { return size; }
@@ -41,10 +66,8 @@ private:
        virtual void location_changed(Buffer *, unsigned, unsigned) const;
 
 public:
-       void attach(int, const Uniform &);
        void attach(const Program::UniformInfo &, const Uniform &);
-
-       void apply(int) const;
+       virtual void apply(int) const;
 };
 
 } // namespace GL
index 7323df905db7093fcbb5db5572b9b7f7faedb5ca..ec273c2277532c9f8a985341663ce9c4ea5836c6 100644 (file)
@@ -20,7 +20,7 @@ namespace GL {
 
 ProgramData::ProgramData(const Program *p):
        tied_program(p),
-       last_block(0),
+       last_buffer_block(0),
        buffer(0),
        dirty(0)
 { }
@@ -29,7 +29,7 @@ ProgramData::ProgramData(const Program *p):
 ProgramData::ProgramData(const ProgramData &other):
        tied_program(other.tied_program),
        uniforms(other.uniforms),
-       last_block(0),
+       last_buffer_block(0),
        buffer(0),
        dirty(0)
 {
@@ -39,7 +39,7 @@ ProgramData::ProgramData(const ProgramData &other):
 
 ProgramData::ProgramData(const ProgramData &other, const Program *p):
        tied_program(p),
-       last_block(0),
+       last_buffer_block(0),
        buffer(0),
        dirty(0)
 {
@@ -66,7 +66,7 @@ ProgramData &ProgramData::operator=(const ProgramData &other)
                delete i->block;
        programs.clear();
 
-       last_block = 0;
+       last_buffer_block = 0;
        buffer = 0;
        dirty = 0;
 
@@ -594,12 +594,13 @@ void ProgramData::update_block_uniform_indices(SharedBlock &block, const Program
                        if(!buffer)
                                buffer = new Buffer(UNIFORM_BUFFER);
 
-                       block.block = new UniformBlock(info.data_size);
-                       block.block->use_buffer(buffer, last_block);
-                       last_block = block.block;
+                       BufferBackedUniformBlock *bb_block = new BufferBackedUniformBlock(info.data_size);
+                       block.block = bb_block;
+                       bb_block->use_buffer(buffer, last_buffer_block);
+                       last_buffer_block = bb_block;
                }
                else
-                       block.block = new UniformBlock;
+                       block.block = new DefaultUniformBlock;
        }
 }
 
@@ -617,7 +618,7 @@ void ProgramData::apply() const
        if(!prog)
                throw invalid_operation("ProgramData::apply");
 
-       UniformBlock *old_last_block = last_block;
+       BufferBackedUniformBlock *old_last_block = last_buffer_block;
        vector<ProgramBlock>::iterator prog_begin = get_program(*prog);
        Program::LayoutHash prog_hash = prog->get_uniform_layout_hash();
 
@@ -677,16 +678,16 @@ void ProgramData::apply() const
                if(buffered_blocks_updated && !ARB_direct_state_access)
                        buffer->bind();
 
-               if(last_block!=old_last_block)
+               if(last_buffer_block!=old_last_block)
                {
-                       unsigned required_size = last_block->get_required_buffer_size();
-                       if(last_block->get_required_buffer_size()>buffer->get_size())
+                       unsigned required_size = last_buffer_block->get_required_buffer_size();
+                       if(last_buffer_block->get_required_buffer_size()>buffer->get_size())
                        {
                                if(buffer->get_size()>0)
                                {
                                        delete buffer;
                                        buffer = new Buffer(UNIFORM_BUFFER);
-                                       last_block->change_buffer(buffer);
+                                       last_buffer_block->change_buffer(buffer);
                                }
 
                                buffer->storage(required_size);
index 6f20d4d8317da1d393e5da555c0d4a3989498f67..a90d868e3bb7e3598200f074791189ee85e0cc15 100644 (file)
@@ -21,6 +21,7 @@ public:
 };
 
 class Buffer;
+class BufferBackedUniformBlock;
 class Uniform;
 class UniformBlock;
 struct Color;
@@ -153,7 +154,7 @@ private:
        std::vector<TaggedUniform> uniforms;
        mutable std::vector<SharedBlock> blocks;
        mutable std::vector<ProgramBlock> programs;
-       mutable UniformBlock *last_block;
+       mutable BufferBackedUniformBlock *last_buffer_block;
        mutable Buffer *buffer;
        mutable Mask dirty;