TypeDeclaration *type = variable->type_declaration;
while(BasicTypeDeclaration *basic = dynamic_cast<BasicTypeDeclaration *>(type))
type = basic->base_type;
- allowed = (scope==GLOBAL && dynamic_cast<ImageTypeDeclaration *>(type));
- err_descr = "variable of non-opaque type";
+ bool uniform = (variable->interface=="uniform");
+ allowed = (scope==GLOBAL && uniform && dynamic_cast<ImageTypeDeclaration *>(type));
+ err_descr = (uniform ? "variable of non-opaque type" : "non-uniform variable");
}
else if(iface_block)
- allowed = true;
+ {
+ allowed = (iface_block->interface=="uniform");
+ err_descr = "non-uniform interface block";
+ }
}
else if(i->name=="constant_id")
{
}
}
else if(i->name=="offset")
- allowed = (variable && scope==INTERFACE_BLOCK);
+ allowed = (variable && scope==INTERFACE_BLOCK && iface_block->interface=="uniform");
+ else if(i->name=="align")
+ allowed = (scope==INTERFACE_BLOCK && iface_block->interface=="uniform");
else if(i->name=="points")
{
allowed = (stage->type==Stage::GEOMETRY && iface_layout && (iface_layout->interface=="in" || iface_layout->interface=="out"));
allowed = (iface_block && !variable && iface_block->interface=="uniform");
value = false;
}
+ else if(i->name=="column_major" || i->name=="row_major")
+ {
+ allowed = (variable && scope==INTERFACE_BLOCK);
+ if(allowed)
+ {
+ BasicTypeDeclaration *basic = dynamic_cast<BasicTypeDeclaration *>(variable->type_declaration);
+ while(basic && basic->kind==BasicTypeDeclaration::ARRAY)
+ basic = dynamic_cast<BasicTypeDeclaration *>(basic->base_type);
+ allowed = (basic && basic->kind==BasicTypeDeclaration::MATRIX);
+ err_descr = "non-matrix variable";
+ }
+ }
if(!allowed)
{
{
if(scope==STRUCT || scope==INTERFACE_BLOCK)
error(var, format("Constant qualifier not allowed on %s", descr));
+ if(!var.init_expression)
+ error(var, "Constant variable must have an initializer");
}
if(!var.interpolation.empty() || !var.sampling.empty())
void IdentifierValidator::visit(InterfaceBlock &iface)
{
- string key = iface.interface+iface.block_name;
+ string key = format("%s %s", iface.interface, iface.block_name);
map<string, InterfaceBlock *>::const_iterator i = interface_blocks.find(key);
if(i!=interface_blocks.end())
multiple_definition(format("interface block '%s %s'", iface.interface, iface.block_name), iface, *i->second);