This is necessary for splitting the API-specific code.
#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>
#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"
if(!has_stages())
throw invalid_operation("Program::link");
- uniforms.clear();
- uniform_blocks.clear();
- attributes.clear();
+ reflect_data = ReflectData();
glLinkProgram(id);
int status = 0;
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;
}
}
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);
}
{
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)
{
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;
}
}
- 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());
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;
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();
}
}
{
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];
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;
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;
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;
}
}
- 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 = █
}
- 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)
{
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;
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;
}
}
-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;
}
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;
}
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)
}
-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)
{
#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 {
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,
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:
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 &);
--- /dev/null
+#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
--- /dev/null
+#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
#define MSP_GL_UNIFORM_H_
#include <algorithm>
-#include "program.h"
+#include "reflectdata.h"
namespace Msp {
namespace GL {
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;
};
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
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
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);
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);
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");
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");
#include <map>
#include <vector>
+#include <msp/core/noncopyable.h>
#include "bufferable.h"
-#include "program.h"
+#include "reflectdata.h"
#include "vector.h"
namespace Msp {
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
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;
};
virtual unsigned get_alignment() const;
public:
- void attach(const Program::UniformInfo &, const Uniform &);
+ void attach(const ReflectData::UniformInfo &, const Uniform &);
};
} // namespace GL
#include <algorithm>
#include <cmath>
+#include <msp/strings/format.h>
#include "environmentmap.h"
#include "mesh.h"
#include "renderer.h"
#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"
#include "basicmaterial.h"
#include "gl.h"
#include "pbrmaterial.h"
+#include "program.h"
#include "resources.h"
#include "uniform.h"
#include "unlitmaterial.h"
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);
{
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)))
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())
#include "mesh.h"
#include "object.h"
#include "objectinstance.h"
+#include "program.h"
#include "renderer.h"
#include "technique.h"
#include "vertexsetup.h"
{
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");
}
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;
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)
}
}
-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)
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)
{
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)
// 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)
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)
{
}
-ProgramData::SharedBlock::SharedBlock(Program::LayoutHash h):
+ProgramData::SharedBlock::SharedBlock(ReflectData::LayoutHash h):
block_hash(h),
used(0),
dirty(0),
}
-ProgramData::ProgramBlock::ProgramBlock(Program::LayoutHash h):
+ProgramData::ProgramBlock::ProgramBlock(ReflectData::LayoutHash h):
prog_hash(h),
bind_point(-1),
block_index(-1)
#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"
class Buffer;
class BufferBackedUniformBlock;
class PipelineState;
+class Program;
class UniformBlock;
struct Color;
struct SharedBlock
{
- Program::LayoutHash block_hash;
+ ReflectData::LayoutHash block_hash;
Mask used;
Mask dirty;
UniformBlock *block;
} 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
} masks;
};
- ProgramBlock(Program::LayoutHash);
+ ProgramBlock(ReflectData::LayoutHash);
};
// XXX All these mutables are a bit silly, but I'm out of better ideas
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:
#include <msp/core/maputils.h>
+#include <msp/strings/format.h>
#include "blend.h"
#include "error.h"
#include "framebuffer.h"