X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Fresolve.cpp;h=fbe60d79def36ee514e9598541a2ab99f05b4539;hp=7c58bc6b0fe309b3137e2e10b239601cf5797e8e;hb=HEAD;hpb=f127ac306c555464b76818aa73977c5ce5096f95 diff --git a/source/glsl/resolve.cpp b/source/glsl/resolve.cpp index 7c58bc6b..1d165b7e 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,11 +77,26 @@ 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; + type = resolved; } void TypeResolver::visit(Block &block) @@ -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))) @@ -1104,6 +1144,13 @@ void ExpressionResolver::visit(FunctionCall &call) 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); } @@ -1198,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; }