From 5945ad9b63bbc55c3ed21f0c023d17f73aaac370 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 12 Nov 2016 20:08:24 +0200 Subject: [PATCH] Add a module for builtin interface variables Required to make unused assignment removal work for gl_Position. --- source/programcompiler.cpp | 67 +++++++++++++++++++++++++++++++++++++- source/programcompiler.h | 6 ++++ source/programparser.cpp | 11 ++++++- source/programsyntax.cpp | 3 +- source/programsyntax.h | 2 ++ 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index 096a5d84..541fd8e2 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -8,6 +8,26 @@ using namespace std; +namespace { + +const char builtins_src[] = + "////// vertex\n" + "out gl_PerVertex {\n" + " vec4 gl_Position;\n" + " float gl_ClipDistance[];\n" + "};" + "////// geometry\n" + "in gl_PerVertex {\n" + " vec4 gl_Position;\n" + " float gl_ClipDistance[];\n" + "} gl_in[];\n" + "out gl_PerVertex {\n" + " vec4 gl_Position;\n" + " float gl_ClipDistance[];\n" + "};\n"; + +} + namespace Msp { namespace GL { @@ -51,6 +71,35 @@ void ProgramCompiler::add_shaders(Program &program) program.bind_attribute(TEXCOORD4, "texcoord"); } +Module *ProgramCompiler::create_builtins_module() +{ + ProgramParser parser; + Module *module = new Module(parser.parse(builtins_src)); + for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) + { + VariableResolver resolver; + i->content.visit(resolver); + for(map::iterator j=i->content.variables.begin(); j!=i->content.variables.end(); ++j) + j->second->linked_declaration = j->second; + } + return module; +} + +Module &ProgramCompiler::get_builtins_module() +{ + static RefPtr builtins_module = create_builtins_module(); + return *builtins_module; +} + +Stage *ProgramCompiler::get_builtins(StageType type) +{ + Module &module = get_builtins_module(); + for(list::iterator i=module.stages.begin(); i!=module.stages.end(); ++i) + if(i->type==type) + return &*i; + return 0; +} + void ProgramCompiler::process() { for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) @@ -242,7 +291,7 @@ void ProgramCompiler::Formatter::visit(VariableDeclaration &var) formatted += "const "; if(!var.sampling.empty()) formatted += format("%s ", var.sampling); - if(!var.interface.empty()) + if(!var.interface.empty() && var.interface!=block_interface) formatted += format("%s ", var.interface); formatted += format("%s %s", var.type, var.name); if(var.array) @@ -263,6 +312,7 @@ void ProgramCompiler::Formatter::visit(VariableDeclaration &var) void ProgramCompiler::Formatter::visit(InterfaceBlock &iface) { + SetForScope set(block_interface, iface.interface); formatted += format("%s %s\n", iface.interface, iface.name); iface.members.visit(*this); formatted += ';'; @@ -333,6 +383,17 @@ ProgramCompiler::VariableResolver::VariableResolver(): anonymous(false) { } +void ProgramCompiler::VariableResolver::apply(Stage &s) +{ + SetForScope set(stage, &s); + Stage *builtins = get_builtins(stage->type); + if(builtins) + blocks.push_back(&builtins->content); + stage->content.visit(*this); + if(builtins) + blocks.pop_back(); +} + void ProgramCompiler::VariableResolver::visit(Block &block) { blocks.push_back(&block); @@ -407,6 +468,9 @@ void ProgramCompiler::VariableResolver::visit(VariableDeclaration &var) var.type_declaration = j->second; } + if(!block_interface.empty() && var.interface.empty()) + var.interface = block_interface; + TraversingVisitor::visit(var); blocks.back()->variables[var.name] = &var; if(anonymous && blocks.size()>1) @@ -416,6 +480,7 @@ void ProgramCompiler::VariableResolver::visit(VariableDeclaration &var) void ProgramCompiler::VariableResolver::visit(InterfaceBlock &iface) { SetFlag set(anonymous); + SetForScope set2(block_interface, iface.interface); TraversingVisitor::visit(iface); } diff --git a/source/programcompiler.h b/source/programcompiler.h index 829f7535..695c2e26 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -28,6 +28,7 @@ private: unsigned indent; bool parameter_list; bool else_if; + std::string block_interface; Formatter(); @@ -55,9 +56,11 @@ private: std::vector blocks; ProgramSyntax::StructDeclaration *type; bool anonymous; + std::string block_interface; VariableResolver(); + virtual void apply(ProgramSyntax::Stage &); virtual void visit(ProgramSyntax::Block &); virtual void visit(ProgramSyntax::VariableReference &); virtual void visit(ProgramSyntax::MemberAccess &); @@ -137,6 +140,9 @@ public: void add_shaders(Program &); private: + static ProgramSyntax::Module *create_builtins_module(); + static ProgramSyntax::Module &get_builtins_module(); + static ProgramSyntax::Stage *get_builtins(ProgramSyntax::StageType); void process(); void generate(ProgramSyntax::Stage &); bool optimize(ProgramSyntax::Stage &); diff --git a/source/programparser.cpp b/source/programparser.cpp index 36cc6e08..11c9a9fe 100644 --- a/source/programparser.cpp +++ b/source/programparser.cpp @@ -650,7 +650,16 @@ InterfaceBlock *ProgramParser::parse_interface_block() iface->name = expect_identifier(); parse_block(iface->members, true); - expect(";"); + if(!check(";")) + { + iface->instance_name = expect_identifier(); + if(check("[")) + { + iface->array = true; + expect("]"); + } + expect(";"); + } return iface.release(); } diff --git a/source/programsyntax.cpp b/source/programsyntax.cpp index 4341f06b..dcd19f2b 100644 --- a/source/programsyntax.cpp +++ b/source/programsyntax.cpp @@ -110,7 +110,8 @@ void VariableDeclaration::visit(NodeVisitor &visitor) } -InterfaceBlock::InterfaceBlock() +InterfaceBlock::InterfaceBlock(): + array(false) { members.use_braces = true; } diff --git a/source/programsyntax.h b/source/programsyntax.h index cbce078e..88f333ac 100644 --- a/source/programsyntax.h +++ b/source/programsyntax.h @@ -204,6 +204,8 @@ struct InterfaceBlock: Node std::string interface; std::string name; Block members; + std::string instance_name; + bool array; InterfaceBlock(); -- 2.45.2