]> git.tdb.fi Git - libs/gl.git/blobdiff - source/render/programdata.cpp
Store simpler states by value in PipelineState
[libs/gl.git] / source / render / programdata.cpp
index 1dcac641907d382999943f27784946ab2465821d..e7c171754aed006dab1ecbdcedd272ddd894a396 100644 (file)
@@ -17,57 +17,23 @@ namespace Msp {
 namespace GL {
 
 ProgramData::ProgramData(const Program *p):
-       tied_program(p),
-       generation(0),
-       last_buffer_block(0),
-       buffer(0),
-       dirty(0)
+       tied_program(p)
 { }
 
-// Blocks are intentionally left uncopied
-ProgramData::ProgramData(const ProgramData &other):
+ProgramData::ProgramData(ProgramData &&other):
        tied_program(other.tied_program),
-       uniforms(other.uniforms),
-       uniform_data(other.uniform_data),
+       uniforms(move(other.uniforms)),
+       uniform_data(move(other.uniform_data)),
        generation(other.generation),
-       last_buffer_block(0),
-       buffer(0),
-       dirty(0)
-{ }
-
-ProgramData::ProgramData(const ProgramData &other, const Program *p):
-       tied_program(p),
-       last_buffer_block(0),
-       buffer(0),
-       dirty(0)
-{
-       if(tied_program)
-       {
-               for(const TaggedUniform &u: other.uniforms)
-                       validate_tag(u.tag);
-       }
-
-       uniforms = other.uniforms;
-       uniform_data = other.uniform_data;
-}
-
-ProgramData &ProgramData::operator=(const ProgramData &other)
+       blocks(move(other.blocks)),
+       programs(move(other.programs)),
+       last_buffer_block(other.last_buffer_block),
+       buffer(other.buffer),
+       dirty(other.dirty),
+       debug_name(move(other.debug_name))
 {
-       tied_program = other.tied_program;
-
-       uniforms = other.uniforms;
-       uniform_data = other.uniform_data;
-
-       for(SharedBlock &b: blocks)
-               delete b.block;
-       blocks.clear();
-       programs.clear();
-
-       last_buffer_block = 0;
-       buffer = 0;
-       dirty = 0;
-
-       return *this;
+       other.blocks.clear();
+       other.buffer = 0;
 }
 
 ProgramData::~ProgramData()
@@ -150,7 +116,15 @@ bool ProgramData::validate_tag(Tag tag) const
 void ProgramData::mark_dirty(Mask bits)
 {
        if(!dirty)
+       {
+               if(generation && !streaming)
+               {
+                       streaming = true;
+                       if(buffer && buffer->get_size())
+                               recreate_buffer();
+               }
                ++generation;
+       }
        dirty |= bits;
 }
 
@@ -159,6 +133,11 @@ void ProgramData::uniform(Tag tag, int v)
        uniform(tag, INT, 1, &v);
 }
 
+void ProgramData::uniform(Tag tag, unsigned v)
+{
+       uniform(tag, UNSIGNED_INT, 1, &v);
+}
+
 void ProgramData::uniform(Tag tag, float v)
 {
        uniform(tag, FLOAT, 1, &v);
@@ -170,6 +149,12 @@ void ProgramData::uniform(Tag tag, int v0, int v1)
        uniform2(tag, va);
 }
 
+void ProgramData::uniform(Tag tag, unsigned v0, unsigned v1)
+{
+       unsigned va[2] = { v0, v1 };
+       uniform2(tag, va);
+}
+
 void ProgramData::uniform(Tag tag, float v0, float v1)
 {
        float va[2] = { v0, v1 };
@@ -181,6 +166,11 @@ void ProgramData::uniform2(Tag tag, const int *v)
        uniform(tag, INT_VEC2, 1, v);
 }
 
+void ProgramData::uniform2(Tag tag, const unsigned *v)
+{
+       uniform(tag, UINT_VEC2, 1, v);
+}
+
 void ProgramData::uniform2(Tag tag, const float *v)
 {
        uniform(tag, FLOAT_VEC2, 1, v);
@@ -192,6 +182,12 @@ void ProgramData::uniform(Tag tag, int v0, int v1, int v2)
        uniform3(tag, va);
 }
 
+void ProgramData::uniform(Tag tag, unsigned v0, unsigned v1, unsigned v2)
+{
+       unsigned va[3] = { v0, v1, v2 };
+       uniform3(tag, va);
+}
+
 void ProgramData::uniform(Tag tag, float v0, float v1, float v2)
 {
        float va[3] = { v0, v1, v2 };
@@ -203,6 +199,11 @@ void ProgramData::uniform3(Tag tag, const int *v)
        uniform(tag, INT_VEC3, 1, v);
 }
 
+void ProgramData::uniform3(Tag tag, const unsigned *v)
+{
+       uniform(tag, UINT_VEC3, 1, v);
+}
+
 void ProgramData::uniform3(Tag tag, const float *v)
 {
        uniform(tag, FLOAT_VEC3, 1, v);
@@ -214,6 +215,12 @@ void ProgramData::uniform(Tag tag, int v0, int v1, int v2, int v3)
        uniform4(tag, va);
 }
 
+void ProgramData::uniform(Tag tag, unsigned v0, unsigned v1, unsigned v2, unsigned v3)
+{
+       unsigned va[4] = { v0, v1, v2, v3 };
+       uniform4(tag, va);
+}
+
 void ProgramData::uniform(Tag tag, float v0, float v1, float v2, float v3)
 {
        float va[4] = { v0, v1, v2, v3 };
@@ -230,6 +237,11 @@ void ProgramData::uniform4(Tag tag, const int *v)
        uniform(tag, INT_VEC4, 1, v);
 }
 
+void ProgramData::uniform4(Tag tag, const unsigned *v)
+{
+       uniform(tag, UINT_VEC4, 1, v);
+}
+
 void ProgramData::uniform4(Tag tag, const float *v)
 {
        uniform(tag, FLOAT_VEC4, 1, v);
@@ -290,6 +302,11 @@ void ProgramData::uniform_array(Tag tag, unsigned n, const int *v)
        uniform(tag, INT, n, v);
 }
 
+void ProgramData::uniform_array(Tag tag, unsigned n, const unsigned *v)
+{
+       uniform(tag, UNSIGNED_INT, n, v);
+}
+
 void ProgramData::uniform_array(Tag tag, unsigned n, const float *v)
 {
        uniform(tag, FLOAT, n, v);
@@ -300,6 +317,11 @@ void ProgramData::uniform1_array(Tag tag, unsigned n, const int *v)
        uniform(tag, INT, n, v);
 }
 
+void ProgramData::uniform1_array(Tag tag, unsigned n, const unsigned *v)
+{
+       uniform(tag, UNSIGNED_INT, n, v);
+}
+
 void ProgramData::uniform1_array(Tag tag, unsigned n, const float *v)
 {
        uniform(tag, FLOAT, n, v);
@@ -310,6 +332,11 @@ void ProgramData::uniform2_array(Tag tag, unsigned n, const int *v)
        uniform(tag, INT_VEC2, n, v);
 }
 
+void ProgramData::uniform2_array(Tag tag, unsigned n, const unsigned *v)
+{
+       uniform(tag, UINT_VEC2, n, v);
+}
+
 void ProgramData::uniform2_array(Tag tag, unsigned n, const float *v)
 {
        uniform(tag, FLOAT_VEC2, n, v);
@@ -320,6 +347,11 @@ void ProgramData::uniform3_array(Tag tag, unsigned n, const int *v)
        uniform(tag, INT_VEC3, n, v);
 }
 
+void ProgramData::uniform3_array(Tag tag, unsigned n, const unsigned *v)
+{
+       uniform(tag, INT_VEC3, n, v);
+}
+
 void ProgramData::uniform3_array(Tag tag, unsigned n, const float *v)
 {
        uniform(tag, FLOAT_VEC3, n, v);
@@ -330,6 +362,11 @@ void ProgramData::uniform4_array(Tag tag, unsigned n, const int *v)
        uniform(tag, INT_VEC4, n, v);
 }
 
+void ProgramData::uniform4_array(Tag tag, unsigned n, const unsigned *v)
+{
+       uniform(tag, UINT_VEC4, n, v);
+}
+
 void ProgramData::uniform4_array(Tag tag, unsigned n, const float *v)
 {
        uniform(tag, FLOAT_VEC4, n, v);
@@ -413,6 +450,12 @@ void ProgramData::copy_uniform(const ProgramData &source, Tag tag)
        uniform(tag, tu.type, tu.array_size, source.uniform_data.data()+tu.data_offset);
 }
 
+void ProgramData::copy_uniforms(const ProgramData &source)
+{
+       for(const TaggedUniform &u: source.uniforms)
+               uniform(u.tag, u.type, u.array_size, source.uniform_data.data()+u.data_offset);
+}
+
 int ProgramData::find_uniform_index(Tag tag) const
 {
        auto i = lower_bound_member(uniforms, tag, &TaggedUniform::tag);
@@ -467,6 +510,21 @@ vector<ProgramData::ProgramBlock>::iterator ProgramData::get_program(const Progr
        return programs.begin()+index;
 }
 
+void ProgramData::recreate_buffer() const
+{
+       Buffer *old_buffer = buffer;
+       // Create the new buffer first to ensure it has a different address
+       buffer = new Buffer;
+       delete old_buffer;
+       if(last_buffer_block)
+               last_buffer_block->change_buffer(buffer);
+
+#ifdef DEBUG
+       if(!debug_name.empty())
+               buffer->set_debug_name(debug_name);
+#endif
+}
+
 void ProgramData::update_block_uniform_indices(SharedBlock &block, const ReflectData::UniformBlockInfo &info) const
 {
        uint8_t *indices = block.indices.values;
@@ -516,14 +574,7 @@ void ProgramData::update_block_uniform_indices(SharedBlock &block, const Reflect
                if(info.bind_point>=0)
                {
                        if(!buffer)
-                       {
-                               buffer = new Buffer();
-
-#ifdef DEBUG
-                               if(!debug_name.empty())
-                                       buffer->set_debug_name(debug_name);
-#endif
-                       }
+                               recreate_buffer();
 
                        block.block->use_buffer(buffer, last_buffer_block);
                        last_buffer_block = block.block;
@@ -604,24 +655,15 @@ vector<ProgramData::ProgramBlock>::const_iterator ProgramData::prepare_program(c
 
                prog_begin->masks.dirty = 0;
 
-               if(last_buffer_block!=old_last_block)
+               if(last_buffer_block!=old_last_block || (buffer && !buffer->get_size()))
                {
-                       unsigned required_size = last_buffer_block->get_required_buffer_size();
+                       unsigned required_size = last_buffer_block->get_required_buffer_size(streaming);
                        if(last_buffer_block->get_required_buffer_size()>buffer->get_size())
                        {
                                if(buffer->get_size()>0)
-                               {
-                                       delete buffer;
-                                       buffer = new Buffer();
-                                       last_buffer_block->change_buffer(buffer);
-
-#ifdef DEBUG
-                                       if(!debug_name.empty())
-                                               buffer->set_debug_name(debug_name);
-#endif
-                               }
+                                       recreate_buffer();
 
-                               buffer->storage(required_size);
+                               buffer->storage(required_size, (streaming ? STREAMING : STATIC));
                        }
                }
        }
@@ -629,16 +671,17 @@ vector<ProgramData::ProgramBlock>::const_iterator ProgramData::prepare_program(c
        return prog_begin;
 }
 
-void ProgramData::apply(const Program &prog, PipelineState &state) const
+void ProgramData::apply(const Program &prog, PipelineState &state, unsigned frame) const
 {
        auto prog_begin = prepare_program(prog);
        ReflectData::LayoutHash prog_hash = prog_begin->prog_hash;
+
        for(auto i=prog_begin+1; (i!=programs.end() && i->prog_hash==prog_hash); ++i)
                if(i->block)
                {
                        state.set_uniform_block(i->bind_point, i->block);
                        if(i->bind_point>=0)
-                               i->block->refresh();
+                               i->block->refresh(frame);
                }
 }
 
@@ -654,14 +697,6 @@ void ProgramData::set_debug_name(const string &name)
 }
 
 
-ProgramData::TaggedUniform::TaggedUniform():
-       type(VOID),
-       array_size(0),
-       data_offset(0),
-       data_size(0)
-{ }
-
-
 ProgramData::SharedBlock::SharedBlock(ReflectData::LayoutHash h):
        block_hash(h),
        used(0),