X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Fgenerate.cpp;h=ab487a44c470bca769af032b9ce2966c7a0df5d2;hp=113b4324aa2b64432b41cf7be63ff13ca30ed8c4;hb=9229a3e70dace406d897148857ed6567986c3bcd;hpb=7f2ffe6e62bc7d7b2af7d3c3cccc57f87d8bf90f diff --git a/source/glsl/generate.cpp b/source/glsl/generate.cpp index 113b4324..ab487a44 100644 --- a/source/glsl/generate.cpp +++ b/source/glsl/generate.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "builtin.h" #include "generate.h" @@ -190,6 +191,9 @@ void TypeResolver::visit(BasicTypeDeclaration &type) if(basic_base->kind==BasicTypeDeclaration::VECTOR) { type.kind = BasicTypeDeclaration::MATRIX; + /* A matrix's base type is its column vector type. This will put + the column vector's size, i.e. the matrix's row count, in the high + half of the size. */ type.size |= basic_base->size<<16; } @@ -590,11 +594,11 @@ void ExpressionResolver::convert_to(RefPtr &expr, BasicTypeDeclarati bool ExpressionResolver::convert_to_element(RefPtr &expr, BasicTypeDeclaration &elem_type) { - if(BasicTypeDeclaration *expr_type = dynamic_cast(expr->type)) + if(BasicTypeDeclaration *expr_basic = dynamic_cast(expr->type)) { BasicTypeDeclaration *to_type = &elem_type; - if(is_vector_or_matrix(*expr_type)) - to_type = find_type(elem_type, expr_type->kind, expr_type->size); + if(is_vector_or_matrix(*expr_basic)) + to_type = find_type(elem_type, expr_basic->kind, expr_basic->size); if(to_type) { convert_to(expr, *to_type); @@ -916,8 +920,22 @@ bool FunctionResolver::apply(Stage &s) void FunctionResolver::visit(FunctionCall &call) { - map::iterator i = stage->functions.find(call.name); - FunctionDeclaration *declaration = (i!=stage->functions.end() ? i->second : 0); + string arg_types; + bool has_signature = true; + for(NodeArray::const_iterator i=call.arguments.begin(); (has_signature && i!=call.arguments.end()); ++i) + { + if((*i)->type) + append(arg_types, ",", (*i)->type->name); + else + has_signature = false; + } + + FunctionDeclaration *declaration = 0; + if(has_signature) + { + map::iterator i = stage->functions.find(format("%s(%s)", call.name, arg_types)); + declaration = (i!=stage->functions.end() ? i->second : 0); + } r_any_resolved |= (declaration!=call.declaration); call.declaration = declaration; @@ -926,8 +944,23 @@ void FunctionResolver::visit(FunctionCall &call) void FunctionResolver::visit(FunctionDeclaration &func) { - FunctionDeclaration *&stage_decl = stage->functions[func.name]; - vector &decls = declarations[func.name]; + if(func.signature.empty()) + { + string param_types; + for(NodeArray::const_iterator i=func.parameters.begin(); i!=func.parameters.end(); ++i) + { + if((*i)->type_declaration) + append(param_types, ",", (*i)->type_declaration->name); + else + return; + } + func.signature = format("(%s)", param_types); + r_any_resolved = true; + } + + string key = func.name+func.signature; + FunctionDeclaration *&stage_decl = stage->functions[key]; + vector &decls = declarations[key]; if(func.definition==&func) { stage_decl = &func; @@ -1007,6 +1040,9 @@ VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration if(stage->content.variables.count(name)) return 0; + if(stage->type==Stage::GEOMETRY && !copy_block && var.interface=="out" && var.array) + return 0; + VariableDeclaration* iface_var = new VariableDeclaration; iface_var->sampling = var.sampling; iface_var->interface = iface; @@ -1029,6 +1065,8 @@ VariableDeclaration *InterfaceGenerator::generate_interface(VariableDeclaration iface_target_block->body.insert(iface_insert_point, iface_var); iface_target_block->variables.insert(make_pair(name, iface_var)); + if(iface_target_block==&stage->content && iface=="in") + declared_inputs.push_back(iface_var); return iface_var; } @@ -1104,8 +1142,14 @@ void InterfaceGenerator::visit(VariableReference &var) i = prev_vars.find(in_prefix+var.name); if(i!=prev_vars.end() && i->second->interface=="out") { - generate_interface(*i->second, "in", i->second->name); - var.name = i->second->name; + if(stage->type==Stage::GEOMETRY && i->second->array) + stage->diagnostics.push_back(Diagnostic(Diagnostic::WARN, var.source, var.line, + format("Can't access '%s' through automatic interface because it's an array", var.name))); + else + { + generate_interface(*i->second, "in", i->second->name); + var.name = i->second->name; + } return; } @@ -1155,11 +1199,13 @@ void InterfaceGenerator::visit(VariableDeclaration &var) } } } - else if(var.interface=="in") + else if(var.interface=="in" && current_block==&stage->content) { + declared_inputs.push_back(&var); + /* Try to link input variables in global scope with output variables from previous stage. */ - if(current_block==&stage->content && !var.linked_declaration && stage->previous) + if(!var.linked_declaration && stage->previous) { const map &prev_vars = stage->previous->content.variables; map::const_iterator i = prev_vars.find(var.name); @@ -1204,12 +1250,8 @@ void InterfaceGenerator::visit(FunctionDeclaration &func) void InterfaceGenerator::visit(Passthrough &pass) { - vector pass_vars; - - // Pass through all input variables of this stage. - for(map::const_iterator i=stage->content.variables.begin(); i!=stage->content.variables.end(); ++i) - if(i->second->interface=="in") - pass_vars.push_back(i->second); + // Pass through all input variables declared so far. + vector pass_vars = declared_inputs; if(stage->previous) {