#include <msp/core/algorithm.h>
#include <msp/core/raii.h>
+#include <msp/strings/regex.h>
#include <msp/strings/utils.h>
#include "reflect.h"
#include "resolve.h"
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);
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<ImageTypeDeclaration *>(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;
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));
}
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<StructDeclaration *>(get_ultimate_base_type(var.type_declaration)))
{
TypeDeclaration *arg_type = call.arguments[i]->type;
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<BasicTypeDeclaration *>(arg_type);
BasicTypeDeclaration *param_basic = dynamic_cast<BasicTypeDeclaration *>(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<ImageTypeDeclaration *>(arg_type);
+ ImageTypeDeclaration *param_image = dynamic_cast<ImageTypeDeclaration *>(param_type);
+ if(!arg_image || !param_image || arg_image->base_image!=param_image)
+ return;
}
- else if(!arg_type || !param_type || arg_type!=param_type)
- return;
}
resolve(call, call.declaration->return_type_declaration, false);
}
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<const ImageTypeDeclaration *>(type))
+ if(image->base_image)
+ type = image->base_image;
+ append(arg_types, ",", type->name);
+ }
else
has_signature = false;
}