X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fglsl%2Fgenerate.cpp;h=434dbe7a8486e0d73104c9a2c0e0ad451c67d39a;hb=bd8816692056230c36504dcccd76c6946dff47b1;hp=3ff04eb9890124f7098c015dafe1099d77d7d34e;hpb=a666a62ba1db594a03b499e45886dab3a5a0f2a4;p=libs%2Fgl.git diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 3ff04eb9..434dbe7a 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -80,12 +80,18 @@ void BlockResolver::enter(Block &block) void BlockResolver::visit(InterfaceBlock &iface) { - current_block->interfaces.insert(&iface); + /* Block names can't be used for any other identifiers so we can put them + in the same map with instance names. */ + current_block->interfaces[iface.name] = &iface; + if(!iface.instance_name.empty()) + current_block->interfaces[iface.instance_name] = &iface; TraversingVisitor::visit(iface); } VariableResolver::VariableResolver(): + builtins(0), + members(0), record_target(false), assignment_target(0), self_referencing(false) @@ -111,7 +117,7 @@ void VariableResolver::enter(Block &block) void VariableResolver::visit(VariableReference &var) { var.declaration = 0; - type = 0; + members = 0; for(Block *block=current_block; block; block=next_block(*block)) { map::iterator i = block->variables.find(var.name); @@ -119,18 +125,30 @@ void VariableResolver::visit(VariableReference &var) var.declaration = i->second; else { - const set &ifaces = block->interfaces; - for(set::const_iterator j=ifaces.begin(); (!var.declaration && j!=ifaces.end()); ++j) - { - i = (*j)->members.variables.find(var.name); - if(i!=(*j)->members.variables.end()) - var.declaration = i->second; - } + const map &ifaces = block->interfaces; + for(map::const_iterator j=ifaces.begin(); (!var.declaration && j!=ifaces.end()); ++j) + if(j->second->instance_name.empty()) + { + i = j->second->members.variables.find(var.name); + if(i!=j->second->members.variables.end()) + var.declaration = i->second; + } } if(var.declaration) { - type = var.declaration->type_declaration; + if(var.declaration->type_declaration) + members = &var.declaration->type_declaration->members.variables; + break; + } + + map::iterator j = block->interfaces.find(var.name); + if(j!=block->interfaces.end() && j->second->instance_name==var.name) + { + iface_ref = new InterfaceBlockReference; + iface_ref->name = var.name; + iface_ref->declaration = j->second; + members = &j->second->members.variables; break; } } @@ -149,21 +167,43 @@ void VariableResolver::visit(VariableReference &var) self_referencing = true; } +void VariableResolver::visit(InterfaceBlockReference &iface) +{ + iface.declaration = 0; + for(Block *block=current_block; block; block=next_block(*block)) + { + map::iterator j = block->interfaces.find(iface.name); + if(j!=block->interfaces.end()) + { + iface.declaration = j->second; + members = &j->second->members.variables; + break; + } + } +} + void VariableResolver::visit(MemberAccess &memacc) { - type = 0; - TraversingVisitor::visit(memacc); + members = 0; + iface_ref = 0; + memacc.left->visit(*this); + + if(iface_ref) + memacc.left = iface_ref; + iface_ref = 0; + memacc.declaration = 0; - if(type) + if(members) { - map::iterator i = type->members.variables.find(memacc.member); - if(i!=type->members.variables.end()) + map::iterator i = members->find(memacc.member); + if(i!=members->end()) { memacc.declaration = i->second; - type = i->second->type_declaration; + if(i->second->type_declaration) + members = &i->second->type_declaration->members.variables; } else - type = 0; + members = 0; } } @@ -175,13 +215,17 @@ void VariableResolver::visit(BinaryExpression &binary) SetForScope set(record_target, false); binary.right->visit(*this); } - type = 0; + members = 0; + iface_ref = 0; binary.left->visit(*this); + if(iface_ref) + binary.left = iface_ref; + iface_ref = 0; } else { TraversingVisitor::visit(binary); - type = 0; + members = 0; } } @@ -259,7 +303,8 @@ void FunctionResolver::visit(FunctionDeclaration &func) InterfaceGenerator::InterfaceGenerator(): stage(0), - function_scope(false) + function_scope(false), + iface_block(0) { } string InterfaceGenerator::get_out_prefix(Stage::Type type) @@ -368,6 +413,18 @@ void InterfaceGenerator::visit(VariableReference &var) void InterfaceGenerator::visit(VariableDeclaration &var) { + if(iface_block) + { + if(iface_block->linked_block) + { + const map &linked_vars = iface_block->linked_block->members.variables; + map::const_iterator i = linked_vars.find(var.name); + if(i!=linked_vars.end()) + var.linked_declaration = i->second; + } + return; + } + if(var.interface=="out") { /* For out variables in function scope, generate a global interface and @@ -403,6 +460,26 @@ void InterfaceGenerator::visit(VariableDeclaration &var) TraversingVisitor::visit(var); } +void InterfaceGenerator::visit(InterfaceBlock &iface) +{ + if(iface.interface=="in") + { + if(!iface.linked_block && stage->previous) + { + const map &prev_blocks = stage->previous->content.interfaces; + map::const_iterator i = prev_blocks.find(iface.name); + if(i!=prev_blocks.end() && i->second->interface=="out" && i->second->name==iface.name) + { + iface.linked_block = i->second; + i->second->linked_block = &iface; + } + } + } + + SetForScope set_iface(iface_block, &iface); + TraversingVisitor::visit(iface); +} + void InterfaceGenerator::visit(FunctionDeclaration &func) { SetFlag set_scope(function_scope, true); @@ -434,7 +511,7 @@ void InterfaceGenerator::visit(Passthrough &pass) if(stage->type==Stage::GEOMETRY) { - VariableReference *ref = new VariableReference; + InterfaceBlockReference *ref = new InterfaceBlockReference; ref->name = "gl_in"; BinaryExpression *subscript = new BinaryExpression;