X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Frender%2Fprogramdata.cpp;h=e7c171754aed006dab1ecbdcedd272ddd894a396;hb=016f0f0dd51511f98d0bf398d99199d7dec1543c;hp=cfd2c0f5257b0d45d341ff15119805ea96038474;hpb=e70662d7812464159f2e47f4bebb69d88f89ae93;p=libs%2Fgl.git diff --git a/source/render/programdata.cpp b/source/render/programdata.cpp index cfd2c0f5..e7c17175 100644 --- a/source/render/programdata.cpp +++ b/source/render/programdata.cpp @@ -20,46 +20,6 @@ ProgramData::ProgramData(const Program *p): tied_program(p) { } -// Blocks are intentionally left uncopied -ProgramData::ProgramData(const ProgramData &other): - tied_program(other.tied_program), - uniforms(other.uniforms), - uniform_data(other.uniform_data), - generation(other.generation) -{ } - -ProgramData::ProgramData(const ProgramData &other, const Program *p): - tied_program(p) -{ - 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) -{ - 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; -} - ProgramData::ProgramData(ProgramData &&other): tied_program(other.tied_program), uniforms(move(other.uniforms)), @@ -156,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; } @@ -482,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); @@ -536,6 +510,21 @@ vector::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; @@ -585,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; @@ -673,24 +655,15 @@ vector::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); + recreate_buffer(); -#ifdef DEBUG - if(!debug_name.empty()) - buffer->set_debug_name(debug_name); -#endif - } - - buffer->storage(required_size); + buffer->storage(required_size, (streaming ? STREAMING : STATIC)); } } } @@ -698,16 +671,17 @@ vector::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); } }