]> git.tdb.fi Git - libs/gl.git/commitdiff
Split reflection data from Program to a separate struct
authorMikko Rasa <tdb@tdb.fi>
Sun, 26 Sep 2021 11:32:25 +0000 (14:32 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 26 Sep 2021 14:24:38 +0000 (17:24 +0300)
This is necessary for splitting the API-specific code.

15 files changed:
source/core/program.cpp
source/core/program.h
source/core/reflectdata.cpp [new file with mode: 0644]
source/core/reflectdata.h [new file with mode: 0644]
source/core/uniform.h
source/core/uniformblock.cpp
source/core/uniformblock.h
source/effects/environmentmap.cpp
source/materials/lighting.cpp
source/materials/material.cpp
source/materials/renderpass.cpp
source/render/instancearray.cpp
source/render/programdata.cpp
source/render/programdata.h
source/render/sequence.cpp

index 8bec2f6f488295474804d641516b825de8ef309a..82f438cdbf02112ff3362018b7587b066f251fbd 100644 (file)
@@ -1,7 +1,6 @@
 #include <cstring>
 #include <set>
 #include <msp/core/algorithm.h>
-#include <msp/core/hash.h>
 #include <msp/core/maputils.h>
 #include <msp/core/raii.h>
 #include <msp/gl/extensions/arb_es2_compatibility.h>
@@ -16,7 +15,6 @@
 #include <msp/gl/extensions/khr_debug.h>
 #include <msp/gl/extensions/nv_non_square_matrices.h>
 #include <msp/io/print.h>
-#include <msp/strings/format.h>
 #include "buffer.h"
 #include "error.h"
 #include "program.h"
@@ -236,9 +234,7 @@ void Program::link()
        if(!has_stages())
                throw invalid_operation("Program::link");
 
-       uniforms.clear();
-       uniform_blocks.clear();
-       attributes.clear();
+       reflect_data = ReflectData();
 
        glLinkProgram(id);
        int status = 0;
@@ -266,13 +262,13 @@ void Program::link()
                query_attributes();
                if(transient)
                {
-                       for(unsigned i=0; i<uniform_blocks.size(); ++i)
+                       for(unsigned i=0; i<reflect_data.uniform_blocks.size(); ++i)
                        {
-                               auto j = transient->blocks.find(uniform_blocks[i].name);
+                               auto j = transient->blocks.find(reflect_data.uniform_blocks[i].name);
                                if(j!=transient->blocks.end())
                                {
                                        glUniformBlockBinding(id, i, j->second);
-                                       uniform_blocks[i].bind_point = j->second;
+                                       reflect_data.uniform_blocks[i].bind_point = j->second;
                                }
                        }
 
@@ -300,9 +296,9 @@ void Program::link()
        delete transient;
        transient = 0;
 
-       for(const UniformInfo &u: uniforms)
+       for(const ReflectData::UniformInfo &u: reflect_data.uniforms)
                require_type(u.type);
-       for(const AttributeInfo &a: attributes)
+       for(const ReflectData::AttributeInfo &a: reflect_data.attributes)
                require_type(a.type);
 }
 
@@ -310,7 +306,7 @@ void Program::query_uniforms()
 {
        unsigned count = 0;
        glGetProgramiv(id, GL_ACTIVE_UNIFORMS, reinterpret_cast<int *>(&count));
-       uniforms.reserve(count);
+       reflect_data.uniforms.reserve(count);
        vector<string> uniform_names(count);
        for(unsigned i=0; i<count; ++i)
        {
@@ -326,8 +322,8 @@ void Program::query_uniforms()
                        if(len>3 && !strcmp(name+len-3, "[0]"))
                                name[len-3] = 0;
 
-                       uniforms.push_back(UniformInfo());
-                       UniformInfo &info = uniforms.back();
+                       reflect_data.uniforms.push_back(ReflectData::UniformInfo());
+                       ReflectData::UniformInfo &info = reflect_data.uniforms.back();
                        info.name = name;
                        info.tag = name;
                        info.array_size = size;
@@ -336,22 +332,22 @@ void Program::query_uniforms()
                }
        }
 
-       sort_member(uniforms, &UniformInfo::tag);
+       sort_member(reflect_data.uniforms, &ReflectData::UniformInfo::tag);
 
        if(ARB_uniform_buffer_object)
        {
-               vector<UniformInfo *> uniforms_by_index(count);
+               vector<ReflectData::UniformInfo *> uniforms_by_index(count);
                for(unsigned i=0; i<count; ++i)
                        if(!uniform_names[i].empty())
                                // The element is already known to be present
-                               uniforms_by_index[i] = &*lower_bound_member(uniforms, Tag(uniform_names[i]), &UniformInfo::tag);
+                               uniforms_by_index[i] = &*lower_bound_member(reflect_data.uniforms, Tag(uniform_names[i]), &ReflectData::UniformInfo::tag);
                query_uniform_blocks(uniforms_by_index);
        }
 
-       uniform_blocks.push_back(UniformBlockInfo());
-       UniformBlockInfo &default_block = uniform_blocks.back();
+       reflect_data.uniform_blocks.push_back(ReflectData::UniformBlockInfo());
+       ReflectData::UniformBlockInfo &default_block = reflect_data.uniform_blocks.back();
 
-       for(UniformInfo &u: uniforms)
+       for(ReflectData::UniformInfo &u: reflect_data.uniforms)
                if(!u.block)
                {
                        u.location = glGetUniformLocation(id, u.name.c_str());
@@ -362,24 +358,23 @@ void Program::query_uniforms()
                                glGetUniformiv(id, u.location, &u.binding);
                }
 
-       default_block.layout_hash = compute_layout_hash(default_block.uniforms);
-
-       update_layout_hash();
+       default_block.update_layout_hash();
+       reflect_data.update_layout_hash();
 }
 
-void Program::query_uniform_blocks(const vector<UniformInfo *> &uniforms_by_index)
+void Program::query_uniform_blocks(const vector<ReflectData::UniformInfo *> &uniforms_by_index)
 {
        unsigned count = 0;
        glGetProgramiv(id, GL_ACTIVE_UNIFORM_BLOCKS, reinterpret_cast<int *>(&count));
        // Reserve an extra index for the default block
-       uniform_blocks.reserve(count+1);
+       reflect_data.uniform_blocks.reserve(count+1);
        for(unsigned i=0; i<count; ++i)
        {
                char name[128];
                int len;
                glGetActiveUniformBlockName(id, i, sizeof(name), &len, name);
-               uniform_blocks.push_back(UniformBlockInfo());
-               UniformBlockInfo &info = uniform_blocks.back();
+               reflect_data.uniform_blocks.push_back(ReflectData::UniformBlockInfo());
+               ReflectData::UniformBlockInfo &info = reflect_data.uniform_blocks.back();
                info.name = name;
 
                int value;
@@ -431,8 +426,8 @@ void Program::query_uniform_blocks(const vector<UniformInfo *> &uniforms_by_inde
                                uniforms_by_index[query_indices[j]]->matrix_stride = values[j];
                }
 
-               sort(info.uniforms, uniform_location_compare);
-               info.layout_hash = compute_layout_hash(info.uniforms);
+               info.sort_uniforms();
+               info.update_layout_hash();
        }
 }
 
@@ -440,7 +435,7 @@ void Program::query_attributes()
 {
        unsigned count = 0;
        glGetProgramiv(id, GL_ACTIVE_ATTRIBUTES, reinterpret_cast<int *>(&count));
-       attributes.reserve(count);
+       reflect_data.attributes.reserve(count);
        for(unsigned i=0; i<count; ++i)
        {
                char name[128];
@@ -453,8 +448,8 @@ void Program::query_attributes()
                        if(len>3 && !strcmp(name+len-3, "[0]"))
                                name[len-3] = 0;
 
-                       attributes.push_back(AttributeInfo());
-                       AttributeInfo &info = attributes.back();
+                       reflect_data.attributes.push_back(ReflectData::AttributeInfo());
+                       ReflectData::AttributeInfo &info = reflect_data.attributes.back();
                        info.name = name;
                        info.location = glGetAttribLocation(id, name);
                        info.array_size = size;
@@ -468,15 +463,15 @@ void Program::collect_uniforms()
        const SpirVModule &mod = static_cast<const SpirVModule &>(*module);
 
        // Prepare the default block
-       uniform_blocks.push_back(UniformBlockInfo());
+       reflect_data.uniform_blocks.push_back(ReflectData::UniformBlockInfo());
        vector<vector<string> > block_uniform_names(1);
 
        for(const SpirVModule::Variable &v: mod.get_variables())
        {
                if(v.storage==SpirVModule::UNIFORM && v.struct_type)
                {
-                       uniform_blocks.push_back(UniformBlockInfo());
-                       UniformBlockInfo &info = uniform_blocks.back();
+                       reflect_data.uniform_blocks.push_back(ReflectData::UniformBlockInfo());
+                       ReflectData::UniformBlockInfo &info = reflect_data.uniform_blocks.back();
                        info.name = v.struct_type->name;
                        info.bind_point = v.binding;
                        info.data_size = v.struct_type->size;
@@ -490,8 +485,8 @@ void Program::collect_uniforms()
                else if(v.storage==SpirVModule::UNIFORM_CONSTANT && v.location>=0)
                {
                        block_uniform_names[0].push_back(v.name);
-                       uniforms.push_back(UniformInfo());
-                       UniformInfo &info = uniforms.back();
+                       reflect_data.uniforms.push_back(ReflectData::UniformInfo());
+                       ReflectData::UniformInfo &info = reflect_data.uniforms.back();
                        info.name = v.name;
                        info.tag = v.name;
                        info.location = v.location;
@@ -501,23 +496,23 @@ void Program::collect_uniforms()
                }
        }
 
-       sort_member(uniforms, &UniformInfo::tag);
+       sort_member(reflect_data.uniforms, &ReflectData::UniformInfo::tag);
 
-       for(unsigned i=0; i<uniform_blocks.size(); ++i)
+       for(unsigned i=0; i<reflect_data.uniform_blocks.size(); ++i)
        {
-               UniformBlockInfo &block = uniform_blocks[i];
+               ReflectData::UniformBlockInfo &block = reflect_data.uniform_blocks[i];
                for(const string &n: block_uniform_names[i])
                {
                        // The element is already known to be present
-                       UniformInfo &uni = *lower_bound_member(uniforms, Tag(n), &UniformInfo::tag);
+                       ReflectData::UniformInfo &uni = *lower_bound_member(reflect_data.uniforms, Tag(n), &ReflectData::UniformInfo::tag);
                        block.uniforms.push_back(&uni);
                        uni.block = &block;
                }
-               sort(block.uniforms, uniform_location_compare);
-               block.layout_hash = compute_layout_hash(block.uniforms);
+               block.sort_uniforms();
+               block.update_layout_hash();
        }
 
-       update_layout_hash();
+       reflect_data.update_layout_hash();
 }
 
 void Program::collect_block_uniforms(const SpirVModule::Structure &strct, const string &prefix, unsigned base_offset, vector<string> &uniform_names)
@@ -551,8 +546,8 @@ void Program::collect_block_uniforms(const SpirVModule::Structure &strct, const
                {
                        string name = prefix+m.name;
                        uniform_names.push_back(name);
-                       uniforms.push_back(UniformInfo());
-                       UniformInfo &info = uniforms.back();
+                       reflect_data.uniforms.push_back(ReflectData::UniformInfo());
+                       ReflectData::UniformInfo &info = reflect_data.uniforms.back();
                        info.name = name;
                        info.tag = name;
                        info.offset = offset;
@@ -574,8 +569,8 @@ void Program::collect_attributes()
                        for(const SpirVModule::Variable *v: e.globals)
                                if(v->storage==SpirVModule::INPUT)
                                {
-                                       attributes.push_back(AttributeInfo());
-                                       AttributeInfo &info = attributes.back();
+                                       reflect_data.attributes.push_back(ReflectData::AttributeInfo());
+                                       ReflectData::AttributeInfo &info = reflect_data.attributes.back();
                                        info.name = v->name;
                                        info.location = v->location;
                                        info.array_size = v->array_size;
@@ -584,47 +579,26 @@ void Program::collect_attributes()
                }
 }
 
-void Program::update_layout_hash()
-{
-       string layout_descriptor;
-       for(const UniformBlockInfo &b: uniform_blocks)
-               layout_descriptor += format("%d:%x\n", b.bind_point, b.layout_hash);
-       uniform_layout_hash = hash32(layout_descriptor);
-}
-
-Program::LayoutHash Program::compute_layout_hash(const vector<const UniformInfo *> &uniforms)
-{
-       string layout_descriptor;
-       for(const UniformInfo *u: uniforms)
-               layout_descriptor += format("%d:%s:%x:%d\n", u->location, u->name, u->type, u->array_size);
-       return hash32(layout_descriptor);
-}
-
-bool Program::uniform_location_compare(const UniformInfo *uni1, const UniformInfo *uni2)
-{
-       return uni1->location<uni2->location;
-}
-
-const Program::UniformBlockInfo &Program::get_uniform_block_info(const string &name) const
+const ReflectData::UniformBlockInfo &Program::get_uniform_block_info(const string &name) const
 {
-       auto i = find_member(uniform_blocks, name, &UniformBlockInfo::name);
-       if(i==uniform_blocks.end())
+       auto i = find_member(reflect_data.uniform_blocks, name, &ReflectData::UniformBlockInfo::name);
+       if(i==reflect_data.uniform_blocks.end())
                throw key_error(name);
        return *i;
 }
 
-const Program::UniformInfo &Program::get_uniform_info(const string &name) const
+const ReflectData::UniformInfo &Program::get_uniform_info(const string &name) const
 {
-       auto i = lower_bound_member(uniforms, Tag(name), &UniformInfo::tag);
-       if(i==uniforms.end() || i->name!=name)
+       auto i = lower_bound_member(reflect_data.uniforms, Tag(name), &ReflectData::UniformInfo::tag);
+       if(i==reflect_data.uniforms.end() || i->name!=name)
                throw key_error(name);
        return *i;
 }
 
-const Program::UniformInfo &Program::get_uniform_info(Tag tag) const
+const ReflectData::UniformInfo &Program::get_uniform_info(Tag tag) const
 {
-       auto i = lower_bound_member(uniforms, tag, &UniformInfo::tag);
-       if(i==uniforms.end() || i->tag!=tag)
+       auto i = lower_bound_member(reflect_data.uniforms, tag, &ReflectData::UniformInfo::tag);
+       if(i==reflect_data.uniforms.end() || i->tag!=tag)
                throw key_error(tag);
        return *i;
 }
@@ -634,26 +608,26 @@ int Program::get_uniform_location(const string &name) const
        if(name[name.size()-1]==']')
                throw invalid_argument("Program::get_uniform_location");
 
-       auto i = lower_bound_member(uniforms, Tag(name), &UniformInfo::tag);
-       return i!=uniforms.end() && i->name==name && i->block->bind_point<0 ? i->location : -1;
+       auto i = lower_bound_member(reflect_data.uniforms, Tag(name), &ReflectData::UniformInfo::tag);
+       return i!=reflect_data.uniforms.end() && i->name==name && i->block->bind_point<0 ? i->location : -1;
 }
 
 int Program::get_uniform_location(Tag tag) const
 {
-       auto i = lower_bound_member(uniforms, tag, &UniformInfo::tag);
-       return i!=uniforms.end() && i->tag==tag && i->block->bind_point<0 ? i->location : -1;
+       auto i = lower_bound_member(reflect_data.uniforms, tag, &ReflectData::UniformInfo::tag);
+       return i!=reflect_data.uniforms.end() && i->tag==tag && i->block->bind_point<0 ? i->location : -1;
 }
 
 int Program::get_uniform_binding(Tag tag) const
 {
-       auto i = lower_bound_member(uniforms, tag, &UniformInfo::tag);
-       return i!=uniforms.end() && i->tag==tag ? i->binding : -1;
+       auto i = lower_bound_member(reflect_data.uniforms, tag, &ReflectData::UniformInfo::tag);
+       return i!=reflect_data.uniforms.end() && i->tag==tag ? i->binding : -1;
 }
 
-const Program::AttributeInfo &Program::get_attribute_info(const string &name) const
+const ReflectData::AttributeInfo &Program::get_attribute_info(const string &name) const
 {
-       auto i = lower_bound_member(attributes, name, &AttributeInfo::name);
-       if(i==attributes.end() || i->name!=name)
+       auto i = lower_bound_member(reflect_data.attributes, name, &ReflectData::AttributeInfo::name);
+       if(i==reflect_data.attributes.end() || i->name!=name)
                throw key_error(name);
        return *i;
 }
@@ -663,8 +637,8 @@ int Program::get_attribute_location(const string &name) const
        if(name[name.size()-1]==']')
                throw invalid_argument("Program::get_attribute_location");
 
-       auto i = lower_bound_member(attributes, name, &AttributeInfo::name);
-       return i!=attributes.end() && i->name==name ? i->location : -1;
+       auto i = lower_bound_member(reflect_data.attributes, name, &ReflectData::AttributeInfo::name);
+       return i!=reflect_data.attributes.end() && i->name==name ? i->location : -1;
 }
 
 void Program::set_debug_name(const string &name)
@@ -695,31 +669,6 @@ void Program::set_stage_debug_name(unsigned stage_id, Stage type)
 }
 
 
-Program::UniformInfo::UniformInfo():
-       block(0),
-       location(-1),
-       array_size(0),
-       array_stride(0),
-       matrix_stride(0),
-       type(VOID),
-       binding(-1)
-{ }
-
-
-Program::UniformBlockInfo::UniformBlockInfo():
-       data_size(0),
-       bind_point(-1),
-       layout_hash(0)
-{ }
-
-
-Program::AttributeInfo::AttributeInfo():
-       location(-1),
-       array_size(0),
-       type(VOID)
-{ }
-
-
 Program::Loader::Loader(Program &p, Collection &c):
        DataFile::CollectionObjectLoader<Program>(p, &c)
 {
index 1ca146f1e998c0fd0d05221a4dab0b66a6da31e6..b7f46ee4082a74a17ff68aa24328b6c5c01cf9f5 100644 (file)
@@ -4,10 +4,9 @@
 #include <string>
 #include <vector>
 #include <msp/datafile/objectloader.h>
-#include "datatype.h"
 #include "gl.h"
 #include "module.h"
-#include "tag.h"
+#include "reflectdata.h"
 #include "vertexformat.h"
 
 namespace Msp {
@@ -51,51 +50,6 @@ private:
                void specialize_int(const std::string &, int);
        };
 
-public:
-       typedef unsigned LayoutHash;
-       struct UniformBlockInfo;
-
-       struct UniformInfo
-       {
-               std::string name;
-               const UniformBlockInfo *block;
-               union
-               {
-                       int location;
-                       unsigned offset;
-               };
-               unsigned array_size;
-               unsigned array_stride;
-               unsigned matrix_stride;
-               DataType type;
-               Tag tag;
-               int binding;
-
-               UniformInfo();
-       };
-
-       struct UniformBlockInfo
-       {
-               std::string name;
-               unsigned data_size;
-               int bind_point;
-               std::vector<const UniformInfo *> uniforms;
-               LayoutHash layout_hash;
-
-               UniformBlockInfo();
-       };
-
-       struct AttributeInfo
-       {
-               std::string name;
-               unsigned location;
-               unsigned array_size;
-               DataType type;
-
-               AttributeInfo();
-       };
-
-private:
        enum Stage
        {
                VERTEX,
@@ -116,10 +70,7 @@ private:
        const Module *module;
        TransientData *transient;
        bool linked;
-       std::vector<UniformBlockInfo> uniform_blocks;
-       std::vector<UniformInfo> uniforms;
-       LayoutHash uniform_layout_hash;
-       std::vector<AttributeInfo> attributes;
+       ReflectData reflect_data;
        std::string debug_name;
 
 public:
@@ -146,28 +97,26 @@ public:
        void link();
 private:
        void query_uniforms();
-       void query_uniform_blocks(const std::vector<UniformInfo *> &);
+       void query_uniform_blocks(const std::vector<ReflectData::UniformInfo *> &);
        void query_attributes();
        void collect_uniforms();
        void collect_block_uniforms(const SpirVModule::Structure &, const std::string &, unsigned, std::vector<std::string> &);
        void collect_attributes();
-       void update_layout_hash();
-       static LayoutHash compute_layout_hash(const std::vector<const UniformInfo *> &);
-       static bool uniform_location_compare(const UniformInfo *, const UniformInfo *);
+
 public:
        bool is_linked() const { return linked; }
 
-       LayoutHash get_uniform_layout_hash() const { return uniform_layout_hash; }
-       const std::vector<UniformBlockInfo> &get_uniform_blocks() const { return uniform_blocks; }
-       const UniformBlockInfo &get_uniform_block_info(const std::string &) const;
-       const std::vector<UniformInfo> &get_uniforms() const { return uniforms; }
-       const UniformInfo &get_uniform_info(const std::string &) const;
-       const UniformInfo &get_uniform_info(Tag) const;
+       ReflectData::LayoutHash get_uniform_layout_hash() const { return reflect_data.layout_hash; }
+       const std::vector<ReflectData::UniformBlockInfo> &get_uniform_blocks() const { return reflect_data.uniform_blocks; }
+       const ReflectData::UniformBlockInfo &get_uniform_block_info(const std::string &) const;
+       const std::vector<ReflectData::UniformInfo> &get_uniforms() const { return reflect_data.uniforms; }
+       const ReflectData::UniformInfo &get_uniform_info(const std::string &) const;
+       const ReflectData::UniformInfo &get_uniform_info(Tag) const;
        int get_uniform_location(const std::string &) const;
        int get_uniform_location(Tag) const;
        int get_uniform_binding(Tag) const;
-       const std::vector<AttributeInfo> &get_attributes() const { return attributes; }
-       const AttributeInfo &get_attribute_info(const std::string &) const;
+       const std::vector<ReflectData::AttributeInfo> &get_attributes() const { return reflect_data.attributes; }
+       const ReflectData::AttributeInfo &get_attribute_info(const std::string &) const;
        int get_attribute_location(const std::string &) const;
 
        void set_debug_name(const std::string &);
diff --git a/source/core/reflectdata.cpp b/source/core/reflectdata.cpp
new file mode 100644 (file)
index 0000000..7a141db
--- /dev/null
@@ -0,0 +1,58 @@
+#include <msp/core/algorithm.h>
+#include <msp/core/hash.h>
+#include <msp/strings/format.h>
+#include "reflectdata.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+void ReflectData::update_layout_hash()
+{
+       string layout_descriptor;
+       for(const UniformBlockInfo &b: uniform_blocks)
+               layout_descriptor += format("%d:%x\n", b.bind_point, b.layout_hash);
+       layout_hash = hash32(layout_descriptor);
+}
+
+
+ReflectData::UniformInfo::UniformInfo():
+       block(0),
+       location(-1),
+       array_size(0),
+       array_stride(0),
+       matrix_stride(0),
+       type(VOID),
+       binding(-1)
+{ }
+
+
+ReflectData::UniformBlockInfo::UniformBlockInfo():
+       data_size(0),
+       bind_point(-1),
+       layout_hash(0)
+{ }
+
+void ReflectData::UniformBlockInfo::sort_uniforms()
+{
+       sort(uniforms, [](const UniformInfo *u1, const UniformInfo *u2){ return u1->location<u2->location; });
+}
+
+void ReflectData::UniformBlockInfo::update_layout_hash()
+{
+       string layout_descriptor;
+       for(const UniformInfo *u: uniforms)
+               layout_descriptor += format("%d:%s:%x:%d\n", u->location, u->name, u->type, u->array_size);
+       layout_hash = hash32(layout_descriptor);
+}
+
+
+ReflectData::AttributeInfo::AttributeInfo():
+       location(-1),
+       array_size(0),
+       type(VOID)
+{ }
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/core/reflectdata.h b/source/core/reflectdata.h
new file mode 100644 (file)
index 0000000..90b7ce0
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef MSP_GL_REFLECTDATA_H_
+#define MSP_GL_REFLECTDATA_H_
+
+#include <string>
+#include <vector>
+#include "datatype.h"
+#include "tag.h"
+
+namespace Msp {
+namespace GL {
+
+/**
+Reflection data for shader programs.
+*/
+struct ReflectData
+{
+       typedef unsigned LayoutHash;
+       struct UniformBlockInfo;
+
+       struct UniformInfo
+       {
+               std::string name;
+               const UniformBlockInfo *block;
+               union
+               {
+                       int location;
+                       unsigned offset;
+               };
+               unsigned array_size;
+               unsigned array_stride;
+               unsigned matrix_stride;
+               DataType type;
+               Tag tag;
+               int binding;
+
+               UniformInfo();
+       };
+
+       struct UniformBlockInfo
+       {
+               std::string name;
+               unsigned data_size;
+               int bind_point;
+               std::vector<const UniformInfo *> uniforms;
+               LayoutHash layout_hash;
+
+               UniformBlockInfo();
+
+               void sort_uniforms();
+               void update_layout_hash();
+       };
+
+       struct AttributeInfo
+       {
+               std::string name;
+               unsigned location;
+               unsigned array_size;
+               DataType type;
+
+               AttributeInfo();
+       };
+
+       std::vector<UniformBlockInfo> uniform_blocks;
+       std::vector<UniformInfo> uniforms;
+       LayoutHash layout_hash;
+       std::vector<AttributeInfo> attributes;
+
+       void update_layout_hash();
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
index bc78bab8c1c891ad55086397f2bbcc9250d949a4..e12f65216c82b0bf572930c7cc33e4626d4a40ea 100644 (file)
@@ -2,7 +2,7 @@
 #define MSP_GL_UNIFORM_H_
 
 #include <algorithm>
-#include "program.h"
+#include "reflectdata.h"
 
 namespace Msp {
 namespace GL {
@@ -18,7 +18,7 @@ public:
        virtual ~Uniform() { }
 
        virtual void apply(int) const = 0;
-       virtual void store(const Program::UniformInfo &, void *) const = 0;
+       virtual void store(const ReflectData::UniformInfo &, void *) const = 0;
        virtual Uniform *clone() const = 0;
 };
 
@@ -45,10 +45,10 @@ public:
 
        static void apply(int, unsigned, const T *);
 
-       virtual void store(const Program::UniformInfo &info, void *buffer) const
+       virtual void store(const ReflectData::UniformInfo &info, void *buffer) const
        { store(info, buffer, &value); }
 
-       static void store(const Program::UniformInfo &, void *buffer, const T *value)
+       static void store(const ReflectData::UniformInfo &, void *buffer, const T *value)
        { *reinterpret_cast<T *>(buffer) = *value; }
 
        virtual UniformScalar *clone() const
@@ -82,10 +82,10 @@ public:
 
        static void apply(int index, unsigned size, const T *value);
 
-       virtual void store(const Program::UniformInfo &info, void *buffer) const
+       virtual void store(const ReflectData::UniformInfo &info, void *buffer) const
        { store(info, buffer, value); }
 
-       static void store(const Program::UniformInfo &, void *buffer, const T *value)
+       static void store(const ReflectData::UniformInfo &, void *buffer, const T *value)
        { std::copy(value, value+vecsize, reinterpret_cast<T *>(buffer)); }
 
        virtual UniformVector *clone() const
@@ -121,10 +121,10 @@ public:
 
        static void apply(int index, unsigned size, const T *value);
 
-       virtual void store(const Program::UniformInfo &info, void *buffer) const
+       virtual void store(const ReflectData::UniformInfo &info, void *buffer) const
        { store(info, buffer, value); }
 
-       static void store(const Program::UniformInfo &info, void *buffer, const T *value)
+       static void store(const ReflectData::UniformInfo &info, void *buffer, const T *value)
        {
                for(unsigned i=0; i<cols; ++i)
                        UniformVector<T, rows>::store(info, reinterpret_cast<char *>(buffer)+i*info.matrix_stride, value+i*rows);
@@ -177,7 +177,7 @@ public:
        virtual void apply(int index) const
        { T::apply(index, size_, values); }
 
-       virtual void store(const Program::UniformInfo &info, void *buffer) const
+       virtual void store(const ReflectData::UniformInfo &info, void *buffer) const
        {
                for(unsigned i=0; i<size_; ++i)
                        T::store(info, reinterpret_cast<char *>(buffer)+i*info.array_stride, values+i*elemsize);
index af4016ee5da8b32ad926689e0c211a3b0dbc4042..4b07241fab3943d14f35932ea498024bdc5ad2d2 100644 (file)
@@ -20,7 +20,7 @@ DefaultUniformBlock::DefaultUniformBlock()
        static Require _req(ARB_shader_objects);
 }
 
-void DefaultUniformBlock::attach(const Program::UniformInfo &info, const Uniform &uni)
+void DefaultUniformBlock::attach(const ReflectData::UniformInfo &info, const Uniform &uni)
 {
        if(info.block->bind_point>=0)
                throw invalid_argument("DefaultUniformBlock::attach");
@@ -62,7 +62,7 @@ unsigned BufferBackedUniformBlock::get_alignment() const
        return Limits::get_global().uniform_buffer_alignment;
 }
 
-void BufferBackedUniformBlock::attach(const Program::UniformInfo &info, const Uniform &uni)
+void BufferBackedUniformBlock::attach(const ReflectData::UniformInfo &info, const Uniform &uni)
 {
        if(info.block->bind_point<0)
                throw invalid_argument("BufferBackedUniformBlock::attach");
index 18b651c7b4e498c12f2bdccba4c190dbe5c30663..08eaa9b857e3dcbc1c8de08e7a129433dbc6b0ee 100644 (file)
@@ -3,8 +3,9 @@
 
 #include <map>
 #include <vector>
+#include <msp/core/noncopyable.h>
 #include "bufferable.h"
-#include "program.h"
+#include "reflectdata.h"
 #include "vector.h"
 
 namespace Msp {
@@ -26,7 +27,7 @@ protected:
 public:
        virtual ~UniformBlock() { }
 
-       virtual void attach(const Program::UniformInfo &, const Uniform &) = 0;
+       virtual void attach(const ReflectData::UniformInfo &, const Uniform &) = 0;
 };
 
 /** Stores uniforms for the default uniform block.  Uniforms are associated
@@ -39,7 +40,7 @@ private:
 public:
        DefaultUniformBlock();
 
-       virtual void attach(const Program::UniformInfo &, const Uniform &);
+       virtual void attach(const ReflectData::UniformInfo &, const Uniform &);
        void attach(int, const Uniform &);
        void apply() const;
 };
@@ -62,7 +63,7 @@ private:
        virtual unsigned get_alignment() const;
 
 public:
-       void attach(const Program::UniformInfo &, const Uniform &);
+       void attach(const ReflectData::UniformInfo &, const Uniform &);
 };
 
 } // namespace GL
index 0cd1d4b99e3821f0c28b0b06c72328c93a28cbac..2291a2023471ca4c960b1dd922bbff6896b0aa98 100644 (file)
@@ -1,5 +1,6 @@
 #include <algorithm>
 #include <cmath>
+#include <msp/strings/format.h>
 #include "environmentmap.h"
 #include "mesh.h"
 #include "renderer.h"
index 721d5cdca8593a131e0a82070648a7dc6c3082fa..4c22ba3c01e70b01d68852f31f411799fce2f91f 100644 (file)
@@ -1,7 +1,9 @@
 #include <stdexcept>
 #include <cmath>
 #include <msp/core/algorithm.h>
+#include <msp/datafile/collection.h>
 #include <msp/fs/utils.h>
+#include <msp/strings/format.h>
 #include "error.h"
 #include "light.h"
 #include "lighting.h"
index d03a72a53eaca89a5debb1ccace6a6054c80e504..328d89a462ccd4db069499ab45ed5fe2d98d7c35 100644 (file)
@@ -3,6 +3,7 @@
 #include "basicmaterial.h"
 #include "gl.h"
 #include "pbrmaterial.h"
+#include "program.h"
 #include "resources.h"
 #include "uniform.h"
 #include "unlitmaterial.h"
index f144a5dd5230927f683d3c0e781d8fb0a0fe799f..43d5803e7f1d0a799880ff99a9d8af7375cec1df 100644 (file)
@@ -98,8 +98,8 @@ void RenderPass::set_texture(unsigned index, const Texture *tex, const Sampler *
        if(!shprog)
                throw invalid_operation("RenderPass::set_texture");
 
-       const vector<Program::UniformInfo> &uniforms = shprog->get_uniforms();
-       for(const Program::UniformInfo &u: uniforms)
+       const vector<ReflectData::UniformInfo> &uniforms = shprog->get_uniforms();
+       for(const ReflectData::UniformInfo &u: uniforms)
                if(is_image(u.type) && u.binding==static_cast<int>(index))
                        return set_texture(u.tag, tex, samp);
 
@@ -107,7 +107,7 @@ void RenderPass::set_texture(unsigned index, const Texture *tex, const Sampler *
        {
                for(Tag t: shdata->get_uniform_tags())
                {
-                       auto j = find_member(uniforms, t, &Program::UniformInfo::tag);
+                       auto j = find_member(uniforms, t, &ReflectData::UniformInfo::tag);
                        if(j==uniforms.end() || !is_image(j->type))
                                continue;
                        if(const Uniform1i *uni1i = dynamic_cast<const Uniform1i *>(shdata->find_uniform(t)))
@@ -252,7 +252,7 @@ void RenderPass::Loader::texunit(unsigned)
        string name;
        if(obj.shprog)
        {
-               for(const Program::UniformInfo &u: obj.shprog->get_uniforms())
+               for(const ReflectData::UniformInfo &u: obj.shprog->get_uniforms())
                        if(is_image(u.type) && u.binding>=0)
                        {
                                if(!name.empty())
index a53a988105d410a3fd3d58be119876b43a58f040..be3f17d4bc24cd6e2cd3d612321448a7302caf02 100644 (file)
@@ -10,6 +10,7 @@
 #include "mesh.h"
 #include "object.h"
 #include "objectinstance.h"
+#include "program.h"
 #include "renderer.h"
 #include "technique.h"
 #include "vertexsetup.h"
index 1ef013ddac86e5a6be72643fe711764f01428d30..65934d382ae29fad792c0b67031a406658b7b3fb 100644 (file)
@@ -159,7 +159,7 @@ bool ProgramData::validate_tag(Tag tag) const
        {
                if(tied_program)
                {
-                       const Program::UniformInfo &info = tied_program->get_uniform_info(tag);
+                       const ReflectData::UniformInfo &info = tied_program->get_uniform_info(tag);
                        if(is_image(info.type))
                                throw invalid_operation("ProgramData::uniform");
                }
@@ -473,25 +473,25 @@ int ProgramData::find_uniform_index(Tag tag) const
 
 vector<ProgramData::ProgramBlock>::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<Program::UniformBlockInfo> &block_infos = prog.get_uniform_blocks();
+       const vector<ReflectData::UniformBlockInfo> &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<Program::LayoutHash> block_hashes;
+       vector<ReflectData::LayoutHash> 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<block_infos.size(); ++j)
        {
-               const Program::UniformBlockInfo &info = block_infos[j];
+               const ReflectData::UniformBlockInfo &info = block_infos[j];
                block_hashes[index+1+j] = info.layout_hash;
                programs[index+1+j].bind_point = info.bind_point;
 
@@ -519,7 +519,7 @@ vector<ProgramData::ProgramBlock>::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)
@@ -586,7 +586,7 @@ void ProgramData::update_block_uniform_indices(SharedBlock &block, const Program
        }
 }
 
-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; i<info.uniforms.size(); ++i)
@@ -620,7 +620,7 @@ vector<ProgramData::ProgramBlock>::const_iterator ProgramData::prepare_program(c
                        dirty = 0;
                }
 
-               const vector<Program::UniformBlockInfo> &block_infos = prog.get_uniform_blocks();
+               const vector<ReflectData::UniformBlockInfo> &block_infos = prog.get_uniform_blocks();
 
                if(prog_begin->masks.dirty==ALL_ONES)
                {
@@ -628,7 +628,7 @@ vector<ProgramData::ProgramBlock>::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 +642,7 @@ vector<ProgramData::ProgramBlock>::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,7 +684,7 @@ vector<ProgramData::ProgramBlock>::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)
                {
@@ -725,7 +725,7 @@ void ProgramData::TaggedUniform::replace_value(Uniform *v)
 }
 
 
-ProgramData::SharedBlock::SharedBlock(Program::LayoutHash h):
+ProgramData::SharedBlock::SharedBlock(ReflectData::LayoutHash h):
        block_hash(h),
        used(0),
        dirty(0),
@@ -740,7 +740,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)
index 1bcd3aab42c6ea2158f5beb0fbdcaab8f200720e..380f352a66376b6b168805bea5f6c46f4ee0cae5 100644 (file)
@@ -6,7 +6,7 @@
 #include <msp/datafile/objectloader.h>
 #include "datatype.h"
 #include "matrix.h"
-#include "program.h"
+#include "reflectdata.h"
 #include "tag.h"
 #include "uniform.h"
 #include "vector.h"
@@ -24,6 +24,7 @@ public:
 class Buffer;
 class BufferBackedUniformBlock;
 class PipelineState;
+class Program;
 class UniformBlock;
 struct Color;
 
@@ -112,7 +113,7 @@ private:
 
        struct SharedBlock
        {
-               Program::LayoutHash block_hash;
+               ReflectData::LayoutHash block_hash;
                Mask used;
                Mask dirty;
                UniformBlock *block;
@@ -127,14 +128,14 @@ private:
                        } dynamic;
                } indices;
 
-               SharedBlock(Program::LayoutHash);
+               SharedBlock(ReflectData::LayoutHash);
 
                const std::uint8_t *get_uniform_indices() const;
        };
 
        struct ProgramBlock
        {
-               Program::LayoutHash prog_hash;
+               ReflectData::LayoutHash prog_hash;
                int bind_point;
                int block_index;
                union
@@ -147,7 +148,7 @@ private:
                        } masks;
                };
 
-               ProgramBlock(Program::LayoutHash);
+               ProgramBlock(ReflectData::LayoutHash);
        };
 
        // XXX All these mutables are a bit silly, but I'm out of better ideas
@@ -247,8 +248,8 @@ public:
 private:
        int find_uniform_index(Tag) const;
        std::vector<ProgramBlock>::iterator get_program(const Program &) const;
-       void update_block_uniform_indices(SharedBlock &, const Program::UniformBlockInfo &) const;
-       void update_block(SharedBlock &, const Program::UniformBlockInfo &) const;
+       void update_block_uniform_indices(SharedBlock &, const ReflectData::UniformBlockInfo &) const;
+       void update_block(SharedBlock &, const ReflectData::UniformBlockInfo &) const;
 
        std::vector<ProgramBlock>::const_iterator prepare_program(const Program &) const;
 public:
index 5a3afa452e2e9235ade6e0cfc6558073672fa23e..ef96a9e7cb8adf8dfff2cfdf17f52127ac015dc5 100644 (file)
@@ -1,4 +1,5 @@
 #include <msp/core/maputils.h>
+#include <msp/strings/format.h>
 #include "blend.h"
 #include "error.h"
 #include "framebuffer.h"