throw invalid_operation("ProgramCompiler::add_shaders");
string head = "#version 150\n";
- if(module->vertex_context.present)
- program.attach_shader_owned(new VertexShader(head+format_context(module->vertex_context)));
- if(module->geometry_context.present)
- program.attach_shader_owned(new GeometryShader(head+format_context(module->geometry_context)));
- if(module->fragment_context.present)
- program.attach_shader_owned(new FragmentShader(head+format_context(module->fragment_context)));
+ if(module->vertex_stage.present)
+ program.attach_shader_owned(new VertexShader(head+format_stage(module->vertex_stage)));
+ if(module->geometry_stage.present)
+ program.attach_shader_owned(new GeometryShader(head+format_stage(module->geometry_stage)));
+ if(module->fragment_stage.present)
+ program.attach_shader_owned(new FragmentShader(head+format_stage(module->fragment_stage)));
program.bind_attribute(VERTEX4, "vertex");
program.bind_attribute(NORMAL3, "normal");
void ProgramCompiler::process()
{
- if(module->vertex_context.present)
- generate(module->vertex_context);
- if(module->geometry_context.present)
- generate(module->geometry_context);
- if(module->fragment_context.present)
- generate(module->fragment_context);
+ if(module->vertex_stage.present)
+ generate(module->vertex_stage);
+ if(module->geometry_stage.present)
+ generate(module->geometry_stage);
+ if(module->fragment_stage.present)
+ generate(module->fragment_stage);
- if(module->vertex_context.present)
- optimize(module->vertex_context);
- if(module->geometry_context.present)
- optimize(module->geometry_context);
- if(module->fragment_context.present)
- optimize(module->fragment_context);
+ if(module->vertex_stage.present)
+ optimize(module->vertex_stage);
+ if(module->geometry_stage.present)
+ optimize(module->geometry_stage);
+ if(module->fragment_stage.present)
+ optimize(module->fragment_stage);
}
-void ProgramCompiler::generate(Context &context)
+void ProgramCompiler::generate(Stage &stage)
{
- inject_block(context.content, module->global_context.content);
+ inject_block(stage.content, module->shared.content);
- resolve_variables(context);
+ resolve_variables(stage);
InterfaceGenerator generator;
- generator.visit(context);
+ generator.visit(stage);
- resolve_variables(context);
+ resolve_variables(stage);
VariableRenamer renamer;
- context.content.visit(renamer);
+ stage.content.visit(renamer);
}
-void ProgramCompiler::optimize(Context &context)
+void ProgramCompiler::optimize(Stage &stage)
{
while(1)
{
UnusedVariableLocator unused_locator;
- unused_locator.visit(context);
+ unused_locator.visit(stage);
NodeRemover remover;
remover.to_remove = unused_locator.unused_nodes;
- remover.visit(context);
+ remover.visit(stage);
if(!remover.n_removed)
break;
target.body.insert(insert_point, (*i)->clone());
}
-void ProgramCompiler::resolve_variables(Context &context)
+void ProgramCompiler::resolve_variables(Stage &stage)
{
VariableResolver resolver;
- context.content.visit(resolver);
+ stage.content.visit(resolver);
}
-string ProgramCompiler::format_context(Context &context)
+string ProgramCompiler::format_stage(Stage &stage)
{
Formatter formatter;
- context.content.visit(formatter);
+ stage.content.visit(formatter);
return formatter.formatted;
}
ProgramCompiler::InterfaceGenerator::InterfaceGenerator():
- context(0),
+ stage(0),
scope_level(0),
remove_node(false)
{ }
-string ProgramCompiler::InterfaceGenerator::get_out_prefix(ContextType type)
+string ProgramCompiler::InterfaceGenerator::get_out_prefix(StageType type)
{
if(type==VERTEX)
return "_vs_out_";
return string();
}
-void ProgramCompiler::InterfaceGenerator::visit(Context &ctx)
+void ProgramCompiler::InterfaceGenerator::visit(Stage &s)
{
- SetForScope<Context *> set(context, &ctx);
- if(context->previous)
- in_prefix = get_out_prefix(context->previous->type);
- out_prefix = get_out_prefix(context->type);
- ctx.content.visit(*this);
+ SetForScope<Stage *> set(stage, &s);
+ if(stage->previous)
+ in_prefix = get_out_prefix(stage->previous->type);
+ out_prefix = get_out_prefix(stage->type);
+ stage->content.visit(*this);
}
void ProgramCompiler::InterfaceGenerator::visit(Block &block)
bool ProgramCompiler::InterfaceGenerator::generate_interface(VariableDeclaration &out, const string &iface, const string &name)
{
- const map<string, VariableDeclaration *> &context_vars = (iface=="in" ? context->in_variables : context->out_variables);
- if(context_vars.count(name) || iface_declarations.count(name))
+ const map<string, VariableDeclaration *> &stage_vars = (iface=="in" ? stage->in_variables : stage->out_variables);
+ if(stage_vars.count(name) || iface_declarations.count(name))
return false;
VariableDeclaration* iface_var = new VariableDeclaration;
iface_var->type = out.type;
iface_var->type_declaration = out.type_declaration;
iface_var->name = name;
- iface_var->array = (out.array || (context->type==GEOMETRY && iface=="in"));
+ iface_var->array = (out.array || (stage->type==GEOMETRY && iface=="in"));
iface_var->array_size = out.array_size;
if(iface=="in")
iface_var->linked_declaration = &out;
void ProgramCompiler::InterfaceGenerator::visit(VariableReference &var)
{
- if(var.declaration || !context->previous)
+ if(var.declaration || !stage->previous)
return;
if(iface_declarations.count(var.name))
return;
- const map<string, VariableDeclaration *> &prev_out = context->previous->out_variables;
+ const map<string, VariableDeclaration *> &prev_out = stage->previous->out_variables;
map<string, VariableDeclaration *>::const_iterator i = prev_out.find(var.name);
if(i==prev_out.end())
i = prev_out.find(in_prefix+var.name);
if(var.interface=="out")
{
if(scope_level==1)
- context->out_variables[var.name] = &var;
+ stage->out_variables[var.name] = &var;
else if(generate_interface(var, "out", change_prefix(var.name, string())))
{
remove_node = true;
}
else if(var.interface=="in")
{
- context->in_variables[var.name] = &var;
+ stage->in_variables[var.name] = &var;
if(var.linked_declaration)
var.linked_declaration->linked_declaration = &var;
- else if(context->previous)
+ else if(stage->previous)
{
- const map<string, VariableDeclaration *> &prev_out = context->previous->out_variables;
+ const map<string, VariableDeclaration *> &prev_out = stage->previous->out_variables;
map<string, VariableDeclaration *>::const_iterator i = prev_out.find(var.name);
if(i!=prev_out.end())
{
void ProgramCompiler::InterfaceGenerator::visit(Passthrough &pass)
{
- if(context->previous)
+ if(stage->previous)
{
- const map<string, VariableDeclaration *> &prev_out = context->previous->out_variables;
+ const map<string, VariableDeclaration *> &prev_out = stage->previous->out_variables;
for(map<string, VariableDeclaration *>::const_iterator i=prev_out.begin(); i!=prev_out.end(); ++i)
{
string out_name = change_prefix(i->second->name, out_prefix);
ProgramCompiler::UnusedVariableLocator::UnusedVariableLocator():
- context(0),
+ stage(0),
assignment(false),
assignment_target(0)
{ }
-void ProgramCompiler::UnusedVariableLocator::visit(Context &ctx)
+void ProgramCompiler::UnusedVariableLocator::visit(Stage &s)
{
- context = &ctx;
- ctx.content.visit(*this);
+ stage = &s;
+ stage->content.visit(*this);
}
void ProgramCompiler::UnusedVariableLocator::visit(VariableReference &var)
TraversingVisitor::visit(expr);
if(assignment && assignment_target)
{
- if(assignment_target->interface!="out" || (context->type!=FRAGMENT && !assignment_target->linked_declaration))
+ if(assignment_target->interface!="out" || (stage->type!=FRAGMENT && !assignment_target->linked_declaration))
{
unused_nodes.insert(&expr);
assignments[assignment_target] = &expr;
ProgramCompiler::NodeRemover::NodeRemover():
- context(0),
+ stage(0),
n_removed(0),
immutable_block(false),
remove_block(false)
{ }
-void ProgramCompiler::NodeRemover::visit(Context &ctx)
+void ProgramCompiler::NodeRemover::visit(Stage &s)
{
- context = &ctx;
- ctx.content.visit(*this);
+ stage = &s;
+ stage->content.visit(*this);
}
void ProgramCompiler::NodeRemover::visit(Block &block)
{
if(to_remove.count(&var))
{
- context->in_variables.erase(var.name);
- context->out_variables.erase(var.name);
+ stage->in_variables.erase(var.name);
+ stage->out_variables.erase(var.name);
if(var.linked_declaration)
var.linked_declaration->linked_declaration = 0;
}
struct InterfaceGenerator: ProgramSyntax::TraversingVisitor
{
- ProgramSyntax::Context *context;
+ ProgramSyntax::Stage *stage;
std::string in_prefix;
std::string out_prefix;
unsigned scope_level;
InterfaceGenerator();
- static std::string get_out_prefix(ProgramSyntax::ContextType);
- void visit(ProgramSyntax::Context &);
+ static std::string get_out_prefix(ProgramSyntax::StageType);
+ void visit(ProgramSyntax::Stage &);
virtual void visit(ProgramSyntax::Block &);
std::string change_prefix(const std::string &, const std::string &) const;
bool generate_interface(ProgramSyntax::VariableDeclaration &, const std::string &, const std::string &);
struct UnusedVariableLocator: ProgramSyntax::TraversingVisitor
{
- ProgramSyntax::Context *context;
+ ProgramSyntax::Stage *stage;
std::set<ProgramSyntax::Node *> unused_nodes;
std::map<ProgramSyntax::VariableDeclaration *, ProgramSyntax::Node *> assignments;
bool assignment;
UnusedVariableLocator();
- void visit(ProgramSyntax::Context &);
+ void visit(ProgramSyntax::Stage &);
virtual void visit(ProgramSyntax::VariableReference &);
virtual void visit(ProgramSyntax::MemberAccess &);
virtual void visit(ProgramSyntax::BinaryExpression &);
struct NodeRemover: ProgramSyntax::TraversingVisitor
{
- ProgramSyntax::Context *context;
+ ProgramSyntax::Stage *stage;
std::set<ProgramSyntax::Node *> to_remove;
unsigned n_removed;
bool immutable_block;
NodeRemover();
- void visit(ProgramSyntax::Context &);
+ void visit(ProgramSyntax::Stage &);
virtual void visit(ProgramSyntax::Block &);
virtual void visit(ProgramSyntax::StructDeclaration &);
virtual void visit(ProgramSyntax::VariableDeclaration &);
private:
void process();
- void generate(ProgramSyntax::Context &);
- void optimize(ProgramSyntax::Context &);
+ void generate(ProgramSyntax::Stage &);
+ void optimize(ProgramSyntax::Stage &);
static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &);
- static void resolve_variables(ProgramSyntax::Context &);
- std::string format_context(ProgramSyntax::Context &);
+ static void resolve_variables(ProgramSyntax::Stage &);
+ std::string format_stage(ProgramSyntax::Stage &);
};
} // namespace GL