]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/reflect.cpp
151735ab18f3790d51b94bbf61da68726ce56a39
[libs/gl.git] / source / glsl / reflect.cpp
1 #include "reflect.h"
2
3 using namespace std;
4
5 namespace Msp {
6 namespace GL {
7 namespace SL {
8
9 LocationCounter::LocationCounter():
10         r_count(0)
11 { }
12
13 void LocationCounter::visit(BasicTypeDeclaration &basic)
14 {
15         r_count = basic.kind==BasicTypeDeclaration::MATRIX ? basic.size>>16 : 1;
16 }
17
18 void LocationCounter::visit(ImageTypeDeclaration &)
19 {
20         r_count = 1;
21 }
22
23 void LocationCounter::visit(StructDeclaration &strct)
24 {
25         unsigned total = 0;
26         for(NodeList<Statement>::const_iterator i=strct.members.body.begin(); i!=strct.members.body.end(); ++i)
27         {
28                 r_count = 1;
29                 (*i)->visit(*this);
30                 total += r_count;
31         }
32         r_count = total;
33 }
34
35 void LocationCounter::visit(VariableDeclaration &var)
36 {
37         r_count = 1;
38         if(var.type_declaration)
39                 var.type_declaration->visit(*this);
40         if(var.array)
41                 if(const Literal *literal = dynamic_cast<const Literal *>(var.array_size.get()))
42                         if(literal->value.check_type<int>())
43                                 r_count *= literal->value.value<int>();
44 }
45
46
47 void MemoryRequirementsCalculator::visit(BasicTypeDeclaration &basic)
48 {
49         if(basic.kind==BasicTypeDeclaration::BOOL)
50         {
51                 r_size = 1;
52                 r_alignment = 1;
53         }
54         else if(basic.kind==BasicTypeDeclaration::INT || basic.kind==BasicTypeDeclaration::FLOAT)
55         {
56                 r_size = basic.size/8;
57                 r_alignment = r_size;
58         }
59         else if(basic.kind==BasicTypeDeclaration::VECTOR || basic.kind==BasicTypeDeclaration::MATRIX)
60         {
61                 basic.base_type->visit(*this);
62                 unsigned n_elem = basic.size&0xFFFF;
63                 r_size *= n_elem;
64                 if(basic.kind==BasicTypeDeclaration::VECTOR)
65                         r_alignment *= (n_elem==3 ? 4 : n_elem);
66         }
67         else if(basic.kind==BasicTypeDeclaration::ARRAY)
68                 basic.base_type->visit(*this);
69 }
70
71 void MemoryRequirementsCalculator::visit(StructDeclaration &strct)
72 {
73         unsigned total = 0;
74         unsigned max_align = 1;
75         for(NodeList<Statement>::iterator i=strct.members.body.begin(); i!=strct.members.body.end(); ++i)
76         {
77                 r_size = 0;
78                 r_alignment = 1;
79                 r_offset = -1;
80                 (*i)->visit(*this);
81                 if(r_offset)
82                         total = r_offset;
83                 total += r_alignment-1;
84                 total -= total%r_alignment;
85                 total += r_size;
86                 max_align = max(max_align, r_alignment);
87         }
88         r_size = total;
89         r_alignment = max_align;
90 }
91
92 void MemoryRequirementsCalculator::visit(VariableDeclaration &var)
93 {
94         if(var.layout)
95         {
96                 const vector<Layout::Qualifier> qualifiers = var.layout->qualifiers;
97                 for(vector<Layout::Qualifier>::const_iterator i=qualifiers.begin(); (r_offset<0 && i!=qualifiers.end()); ++i)
98                         if(i->name=="offset")
99                                 r_offset = i->value;
100         }
101
102         if(var.type_declaration)
103                 var.type_declaration->visit(*this);
104         if(var.array)
105                 if(const Literal *literal = dynamic_cast<const Literal *>(var.array_size.get()))
106                         if(literal->value.check_type<int>())
107                                 r_size += r_alignment*(literal->value.value<int>()-1);
108 }
109
110
111 set<Node *> DependencyCollector::apply(FunctionDeclaration &func)
112 {
113         func.visit(*this);
114         return dependencies;
115 }
116
117 void DependencyCollector::visit(VariableReference &var)
118 {
119         if(var.declaration && !locals.count(var.declaration))
120         {
121                 dependencies.insert(var.declaration);
122                 var.declaration->visit(*this);
123         }
124 }
125
126 void DependencyCollector::visit(InterfaceBlockReference &iface)
127 {
128         if(iface.declaration)
129         {
130                 dependencies.insert(iface.declaration);
131                 iface.declaration->visit(*this);
132         }
133 }
134
135 void DependencyCollector::visit(FunctionCall &call)
136 {
137         if(call.declaration)
138                 dependencies.insert(call.declaration);
139         TraversingVisitor::visit(call);
140 }
141
142 void DependencyCollector::visit(VariableDeclaration &var)
143 {
144         locals.insert(&var);
145         if(var.type_declaration)
146         {
147                 dependencies.insert(var.type_declaration);
148                 var.type_declaration->visit(*this);
149         }
150
151         TraversingVisitor::visit(var);
152 }
153
154 } // namespace SL
155 } // namespace GL
156 } // namespace Msp