Home | History | Annotate | Download | only in randomshaders
      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
    505