Add CTS_ARB_gl_spirv test implementation
[platform/upstream/VK-GL-CTS.git] / framework / randomshaders / rsgVariableManager.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Random Shader Generator
3  * ----------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Variable manager.
22  *//*--------------------------------------------------------------------*/
23
24 #include "rsgVariableManager.hpp"
25
26 #include <algorithm>
27 #include <map>
28 #include <set>
29
30 using std::vector;
31 using std::set;
32 using std::map;
33
34 namespace rsg
35 {
36
37 class SubValueRangeIterator
38 {
39 public:
40                                                                         SubValueRangeIterator                   (const ConstValueRangeAccess& valueRange);
41                                                                         ~SubValueRangeIterator                  (void) {}
42
43         bool                                                    hasItem                                                 (void) const;
44         ConstValueRangeAccess                   getItem                                                 (void) const;
45         void                                                    next                                                    (void);
46
47 private:
48
49         vector<ConstValueRangeAccess>   m_stack;
50 };
51
52 SubValueRangeIterator::SubValueRangeIterator (const ConstValueRangeAccess& valueRange)
53 {
54         m_stack.push_back(valueRange);
55 }
56
57 inline bool SubValueRangeIterator::hasItem (void) const
58 {
59         return !m_stack.empty();
60 }
61
62 inline ConstValueRangeAccess SubValueRangeIterator::getItem (void) const
63 {
64         return m_stack[m_stack.size()-1];
65 }
66
67 void SubValueRangeIterator::next (void)
68 {
69         ConstValueRangeAccess curItem = getItem();
70         m_stack.pop_back(); // Remove current
71
72         switch (curItem.getType().getBaseType())
73         {
74                 case VariableType::TYPE_ARRAY:
75                 {
76                         int numElements = curItem.getType().getNumElements();
77                         for (int ndx = 0; ndx < numElements; ndx++)
78                                 m_stack.push_back(curItem.member(ndx));
79                         break;
80                 }
81
82                 case VariableType::TYPE_STRUCT:
83                 {
84                         int numMembers = (int)curItem.getType().getMembers().size();
85                         for (int ndx = 0; ndx < numMembers; ndx++)
86                                 m_stack.push_back(curItem.member(ndx));
87                         break;
88                 }
89
90                 default:
91                         break; // \todo [2011-02-03 pyry] Swizzle control?
92         }
93 }
94
95 ValueEntry::ValueEntry (const Variable* variable)
96         : m_variable    (variable)
97         , m_valueRange  (variable->getType())
98 {
99 }
100
101 VariableScope::VariableScope (void)
102 {
103 }
104
105 VariableScope::~VariableScope (void)
106 {
107         for (vector<Variable*>::iterator i = m_declaredVariables.begin(); i != m_declaredVariables.end(); i++)
108                 delete *i;
109
110         for (vector<Variable*>::iterator i = m_liveVariables.begin(); i != m_liveVariables.end(); i++)
111                 delete *i;
112 }
113
114 Variable* VariableScope::allocate (const VariableType& type, Variable::Storage storage, const char* name)
115 {
116         Variable* variable = new Variable(type, storage, name);
117         try
118         {
119                 m_liveVariables.push_back(variable);
120                 return variable;
121         }
122         catch (const std::exception&)
123         {
124                 delete variable;
125                 throw;
126         }
127 }
128
129 void VariableScope::declare (Variable* variable)
130 {
131         m_declaredVariables.push_back(variable);
132         removeLive(variable);
133 }
134
135 void VariableScope::removeLive (const Variable* variable)
136 {
137         vector<Variable*>::iterator pos = std::find(m_liveVariables.begin(), m_liveVariables.end(), variable);
138         DE_ASSERT(pos != m_liveVariables.end());
139
140         // \todo [pyry] Not so efficient
141         m_liveVariables.erase(pos);
142 }
143
144 ValueScope::ValueScope (void)
145 {
146 }
147
148 ValueScope::~ValueScope (void)
149 {
150         clear();
151 }
152
153 void ValueScope::clear (void)
154 {
155         for (vector<ValueEntry*>::iterator i = m_entries.begin(); i != m_entries.end(); i++)
156                 delete *i;
157         m_entries.clear();
158 }
159
160 ValueEntry* ValueScope::allocate (const Variable* variable)
161 {
162         ValueEntry* entry = new ValueEntry(variable);
163         try
164         {
165                 m_entries.push_back(entry);
166                 return entry;
167         }
168         catch (const std::exception&)
169         {
170                 delete entry;
171                 throw;
172         }
173 }
174
175 class CompareEntryVariable
176 {
177 public:
178         CompareEntryVariable (const Variable* variable)
179                 : m_variable(variable)
180         {
181         }
182
183         bool operator== (const ValueEntry* entry) const
184         {
185                 return entry->getVariable() == m_variable;
186         }
187
188 private:
189         const Variable* m_variable;
190 };
191
192 bool operator== (const ValueEntry* entry, const CompareEntryVariable& cmp)
193 {
194         return cmp == entry;
195 }
196
197 ValueEntry* ValueScope::findEntry (const Variable* variable) const
198 {
199         vector<ValueEntry*>::const_iterator pos = std::find(m_entries.begin(), m_entries.end(), CompareEntryVariable(variable));
200         return pos != m_entries.end() ? *pos : DE_NULL;
201 }
202
203 void ValueScope::setValue (const Variable* variable, ConstValueRangeAccess value)
204 {
205         ValueEntry* entry = findEntry(variable);
206         DE_ASSERT(entry);
207
208         ValueRangeAccess dst = entry->getValueRange();
209         dst.getMin() = value.getMin().value();
210         dst.getMax() = value.getMax().value();
211 }
212
213 void ValueScope::removeValue (const Variable* variable)
214 {
215         vector<ValueEntry*>::iterator pos = std::find(m_entries.begin(), m_entries.end(), CompareEntryVariable(variable));
216         if (pos != m_entries.end())
217         {
218                 ValueEntry* entry = *pos;
219                 m_entries.erase(pos);
220                 delete entry;
221         }
222 }
223
224 VariableManager::VariableManager (NameAllocator& nameAllocator)
225         : m_numAllocatedScalars                         (0)
226         , m_numAllocatedShaderInScalars         (0)
227         , m_numAllocatedShaderInVariables       (0)
228         , m_numAllocatedUniformScalars          (0)
229         , m_nameAllocator                                       (nameAllocator)
230 {
231 }
232
233 VariableManager::~VariableManager (void)
234 {
235 }
236
237 Variable* VariableManager::allocate (const VariableType& type)
238 {
239         return allocate(type, Variable::STORAGE_LOCAL, m_nameAllocator.allocate().c_str());
240 }
241
242 Variable* VariableManager::allocate (const VariableType& type, Variable::Storage storage, const char* name)
243 {
244         VariableScope&  varScope        = getCurVariableScope();
245         ValueScope&             valueScope      = getCurValueScope();
246         int                             numScalars      = type.getScalarSize();
247
248         // Allocate in current scope
249         Variable* variable = varScope.allocate(type, Variable::STORAGE_LOCAL, name);
250
251         // Allocate value entry
252         ValueEntry* valueEntry = valueScope.allocate(variable);
253
254         // Add to cache
255         m_entryCache.push_back(valueEntry);
256
257         m_numAllocatedScalars += numScalars;
258
259         // Set actual storage - affects uniform/shader in allocations.
260         setStorage(variable, storage);
261
262         return variable;
263 }
264
265 void VariableManager::setStorage (Variable* variable, Variable::Storage storage)
266 {
267         int numScalars = variable->getType().getScalarSize();
268
269         // Decrement old.
270         if (variable->getStorage() == Variable::STORAGE_SHADER_IN)
271         {
272                 m_numAllocatedShaderInScalars   -= numScalars;
273                 m_numAllocatedShaderInVariables -= 1;
274         }
275         else if (variable->getStorage() == Variable::STORAGE_UNIFORM)
276                 m_numAllocatedUniformScalars -= numScalars;
277
278         // Add new.
279         if (storage == Variable::STORAGE_SHADER_IN)
280         {
281                 m_numAllocatedShaderInScalars   += numScalars;
282                 m_numAllocatedShaderInVariables += 1;
283         }
284         else if (storage == Variable::STORAGE_UNIFORM)
285                 m_numAllocatedUniformScalars += numScalars;
286
287         variable->setStorage(storage);
288 }
289
290 bool VariableManager::canDeclareInCurrentScope (const Variable* variable) const
291 {
292         const vector<Variable*>& curLiveVars = getCurVariableScope().getLiveVariables();
293         return std::find(curLiveVars.begin(), curLiveVars.end(), variable) != curLiveVars.end();
294 }
295
296 const vector<Variable*>& VariableManager::getLiveVariables (void) const
297 {
298         return getCurVariableScope().getLiveVariables();
299 }
300
301 void VariableManager::declareVariable (Variable* variable)
302 {
303         // Remove from cache if exists in there.
304         std::vector<const ValueEntry*>::iterator pos = std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
305         if (pos != m_entryCache.end())
306                 m_entryCache.erase(pos);
307
308         DE_ASSERT(std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable)) == m_entryCache.end());
309
310         // Remove from scope stack.
311         for (vector<ValueScope*>::const_iterator stackIter = m_valueScopeStack.begin(); stackIter != m_valueScopeStack.end(); stackIter++)
312         {
313                 ValueScope* scope = *stackIter;
314                 scope->removeValue(variable);
315         }
316
317         // Declare in current scope.
318         getCurVariableScope().declare(variable);
319 }
320
321 const ValueEntry* VariableManager::getValue (const Variable* variable) const
322 {
323         vector<const ValueEntry*>::const_iterator pos = std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
324         return pos != m_entryCache.end() ? *pos : DE_NULL;
325 }
326
327 void VariableManager::removeValueFromCurrentScope (const Variable* variable)
328 {
329         // Remove from cache
330         std::vector<const ValueEntry*>::iterator pos = std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
331         DE_ASSERT(pos != m_entryCache.end());
332         m_entryCache.erase(pos);
333
334         // Remove from current scope \note May not exist in there.
335         getCurValueScope().removeValue(variable);
336 }
337
338 const ValueEntry* VariableManager::getParentValue (const Variable* variable) const
339 {
340         if (m_valueScopeStack.size() < 2)
341                 return DE_NULL; // Only single value scope
342
343         for (vector<ValueScope*>::const_reverse_iterator i = m_valueScopeStack.rbegin()+1; i != m_valueScopeStack.rend(); i++)
344         {
345                 const ValueScope*       scope   = *i;
346                 ValueEntry*                     entry   = scope->findEntry(variable);
347
348                 if (entry)
349                         return entry;
350         }
351
352         return DE_NULL; // Not found in stack
353 }
354
355 void VariableManager::setValue (const Variable* variable, ConstValueRangeAccess value)
356 {
357         ValueScope& curScope = getCurValueScope();
358
359         if (!curScope.findEntry(variable))
360         {
361                 // New value, allocate and update cache.
362                 ValueEntry*                                                                     newEntry        = curScope.allocate(variable);
363                 std::vector<const ValueEntry*>::iterator        cachePos        = std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(variable));
364
365                 if (cachePos != m_entryCache.end())
366                         *cachePos = newEntry;
367                 else
368                         m_entryCache.push_back(newEntry);
369         }
370
371         curScope.setValue(variable, value);
372 }
373
374 void VariableManager::reserve (ReservedScalars& store, int numScalars)
375 {
376         DE_ASSERT(store.numScalars == 0);
377         store.numScalars                 = numScalars;
378         m_numAllocatedScalars   += numScalars;
379 }
380
381 void VariableManager::release (ReservedScalars& store)
382 {
383         m_numAllocatedScalars   -= store.numScalars;
384         store.numScalars                 = 0;
385 }
386
387 void VariableManager::pushVariableScope (VariableScope& scope)
388 {
389         // Expects emtpy scope
390         DE_ASSERT(scope.getDeclaredVariables().size() == 0);
391         DE_ASSERT(scope.getLiveVariables().size() == 0);
392
393         m_variableScopeStack.push_back(&scope);
394 }
395
396 void VariableManager::popVariableScope (void)
397 {
398         VariableScope& curScope = getCurVariableScope();
399
400         // Migrate live variables to parent scope.
401         // Variables allocated in child scopes can be declared in any parent scope but not the other way around.
402         if (m_variableScopeStack.size() > 1)
403         {
404                 VariableScope&          parentScope             = *m_variableScopeStack[m_variableScopeStack.size()-2];
405                 vector<Variable*>&      curLiveVars             = curScope.getLiveVariables();
406                 vector<Variable*>&      parenLiveVars   = parentScope.getLiveVariables();
407
408                 while (!curLiveVars.empty())
409                 {
410                         Variable* liveVar = curLiveVars.back();
411                         parenLiveVars.push_back(liveVar);
412                         curLiveVars.pop_back();
413                 }
414         }
415
416         // All variables should be either migrated to parent or declared (in case of root scope).
417         DE_ASSERT(curScope.getLiveVariables().size() == 0);
418
419         m_variableScopeStack.pop_back();
420 }
421
422 void VariableManager::pushValueScope (ValueScope& scope)
423 {
424         // Value scope should be empty
425         DE_ASSERT(scope.getValues().size() == 0);
426
427         m_valueScopeStack.push_back(&scope);
428 }
429
430 void VariableManager::popValueScope (void)
431 {
432         ValueScope& oldScope = getCurValueScope();
433
434         // Pop scope and clear cache.
435         m_valueScopeStack.pop_back();
436         m_entryCache.clear();
437
438         // Re-build entry cache.
439         if (!m_valueScopeStack.empty())
440         {
441                 ValueScope& newTopScope = getCurValueScope();
442
443                 // Speed up computing intersections.
444                 map<const Variable*, const ValueEntry*> oldValues;
445                 const vector<ValueEntry*>&                              oldEntries = oldScope.getValues();
446
447                 for (vector<ValueEntry*>::const_iterator valueIter = oldEntries.begin(); valueIter != oldEntries.end(); valueIter++)
448                         oldValues[(*valueIter)->getVariable()] = *valueIter;
449
450                 set<const Variable*> addedVars;
451
452                 // Re-build based on current stack.
453                 for (vector<ValueScope*>::reverse_iterator scopeIter = m_valueScopeStack.rbegin(); scopeIter != m_valueScopeStack.rend(); scopeIter++)
454                 {
455                         const ValueScope*                       scope                   = *scopeIter;
456                         const vector<ValueEntry*>&      valueEntries    = scope->getValues();
457
458                         for (vector<ValueEntry*>::const_iterator valueIter = valueEntries.begin(); valueIter != valueEntries.end(); valueIter++)
459                         {
460                                 const ValueEntry*       entry   = *valueIter;
461                                 const Variable*         var             = entry->getVariable();
462
463                                 if (addedVars.find(var) != addedVars.end())
464                                         continue; // Already in cache, set deeper in scope stack.
465
466                                 DE_ASSERT(std::find(m_entryCache.begin(), m_entryCache.end(), CompareEntryVariable(var)) == m_entryCache.end());
467
468                                 if (oldValues.find(var) != oldValues.end())
469                                 {
470                                         const ValueEntry* oldEntry = oldValues[var];
471
472                                         // Build new intersected value and store into current scope.
473                                         ValueRange intersectedValue(var->getType());
474                                         DE_ASSERT(oldEntry->getValueRange().intersects(entry->getValueRange())); // Must intersect
475                                         ValueRange::computeIntersection(intersectedValue, entry->getValueRange(), oldEntry->getValueRange());
476
477                                         if (!newTopScope.findEntry(var))
478                                                 newTopScope.allocate(var);
479
480                                         newTopScope.setValue(var, intersectedValue.asAccess());
481
482                                         // Add entry from top scope to cache.
483                                         m_entryCache.push_back(newTopScope.findEntry(var));
484                                 }
485                                 else
486                                         m_entryCache.push_back(entry); // Just add to cache.
487
488                                 addedVars.insert(var); // Record as cached variable.
489                         }
490                 }
491
492                 // Copy entries from popped scope that don't yet exist in the stack.
493                 for (vector<ValueEntry*>::const_iterator valueIter = oldEntries.begin(); valueIter != oldEntries.end(); valueIter++)
494                 {
495                         const ValueEntry*       oldEntry        = *valueIter;
496                         const Variable*         var                     = oldEntry->getVariable();
497
498                         if (addedVars.find(var) == addedVars.end())
499                                 setValue(var, oldEntry->getValueRange());
500                 }
501         }
502 }
503
504 } // rsg