You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
338 lines
9.9 KiB
338 lines
9.9 KiB
#ifndef _RSGVARIABLEMANAGER_HPP
|
|
#define _RSGVARIABLEMANAGER_HPP
|
|
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program Random Shader Generator
|
|
* ----------------------------------------------------
|
|
*
|
|
* Copyright 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*//*!
|
|
* \file
|
|
* \brief Variable manager.
|
|
*
|
|
* Memory management:
|
|
* Variable manager owns variable objects until they are either explictly
|
|
* removed or moved to currently active scope. After that the ownership
|
|
* is transferred to Scope or the object that called removeEntry().
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "rsgDefs.hpp"
|
|
#include "rsgVariable.hpp"
|
|
#include "rsgVariableValue.hpp"
|
|
#include "rsgNameAllocator.hpp"
|
|
|
|
#include <iterator>
|
|
#include <vector>
|
|
#include <set>
|
|
|
|
namespace rsg
|
|
{
|
|
|
|
class ValueEntry
|
|
{
|
|
public:
|
|
ValueEntry (const Variable* variable);
|
|
~ValueEntry (void) {}
|
|
|
|
const Variable* getVariable (void) const { return m_variable; }
|
|
|
|
ConstValueRangeAccess getValueRange (void) const { return m_valueRange.asAccess(); }
|
|
ValueRangeAccess getValueRange (void) { return m_valueRange.asAccess(); }
|
|
|
|
private:
|
|
const Variable* m_variable;
|
|
ValueRange m_valueRange;
|
|
};
|
|
|
|
// Variable scope manages variable allocation.
|
|
class VariableScope
|
|
{
|
|
public:
|
|
VariableScope (void);
|
|
~VariableScope (void);
|
|
|
|
Variable* allocate (const VariableType& type, Variable::Storage storage, const char* name);
|
|
void declare (Variable* variable); //!< Move from live set to declared set
|
|
void removeLive (const Variable* variable); //!< Just remove from live set (when migrating to parent).
|
|
|
|
const std::vector<Variable*>& getDeclaredVariables (void) const { return m_declaredVariables; }
|
|
|
|
std::vector<Variable*>& getLiveVariables (void) { return m_liveVariables; }
|
|
const std::vector<Variable*>& getLiveVariables (void) const { return m_liveVariables; }
|
|
|
|
private:
|
|
VariableScope (const VariableScope& other);
|
|
VariableScope& operator= (const VariableScope& other);
|
|
|
|
std::vector<Variable*> m_declaredVariables; //!< Variables declared in this scope. Not available for expressions.
|
|
std::vector<Variable*> m_liveVariables; //!< Live variables (available for expression) that can be declared in this scope.
|
|
};
|
|
|
|
class ValueScope
|
|
{
|
|
public:
|
|
ValueScope (void);
|
|
~ValueScope (void);
|
|
|
|
ValueEntry* allocate (const Variable* variable);
|
|
ValueEntry* findEntry (const Variable* variable) const;
|
|
void setValue (const Variable* variable, ConstValueRangeAccess value);
|
|
void removeValue (const Variable* variable);
|
|
|
|
std::vector<ValueEntry*>& getValues (void) { return m_entries; }
|
|
const std::vector<ValueEntry*>& getValues (void) const { return m_entries; }
|
|
|
|
void clear (void);
|
|
|
|
private:
|
|
ValueScope (const ValueScope& other);
|
|
ValueScope& operator= (const ValueScope& other);
|
|
|
|
std::vector<ValueEntry*> m_entries;
|
|
};
|
|
|
|
class ReservedScalars
|
|
{
|
|
public:
|
|
int numScalars;
|
|
|
|
ReservedScalars (void)
|
|
: numScalars(0)
|
|
{
|
|
}
|
|
};
|
|
|
|
// \todo [2011-05-26 pyry] Clean up this a bit, separate const variant.
|
|
template <typename Item, typename Iterator, class Filter>
|
|
class FilteredIterator : public std::iterator<std::input_iterator_tag, Item>
|
|
{
|
|
public:
|
|
FilteredIterator (Iterator iter, Iterator end, Filter filter)
|
|
: m_iter (iter)
|
|
, m_end (end)
|
|
, m_filter (filter)
|
|
{
|
|
}
|
|
|
|
FilteredIterator operator+ (ptrdiff_t offset) const
|
|
{
|
|
Iterator nextEntry = m_iter;
|
|
while (offset--)
|
|
nextEntry = findNext(m_filter, nextEntry, m_end);
|
|
return FilteredIterator(nextEntry, m_end, m_filter);
|
|
}
|
|
|
|
FilteredIterator& operator++ ()
|
|
{
|
|
// Pre-increment
|
|
m_iter = findNext(m_filter, m_iter, m_end);
|
|
return *this;
|
|
}
|
|
|
|
FilteredIterator operator++ (int)
|
|
{
|
|
// Post-increment
|
|
FilteredIterator copy = *this;
|
|
m_iter = findNext(m_filter, m_iter, m_end);
|
|
return copy;
|
|
}
|
|
|
|
bool operator== (const FilteredIterator& other) const
|
|
{
|
|
return m_iter == other.m_iter;
|
|
}
|
|
|
|
bool operator!= (const FilteredIterator& other) const
|
|
{
|
|
return m_iter != other.m_iter;
|
|
}
|
|
|
|
const Item& operator* (void)
|
|
{
|
|
DE_ASSERT(m_iter != m_end);
|
|
DE_ASSERT(m_filter(*m_iter));
|
|
return *m_iter;
|
|
}
|
|
|
|
private:
|
|
static Iterator findNext (Filter filter, Iterator iter, Iterator end)
|
|
{
|
|
do
|
|
iter++;
|
|
while (iter != end && !filter(*iter));
|
|
return iter;
|
|
}
|
|
|
|
Iterator m_iter;
|
|
Iterator m_end;
|
|
Filter m_filter;
|
|
};
|
|
|
|
template <class Filter>
|
|
class ValueEntryIterator : public FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>
|
|
{
|
|
public:
|
|
ValueEntryIterator (std::vector<const ValueEntry*>::const_iterator begin, std::vector<const ValueEntry*>::const_iterator end, Filter filter)
|
|
: FilteredIterator<const ValueEntry*, std::vector<const ValueEntry*>::const_iterator, Filter>(begin, end, filter)
|
|
{
|
|
}
|
|
};
|
|
|
|
class VariableManager
|
|
{
|
|
public:
|
|
VariableManager (NameAllocator& nameAllocator);
|
|
~VariableManager (void);
|
|
|
|
int getNumAllocatedScalars (void) const { return m_numAllocatedScalars; }
|
|
int getNumAllocatedShaderInScalars (void) const { return m_numAllocatedShaderInScalars; }
|
|
int getNumAllocatedShaderInVariables(void) const { return m_numAllocatedShaderInVariables; }
|
|
int getNumAllocatedUniformScalars (void) const { return m_numAllocatedUniformScalars; }
|
|
|
|
void reserve (ReservedScalars& store, int numScalars);
|
|
void release (ReservedScalars& store);
|
|
|
|
Variable* allocate (const VariableType& type);
|
|
Variable* allocate (const VariableType& type, Variable::Storage storage, const char* name);
|
|
|
|
void setStorage (Variable* variable, Variable::Storage storage);
|
|
|
|
void setValue (const Variable* variable, ConstValueRangeAccess value);
|
|
const ValueEntry* getValue (const Variable* variable) const;
|
|
const ValueEntry* getParentValue (const Variable* variable) const;
|
|
|
|
void removeValueFromCurrentScope (const Variable* variable);
|
|
|
|
void declareVariable (Variable* variable);
|
|
bool canDeclareInCurrentScope (const Variable* variable) const;
|
|
const std::vector<Variable*>& getLiveVariables (void) const;
|
|
|
|
void pushVariableScope (VariableScope& scope);
|
|
void popVariableScope (void);
|
|
|
|
void pushValueScope (ValueScope& scope);
|
|
void popValueScope (void);
|
|
|
|
template <class Filter>
|
|
ValueEntryIterator<Filter> getBegin (Filter filter = Filter()) const;
|
|
|
|
template <class Filter>
|
|
ValueEntryIterator<Filter> getEnd (Filter filter = Filter()) const;
|
|
|
|
template <class Filter>
|
|
bool hasEntry (Filter filter = Filter()) const;
|
|
|
|
private:
|
|
VariableManager (const VariableManager& other);
|
|
VariableManager& operator= (const VariableManager& other);
|
|
|
|
VariableScope& getCurVariableScope (void) { return *m_variableScopeStack.back(); }
|
|
const VariableScope& getCurVariableScope (void) const { return *m_variableScopeStack.back(); }
|
|
|
|
ValueScope& getCurValueScope (void) { return *m_valueScopeStack.back(); }
|
|
const ValueScope& getCurValueScope (void) const { return *m_valueScopeStack.back(); }
|
|
|
|
std::vector<VariableScope*> m_variableScopeStack;
|
|
std::vector<ValueScope*> m_valueScopeStack;
|
|
|
|
std::vector<const ValueEntry*> m_entryCache; //!< For faster value entry access.
|
|
|
|
int m_numAllocatedScalars;
|
|
int m_numAllocatedShaderInScalars;
|
|
int m_numAllocatedShaderInVariables;
|
|
int m_numAllocatedUniformScalars;
|
|
NameAllocator& m_nameAllocator;
|
|
};
|
|
|
|
template <class Filter>
|
|
ValueEntryIterator<Filter> VariableManager::getBegin (Filter filter) const
|
|
{
|
|
std::vector<const ValueEntry*>::const_iterator first = m_entryCache.begin();
|
|
while (first != m_entryCache.end() && !filter(*first))
|
|
first++;
|
|
return ValueEntryIterator<Filter>(first, m_entryCache.end(), filter);
|
|
}
|
|
|
|
template <class Filter>
|
|
ValueEntryIterator<Filter> VariableManager::getEnd (Filter filter) const
|
|
{
|
|
return ValueEntryIterator<Filter>(m_entryCache.end(), m_entryCache.end(), filter);
|
|
}
|
|
|
|
template <class Filter>
|
|
bool VariableManager::hasEntry (Filter filter) const
|
|
{
|
|
for (std::vector<const ValueEntry*>::const_iterator i = m_entryCache.begin(); i != m_entryCache.end(); i++)
|
|
{
|
|
if (filter(*i))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Common filters
|
|
|
|
class AnyEntry
|
|
{
|
|
public:
|
|
typedef ValueEntryIterator<AnyEntry> Iterator;
|
|
|
|
bool operator() (const ValueEntry* entry) const
|
|
{
|
|
DE_UNREF(entry);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class IsWritableEntry
|
|
{
|
|
public:
|
|
bool operator() (const ValueEntry* entry) const
|
|
{
|
|
switch (entry->getVariable()->getStorage())
|
|
{
|
|
case Variable::STORAGE_LOCAL:
|
|
case Variable::STORAGE_SHADER_OUT:
|
|
case Variable::STORAGE_PARAMETER_IN:
|
|
case Variable::STORAGE_PARAMETER_OUT:
|
|
case Variable::STORAGE_PARAMETER_INOUT:
|
|
return true;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
};
|
|
|
|
template <Variable::Storage Storage>
|
|
class EntryStorageFilter
|
|
{
|
|
public:
|
|
typedef ValueEntryIterator<EntryStorageFilter<Storage> > Iterator;
|
|
|
|
bool operator() (const ValueEntry* entry) const
|
|
{
|
|
return entry->getVariable()->getStorage() == Storage;
|
|
}
|
|
};
|
|
|
|
typedef EntryStorageFilter<Variable::STORAGE_LOCAL> LocalEntryFilter;
|
|
typedef EntryStorageFilter<Variable::STORAGE_SHADER_IN> ShaderInEntryFilter;
|
|
typedef EntryStorageFilter<Variable::STORAGE_SHADER_OUT> ShaderOutEntryFilter;
|
|
|
|
} // rsg
|
|
|
|
#endif // _RSGVARIABLEMANAGER_HPP
|