From 492325880c47450f50dcdebdcb336b37230ef867 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 10 Apr 2021 23:00:39 +0300 Subject: [PATCH] Split UniformBlock into two classes 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 | 85 ++++++++++++++++++----------------- source/core/uniformblock.h | 41 +++++++++++++---- source/render/programdata.cpp | 27 +++++------ source/render/programdata.h | 3 +- 4 files changed, 92 insertions(+), 64 deletions(-) diff --git a/source/core/uniformblock.cpp b/source/core/uniformblock.cpp index 6f63e385..25511d25 100644 --- a/source/core/uniformblock.cpp +++ b/source/core/uniformblock.cpp @@ -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::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::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i) - i->second->apply(i->first); - } + refresh(); + buf_range->bind_to(UNIFORM_BUFFER, index); } } // namespace GL diff --git a/source/core/uniformblock.h b/source/core/uniformblock.h index c8b8d36a..5a037edb 100644 --- a/source/core/uniformblock.h +++ b/source/core/uniformblock.h @@ -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 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 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 diff --git a/source/render/programdata.cpp b/source/render/programdata.cpp index 7323df90..ec273c22 100644 --- a/source/render/programdata.cpp +++ b/source/render/programdata.cpp @@ -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::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); diff --git a/source/render/programdata.h b/source/render/programdata.h index 6f20d4d8..a90d868e 100644 --- a/source/render/programdata.h +++ b/source/render/programdata.h @@ -21,6 +21,7 @@ public: }; class Buffer; +class BufferBackedUniformBlock; class Uniform; class UniformBlock; struct Color; @@ -153,7 +154,7 @@ private: std::vector uniforms; mutable std::vector blocks; mutable std::vector programs; - mutable UniformBlock *last_block; + mutable BufferBackedUniformBlock *last_buffer_block; mutable Buffer *buffer; mutable Mask dirty; -- 2.43.0