X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fprogramcompiler.cpp;h=d021ab4f75732769855e9370fe0c8eec990aca20;hp=518b31e17f0d76213f2de8c52160cb3602f346b5;hb=bec07999d95b76f4b47cffcc564d0cd0afc0435e;hpb=71972b08fd031e177a005eb1924a5c7a15459291 diff --git a/source/programcompiler.cpp b/source/programcompiler.cpp index 518b31e1..d021ab4f 100644 --- a/source/programcompiler.cpp +++ b/source/programcompiler.cpp @@ -4,7 +4,9 @@ #include #include #include +#include #include +#include #include #include "error.h" #include "program.h" @@ -57,7 +59,7 @@ void ProgramCompiler::compile(const string &source, const string &src_name) delete module; module = new Module(); ProgramParser parser; - imported_names.insert(src_name); + imported_names.push_back(src_name); append_module(parser.parse(source, src_name, 1)); process(); } @@ -68,7 +70,7 @@ void ProgramCompiler::compile(IO::Base &io, Resources *res, const string &src_na delete module; module = new Module(); ProgramParser parser; - imported_names.insert(src_name); + imported_names.push_back(src_name); append_module(parser.parse(io, src_name, 1)); process(); } @@ -83,25 +85,64 @@ void ProgramCompiler::add_shaders(Program &program) if(!module) throw invalid_operation("ProgramCompiler::add_shaders"); - for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) + try { - if(i->type==VERTEX) + for(list::iterator i=module->stages.begin(); i!=module->stages.end(); ++i) { - program.attach_shader_owned(new VertexShader(apply(*i))); - for(map::iterator j=i->locations.begin(); j!=i->locations.end(); ++j) - program.bind_attribute(j->second, j->first); + if(i->type==VERTEX) + { + program.attach_shader_owned(new VertexShader(apply(*i))); + for(map::iterator j=i->locations.begin(); j!=i->locations.end(); ++j) + program.bind_attribute(j->second, j->first); + } + else if(i->type==GEOMETRY) + program.attach_shader_owned(new GeometryShader(apply(*i))); + else if(i->type==FRAGMENT) + { + program.attach_shader_owned(new FragmentShader(apply(*i))); + if(EXT_gpu_shader4) + { + for(map::iterator j=i->locations.begin(); j!=i->locations.end(); ++j) + program.bind_fragment_data(j->second, j->first); + } + } } - else if(i->type==GEOMETRY) - program.attach_shader_owned(new GeometryShader(apply(*i))); - else if(i->type==FRAGMENT) + } + catch(const compile_error &e) + { + static const Regex r_message("^(([0-9]+)\\(([0-9]+)\\) :|ERROR: ([0-9]+):([0-9]+):) (.*)$"); + vector lines = split(e.what(), '\n'); + string translated; + for(vector::const_iterator i=lines.begin(); i!=lines.end(); ++i) { - program.attach_shader_owned(new FragmentShader(apply(*i))); - if(EXT_gpu_shader4) + RegMatch m = r_message.match(*i); + if(m) { - for(map::iterator j=i->locations.begin(); j!=i->locations.end(); ++j) - program.bind_fragment_data(j->second, j->first); + unsigned index = 0; + unsigned line = 0; + if(m[2]) + { + index = lexical_cast(m[2].str); + line = lexical_cast(m[3].str); + } + else if(m[4]) + { + index = lexical_cast(m[4].str); + line = lexical_cast(m[5].str); + } + const char *src = ""; + if(index==0) + src = ""; + else if(index-1target->required_version) + target->required_version = stage.required_version; for(NodeList::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i) target->content.body.push_back(*i); apply(*target); @@ -191,9 +234,9 @@ void ProgramCompiler::process() void ProgramCompiler::import(const string &name) { string fn = name+".glsl"; - if(imported_names.count(fn)) + if(find(imported_names, fn)!=imported_names.end()) return; - imported_names.insert(fn); + imported_names.push_back(fn); RefPtr io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn)); if(!io) @@ -204,6 +247,8 @@ void ProgramCompiler::import(const string &name) void ProgramCompiler::generate(Stage &stage) { + if(module->shared.required_version>stage.required_version) + stage.required_version = module->shared.required_version; inject_block(stage.content, module->shared.content); apply(stage); @@ -307,6 +352,7 @@ void ProgramCompiler::BlockModifier::visit(Block &block) ProgramCompiler::Formatter::Formatter(): + source_index(0), source_line(1), indent(0), parameter_list(false) @@ -949,7 +995,7 @@ bool ProgramCompiler::InterfaceGenerator::generate_interface(VariableDeclaration return true; } -void ProgramCompiler::InterfaceGenerator::insert_assignment(const string &left, ProgramSyntax::Expression *right) +ExpressionStatement &ProgramCompiler::InterfaceGenerator::insert_assignment(const string &left, ProgramSyntax::Expression *right) { Assignment *assign = new Assignment; VariableReference *ref = new VariableReference; @@ -962,6 +1008,8 @@ void ProgramCompiler::InterfaceGenerator::insert_assignment(const string &left, stmt->expression = assign; stmt->visit(*this); insert_nodes.push_back(stmt); + + return *stmt; } void ProgramCompiler::InterfaceGenerator::visit(VariableReference &var) @@ -993,7 +1041,9 @@ void ProgramCompiler::InterfaceGenerator::visit(VariableDeclaration &var) remove_node = true; if(var.init_expression) { - insert_assignment(var.name, var.init_expression->clone()); + ExpressionStatement &stmt = insert_assignment(var.name, var.init_expression->clone()); + stmt.source = var.source; + stmt.line = var.line; return; } } @@ -1631,7 +1681,7 @@ void ProgramCompiler::UnusedVariableLocator::merge_down_variables() { if(!i->second.referenced) unused_nodes.insert(i->first); - clear_assignments(i->second, true); + clear_assignments(i->second, i->first->interface!="out"); continue; } @@ -1904,10 +1954,32 @@ void ProgramCompiler::LegacyConverter::visit(FunctionCall &call) call.name = "texture2D"; else if(type=="sampler3D") call.name = "texture3D"; + else if(type=="samplerCube") + call.name = "textureCube"; else if(type=="sampler1DShadow") call.name = "shadow1D"; else if(type=="sampler2DShadow") call.name = "shadow2D"; + else if(type=="sampler1DArray") + { + check_extension(EXT_texture_array); + call.name = "texture1DArray"; + } + else if(type=="sampler2DArray") + { + check_extension(EXT_texture_array); + call.name = "texture2DArray"; + } + else if(type=="sampler1DArrayShadow") + { + check_extension(EXT_texture_array); + call.name = "shadow1DArray"; + } + else if(type=="sampler2DArrayShadow") + { + check_extension(EXT_texture_array); + call.name = "shadow2DArray"; + } for(; i!=call.arguments.end(); ++i) (*i)->visit(*this);