X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Fresolve.cpp;h=aeccd1bf05ad18debdc3717264b4e58bfdf25493;hb=08d3b5a55fad7439b47fc93d8ba604cbeb7e19ca;hp=3aeab30bd703711d28909cea07b15adc4fc1318d;hpb=03b2ea5c9c611cfa5f02afb49ed7e05743e691b4;p=libs%2Fgl.git diff --git a/source/glsl/resolve.cpp b/source/glsl/resolve.cpp index 3aeab30b..aeccd1bf 100644 --- a/source/glsl/resolve.cpp +++ b/source/glsl/resolve.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include "reflect.h" #include "resolve.h" @@ -46,7 +47,27 @@ TypeDeclaration *TypeResolver::get_or_create_array_type(TypeDeclaration &type) return array; } -void TypeResolver::resolve_type(TypeDeclaration *&type, const string &name, bool array) +TypeDeclaration *TypeResolver::get_or_create_image_type(ImageTypeDeclaration &type, const std::string &texel_format) +{ + if(texel_format.empty()) + return &type; + + auto key = make_pair(&type, texel_format); + auto i = image_types.find(key); + if(i!=image_types.end()) + return i->second; + + ImageTypeDeclaration *image = new ImageTypeDeclaration(type); + image->source = INTERNAL_SOURCE; + image->name = format("%s_%s", type.name, texel_format); + image->format = texel_format; + image->base_image = &type; + stage->content.body.insert(type_insert_point, image); + image_types[key] = image; + return image; +} + +void TypeResolver::resolve_type(TypeDeclaration *&type, const string &name, bool array, const Layout *layout) { TypeDeclaration *resolved = 0; auto i = stage->types.find(name); @@ -56,8 +77,23 @@ void TypeResolver::resolve_type(TypeDeclaration *&type, const string &name, bool resolved = (j!=alias_map.end() ? j->second : i->second); } - if(resolved && array) - resolved = get_or_create_array_type(*resolved); + if(resolved) + { + if(ImageTypeDeclaration *image = dynamic_cast(resolved)) + if(layout) + { + static const Regex r_format("^(r|rg|rgba)(8|16|8_snorm|16_snorm|16f|32f)$"); + for(const Layout::Qualifier &q: layout->qualifiers) + if(r_format.match(q.name)) + { + resolved = get_or_create_image_type(*image, q.name); + break; + } + } + + if(array) + resolved = get_or_create_array_type(*resolved); + } r_any_resolved |= (resolved!=type); type=resolved; @@ -99,6 +135,10 @@ void TypeResolver::visit(BasicTypeDeclaration &type) void TypeResolver::visit(ImageTypeDeclaration &type) { resolve_type(type.base_type, type.base, false); + + if(!type.format.empty() && type.base_image) + image_types[make_pair(type.base_image, type.format)] = &type; + stage->types.insert(make_pair(type.name, &type)); } @@ -116,7 +156,7 @@ void TypeResolver::visit(StructDeclaration &strct) void TypeResolver::visit(VariableDeclaration &var) { - resolve_type(var.type_declaration, var.type, var.array); + resolve_type(var.type_declaration, var.type, var.array, var.layout.get()); var.block_declaration = 0; if(StructDeclaration *strct = dynamic_cast(get_ultimate_base_type(var.type_declaration))) @@ -179,7 +219,7 @@ void VariableResolver::visit(RefPtr &expr) r_replacement_expr = 0; } -void VariableResolver::check_assignment_target(Statement *declaration) +void VariableResolver::check_assignment_target(VariableDeclaration *declaration) { if(record_target) { @@ -1084,7 +1124,36 @@ void ExpressionResolver::visit(FunctionCall &call) TraversingVisitor::visit(call); if(call.declaration) + { + for(unsigned i=0; itype; + TypeDeclaration *param_type = call.declaration->parameters[i]->type_declaration; + if(arg_type==param_type) + continue; + else if(!arg_type || !param_type) + return; + + BasicTypeDeclaration *arg_basic = dynamic_cast(arg_type); + BasicTypeDeclaration *param_basic = dynamic_cast(param_type); + if(arg_basic && param_basic) + { + Compatibility compat = get_compatibility(*param_basic, *arg_basic); + if(compat==RIGHT_CONVERTIBLE) + convert_to(call.arguments[i], *param_basic); + else if(compat!=SAME_TYPE) + return; + } + else + { + ImageTypeDeclaration *arg_image = dynamic_cast(arg_type); + ImageTypeDeclaration *param_image = dynamic_cast(param_type); + if(!arg_image || !param_image || arg_image->base_image!=param_image) + return; + } + } resolve(call, call.declaration->return_type_declaration, false); + } else if(call.constructor) visit_constructor(call); } @@ -1176,8 +1245,13 @@ void FunctionResolver::visit(FunctionCall &call) bool has_signature = true; for(auto i=call.arguments.begin(); (has_signature && i!=call.arguments.end()); ++i) { - if((*i)->type) - append(arg_types, ",", (*i)->type->name); + if(const TypeDeclaration *type = (*i)->type) + { + if(const ImageTypeDeclaration *image = dynamic_cast(type)) + if(image->base_image) + type = image->base_image; + append(arg_types, ",", type->name); + } else has_signature = false; }