From: Mikko Rasa Date: Sat, 10 Apr 2021 12:04:26 +0000 (+0300) Subject: Use Tag to identify uniforms in Program and ProgramData X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=fa2b4c8a93ebad2497cacfdeaa9a2c20be486520;p=libs%2Fgl.git Use Tag to identify uniforms in Program and ProgramData Setting uniforms is a common operation and this should be faster than using strings. --- diff --git a/source/core/program.cpp b/source/core/program.cpp index dd38075a..2c15bc77 100644 --- a/source/core/program.cpp +++ b/source/core/program.cpp @@ -372,13 +372,14 @@ void Program::query_uniforms() uniforms.push_back(UniformInfo()); UniformInfo &info = uniforms.back(); info.name = name; + info.tag = name; info.array_size = size; info.type = from_gl_type(type); uniform_names[i] = name; } } - sort(uniforms, &uniform_name_compare); + sort(uniforms, &uniform_tag_compare); if(ARB_uniform_buffer_object) { @@ -386,7 +387,7 @@ void Program::query_uniforms() for(unsigned i=0; i); + uniforms_by_index[i] = &*lower_bound(uniforms, Tag(uniform_names[i]), &search); query_uniform_blocks(uniforms_by_index); } @@ -531,13 +532,14 @@ void Program::collect_uniforms() uniforms.push_back(UniformInfo()); UniformInfo &info = uniforms.back(); info.name = i->name; + info.tag = i->name; info.location = i->location; info.array_size = i->array_size; info.type = i->type; } } - sort(uniforms, &uniform_name_compare); + sort(uniforms, &uniform_tag_compare); for(unsigned i=0; i::const_iterator j=names.begin(); j!=names.end(); ++j) { // The element is already known to be present - UniformInfo &uni = *lower_bound(uniforms, *j, &name_search); + UniformInfo &uni = *lower_bound(uniforms, Tag(*j), &search); block.uniforms.push_back(&uni); uni.block = █ } @@ -578,6 +580,7 @@ void Program::collect_block_uniforms(const SpirVModule::Structure &strct, const uniforms.push_back(UniformInfo()); UniformInfo &info = uniforms.back(); info.name = name; + info.tag = name; info.offset = offset; info.array_size = i->array_size; info.array_stride = i->array_stride; @@ -629,15 +632,15 @@ bool Program::uniform_location_compare(const UniformInfo *uni1, const UniformInf return uni1->locationlocation; } -bool Program::uniform_name_compare(const UniformInfo &uni1, const UniformInfo &uni2) +bool Program::uniform_tag_compare(const UniformInfo &uni1, const UniformInfo &uni2) { - return uni1.name -bool Program::name_search(const T &item, const string &name) +template +bool Program::search(const T &item, const A &key) { - return item.name::const_iterator i = lower_bound(uniforms, name, &name_search); + vector::const_iterator i = lower_bound(uniforms, Tag(name), &search); if(i==uniforms.end() || i->name!=name) throw key_error(name); return *i; } +const Program::UniformInfo &Program::get_uniform_info(Tag tag) const +{ + vector::const_iterator i = lower_bound(uniforms, tag, &search); + if(i==uniforms.end() || i->tag!=tag) + throw key_error(tag); + return *i; +} + int Program::get_uniform_location(const string &name) const { if(name[name.size()-1]==']') throw invalid_argument("Program::get_uniform_location"); - vector::const_iterator i = lower_bound(uniforms, name, &name_search); + vector::const_iterator i = lower_bound(uniforms, Tag(name), &search); return i!=uniforms.end() && i->name==name && i->block->bind_point<0 ? i->location : -1; } +int Program::get_uniform_location(Tag tag) const +{ + vector::const_iterator i = lower_bound(uniforms, tag, &search); + return i!=uniforms.end() && i->tag==tag && i->block->bind_point<0 ? i->location : -1; +} + const Program::AttributeInfo &Program::get_attribute_info(const string &name) const { - vector::const_iterator i = lower_bound(attributes, name, &name_search); + vector::const_iterator i = lower_bound(attributes, name, &search); if(i==attributes.end() || i->name!=name) throw key_error(name); return *i; @@ -687,7 +704,7 @@ int Program::get_attribute_location(const string &name) const if(name[name.size()-1]==']') throw invalid_argument("Program::get_attribute_location"); - vector::const_iterator i = lower_bound(attributes, name, &name_search); + vector::const_iterator i = lower_bound(attributes, name, &search); return i!=attributes.end() && i->name==name ? i->location : -1; } diff --git a/source/core/program.h b/source/core/program.h index 6613a134..939521dc 100644 --- a/source/core/program.h +++ b/source/core/program.h @@ -8,6 +8,7 @@ #include "datatype.h" #include "gl.h" #include "module.h" +#include "tag.h" #include "vertexformat.h" namespace Msp { @@ -72,6 +73,7 @@ public: unsigned array_stride; unsigned matrix_stride; DataType type; + Tag tag; UniformInfo(); }; @@ -160,9 +162,9 @@ private: void update_layout_hash(); static LayoutHash compute_layout_hash(const std::vector &); static bool uniform_location_compare(const UniformInfo *, const UniformInfo *); - static bool uniform_name_compare(const UniformInfo &, const UniformInfo &); - template - static bool name_search(const T &, const std::string &); + static bool uniform_tag_compare(const UniformInfo &, const UniformInfo &); + template + static bool search(const T &, const A &); public: bool is_linked() const { return linked; } DEPRECATED std::string get_info_log() const; @@ -172,7 +174,9 @@ public: const UniformBlockInfo &get_uniform_block_info(const std::string &) const; const std::vector &get_uniforms() const { return uniforms; } const UniformInfo &get_uniform_info(const std::string &) const; + const UniformInfo &get_uniform_info(Tag) const; int get_uniform_location(const std::string &) const; + int get_uniform_location(Tag) const; const std::vector &get_attributes() const { return attributes; } const AttributeInfo &get_attribute_info(const std::string &) const; int get_attribute_location(const std::string &) const; diff --git a/source/core/tag.cpp b/source/core/tag.cpp new file mode 100644 index 00000000..b5f86033 --- /dev/null +++ b/source/core/tag.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include "tag.h" + +using namespace std; + +namespace { + +#ifdef DEBUG +map tag_names; +#endif + +} + +namespace Msp { +namespace GL { + +Tag::Tag(const char *s): + id((s && *s) ? hash32(s, strlen(s)) : 0) +{ +#ifdef DEBUG + if(s) + tag_names.insert(make_pair(*this, string(s))); +#endif +} + +Tag::Tag(const std::string &s): + id(s.empty() ? 0 : hash32(s)) +{ +#ifdef DEBUG + if(!s.empty()) + tag_names.insert(make_pair(*this, s)); +#endif +} + +string Tag::str() const +{ +#ifdef DEBUG + map::const_iterator i=tag_names.find(*this); + if(i!=tag_names.end()) + return i->second; +#endif + return format("Tag(%d)", id); +} + +void operator<<(LexicalConverter &conv, Tag tag) +{ + conv.result(tag.str()); +} + +} // namespace GL +} // namespace Msp diff --git a/source/core/tag.h b/source/core/tag.h new file mode 100644 index 00000000..dbc0b3ef --- /dev/null +++ b/source/core/tag.h @@ -0,0 +1,34 @@ +#ifndef MSP_GL_TAG_H_ +#define MSP_GL_TAG_H_ + +#include +#include + +namespace Msp { +namespace GL { + +/** +Provides transparent string-to-hash conversion for faster comparison. An empty +string is guaranteed to have an id of 0. +*/ +struct Tag +{ + unsigned id; + + Tag(): id(0) { } + Tag(const char *); + Tag(const std::string &s); + + std::string str() const; + + bool operator<(Tag t) const { return id::const_iterator i = uniform_slots.find(slot); + map::const_iterator i = uniform_slots.find(slot); if(i==uniform_slots.end()) - { - static string empty; - return empty; - } + return Tag(); return i->second; } diff --git a/source/materials/renderpass.h b/source/materials/renderpass.h index b674945e..0e8ccdf2 100644 --- a/source/materials/renderpass.h +++ b/source/materials/renderpass.h @@ -64,7 +64,7 @@ private: RefPtr shprog; bool shprog_from_material; RefPtr shdata; - std::map uniform_slots; + std::map uniform_slots; RefPtr material; std::string material_slot; Texturing *texturing; @@ -86,7 +86,7 @@ public: void set_shader_program(const Program *, const ProgramData *); const Program *get_shader_program() const { return shprog.get(); } const ProgramData *get_shader_data() const { return shdata.get(); } - const std::string &get_slotted_uniform_name(const std::string &) const; + Tag get_slotted_uniform_tag(Tag) const; void set_material(const Material *, DataFile::Collection * = 0); const Material *get_material() const { return material.get(); } const std::string &get_material_slot_name() const { return material_slot; } diff --git a/source/materials/technique.cpp b/source/materials/technique.cpp index 22f8f3b6..a382376e 100644 --- a/source/materials/technique.cpp +++ b/source/materials/technique.cpp @@ -69,20 +69,20 @@ bool Technique::replace_material(const string &slot, const Material &mat) bool Technique::replace_uniforms(const ProgramData &shdata) { bool replaced = false; - const vector &uniform_names = shdata.get_uniform_names(); + const vector &uniform_tags = shdata.get_uniform_tags(); for(PassMap::iterator i=passes.begin(); i!=passes.end(); ++i) { RefPtr new_shdata; - for(vector::const_iterator j=uniform_names.begin(); j!=uniform_names.end(); ++j) + for(vector::const_iterator j=uniform_tags.begin(); j!=uniform_tags.end(); ++j) { - const string &name = i->second.get_slotted_uniform_name(*j); - if(name.empty()) + Tag tag = i->second.get_slotted_uniform_tag(*j); + if(!tag.id) continue; if(!new_shdata) new_shdata = new ProgramData(*i->second.get_shader_data()); - new_shdata->uniform(name, shdata.get_uniform(*j)); + new_shdata->uniform(tag, shdata.get_uniform(*j)); replaced = true; } diff --git a/source/render/programdata.cpp b/source/render/programdata.cpp index 401ed189..9c23e8a5 100644 --- a/source/render/programdata.cpp +++ b/source/render/programdata.cpp @@ -32,7 +32,7 @@ ProgramData::ProgramData(const ProgramData &other): buffer(0), dirty(0) { - for(vector::iterator i=uniforms.begin(); i!=uniforms.end(); ++i) + for(vector::iterator i=uniforms.begin(); i!=uniforms.end(); ++i) i->value = i->value->clone(); } @@ -44,12 +44,12 @@ ProgramData::ProgramData(const ProgramData &other, const Program *p): { if(tied_program) { - for(vector::const_iterator i=other.uniforms.begin(); i!=other.uniforms.end(); ++i) - validate_name(i->name); + for(vector::const_iterator i=other.uniforms.begin(); i!=other.uniforms.end(); ++i) + validate_tag(i->tag); } uniforms = other.uniforms; - for(vector::iterator i=uniforms.begin(); i!=uniforms.end(); ++i) + for(vector::iterator i=uniforms.begin(); i!=uniforms.end(); ++i) i->value = i->value->clone(); } @@ -58,7 +58,7 @@ ProgramData &ProgramData::operator=(const ProgramData &other) tied_program = other.tied_program; uniforms = other.uniforms; - for(vector::iterator i=uniforms.begin(); i!=uniforms.end(); ++i) + for(vector::iterator i=uniforms.begin(); i!=uniforms.end(); ++i) i->value = i->value->clone(); for(BlockMap::iterator i=blocks.begin(); i!=blocks.end(); ++i) @@ -74,7 +74,7 @@ ProgramData &ProgramData::operator=(const ProgramData &other) ProgramData::~ProgramData() { - for(vector::iterator i=uniforms.begin(); i!=uniforms.end(); ++i) + for(vector::iterator i=uniforms.begin(); i!=uniforms.end(); ++i) delete i->value; for(BlockMap::iterator i=blocks.begin(); i!=blocks.end(); ++i) { @@ -85,11 +85,11 @@ ProgramData::~ProgramData() delete buffer; } -void ProgramData::uniform(const string &name, Uniform *uni) +void ProgramData::uniform(Tag tag, Uniform *uni) { try { - if(!validate_name(name)) + if(!validate_tag(tag)) { delete uni; return; @@ -101,23 +101,23 @@ void ProgramData::uniform(const string &name, Uniform *uni) throw; } - int i = find_uniform_index(name); + int i = find_uniform_index(tag); if(i<0) - return add_uniform(name, uni); + return add_uniform(tag, uni); uniforms[i].replace_value(uni); dirty |= 1< -void ProgramData::uniform(const string &name, V value) +void ProgramData::uniform(Tag tag, V value) { - if(!validate_name(name)) + if(!validate_tag(tag)) return; - int i = find_uniform_index(name); + int i = find_uniform_index(tag); if(i<0) - return add_uniform(name, new T(value)); + return add_uniform(tag, new T(value)); if(T *uni = dynamic_cast(uniforms[i].value)) uni->set(value); @@ -128,14 +128,14 @@ void ProgramData::uniform(const string &name, V value) } template -void ProgramData::uniform_array(const string &name, unsigned n, V value) +void ProgramData::uniform_array(Tag tag, unsigned n, V value) { - if(!validate_name(name)) + if(!validate_tag(tag)) return; - int i = find_uniform_index(name); + int i = find_uniform_index(tag); if(i<0) - return add_uniform(name, new UniformArray(n, value)); + return add_uniform(tag, new UniformArray(n, value)); UniformArray *uni = dynamic_cast *>(uniforms[i].value); if(uni && n==uni->size()) @@ -146,320 +146,318 @@ void ProgramData::uniform_array(const string &name, unsigned n, V value) dirty |= 1<get_uniform_info(name); - else if(name[name.size()-1]==']') - throw invalid_argument("ProgramData::uniform"); + tied_program->get_uniform_info(tag); return true; } #ifdef DEBUG catch(const exception &e) { - IO::print(IO::cerr, "Error while setting uniform %s: %s: %s\n", name, Debug::demangle(typeid(e).name()), e.what()); + IO::print(IO::cerr, "Error while setting uniform %s: %s: %s\n", tag, Debug::demangle(typeid(e).name()), e.what()); return false; } #endif } -void ProgramData::add_uniform(const string &name, Uniform *uni) +void ProgramData::add_uniform(Tag tag, Uniform *uni) { if(uniforms.size()>=MASK_BITS) { delete uni; - throw too_many_uniforms(name); + throw too_many_uniforms(tag.str()); } - vector::iterator j = lower_bound(uniforms.begin(), uniforms.end(), name, uniform_name_compare); + vector::iterator j = lower_bound(uniforms.begin(), uniforms.end(), tag, uniform_tag_compare); - NamedUniform nu; - nu.name = name; + TaggedUniform nu; + nu.tag = tag; nu.value = uni; uniforms.insert(j, nu); dirty = ALL_ONES; } -void ProgramData::uniform(const string &name, const Uniform &u) +void ProgramData::uniform(Tag tag, const Uniform &u) { - uniform(name, u.clone()); + uniform(tag, u.clone()); } -void ProgramData::uniform(const string &name, int v) +void ProgramData::uniform(Tag tag, int v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, float v) +void ProgramData::uniform(Tag tag, float v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, int v0, int v1) +void ProgramData::uniform(Tag tag, int v0, int v1) { int va[2] = { v0, v1 }; - uniform2(name, va); + uniform2(tag, va); } -void ProgramData::uniform(const string &name, float v0, float v1) +void ProgramData::uniform(Tag tag, float v0, float v1) { float va[2] = { v0, v1 }; - uniform2(name, va); + uniform2(tag, va); } -void ProgramData::uniform2(const string &name, const int *v) +void ProgramData::uniform2(Tag tag, const int *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform2(const string &name, const float *v) +void ProgramData::uniform2(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, int v0, int v1, int v2) +void ProgramData::uniform(Tag tag, int v0, int v1, int v2) { int va[3] = { v0, v1, v2 }; - uniform3(name, va); + uniform3(tag, va); } -void ProgramData::uniform(const string &name, float v0, float v1, float v2) +void ProgramData::uniform(Tag tag, float v0, float v1, float v2) { float va[3] = { v0, v1, v2 }; - uniform3(name, va); + uniform3(tag, va); } -void ProgramData::uniform(const string &name, const Vector3 &v) +void ProgramData::uniform(Tag tag, const Vector3 &v) { - uniform(name, v.x, v.y, v.z); + uniform(tag, v.x, v.y, v.z); } -void ProgramData::uniform3(const string &name, const int *v) +void ProgramData::uniform3(Tag tag, const int *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform3(const string &name, const float *v) +void ProgramData::uniform3(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, int v0, int v1, int v2, int v3) +void ProgramData::uniform(Tag tag, int v0, int v1, int v2, int v3) { int va[4] = { v0, v1, v2, v3 }; - uniform4(name, va); + uniform4(tag, va); } -void ProgramData::uniform(const string &name, float v0, float v1, float v2, float v3) +void ProgramData::uniform(Tag tag, float v0, float v1, float v2, float v3) { float va[4] = { v0, v1, v2, v3 }; - uniform4(name, va); + uniform4(tag, va); } -void ProgramData::uniform(const string &name, const Vector4 &v) +void ProgramData::uniform(Tag tag, const Vector4 &v) { - uniform(name, v.x, v.y, v.z, v.w); + uniform(tag, v.x, v.y, v.z, v.w); } -void ProgramData::uniform(const string &name, const Color &c) +void ProgramData::uniform(Tag tag, const Color &c) { - uniform(name, c.r, c.g, c.b, c.a); + uniform(tag, c.r, c.g, c.b, c.a); } -void ProgramData::uniform4(const string &name, const int *v) +void ProgramData::uniform4(Tag tag, const int *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform4(const string &name, const float *v) +void ProgramData::uniform4(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, const LinAl::Matrix &m) +void ProgramData::uniform(Tag tag, const LinAl::Matrix &m) { - uniform_matrix2(name, &m(0, 0)); + uniform_matrix2(tag, &m(0, 0)); } -void ProgramData::uniform_matrix2(const string &name, const float *v) +void ProgramData::uniform_matrix2(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, const LinAl::Matrix &m) +void ProgramData::uniform(Tag tag, const LinAl::Matrix &m) { - uniform_matrix3x2(name, &m(0, 0)); + uniform_matrix3x2(tag, &m(0, 0)); } -void ProgramData::uniform_matrix3x2(const string &name, const float *v) +void ProgramData::uniform_matrix3x2(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, const LinAl::Matrix &m) +void ProgramData::uniform(Tag tag, const LinAl::Matrix &m) { - uniform_matrix4x2(name, &m(0, 0)); + uniform_matrix4x2(tag, &m(0, 0)); } -void ProgramData::uniform_matrix4x2(const string &name, const float *v) +void ProgramData::uniform_matrix4x2(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, const LinAl::Matrix &m) +void ProgramData::uniform(Tag tag, const LinAl::Matrix &m) { - uniform_matrix2x3(name, &m(0, 0)); + uniform_matrix2x3(tag, &m(0, 0)); } -void ProgramData::uniform_matrix2x3(const string &name, const float *v) +void ProgramData::uniform_matrix2x3(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, const LinAl::Matrix &m) +void ProgramData::uniform(Tag tag, const LinAl::Matrix &m) { - uniform_matrix3(name, &m(0, 0)); + uniform_matrix3(tag, &m(0, 0)); } -void ProgramData::uniform_matrix3(const string &name, const float *v) +void ProgramData::uniform_matrix3(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, const LinAl::Matrix &m) +void ProgramData::uniform(Tag tag, const LinAl::Matrix &m) { - uniform_matrix4x3(name, &m(0, 0)); + uniform_matrix4x3(tag, &m(0, 0)); } -void ProgramData::uniform_matrix4x3(const string &name, const float *v) +void ProgramData::uniform_matrix4x3(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, const LinAl::Matrix &m) +void ProgramData::uniform(Tag tag, const LinAl::Matrix &m) { - uniform_matrix2x4(name, &m(0, 0)); + uniform_matrix2x4(tag, &m(0, 0)); } -void ProgramData::uniform_matrix2x4(const string &name, const float *v) +void ProgramData::uniform_matrix2x4(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, const LinAl::Matrix &m) +void ProgramData::uniform(Tag tag, const LinAl::Matrix &m) { - uniform_matrix3x4(name, &m(0, 0)); + uniform_matrix3x4(tag, &m(0, 0)); } -void ProgramData::uniform_matrix3x4(const string &name, const float *v) +void ProgramData::uniform_matrix3x4(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform(const string &name, const Matrix &m) +void ProgramData::uniform(Tag tag, const Matrix &m) { - uniform_matrix4(name, m.data()); + uniform_matrix4(tag, m.data()); } -void ProgramData::uniform_matrix4(const string &name, const float *v) +void ProgramData::uniform_matrix4(Tag tag, const float *v) { - uniform(name, v); + uniform(tag, v); } -void ProgramData::uniform1_array(const string &name, unsigned n, const int *v) +void ProgramData::uniform1_array(Tag tag, unsigned n, const int *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform1_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform1_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform2_array(const string &name, unsigned n, const int *v) +void ProgramData::uniform2_array(Tag tag, unsigned n, const int *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform2_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform2_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform3_array(const string &name, unsigned n, const int *v) +void ProgramData::uniform3_array(Tag tag, unsigned n, const int *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform3_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform3_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform4_array(const string &name, unsigned n, const int *v) +void ProgramData::uniform4_array(Tag tag, unsigned n, const int *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform4_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform4_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform_matrix2_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform_matrix2_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform_matrix3x2_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform_matrix3x2_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform_matrix4x2_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform_matrix4x2_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform_matrix2x3_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform_matrix2x3_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform_matrix3_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform_matrix3_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform_matrix4x3_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform_matrix4x3_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform_matrix2x4_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform_matrix2x4_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform_matrix3x4_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform_matrix3x4_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::uniform_matrix4_array(const string &name, unsigned n, const float *v) +void ProgramData::uniform_matrix4_array(Tag tag, unsigned n, const float *v) { - uniform_array(name, n, v); + uniform_array(tag, n, v); } -void ProgramData::remove_uniform(const string &name) +void ProgramData::remove_uniform(Tag tag) { - vector::const_iterator i = lower_bound(uniforms.begin(), uniforms.end(), name, uniform_name_compare); - if(i==uniforms.end() || i->name!=name) + vector::const_iterator i = lower_bound(uniforms.begin(), uniforms.end(), tag, uniform_tag_compare); + if(i==uniforms.end() || i->tag!=tag) return; delete i->value; @@ -468,38 +466,38 @@ void ProgramData::remove_uniform(const string &name) dirty = ALL_ONES; } -vector ProgramData::get_uniform_names() const +vector ProgramData::get_uniform_tags() const { - vector names; - names.reserve(uniforms.size()); - for(vector::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i) - names.push_back(i->name); - return names; + vector tags; + tags.reserve(uniforms.size()); + for(vector::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i) + tags.push_back(i->tag); + return tags; } -const Uniform &ProgramData::get_uniform(const string &name) const +const Uniform &ProgramData::get_uniform(Tag tag) const { - int i = find_uniform_index(name); + int i = find_uniform_index(tag); if(i<0) - throw key_error(name); + throw key_error(tag); return *uniforms[i].value; } -const Uniform *ProgramData::find_uniform(const string &name) const +const Uniform *ProgramData::find_uniform(Tag tag) const { - int i = find_uniform_index(name); + int i = find_uniform_index(tag); return (i>=0 ? uniforms[i].value : 0); } -bool ProgramData::uniform_name_compare(const NamedUniform &nu, const string &name) +bool ProgramData::uniform_tag_compare(const TaggedUniform &tu, Tag tag) { - return nu.name::const_iterator i = lower_bound(uniforms.begin(), uniforms.end(), name, uniform_name_compare); - return ((i!=uniforms.end() && i->name==name) ? i-uniforms.begin() : -1); + vector::const_iterator i = lower_bound(uniforms.begin(), uniforms.end(), tag, uniform_tag_compare); + return ((i!=uniforms.end() && i->tag==tag) ? i-uniforms.begin() : -1); } void ProgramData::update_block_uniform_indices(SharedBlock &block, const Program::UniformBlockInfo &info) const @@ -518,7 +516,7 @@ void ProgramData::update_block_uniform_indices(SharedBlock &block, const Program block.used = 0; for(unsigned i=0; iname); + int j = find_uniform_index(info.uniforms[i]->tag); if(j>=0) { indices[i] = j; @@ -679,11 +677,11 @@ void ProgramData::apply() const } -ProgramData::NamedUniform::NamedUniform(): +ProgramData::TaggedUniform::TaggedUniform(): value(0) { } -void ProgramData::NamedUniform::replace_value(Uniform *v) +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 diff --git a/source/render/programdata.h b/source/render/programdata.h index c772272e..0ed16d6f 100644 --- a/source/render/programdata.h +++ b/source/render/programdata.h @@ -7,6 +7,7 @@ #include "datatype.h" #include "matrix.h" #include "program.h" +#include "tag.h" #include "vector.h" namespace Msp { @@ -97,14 +98,13 @@ private: ALL_ONES = static_cast(-1) }; - struct NamedUniform + struct TaggedUniform { - std::string name; + Tag tag; Uniform *value; - NamedUniform(); + TaggedUniform(); - bool compare_name(const std::string &, unsigned) const; void replace_value(Uniform *); }; @@ -153,7 +153,7 @@ private: // XXX All these mutables are a bit silly, but I'm out of better ideas const Program *tied_program; - std::vector uniforms; + std::vector uniforms; mutable BlockMap blocks; mutable ProgramMap programs; mutable UniformBlock *last_block; @@ -168,76 +168,76 @@ public: ~ProgramData(); private: - void uniform(const std::string &, Uniform *); + void uniform(Tag, Uniform *); template - void uniform(const std::string &, V); + void uniform(Tag, V); template - void uniform_array(const std::string &, unsigned, V); - bool validate_name(const std::string &) const; - void add_uniform(const std::string &, Uniform *); + void uniform_array(Tag, unsigned, V); + bool validate_tag(Tag) const; + void add_uniform(Tag, Uniform *); public: - void uniform(const std::string &, const Uniform &); - void uniform(const std::string &, int); - void uniform(const std::string &, float); - void uniform(const std::string &, int, int); - void uniform(const std::string &, float, float); - void uniform2(const std::string &, const int *); - void uniform2(const std::string &, const float *); - void uniform(const std::string &, int, int, int); - void uniform(const std::string &, float, float, float); - void uniform(const std::string &, const Vector3 &); - void uniform3(const std::string &, const int *); - void uniform3(const std::string &, const float *); - void uniform(const std::string &, int, int, int, int); - void uniform(const std::string &, float, float, float, float); - void uniform(const std::string &, const Vector4 &); - void uniform(const std::string &, const Color &); - void uniform4(const std::string &, const int *); - void uniform4(const std::string &, const float *); - void uniform(const std::string &, const LinAl::Matrix &); - void uniform_matrix2(const std::string &, const float *); - void uniform(const std::string &, const LinAl::Matrix &); - void uniform_matrix3x2(const std::string &, const float *); - void uniform(const std::string &, const LinAl::Matrix &); - void uniform_matrix4x2(const std::string &, const float *); - void uniform(const std::string &, const LinAl::Matrix &); - void uniform_matrix2x3(const std::string &, const float *); - void uniform(const std::string &, const LinAl::Matrix &); - void uniform_matrix3(const std::string &, const float *); - void uniform(const std::string &, const LinAl::Matrix &); - void uniform_matrix4x3(const std::string &, const float *); - void uniform(const std::string &, const LinAl::Matrix &); - void uniform_matrix2x4(const std::string &, const float *); - void uniform(const std::string &, const LinAl::Matrix &); - void uniform_matrix3x4(const std::string &, const float *); - void uniform(const std::string &, const Matrix &); - void uniform_matrix4(const std::string &, const float *); - void uniform1_array(const std::string &, unsigned, const int *); - void uniform1_array(const std::string &, unsigned, const float *); - void uniform2_array(const std::string &, unsigned, const int *); - void uniform2_array(const std::string &, unsigned, const float *); - void uniform3_array(const std::string &, unsigned, const int *); - void uniform3_array(const std::string &, unsigned, const float *); - void uniform4_array(const std::string &, unsigned, const int *); - void uniform4_array(const std::string &, unsigned, const float *); - void uniform_matrix2_array(const std::string &, unsigned, const float *); - void uniform_matrix3x2_array(const std::string &, unsigned, const float *); - void uniform_matrix4x2_array(const std::string &, unsigned, const float *); - void uniform_matrix2x3_array(const std::string &, unsigned, const float *); - void uniform_matrix3_array(const std::string &, unsigned, const float *); - void uniform_matrix4x3_array(const std::string &, unsigned, const float *); - void uniform_matrix2x4_array(const std::string &, unsigned, const float *); - void uniform_matrix3x4_array(const std::string &, unsigned, const float *); - void uniform_matrix4_array(const std::string &, unsigned, const float *); - void remove_uniform(const std::string &); - - std::vector get_uniform_names() const; - const Uniform &get_uniform(const std::string &) const; - const Uniform *find_uniform(const std::string &) const; + void uniform(Tag, const Uniform &); + void uniform(Tag, int); + void uniform(Tag, float); + void uniform(Tag, int, int); + void uniform(Tag, float, float); + void uniform2(Tag, const int *); + void uniform2(Tag, const float *); + void uniform(Tag, int, int, int); + void uniform(Tag, float, float, float); + void uniform(Tag, const Vector3 &); + void uniform3(Tag, const int *); + void uniform3(Tag, const float *); + void uniform(Tag, int, int, int, int); + void uniform(Tag, float, float, float, float); + void uniform(Tag, const Vector4 &); + void uniform(Tag, const Color &); + void uniform4(Tag, const int *); + void uniform4(Tag, const float *); + void uniform(Tag, const LinAl::Matrix &); + void uniform_matrix2(Tag, const float *); + void uniform(Tag, const LinAl::Matrix &); + void uniform_matrix3x2(Tag, const float *); + void uniform(Tag, const LinAl::Matrix &); + void uniform_matrix4x2(Tag, const float *); + void uniform(Tag, const LinAl::Matrix &); + void uniform_matrix2x3(Tag, const float *); + void uniform(Tag, const LinAl::Matrix &); + void uniform_matrix3(Tag, const float *); + void uniform(Tag, const LinAl::Matrix &); + void uniform_matrix4x3(Tag, const float *); + void uniform(Tag, const LinAl::Matrix &); + void uniform_matrix2x4(Tag, const float *); + void uniform(Tag, const LinAl::Matrix &); + void uniform_matrix3x4(Tag, const float *); + void uniform(Tag, const Matrix &); + void uniform_matrix4(Tag, const float *); + void uniform1_array(Tag, unsigned, const int *); + void uniform1_array(Tag, unsigned, const float *); + void uniform2_array(Tag, unsigned, const int *); + void uniform2_array(Tag, unsigned, const float *); + void uniform3_array(Tag, unsigned, const int *); + void uniform3_array(Tag, unsigned, const float *); + void uniform4_array(Tag, unsigned, const int *); + void uniform4_array(Tag, unsigned, const float *); + void uniform_matrix2_array(Tag, unsigned, const float *); + void uniform_matrix3x2_array(Tag, unsigned, const float *); + void uniform_matrix4x2_array(Tag, unsigned, const float *); + void uniform_matrix2x3_array(Tag, unsigned, const float *); + void uniform_matrix3_array(Tag, unsigned, const float *); + void uniform_matrix4x3_array(Tag, unsigned, const float *); + void uniform_matrix2x4_array(Tag, unsigned, const float *); + void uniform_matrix3x4_array(Tag, unsigned, const float *); + void uniform_matrix4_array(Tag, unsigned, const float *); + void remove_uniform(Tag); + + std::vector get_uniform_tags() const; + const Uniform &get_uniform(Tag) const; + const Uniform *find_uniform(Tag) const; private: - static bool uniform_name_compare(const NamedUniform &, const std::string &); - int find_uniform_index(const std::string &) const; + static bool uniform_tag_compare(const TaggedUniform &, Tag); + int find_uniform_index(Tag) const; void update_block_uniform_indices(SharedBlock &, const Program::UniformBlockInfo &) const; void update_block(SharedBlock &, const Program::UniformBlockInfo &) const; SharedBlock *get_shared_block(const Program::UniformBlockInfo &) const; diff --git a/source/render/tag.cpp b/source/render/tag.cpp deleted file mode 100644 index b5f86033..00000000 --- a/source/render/tag.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include -#include -#include -#include "tag.h" - -using namespace std; - -namespace { - -#ifdef DEBUG -map tag_names; -#endif - -} - -namespace Msp { -namespace GL { - -Tag::Tag(const char *s): - id((s && *s) ? hash32(s, strlen(s)) : 0) -{ -#ifdef DEBUG - if(s) - tag_names.insert(make_pair(*this, string(s))); -#endif -} - -Tag::Tag(const std::string &s): - id(s.empty() ? 0 : hash32(s)) -{ -#ifdef DEBUG - if(!s.empty()) - tag_names.insert(make_pair(*this, s)); -#endif -} - -string Tag::str() const -{ -#ifdef DEBUG - map::const_iterator i=tag_names.find(*this); - if(i!=tag_names.end()) - return i->second; -#endif - return format("Tag(%d)", id); -} - -void operator<<(LexicalConverter &conv, Tag tag) -{ - conv.result(tag.str()); -} - -} // namespace GL -} // namespace Msp diff --git a/source/render/tag.h b/source/render/tag.h deleted file mode 100644 index dbc0b3ef..00000000 --- a/source/render/tag.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef MSP_GL_TAG_H_ -#define MSP_GL_TAG_H_ - -#include -#include - -namespace Msp { -namespace GL { - -/** -Provides transparent string-to-hash conversion for faster comparison. An empty -string is guaranteed to have an id of 0. -*/ -struct Tag -{ - unsigned id; - - Tag(): id(0) { } - Tag(const char *); - Tag(const std::string &s); - - std::string str() const; - - bool operator<(Tag t) const { return idhas_pass(Tag())) if(const Program *shprog = tech->get_pass(Tag()).get_shader_program()) { - if(shprog->get_uniform_location("font_tex")>=0) + if(shprog->get_uniform_location(Tag("font_tex"))>=0) tex_slot = "font_tex"; - else if(shprog->get_uniform_location("color_tex")>=0) + else if(shprog->get_uniform_location(Tag("color_tex"))>=0) tex_slot = "color_tex"; - else if(shprog->get_uniform_location("diffuse_map")>=0) + else if(shprog->get_uniform_location(Tag("diffuse_map"))>=0) tex_slot = "diffuse_map"; - else if(shprog->get_uniform_location("base_color_map")>=0) + else if(shprog->get_uniform_location(Tag("base_color_map"))>=0) tex_slot = "base_color_map"; }