X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fglsl%2Freflect.cpp;h=82ad244c1d7083c1ad8b61e4c22fee69e25e7f2f;hb=c4aeeced7b397d46772577775bd3a0d6c4706cba;hp=c38e3aecbb3d487c6c7c2f10f510b6495092e872;hpb=c72c4ebe384a0d5a48c268d09449707bd86090a8;p=libs%2Fgl.git diff --git a/source/glsl/reflect.cpp b/source/glsl/reflect.cpp index c38e3aec..82ad244c 100644 --- a/source/glsl/reflect.cpp +++ b/source/glsl/reflect.cpp @@ -1,3 +1,4 @@ +#include #include "reflect.h" using namespace std; @@ -6,6 +7,46 @@ namespace Msp { namespace GL { namespace SL { +bool is_scalar(const BasicTypeDeclaration &type) +{ + return (type.kind==BasicTypeDeclaration::INT || type.kind==BasicTypeDeclaration::FLOAT); +} + +bool is_vector_or_matrix(const BasicTypeDeclaration &type) +{ + return (type.kind==BasicTypeDeclaration::VECTOR || type.kind==BasicTypeDeclaration::MATRIX); +} + +BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &type) +{ + if(is_vector_or_matrix(type) || type.kind==BasicTypeDeclaration::ARRAY) + { + BasicTypeDeclaration *basic_base = dynamic_cast(type.base_type); + return (basic_base ? get_element_type(*basic_base) : 0); + } + else + return &type; +} + +bool can_convert(const BasicTypeDeclaration &from, const BasicTypeDeclaration &to) +{ + if(from.kind==BasicTypeDeclaration::INT && to.kind==BasicTypeDeclaration::FLOAT) + return from.size<=to.size; + else if(from.kind!=to.kind) + return false; + else if(from.kind==BasicTypeDeclaration::INT && from.sign!=to.sign) + return from.sign && from.size<=to.size; + else if(is_vector_or_matrix(from) && from.size==to.size) + { + BasicTypeDeclaration *from_base = dynamic_cast(from.base_type); + BasicTypeDeclaration *to_base = dynamic_cast(to.base_type); + return (from_base && to_base && can_convert(*from_base, *to_base)); + } + else + return false; +} + + unsigned TypeComparer::next_tag = 1; TypeComparer::TypeComparer(): @@ -85,7 +126,7 @@ void TypeComparer::visit(BasicTypeDeclaration &basic) { if(BasicTypeDeclaration *basic1 = multi_visit(basic)) { - if(basic1->kind!=basic.kind || basic1->size!=basic.size) + if(basic1->kind!=basic.kind || basic1->size!=basic.size || basic1->sign!=basic.sign) r_result = false; else if(basic1->base_type && basic.base_type) compare(*basic1->base_type, *basic.base_type); @@ -118,8 +159,8 @@ void TypeComparer::visit(StructDeclaration &strct) else { r_result = true; - NodeList::const_iterator i = strct1->members.body.begin(); - NodeList::const_iterator j = strct.members.body.begin(); + auto i = strct1->members.body.begin(); + auto j = strct.members.body.begin(); for(; (r_result && i!=strct1->members.body.end()); ++i, ++j) compare(**i, **j); } @@ -167,10 +208,10 @@ void LocationCounter::visit(ImageTypeDeclaration &) void LocationCounter::visit(StructDeclaration &strct) { unsigned total = 0; - for(NodeList::const_iterator i=strct.members.body.begin(); i!=strct.members.body.end(); ++i) + for(const RefPtr &s: strct.members.body) { r_count = 1; - (*i)->visit(*this); + s->visit(*this); total += r_count; } r_count = total; @@ -216,12 +257,12 @@ void MemoryRequirementsCalculator::visit(StructDeclaration &strct) { unsigned total = 0; unsigned max_align = 1; - for(NodeList::iterator i=strct.members.body.begin(); i!=strct.members.body.end(); ++i) + for(const RefPtr &s: strct.members.body) { r_size = 0; r_alignment = 1; r_offset = -1; - (*i)->visit(*this); + s->visit(*this); if(r_offset) total = r_offset; total += r_alignment-1; @@ -237,10 +278,9 @@ void MemoryRequirementsCalculator::visit(VariableDeclaration &var) { if(var.layout) { - const vector qualifiers = var.layout->qualifiers; - for(vector::const_iterator i=qualifiers.begin(); (r_offset<0 && i!=qualifiers.end()); ++i) - if(i->name=="offset") - r_offset = i->value; + auto i = find_member(var.layout->qualifiers, string("offset"), &Layout::Qualifier::name); + if(i!=var.layout->qualifiers.end()) + r_offset = i->value; } if(var.type_declaration) @@ -281,7 +321,8 @@ void DependencyCollector::visit(FunctionCall &call) if(call.declaration) { dependencies.insert(call.declaration); - call.declaration->visit(*this); + if(call.declaration->definition) + call.declaration->definition->visit(*this); } TraversingVisitor::visit(call); }