X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Frender%2Fprogramdata.cpp;h=43bcbf3febea57702fb6be343818b01d9d472325;hp=1ef013ddac86e5a6be72643fe711764f01428d30;hb=38712d8ecc57d043a2419ffbaeeb57f7a6586f14;hpb=3a1b9cbe2441ae670a97541dc8ccb0a2860c8302 diff --git a/source/render/programdata.cpp b/source/render/programdata.cpp index 1ef013dd..43bcbf3f 100644 --- a/source/render/programdata.cpp +++ b/source/render/programdata.cpp @@ -1,7 +1,5 @@ #include -#include #include -#include #include #include "buffer.h" #include "color.h" @@ -10,7 +8,6 @@ #include "pipelinestate.h" #include "program.h" #include "programdata.h" -#include "uniform.h" #include "uniformblock.h" #include "vector.h" @@ -31,14 +28,12 @@ ProgramData::ProgramData(const Program *p): ProgramData::ProgramData(const ProgramData &other): tied_program(other.tied_program), uniforms(other.uniforms), + uniform_data(other.uniform_data), generation(other.generation), last_buffer_block(0), buffer(0), dirty(0) -{ - for(TaggedUniform &u: uniforms) - u.value = u.value->clone(); -} +{ } ProgramData::ProgramData(const ProgramData &other, const Program *p): tied_program(p), @@ -53,8 +48,7 @@ ProgramData::ProgramData(const ProgramData &other, const Program *p): } uniforms = other.uniforms; - for(TaggedUniform &u: uniforms) - u.value = u.value->clone(); + uniform_data = other.uniform_data; } ProgramData &ProgramData::operator=(const ProgramData &other) @@ -62,8 +56,7 @@ ProgramData &ProgramData::operator=(const ProgramData &other) tied_program = other.tied_program; uniforms = other.uniforms; - for(TaggedUniform &u: uniforms) - u.value = u.value->clone(); + uniform_data = other.uniform_data; for(SharedBlock &b: blocks) delete b.block; @@ -79,8 +72,6 @@ ProgramData &ProgramData::operator=(const ProgramData &other) ProgramData::~ProgramData() { - for(TaggedUniform &u: uniforms) - delete u.value; for(SharedBlock &b: blocks) { if(b.indices.type_flag==0xFE) @@ -90,65 +81,47 @@ ProgramData::~ProgramData() delete buffer; } -void ProgramData::uniform(Tag tag, Uniform *uni) +void ProgramData::uniform(Tag tag, DataType type, unsigned array_size, const void *value) { - try + if(!validate_tag(tag)) + return; + + auto i = lower_bound_member(uniforms, tag, &TaggedUniform::tag); + if(i==uniforms.end() || i->tag!=tag) { - if(!validate_tag(tag)) - { - delete uni; - return; - } + if(uniforms.size()>=MASK_BITS) + throw too_many_uniforms(tag.str()); + + TaggedUniform tu; + tu.tag = tag; + tu.type = type; + tu.array_size = array_size; + tu.data_offset = uniform_data.size(); + tu.data_size = array_size*get_type_size(type); + i = uniforms.insert(i, tu); + uniform_data.resize(tu.data_offset+tu.data_size); + + mark_dirty(ALL_ONES); } - catch(...) + else if(type!=i->type) + throw invalid_operation("ProgramData::uniform"); + else if(array_size>i->array_size) { - delete uni; - throw; + unsigned add_bytes = (array_size-i->array_size)*get_type_size(type); + uniform_data.insert(uniform_data.begin()+i->data_offset+i->data_size, add_bytes, 0); + for(TaggedUniform &u: uniforms) + if(u.data_offset>i->data_offset) + u.data_offset += add_bytes; + i->array_size = array_size; + i->data_size = array_size*get_type_size(type); } - int i = find_uniform_index(tag); - if(i<0) - return add_uniform(tag, uni); - - uniforms[i].replace_value(uni); - mark_dirty(1< -void ProgramData::uniform(Tag tag, V value) -{ - if(!validate_tag(tag)) - return; - - int i = find_uniform_index(tag); - if(i<0) - return add_uniform(tag, new T(value)); - - if(T *uni = dynamic_cast(uniforms[i].value)) - uni->set(value); - else - uniforms[i].replace_value(new T(value)); + const char *val_begin = static_cast(value); + const char *val_end = val_begin+array_size*get_type_size(type); + char *store_begin = uniform_data.data()+i->data_offset; + copy(val_begin, val_end, store_begin); - mark_dirty(1< -void ProgramData::uniform_array(Tag tag, unsigned n, V value) -{ - if(!validate_tag(tag)) - return; - - int i = find_uniform_index(tag); - if(i<0) - return add_uniform(tag, new UniformArray(n, value)); - - UniformArray *uni = dynamic_cast *>(uniforms[i].value); - if(uni && n==uni->size()) - uni->set(value); - else - uniforms[i].replace_value(new UniformArray(n, value)); - - mark_dirty(1<get_uniform_info(tag); + const ReflectData::UniformInfo &info = tied_program->get_uniform_info(tag); if(is_image(info.type)) throw invalid_operation("ProgramData::uniform"); } @@ -174,24 +147,6 @@ bool ProgramData::validate_tag(Tag tag) const #endif } -void ProgramData::add_uniform(Tag tag, Uniform *uni) -{ - if(uniforms.size()>=MASK_BITS) - { - delete uni; - throw too_many_uniforms(tag.str()); - } - - auto j = lower_bound_member(uniforms, tag, &TaggedUniform::tag); - - TaggedUniform nu; - nu.tag = tag; - nu.value = uni; - uniforms.insert(j, nu); - - mark_dirty(ALL_ONES); -} - void ProgramData::mark_dirty(Mask bits) { if(!dirty) @@ -199,19 +154,14 @@ void ProgramData::mark_dirty(Mask bits) dirty |= bits; } -void ProgramData::uniform(Tag tag, const Uniform &u) -{ - uniform(tag, u.clone()); -} - void ProgramData::uniform(Tag tag, int v) { - uniform(tag, v); + uniform(tag, INT, 1, &v); } void ProgramData::uniform(Tag tag, float v) { - uniform(tag, v); + uniform(tag, FLOAT, 1, &v); } void ProgramData::uniform(Tag tag, int v0, int v1) @@ -228,12 +178,12 @@ void ProgramData::uniform(Tag tag, float v0, float v1) void ProgramData::uniform2(Tag tag, const int *v) { - uniform(tag, v); + uniform(tag, INT_VEC2, 1, v); } void ProgramData::uniform2(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_VEC2, 1, v); } void ProgramData::uniform(Tag tag, int v0, int v1, int v2) @@ -250,12 +200,12 @@ void ProgramData::uniform(Tag tag, float v0, float v1, float v2) void ProgramData::uniform3(Tag tag, const int *v) { - uniform(tag, v); + uniform(tag, INT_VEC3, 1, v); } void ProgramData::uniform3(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_VEC3, 1, v); } void ProgramData::uniform(Tag tag, int v0, int v1, int v2, int v3) @@ -277,52 +227,52 @@ void ProgramData::uniform(Tag tag, const Color &c) void ProgramData::uniform4(Tag tag, const int *v) { - uniform(tag, v); + uniform(tag, INT_VEC4, 1, v); } void ProgramData::uniform4(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_VEC4, 1, v); } void ProgramData::uniform_matrix2(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_MAT2, 1, v); } void ProgramData::uniform_matrix3x2(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_MAT3x2, 1, v); } void ProgramData::uniform_matrix4x2(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_MAT4x2, 1, v); } void ProgramData::uniform_matrix2x3(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_MAT2x3, 1, v); } void ProgramData::uniform_matrix3(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_MAT3, 1, v); } void ProgramData::uniform_matrix4x3(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_MAT4x3, 1, v); } void ProgramData::uniform_matrix2x4(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_MAT2x4, 1, v); } void ProgramData::uniform_matrix3x4(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_MAT3x4, 1, v); } void ProgramData::uniform(Tag tag, const Matrix &m) @@ -332,102 +282,102 @@ void ProgramData::uniform(Tag tag, const Matrix &m) void ProgramData::uniform_matrix4(Tag tag, const float *v) { - uniform(tag, v); + uniform(tag, FLOAT_MAT4, 1, v); } void ProgramData::uniform_array(Tag tag, unsigned n, const int *v) { - uniform_array(tag, n, v); + uniform(tag, INT, n, v); } void ProgramData::uniform_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT, n, v); } void ProgramData::uniform1_array(Tag tag, unsigned n, const int *v) { - uniform_array(tag, n, v); + uniform(tag, INT, n, v); } void ProgramData::uniform1_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT, n, v); } void ProgramData::uniform2_array(Tag tag, unsigned n, const int *v) { - uniform_array(tag, n, v); + uniform(tag, INT_VEC2, n, v); } void ProgramData::uniform2_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_VEC2, n, v); } void ProgramData::uniform3_array(Tag tag, unsigned n, const int *v) { - uniform_array(tag, n, v); + uniform(tag, INT_VEC3, n, v); } void ProgramData::uniform3_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_VEC3, n, v); } void ProgramData::uniform4_array(Tag tag, unsigned n, const int *v) { - uniform_array(tag, n, v); + uniform(tag, INT_VEC4, n, v); } void ProgramData::uniform4_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_VEC4, n, v); } void ProgramData::uniform_matrix2_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_MAT2, n, v); } void ProgramData::uniform_matrix3x2_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_MAT3x2, n, v); } void ProgramData::uniform_matrix4x2_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_MAT4x2, n, v); } void ProgramData::uniform_matrix2x3_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_MAT2x3, n, v); } void ProgramData::uniform_matrix3_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_MAT3, n, v); } void ProgramData::uniform_matrix4x3_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_MAT4x3, n, v); } void ProgramData::uniform_matrix2x4_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_MAT2x4, n, v); } void ProgramData::uniform_matrix3x4_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_MAT3x4, n, v); } void ProgramData::uniform_matrix4_array(Tag tag, unsigned n, const float *v) { - uniform_array(tag, n, v); + uniform(tag, FLOAT_MAT4, n, v); } void ProgramData::remove_uniform(Tag tag) @@ -436,7 +386,10 @@ void ProgramData::remove_uniform(Tag tag) if(i==uniforms.end() || i->tag!=tag) return; - delete i->value; + uniform_data.erase(uniform_data.begin()+i->data_offset, uniform_data.begin()+i->data_offset+i->data_size); + for(TaggedUniform &u: uniforms) + if(u.data_offset>i->data_offset) + u.data_offset -= i->data_size; uniforms.erase(i); mark_dirty(ALL_ONES); @@ -451,18 +404,13 @@ vector ProgramData::get_uniform_tags() const return tags; } -const Uniform &ProgramData::get_uniform(Tag tag) const +void ProgramData::copy_uniform(const ProgramData &source, Tag tag) { - int i = find_uniform_index(tag); + int i = source.find_uniform_index(tag); if(i<0) throw key_error(tag); - return *uniforms[i].value; -} - -const Uniform *ProgramData::find_uniform(Tag tag) const -{ - int i = find_uniform_index(tag); - return (i>=0 ? uniforms[i].value : 0); + const TaggedUniform &tu = source.uniforms[i]; + uniform(tag, tu.type, tu.array_size, source.uniform_data.data()+tu.data_offset); } int ProgramData::find_uniform_index(Tag tag) const @@ -473,25 +421,25 @@ int ProgramData::find_uniform_index(Tag tag) const vector::iterator ProgramData::get_program(const Program &prog) const { - Program::LayoutHash prog_hash = prog.get_uniform_layout_hash(); + ReflectData::LayoutHash prog_hash = prog.get_uniform_layout_hash(); auto i = lower_bound_member(programs, prog_hash, &ProgramBlock::prog_hash); if(i!=programs.end() && i->prog_hash==prog_hash) return i; - const vector &block_infos = prog.get_uniform_blocks(); + const vector &block_infos = prog.get_uniform_blocks(); unsigned index = i-programs.begin(); programs.insert(i, 1+block_infos.size(), ProgramBlock(prog_hash)); /* Block indices may change if new shared blocks need to be inserted. Store the hashes so they can be matched up later. */ - vector block_hashes; + vector block_hashes; block_hashes.reserve(programs.size()); for(const ProgramBlock &b: programs) block_hashes.push_back(b.block_index>=0 ? blocks[b.block_index].block_hash : 0); for(unsigned j=0; j::iterator ProgramData::get_program(const Progr return programs.begin()+index; } -void ProgramData::update_block_uniform_indices(SharedBlock &block, const Program::UniformBlockInfo &info) const +void ProgramData::update_block_uniform_indices(SharedBlock &block, const ReflectData::UniformBlockInfo &info) const { uint8_t *indices = block.indices.values; if(info.uniforms.size()>16) @@ -564,6 +512,7 @@ void ProgramData::update_block_uniform_indices(SharedBlock &block, const Program if(block.used && !block.block) { + block.block = new UniformBlock(info); if(info.bind_point>=0) { if(!buffer) @@ -576,17 +525,13 @@ void ProgramData::update_block_uniform_indices(SharedBlock &block, const Program #endif } - 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; + block.block->use_buffer(buffer, last_buffer_block); + last_buffer_block = block.block; } - else - block.block = new DefaultUniformBlock; } } -void ProgramData::update_block(SharedBlock &block, const Program::UniformBlockInfo &info) const +void ProgramData::update_block(SharedBlock &block, const ReflectData::UniformBlockInfo &info) const { const uint8_t *indices = block.get_uniform_indices(); for(unsigned i=0; itype)) ; // Temporarily ignore deprecated use of sampler uniforms in ProgramData else if(indices[i]!=0xFF) - block.block->attach(*info.uniforms[i], *uniforms[indices[i]].value); + { + const TaggedUniform &tu = uniforms[indices[i]]; + block.block->store(*info.uniforms[i], tu.array_size, uniform_data.data()+tu.data_offset); + } } } vector::const_iterator ProgramData::prepare_program(const Program &prog) const { - BufferBackedUniformBlock *old_last_block = last_buffer_block; + UniformBlock *old_last_block = last_buffer_block; auto prog_begin = get_program(prog); Mask force_dirty = (dirty==ALL_ONES ? ALL_ONES : 0U); @@ -620,7 +568,7 @@ vector::const_iterator ProgramData::prepare_program(c dirty = 0; } - const vector &block_infos = prog.get_uniform_blocks(); + const vector &block_infos = prog.get_uniform_blocks(); if(prog_begin->masks.dirty==ALL_ONES) { @@ -628,7 +576,7 @@ vector::const_iterator ProgramData::prepare_program(c Refresh uniform indices within the program's blocks. */ prog_begin->masks.used = 0; auto j = prog_begin+1; - for(const Program::UniformBlockInfo &b: block_infos) + for(const ReflectData::UniformBlockInfo &b: block_infos) { SharedBlock &shared = blocks[j->block_index]; if(shared.dirty==ALL_ONES) @@ -642,7 +590,7 @@ vector::const_iterator ProgramData::prepare_program(c // Update the contents of all dirty blocks. bool buffered_blocks_updated = false; auto j = prog_begin+1; - for(const Program::UniformBlockInfo &b: block_infos) + for(const ReflectData::UniformBlockInfo &b: block_infos) { SharedBlock &shared = blocks[j->block_index]; if(shared.dirty) @@ -684,18 +632,13 @@ vector::const_iterator ProgramData::prepare_program(c void ProgramData::apply(const Program &prog, PipelineState &state) const { auto prog_begin = prepare_program(prog); - Program::LayoutHash prog_hash = prog_begin->prog_hash; + 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) { - if(i->bind_point<0) - state.set_uniforms(static_cast(i->block)); - else - { - const BufferBackedUniformBlock *block = static_cast(i->block); - block->refresh(); - state.set_uniform_block(i->bind_point, block); - } + state.set_uniform_block(i->bind_point, i->block); + if(i->bind_point>=0) + i->block->refresh(); } } @@ -711,21 +654,7 @@ void ProgramData::set_debug_name(const string &name) } -ProgramData::TaggedUniform::TaggedUniform(): - value(0) -{ } - -void ProgramData::TaggedUniform::replace_value(Uniform *v) -{ - /* UniformBlock does not copy the uniforms, so existing default blocks - will be left with stale pointers. This is not a problem as long as no - one stores pointers to the blocks and expects them to stay valid. */ - delete value; - value = v; -} - - -ProgramData::SharedBlock::SharedBlock(Program::LayoutHash h): +ProgramData::SharedBlock::SharedBlock(ReflectData::LayoutHash h): block_hash(h), used(0), dirty(0), @@ -740,7 +669,7 @@ const uint8_t *ProgramData::SharedBlock::get_uniform_indices() const } -ProgramData::ProgramBlock::ProgramBlock(Program::LayoutHash h): +ProgramData::ProgramBlock::ProgramBlock(ReflectData::LayoutHash h): prog_hash(h), bind_point(-1), block_index(-1)