13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Random Shader Generator
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Expressions.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgExpression.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgVariableManager.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgBinaryOps.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgBuiltinFunctions.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rsgUtils.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace rsg
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IsReadableEntry
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef ValueEntryIterator<IsReadableEntry> Iterator;
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsReadableEntry (deUint32 exprFlags)
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_exprFlags(exprFlags)
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool operator() (const ValueEntry* entry) const
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((m_exprFlags & CONST_EXPR) && (entry->getVariable()->getStorage() != Variable::STORAGE_CONST))
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 m_exprFlags;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IsReadableIntersectingEntry : public IsReadableEntry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef ValueEntryIterator<IsReadableIntersectingEntry> Iterator;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsReadableIntersectingEntry (ConstValueRangeAccess valueRange, deUint32 exprFlags)
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: IsReadableEntry	(exprFlags)
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_valueRange		(valueRange)
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool operator() (const ValueEntry* entry) const
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!IsReadableEntry::operator()(entry))
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (entry->getValueRange().getType() != m_valueRange.getType())
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!entry->getValueRange().intersects(m_valueRange))
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstValueRangeAccess m_valueRange;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IsWritableIntersectingEntry : public IsWritableEntry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef ValueEntryIterator<IsWritableIntersectingEntry> Iterator;
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsWritableIntersectingEntry (ConstValueRangeAccess valueRange)
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_valueRange(valueRange)
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool operator() (const ValueEntry* entry) const
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return IsWritableEntry::operator()(entry) &&
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   entry->getVariable()->getType() == m_valueRange.getType() &&
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   entry->getValueRange().intersects(m_valueRange);
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstValueRangeAccess m_valueRange;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IsWritableSupersetEntry : public IsWritableEntry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef ValueEntryIterator<IsWritableSupersetEntry> Iterator;
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsWritableSupersetEntry (ConstValueRangeAccess valueRange)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_valueRange(valueRange)
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool operator() (const ValueEntry* entry) const
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return IsWritableEntry()(entry) &&
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   entry->getVariable()->getType() == m_valueRange.getType() &&
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			   entry->getValueRange().isSupersetOf(m_valueRange);
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstValueRangeAccess m_valueRange;
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IsSamplerEntry
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef ValueEntryIterator<IsSamplerEntry> Iterator;
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsSamplerEntry (VariableType::Type type)
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: m_type(type)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_type == VariableType::TYPE_SAMPLER_2D || m_type == VariableType::TYPE_SAMPLER_CUBE);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool operator() (const ValueEntry* entry) const
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (entry->getVariable()->getType() == VariableType(m_type, 1))
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(entry->getVariable()->getStorage() == Variable::STORAGE_UNIFORM);
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VariableType::Type m_type;
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool getWeightedBool (de::Random& random, float trueWeight)
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inRange<float>(trueWeight, 0.0f, 1.0f));
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (random.getFloat() < trueWeight);
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid computeRandomValueRangeForInfElements (GeneratorState& state, ValueRangeAccess valueRange)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VariableType&	type	= valueRange.getType();
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random&		rnd		= state.getRandom();
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type.getBaseType())
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_BOOL:
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// No need to handle bool as it will be false, true
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_INT:
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < type.getNumElements(); ndx++)
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (valueRange.getMin().component(ndx).asScalar() != Scalar::min<int>() ||
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					valueRange.getMax().component(ndx).asScalar() != Scalar::max<int>())
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int minIntVal		= -16;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int maxIntVal		=  16;
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int maxRangeLen	= maxIntVal - minIntVal;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int rangeLen	= rnd.getInt(0, maxRangeLen);
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int minVal		= minIntVal + rnd.getInt(0, maxRangeLen-rangeLen);
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int maxVal		= minVal + rangeLen;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMin().component(ndx).asInt() = minVal;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMax().component(ndx).asInt() = maxVal;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_FLOAT:
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < type.getNumElements(); ndx++)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (valueRange.getMin().component(ndx).asScalar() != Scalar::min<float>() ||
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					valueRange.getMax().component(ndx).asScalar() != Scalar::max<float>())
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float step			= 0.1f;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int	maxSteps		= 320;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const float minFloatVal		= -16.0f;
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int rangeLen	= rnd.getInt(0, maxSteps);
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int minStep		= rnd.getInt(0, maxSteps-rangeLen);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float minVal	= minFloatVal + step*minStep;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float maxVal	= minVal + step*rangeLen;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMin().component(ndx).asFloat() = minVal;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMax().component(ndx).asFloat() = maxVal;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw Exception("computeRandomValueRangeForInfElements(): unsupported type");
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid setInfiniteRange (ValueRangeAccess valueRange)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VariableType& type = valueRange.getType();
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type.getBaseType())
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_BOOL:
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < type.getNumElements(); ndx++)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMin().component(ndx) = Scalar::min<bool>();
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMax().component(ndx) = Scalar::max<bool>();
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_INT:
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < type.getNumElements(); ndx++)
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMin().component(ndx) = Scalar::min<int>();
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMax().component(ndx) = Scalar::max<int>();
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_FLOAT:
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < type.getNumElements(); ndx++)
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMin().component(ndx) = Scalar::min<float>();
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				valueRange.getMax().component(ndx) = Scalar::max<float>();
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw Exception("setInfiniteRange(): unsupported type");
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool canAllocateVariable (const GeneratorState& state, const VariableType& type)
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!type.isVoid());
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getExpressionFlags() & NO_VAR_ALLOCATION)
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getVariableManager().getNumAllocatedScalars() + type.getScalarSize() > state.getShaderParameters().maxCombinedVariableScalars)
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class T> float		getWeight	(const GeneratorState& state, ConstValueRangeAccess valueRange)	{ return T::getWeight(state, valueRange);	}
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <class T> Expression*	create		(GeneratorState& state, ConstValueRangeAccess valueRange)		{ return new T(state, valueRange);			}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ExpressionSpec
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float			(*getWeight)		(const GeneratorState& state, ConstValueRangeAccess valueRange);
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Expression*		(*create)			(GeneratorState& state, ConstValueRangeAccess valueRange);
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const ExpressionSpec s_expressionSpecs[] =
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<FloatLiteral>,		create<FloatLiteral>		},
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<IntLiteral>,		create<IntLiteral>			},
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<BoolLiteral>,		create<BoolLiteral>			},
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<ConstructorOp>,		create<ConstructorOp>		},
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<AssignOp>,			create<AssignOp>			},
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<VariableRead>,		create<VariableRead>		},
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<MulOp>,				create<MulOp>				},
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<AddOp>,				create<AddOp>				},
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<SubOp>,				create<SubOp>				},
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<LessThanOp>,		create<LessThanOp>			},
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<LessOrEqualOp>,		create<LessOrEqualOp>		},
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<GreaterThanOp>,		create<GreaterThanOp>		},
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<GreaterOrEqualOp>,	create<GreaterOrEqualOp>	},
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<EqualOp>,			create<EqualOp>				},
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<NotEqualOp>,		create<NotEqualOp>			},
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<SwizzleOp>,			create<SwizzleOp>			},
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<SinOp>,				create<SinOp>				},
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<CosOp>,				create<CosOp>				},
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<TanOp>,				create<TanOp>				},
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<AsinOp>,			create<AsinOp>				},
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<AcosOp>,			create<AcosOp>				},
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<AtanOp>,			create<AtanOp>				},
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<ExpOp>,				create<ExpOp>				},
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<LogOp>,				create<LogOp>				},
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<Exp2Op>,			create<Exp2Op>				},
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<Log2Op>,			create<Log2Op>				},
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<SqrtOp>,			create<SqrtOp>				},
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<InvSqrtOp>,			create<InvSqrtOp>			},
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<ParenOp>,			create<ParenOp>				},
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<TexLookup>,			create<TexLookup>			}
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const ExpressionSpec s_lvalueSpecs[] =
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ getWeight<VariableWrite>,		create<VariableWrite>	}
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(DE_MAX)
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	define DE_MAX(a, b) ((b) > (a) ? (b) : (a))
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAX_EXPRESSION_SPECS = (int)DE_MAX(DE_LENGTH_OF_ARRAY(s_expressionSpecs), DE_LENGTH_OF_ARRAY(s_lvalueSpecs))
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst ExpressionSpec* chooseExpression (GeneratorState& state, const ExpressionSpec* specs, int numSpecs, ConstValueRangeAccess valueRange)
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float weights[MAX_EXPRESSION_SPECS];
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(numSpecs <= (int)DE_LENGTH_OF_ARRAY(weights));
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute weights
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numSpecs; ndx++)
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		weights[ndx] = specs[ndx].getWeight(state, valueRange);
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Choose
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return &state.getRandom().chooseWeighted<const ExpressionSpec&>(specs, specs+numSpecs, weights);
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpression::~Expression (void)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpression* Expression::createRandom (GeneratorState& state, ConstValueRangeAccess valueRange)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return chooseExpression(state, s_expressionSpecs, (int)DE_LENGTH_OF_ARRAY(s_expressionSpecs), valueRange)->create(state, valueRange);
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpression* Expression::createRandomLValue (GeneratorState& state, ConstValueRangeAccess valueRange)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return chooseExpression(state, s_lvalueSpecs, (int)DE_LENGTH_OF_ARRAY(s_lvalueSpecs), valueRange)->create(state, valueRange);
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFloatLiteral::FloatLiteral (GeneratorState& state, ConstValueRangeAccess valueRange)
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_value(VariableType::getScalarType(VariableType::TYPE_FLOAT))
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float minVal	= -10.0f;
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float maxVal	= +10.0f;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float step		= 0.25f;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType() == VariableType(VariableType::TYPE_FLOAT, 1))
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		minVal = valueRange.getMin().component(0).asFloat();
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		maxVal = valueRange.getMax().component(0).asFloat();
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (Scalar::min<float>() == minVal)
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			minVal = -10.0f;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (Scalar::max<float>() == maxVal)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxVal = +10.0f;
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numSteps = (int)((maxVal-minVal)/step) + 1;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float			value	= deFloatClamp(minVal + step*state.getRandom().getInt(0, numSteps), minVal, maxVal);
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecValueAccess	access	= m_value.getValue(VariableType::getScalarType(VariableType::TYPE_FLOAT));
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < EXEC_VEC_WIDTH; ndx++)
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		access.asFloat(ndx) = value;
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat FloatLiteral::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(state);
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VariableType& type = valueRange.getType();
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == VariableType(VariableType::TYPE_FLOAT, 1))
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float minVal = valueRange.getMin().asFloat();
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float maxVal = valueRange.getMax().asFloat();
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (Scalar::min<float>() == minVal && Scalar::max<float>() == maxVal)
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.1f;
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Weight based on value range length
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float rangeLength = maxVal - minVal;
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(rangeLength >= 0.0f);
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatMax(0.1f, 1.0f - rangeLength);
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isVoid())
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return unusedValueWeight;
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FloatLiteral::tokenize (GeneratorState& state, TokenStream& str) const
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(state);
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token(m_value.getValue(VariableType::getScalarType(VariableType::TYPE_FLOAT)).asFloat(0));
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIntLiteral::IntLiteral (GeneratorState& state, ConstValueRangeAccess valueRange)
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_value(VariableType::getScalarType(VariableType::TYPE_INT))
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int minVal = -16;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int maxVal = +16;
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType() == VariableType(VariableType::TYPE_INT, 1))
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		minVal = valueRange.getMin().component(0).asInt();
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		maxVal = valueRange.getMax().component(0).asInt();
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (Scalar::min<int>() == minVal)
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			minVal = -16;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (Scalar::max<int>() == maxVal)
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxVal = 16;
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				value	= state.getRandom().getInt(minVal, maxVal);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecValueAccess	access	= m_value.getValue(VariableType::getScalarType(VariableType::TYPE_INT));
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < EXEC_VEC_WIDTH; ndx++)
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		access.asInt(ndx) = value;
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat IntLiteral::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(state);
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VariableType& type = valueRange.getType();
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == VariableType(VariableType::TYPE_INT, 1))
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int minVal = valueRange.getMin().asInt();
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int maxVal = valueRange.getMax().asInt();
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (Scalar::min<int>() == minVal && Scalar::max<int>() == maxVal)
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.1f;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int rangeLength = maxVal - minVal;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(rangeLength >= 0);
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return deFloatMax(0.1f, 1.0f - rangeLength/4.0f);
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isVoid())
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return unusedValueWeight;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid IntLiteral::tokenize (GeneratorState& state, TokenStream& str) const
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(state);
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token(m_value.getValue(VariableType::getScalarType(VariableType::TYPE_INT)).asInt(0));
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBoolLiteral::BoolLiteral (GeneratorState& state, ConstValueRangeAccess valueRange)
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_value(VariableType::getScalarType(VariableType::TYPE_BOOL))
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int minVal = 0;
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int maxVal = 1;
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType() == VariableType(VariableType::TYPE_BOOL, 1))
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		minVal = valueRange.getMin().component(0).asBool() ? 1 : 0;
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		maxVal = valueRange.getMax().component(0).asBool() ? 1 : 0;
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			value	= state.getRandom().getInt(minVal, maxVal) == 1;
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecValueAccess	access	= m_value.getValue(VariableType::getScalarType(VariableType::TYPE_BOOL));
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < EXEC_VEC_WIDTH; ndx++)
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		access.asBool(ndx) = value;
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat BoolLiteral::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(state);
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VariableType& type = valueRange.getType();
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == VariableType(VariableType::TYPE_BOOL, 1))
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.5f;
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isVoid())
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return unusedValueWeight;
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BoolLiteral::tokenize (GeneratorState& state, TokenStream& str) const
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(state);
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token(m_value.getValue(VariableType::getScalarType(VariableType::TYPE_BOOL)).asBool(0));
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note int-bool and float-bool conversions handled in a special way.
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename SrcType, typename DstType>
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline DstType convert (SrcType src)
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (Scalar::min<SrcType>() == src)
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Scalar::min<DstType>().template as<DstType>();
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (Scalar::max<SrcType>() == src)
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Scalar::max<DstType>().template as<DstType>();
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DstType(src);
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// According to GLSL ES spec.
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline bool		convert<float, bool>	(float src)	{ return src != 0.0f;					}
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline bool		convert<int, bool>		(int src)	{ return src != 0;						}
52674a4e3ea85714c95b67c301cd06df7a78b59d832Pyry Haulostemplate <> inline bool		convert<bool, bool>		(bool src)	{ return src;							}
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline float	convert<bool, float>	(bool src)	{ return src ? 1.0f : 0.0f;				}
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline int		convert<bool, int>		(bool src)	{ return src ? 1 : 0;					}
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline int convert<float, int> (float src)
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (Scalar::min<float>() == src)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Scalar::min<int>().as<int>();
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (Scalar::max<float>() == src)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Scalar::max<int>().as<int>();
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (src > 0.0f)
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (int)deFloatFloor(src);
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return (int)deFloatCeil(src);
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename SrcType, typename DstType>
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void convertValueRange (SrcType srcMin, SrcType srcMax, DstType& dstMin, DstType& dstMax)
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstMin = convert<SrcType, DstType>(srcMin);
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstMax = convert<SrcType, DstType>(srcMax);
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void convertValueRange<float, int> (float srcMin, float srcMax, int& dstMin, int& dstMax)
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (Scalar::min<float>() == srcMin)
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dstMin = Scalar::min<int>().as<int>();
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dstMin = (int)deFloatCeil(srcMin);
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (Scalar::max<float>() == srcMax)
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dstMax = Scalar::max<int>().as<int>();
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dstMax = (int)deFloatFloor(srcMax);
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void convertValueRange<float, bool> (float srcMin, float srcMax, bool& dstMin, bool& dstMax)
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstMin = srcMin > 0.0f;
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstMax = srcMax > 0.0f;
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [pyry] More special cases?
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Returns whether it is possible to convert some SrcType value range to given DstType valueRange
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename SrcType, typename DstType>
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isConversionOk (DstType min, DstType max)
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SrcType sMin, sMax;
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	convertValueRange(min, max, sMin, sMax);
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return sMin <= sMax &&
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   de::inRange(convert<SrcType, DstType>(sMin), min, max) &&
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   de::inRange(convert<SrcType, DstType>(sMax), min, max);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Work-around for non-deterministic float behavior
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> bool isConversionOk<float, float> (float, float) { return true; }
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2011-03-26 pyry] Provide this in ValueAccess?
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>	T				getValueAccessValue			(ConstValueAccess access);
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>				inline float	getValueAccessValue<float>	(ConstValueAccess access) { return access.asFloat();	}
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>				inline int		getValueAccessValue<int>	(ConstValueAccess access) { return access.asInt();		}
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>				inline bool		getValueAccessValue<bool>	(ConstValueAccess access) { return access.asBool();		}
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>	T&				getValueAccessValue			(ValueAccess access);
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>				inline float&	getValueAccessValue<float>	(ValueAccess access) { return access.asFloat();		}
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>				inline int&		getValueAccessValue<int>	(ValueAccess access) { return access.asInt();		}
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>				inline bool&	getValueAccessValue<bool>	(ValueAccess access) { return access.asBool();		}
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename SrcType, typename DstType>
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isConversionOk (ConstValueRangeAccess valueRange)
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isConversionOk<SrcType>(getValueAccessValue<DstType>(valueRange.getMin()), getValueAccessValue<DstType>(valueRange.getMax()));
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename SrcType, typename DstType>
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid convertValueRangeTempl (ConstValueRangeAccess src, ValueRangeAccess dst)
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DstType dMin, dMax;
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	convertValueRange(getValueAccessValue<SrcType>(src.getMin()), getValueAccessValue<SrcType>(src.getMax()), dMin, dMax);
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getValueAccessValue<DstType>(dst.getMin()) = dMin;
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getValueAccessValue<DstType>(dst.getMax()) = dMax;
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename SrcType, typename DstType>
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid convertExecValueTempl (ExecConstValueAccess src, ExecValueAccess dst)
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < EXEC_VEC_WIDTH; ndx++)
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst.as<DstType>(ndx) = convert<SrcType, DstType>(src.as<SrcType>(ndx));
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef bool (*IsConversionOkFunc)		(ConstValueRangeAccess);
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef void (*ConvertValueRangeFunc)	(ConstValueRangeAccess, ValueRangeAccess);
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef void (*ConvertExecValueFunc)	(ExecConstValueAccess, ExecValueAccess);
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getBaseTypeConvNdx (VariableType::Type type)
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_FLOAT:	return 0;
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_INT:	return 1;
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_BOOL:	return 2;
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:						return -1;
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool isConversionOk (VariableType::Type srcType, VariableType::Type dstType, ConstValueRangeAccess valueRange)
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// [src][dst]
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const IsConversionOkFunc convTable[3][3] =
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ isConversionOk<float, float>, isConversionOk<float,	int>,	isConversionOk<float,	bool>	},
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ isConversionOk<int,	float>,	isConversionOk<int,		int>,	isConversionOk<int,		bool>	},
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ isConversionOk<bool,	float>,	isConversionOk<bool,	int>,	isConversionOk<bool,	bool>	}
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return convTable[getBaseTypeConvNdx(srcType)][getBaseTypeConvNdx(dstType)](valueRange);
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid convertValueRange (ConstValueRangeAccess src, ValueRangeAccess dst)
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// [src][dst]
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const ConvertValueRangeFunc convTable[3][3] =
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ convertValueRangeTempl<float, float>, convertValueRangeTempl<float,	int>,	convertValueRangeTempl<float,	bool>	},
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ convertValueRangeTempl<int,	float>,	convertValueRangeTempl<int,		int>,	convertValueRangeTempl<int,		bool>	},
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ convertValueRangeTempl<bool,	float>,	convertValueRangeTempl<bool,	int>,	convertValueRangeTempl<bool,	bool>	}
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	convTable[getBaseTypeConvNdx(src.getType().getBaseType())][getBaseTypeConvNdx(dst.getType().getBaseType())](src, dst);
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid convertExecValue (ExecConstValueAccess src, ExecValueAccess dst)
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// [src][dst]
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const ConvertExecValueFunc convTable[3][3] =
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ convertExecValueTempl<float,	float>,	convertExecValueTempl<float,	int>,	convertExecValueTempl<float,	bool>	},
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ convertExecValueTempl<int,	float>,	convertExecValueTempl<int,		int>,	convertExecValueTempl<int,		bool>	},
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ convertExecValueTempl<bool,	float>,	convertExecValueTempl<bool,		int>,	convertExecValueTempl<bool,		bool>	}
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	convTable[getBaseTypeConvNdx(src.getType().getBaseType())][getBaseTypeConvNdx(dst.getType().getBaseType())](src, dst);
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstructorOp::ConstructorOp (GeneratorState& state, ConstValueRangeAccess valueRange)
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_valueRange(valueRange)
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType().isVoid())
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Use random range
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int maxScalars = 4; // We don't have to be able to assign this value to anywhere
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_valueRange = ValueRange(computeRandomType(state, maxScalars));
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		computeRandomValueRange(state, m_valueRange.asAccess());
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2011-03-26 pyry] Vector conversions
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//	int						remainingDepth	= state.getShaderParameters().maxExpressionDepth - state.getExpressionDepth();
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VariableType&		type			= m_valueRange.getType();
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VariableType::Type		baseType		= type.getBaseType();
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						numScalars		= type.getNumElements();
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						curScalarNdx	= 0;
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2011-03-26 pyry] Separate op for struct constructors!
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(type.isFloatOrVec() || type.isIntOrVec() || type.isBoolOrVec());
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool scalarConversions = state.getProgramParameters().useScalarConversions;
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (curScalarNdx < numScalars)
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ConstValueRangeAccess comp = m_valueRange.asAccess().component(curScalarNdx);
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (scalarConversions)
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int					numInTypes = 0;
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			VariableType::Type	inTypes[3];
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isConversionOk(VariableType::TYPE_FLOAT, baseType, comp))	inTypes[numInTypes++] = VariableType::TYPE_FLOAT;
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isConversionOk(VariableType::TYPE_INT, baseType, comp))		inTypes[numInTypes++] = VariableType::TYPE_INT;
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isConversionOk(VariableType::TYPE_BOOL, baseType, comp))	inTypes[numInTypes++] = VariableType::TYPE_BOOL;
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(numInTypes > 0); // At least nop conversion should be ok
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Choose random
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			VariableType::Type inType = state.getRandom().choose<VariableType::Type>(&inTypes[0], &inTypes[0] + numInTypes);
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compute converted value range
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ValueRange inValueRange(VariableType(inType, 1));
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			convertValueRange(comp, inValueRange);
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_inputValueRanges.push_back(inValueRange);
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			curScalarNdx += 1;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_inputValueRanges.push_back(ValueRange(comp));
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			curScalarNdx += 1;
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryConstructorOp::~ConstructorOp (void)
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Expression*>::iterator i = m_inputExpressions.begin(); i != m_inputExpressions.end(); i++)
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7373c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpression* ConstructorOp::createNextChild (GeneratorState& state)
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					numChildren	= (int)m_inputExpressions.size();
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Expression*			child		= DE_NULL;
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Created in reverse order!
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numChildren < (int)m_inputValueRanges.size())
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ValueRange& inValueRange = m_inputValueRanges[m_inputValueRanges.size()-1-numChildren];
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		child = Expression::createRandom(state, inValueRange);
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		try
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_inputExpressions.push_back(child);
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		catch (const std::exception&)
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete child;
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw;
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return child;
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ConstructorOp::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType().isVoid())
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return unusedValueWeight;
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!valueRange.getType().isFloatOrVec() && !valueRange.getType().isIntOrVec() && !valueRange.getType().isBoolOrVec())
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getExpressionDepth() + getTypeConstructorDepth(valueRange.getType()) > state.getShaderParameters().maxExpressionDepth)
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 1.0f;
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConstructorOp::tokenize (GeneratorState& state, TokenStream& str) const
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VariableType& type = m_valueRange.getType();
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(type.getPrecision() == VariableType::PRECISION_NONE);
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	type.tokenizeShortType(str);
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::LEFT_PAREN;
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Expression*>::const_reverse_iterator i = m_inputExpressions.rbegin(); i != m_inputExpressions.rend(); i++)
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (i != m_inputExpressions.rbegin())
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			str << Token::COMMA;
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(*i)->tokenize(state, str);
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::RIGHT_PAREN;
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ConstructorOp::evaluate (ExecutionContext& evalCtx)
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Evaluate children
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Expression*>::reverse_iterator i = m_inputExpressions.rbegin(); i != m_inputExpressions.rend(); i++)
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(*i)->evaluate(evalCtx);
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute value
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VariableType& type = m_valueRange.getType();
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_value.setStorage(type);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecValueAccess	dst				= m_value.getValue(type);
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				curScalarNdx	= 0;
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<Expression*>::reverse_iterator i = m_inputExpressions.rbegin(); i != m_inputExpressions.rend(); i++)
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ExecConstValueAccess src = (*i)->getValue();
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int elemNdx = 0; elemNdx < src.getType().getNumElements(); elemNdx++)
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			convertExecValue(src.component(elemNdx), dst.component(curScalarNdx++));
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAssignOp::AssignOp (GeneratorState& state, ConstValueRangeAccess valueRange)
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_valueRange	(valueRange)
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_lvalueExpr	(DE_NULL)
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_rvalueExpr	(DE_NULL)
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_valueRange.getType().isVoid())
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute random value range
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int		maxScalars		= state.getShaderParameters().maxCombinedVariableScalars - state.getVariableManager().getNumAllocatedScalars();
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	useRandomRange	= !state.getVariableManager().hasEntry<IsWritableEntry>() || ((maxScalars > 0) && getWeightedBool(state.getRandom(), 0.1f));
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (useRandomRange)
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(maxScalars > 0);
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_valueRange = ValueRange(computeRandomType(state, maxScalars));
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeRandomValueRange(state, m_valueRange.asAccess());
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Use value range from random entry
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \todo [2011-02-28 pyry] Give lower weight to entries without range? Choose subtype range?
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ValueEntry* entry = state.getRandom().choose<const ValueEntry*>(state.getVariableManager().getBegin<IsWritableEntry>(), state.getVariableManager().getEnd<IsWritableEntry>());
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_valueRange = ValueRange(entry->getValueRange());
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeRandomValueRangeForInfElements(state, m_valueRange.asAccess());
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(state.getVariableManager().hasEntry(IsWritableIntersectingEntry(m_valueRange)));
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsWritableIntersectingEntry::Iterator first	= state.getVariableManager().getBegin(IsWritableIntersectingEntry(m_valueRange));
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsWritableIntersectingEntry::Iterator end	= state.getVariableManager().getEnd(IsWritableIntersectingEntry(m_valueRange));
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool possiblyCreateVar = canAllocateVariable(state, m_valueRange.getType()) &&
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 (first == end || getWeightedBool(state.getRandom(), 0.5f));
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!possiblyCreateVar)
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Find all possible valueranges matching given type and intersecting with valuerange
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \todo [pyry] Actually collect all ValueRanges, currently operates only on whole variables
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(first != end);
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Try to select one closest to given range but bigger (eg. superset)
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool supersetExists = false;
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (IsWritableIntersectingEntry::Iterator i = first; i != end; i++)
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((*i)->getValueRange().isSupersetOf(m_valueRange))
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				supersetExists = true;
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!supersetExists)
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Select some other range and compute intersection
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \todo [2011-02-03 pyry] Use some heuristics to select the range?
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstValueRangeAccess selectedRange = state.getRandom().choose<const ValueEntry*>(first, end)->getValueRange();
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ValueRange::computeIntersection(m_valueRange, m_valueRange, selectedRange);
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAssignOp::~AssignOp (void)
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_lvalueExpr;
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_rvalueExpr;
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat AssignOp::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!valueRange.getType().isVoid() &&
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!canAllocateVariable(state, valueRange.getType()) &&
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!state.getVariableManager().hasEntry(IsWritableIntersectingEntry(valueRange)))
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f; // Would require creating a new variable
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!valueRange.getType().isVoid() && state.getExpressionDepth() + getTypeConstructorDepth(valueRange.getType()) + 1 >= state.getShaderParameters().maxExpressionDepth)
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType().isVoid() &&
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!state.getVariableManager().hasEntry<IsWritableEntry>() &&
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().getNumAllocatedScalars() >= state.getShaderParameters().maxCombinedVariableScalars)
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f; // Can not allocate a new entry
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getExpressionDepth() == 0)
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 4.0f;
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f; // \todo [pyry] Fix assign ops
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpression* AssignOp::createNextChild (GeneratorState& state)
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_lvalueExpr == DE_NULL)
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Construct lvalue
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \todo [2011-03-14 pyry] Proper l-value generation:
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//  - pure L-value part is generated first
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//  - variable valuerange is made unbound
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//  - R-value is generated
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//  - R-values in L-value are generated
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_lvalueExpr = Expression::createRandomLValue(state, m_valueRange);
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_lvalueExpr;
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_rvalueExpr == DE_NULL)
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Construct value expr
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_rvalueExpr = Expression::createRandom(state, m_valueRange);
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_rvalueExpr;
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL;
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AssignOp::tokenize (GeneratorState& state, TokenStream& str) const
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_lvalueExpr->tokenize(state, str);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::EQUAL;
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_rvalueExpr->tokenize(state, str);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AssignOp::evaluate (ExecutionContext& evalCtx)
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Evaluate l-value
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_lvalueExpr->evaluate(evalCtx);
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Evaluate value
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_rvalueExpr->evaluate(evalCtx);
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_value.setStorage(m_valueRange.getType());
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_value.getValue(m_valueRange.getType()) = m_rvalueExpr->getValue().value();
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Assign
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	assignMasked(m_lvalueExpr->getLValue(), m_value.getValue(m_valueRange.getType()), evalCtx.getExecutionMask());
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool isShaderInOutSupportedType (const VariableType& type)
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2011-03-11 pyry] Float arrays, structs?
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return type.getBaseType() == VariableType::TYPE_FLOAT;
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariable* allocateNewVariable (GeneratorState& state, ConstValueRangeAccess valueRange)
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Variable* variable = state.getVariableManager().allocate(valueRange.getType());
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Update value range
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	state.getVariableManager().setValue(variable, valueRange);
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Random storage \todo [pyry] Check that scalar count in uniform/input classes is not exceeded
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const Variable::Storage storages[] =
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Variable::STORAGE_CONST,
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Variable::STORAGE_UNIFORM,
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Variable::STORAGE_LOCAL,
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Variable::STORAGE_SHADER_IN
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float weights[DE_LENGTH_OF_ARRAY(storages)];
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Dynamic vs. constant weight.
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float	dynWeight	= computeDynamicRangeWeight(valueRange);
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		numScalars	= valueRange.getType().getScalarSize();
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	uniformOk	= state.getVariableManager().getNumAllocatedUniformScalars() + numScalars <= state.getShaderParameters().maxUniformScalars;
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	shaderInOk	= isShaderInOutSupportedType(valueRange.getType()) &&
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						  (state.getVariableManager().getNumAllocatedShaderInVariables() + NUM_RESERVED_SHADER_INPUTS < state.getShaderParameters().maxInputVariables);
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	weights[0] = de::max(1.0f-dynWeight, 0.1f);
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	weights[1] = uniformOk ? dynWeight*0.5f : 0.0f;
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	weights[2] = dynWeight;
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	weights[3] = shaderInOk ? dynWeight*2.0f : 0.0f;
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	state.getVariableManager().setStorage(variable, state.getRandom().chooseWeighted<Variable::Storage>(&storages[0], &storages[DE_LENGTH_OF_ARRAY(storages)], &weights[0]));
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return variable;
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline float combineWeight (float curCombinedWeight, float partialWeight)
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return curCombinedWeight * partialWeight;
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat computeEntryReadWeight (ConstValueRangeAccess entryValueRange, ConstValueRangeAccess readValueRange)
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VariableType& type = entryValueRange.getType();
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(type == readValueRange.getType());
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float weight = 1.0f;
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type.getBaseType())
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_FLOAT:
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int elemNdx = 0; elemNdx < type.getNumElements(); elemNdx++)
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float entryMin	= entryValueRange.component(elemNdx).getMin().asFloat();
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float entryMax	= entryValueRange.component(elemNdx).getMax().asFloat();
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float readMin	= readValueRange.component(elemNdx).getMin().asFloat();
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float readMax	= readValueRange.component(elemNdx).getMax().asFloat();
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Check for -inf..inf ranges - they don't bring down the weight.
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (Scalar::min<float>() == entryMin && Scalar::max<float>() == entryMax)
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Intersection to entry value range length ratio.
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float intersectionMin		= deFloatMax(entryMin, readMin);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float intersectionMax		= deFloatMin(entryMax, readMax);
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float entryRangeLen			= entryMax - entryMin;
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float readRangeLen			= readMax - readMin;
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float intersectionLen		= intersectionMax - intersectionMin;
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float entryRatio			= (entryRangeLen	> 0.0f) ? (intersectionLen / entryRangeLen)	: 1.0f;
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float readRatio				= (readRangeLen		> 0.0f) ? (intersectionLen / readRangeLen)	: 1.0f;
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float elementWeight			= 0.5f*readRatio + 0.5f*entryRatio;
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				weight = combineWeight(weight, elementWeight);
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_INT:
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int elemNdx = 0; elemNdx < type.getNumElements(); elemNdx++)
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int entryMin	= entryValueRange.component(elemNdx).getMin().asInt();
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int entryMax	= entryValueRange.component(elemNdx).getMax().asInt();
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int readMin		= readValueRange.component(elemNdx).getMin().asInt();
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int readMax		= readValueRange.component(elemNdx).getMax().asInt();
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Check for -inf..inf ranges - they don't bring down the weight.
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (Scalar::min<int>() == entryMin && Scalar::max<int>() == entryMax)
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Intersection to entry value range length ratio.
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int intersectionMin			= deMax32(entryMin, readMin);
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int intersectionMax			= deMin32(entryMax, readMax);
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int entryRangeLen			= entryMax - entryMin;
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int readRangeLen			= readMax - readMin;
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int intersectionLen			= intersectionMax - intersectionMin;
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float entryRatio			= (entryRangeLen	> 0) ? ((float)intersectionLen / (float)entryRangeLen)	: 1.0f;
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float readRatio				= (readRangeLen		> 0) ? ((float)intersectionLen / (float)readRangeLen)	: 1.0f;
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float elementWeight			= 0.5f*readRatio + 0.5f*entryRatio;
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				weight = combineWeight(weight, elementWeight);
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_BOOL:
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \todo
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_ARRAY:
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case VariableType::TYPE_STRUCT:
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Unsupported type");
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deFloatMax(weight, 0.01f);
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableRead::VariableRead (GeneratorState& state, ConstValueRangeAccess valueRange)
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType().isVoid())
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IsReadableEntry	filter			= IsReadableEntry(state.getExpressionFlags());
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int				maxScalars		= state.getShaderParameters().maxCombinedVariableScalars - state.getVariableManager().getNumAllocatedScalars();
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			useRandomRange	= !state.getVariableManager().hasEntry(filter) || ((maxScalars > 0) && getWeightedBool(state.getRandom(), 0.5f));
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (useRandomRange)
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Allocate a new variable
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(maxScalars > 0);
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ValueRange newVarRange(computeRandomType(state, maxScalars));
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeRandomValueRange(state, newVarRange.asAccess());
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_variable = allocateNewVariable(state, newVarRange);
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Use random entry \todo [pyry] Handle -inf..inf ranges?
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_variable = state.getRandom().choose<const ValueEntry*>(state.getVariableManager().getBegin(filter), state.getVariableManager().getEnd(filter))->getVariable();
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Find variable that has value range that intersects with given range
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IsReadableIntersectingEntry::Iterator	first	= state.getVariableManager().getBegin(IsReadableIntersectingEntry(valueRange, state.getExpressionFlags()));
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IsReadableIntersectingEntry::Iterator	end		= state.getVariableManager().getEnd(IsReadableIntersectingEntry(valueRange, state.getExpressionFlags()));
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	createOnReadWeight		= 0.5f;
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool		createVar				= canAllocateVariable(state, valueRange.getType()) && (first == end || getWeightedBool(state.getRandom(), createOnReadWeight));
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (createVar)
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_variable = allocateNewVariable(state, valueRange);
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Copy value entries for computing weights.
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<const ValueEntry*>	availableVars;
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<float>				weights;
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::copy(first, end, std::inserter(availableVars, availableVars.begin()));
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compute weights.
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			weights.resize(availableVars.size());
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < (int)availableVars.size(); ndx++)
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				weights[ndx] = computeEntryReadWeight(availableVars[ndx]->getValueRange(), valueRange);
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Select.
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ValueEntry* entry = state.getRandom().chooseWeighted<const ValueEntry*>(availableVars.begin(), availableVars.end(), weights.begin());
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_variable = entry->getVariable();
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Compute intersection
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ValueRange intersection(m_variable->getType());
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ValueRange::computeIntersection(intersection, entry->getValueRange(), valueRange);
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.getVariableManager().setValue(m_variable, intersection);
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableRead::VariableRead (const Variable* variable)
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_variable = variable;
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat VariableRead::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType().isVoid())
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (state.getVariableManager().hasEntry(IsReadableEntry(state.getExpressionFlags())) ||
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.getVariableManager().getNumAllocatedScalars() < state.getShaderParameters().maxCombinedVariableScalars)
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return unusedValueWeight;
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0.0f;
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!canAllocateVariable(state, valueRange.getType()) &&
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!state.getVariableManager().hasEntry(IsReadableIntersectingEntry(valueRange, state.getExpressionFlags())))
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 1.0f;
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableWrite::VariableWrite (GeneratorState& state, ConstValueRangeAccess valueRange)
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!valueRange.getType().isVoid());
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find variable with range that is superset of given range
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsWritableSupersetEntry::Iterator	first	= state.getVariableManager().getBegin(IsWritableSupersetEntry(valueRange));
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsWritableSupersetEntry::Iterator	end		= state.getVariableManager().getEnd(IsWritableSupersetEntry(valueRange));
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	createOnAssignWeight	= 0.1f; // Will essentially create an unused variable
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool		createVar				= canAllocateVariable(state, valueRange.getType()) && (first == end || getWeightedBool(state.getRandom(), createOnAssignWeight));
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (createVar)
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_variable = state.getVariableManager().allocate(valueRange.getType());
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Storage will be LOCAL
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Choose random
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(first != end);
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ValueEntry* entry = state.getRandom().choose<const ValueEntry*>(first, end);
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_variable = entry->getVariable();
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_variable);
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Reset value range.
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ValueEntry* parentEntry = state.getVariableManager().getParentValue(m_variable);
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (parentEntry)
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Use parent value range.
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().setValue(m_variable, parentEntry->getValueRange());
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Use infinite range.
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueRange infRange(m_variable->getType());
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setInfiniteRange(infRange);
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().setValue(m_variable, infRange);
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat VariableWrite::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!canAllocateVariable(state, valueRange.getType()) &&
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!state.getVariableManager().hasEntry(IsWritableSupersetEntry(valueRange)))
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 1.0f;
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableAccess::evaluate (ExecutionContext& evalCtx)
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_valueAccess = evalCtx.getValue(m_variable);
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryParenOp::ParenOp (GeneratorState& state, ConstValueRangeAccess valueRange)
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_valueRange	(valueRange)
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_child		(DE_NULL)
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(state);
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryParenOp::~ParenOp (void)
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_child;
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpression* ParenOp::createNextChild (GeneratorState& state)
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_child == DE_NULL)
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_child = Expression::createRandom(state, m_valueRange);
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_child;
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL;
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ParenOp::tokenize (GeneratorState& state, TokenStream& str) const
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::LEFT_PAREN;
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_child->tokenize(state, str);
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::RIGHT_PAREN;
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat ParenOp::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType().isVoid())
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return state.getExpressionDepth() + 2 <= state.getShaderParameters().maxExpressionDepth ? unusedValueWeight : 0.0f;
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int requiredDepth = 1 + getConservativeValueExprDepth(state, valueRange);
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return state.getExpressionDepth() + requiredDepth <= state.getShaderParameters().maxExpressionDepth ? 1.0f : 0.0f;
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst int swizzlePrecedence = 2;
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12663c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySwizzleOp::SwizzleOp (GeneratorState& state, ConstValueRangeAccess valueRange)
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_outValueRange		(valueRange)
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numInputElements	(0)
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_child				(DE_NULL)
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_outValueRange.getType().isVoid()); // \todo [2011-06-13 pyry] Void support
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_outValueRange.getType().isFloatOrVec()	||
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  m_outValueRange.getType().isIntOrVec()	||
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			  m_outValueRange.getType().isBoolOrVec());
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_value.setStorage(m_outValueRange.getType());
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numOutputElements	= m_outValueRange.getType().getNumElements();
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Swizzle works for vector types only.
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2011-06-13 pyry] Use components multiple times.
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_numInputElements		= state.getRandom().getInt(deMax32(numOutputElements, 2), 4);
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::set<int> availableElements;
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < m_numInputElements; ndx++)
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		availableElements.insert(ndx);
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Randomize swizzle.
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int elemNdx = 0; elemNdx < (int)DE_LENGTH_OF_ARRAY(m_swizzle); elemNdx++)
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (elemNdx < numOutputElements)
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int inElemNdx = state.getRandom().choose<int>(availableElements.begin(), availableElements.end());
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			availableElements.erase(inElemNdx);
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_swizzle[elemNdx] = (deUint8)inElemNdx;
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_swizzle[elemNdx] = 0;
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13023c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySwizzleOp::~SwizzleOp (void)
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_child;
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpression* SwizzleOp::createNextChild (GeneratorState& state)
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_child)
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return DE_NULL;
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute input value range.
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VariableType	inVarType		= VariableType(m_outValueRange.getType().getBaseType(), m_numInputElements);
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueRange		inValueRange	= ValueRange(inVarType);
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Initialize all inputs to -inf..inf
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setInfiniteRange(inValueRange);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute intersections.
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numOutputElements = m_outValueRange.getType().getNumElements();
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int outElemNdx = 0; outElemNdx < numOutputElements; outElemNdx++)
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int inElemNdx = m_swizzle[outElemNdx];
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueRange::computeIntersection(inValueRange.asAccess().component(inElemNdx), inValueRange.asAccess().component(inElemNdx), m_outValueRange.asAccess().component(outElemNdx));
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create child.
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	state.pushPrecedence(swizzlePrecedence);
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_child = Expression::createRandom(state, inValueRange);
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	state.popPrecedence();
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_child;
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SwizzleOp::tokenize (GeneratorState& state, TokenStream& str) const
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		rgbaSet[]	= { "r", "g", "b", "a" };
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		xyzwSet[]	= { "x", "y", "z", "w" };
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*		stpqSet[]	= { "s", "t", "p", "q" };
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char**	swizzleSet	= DE_NULL;
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (state.getRandom().getInt(0, 2))
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 0: swizzleSet = rgbaSet; break;
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 1: swizzleSet = xyzwSet; break;
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 2: swizzleSet = stpqSet; break;
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default: DE_ASSERT(DE_FALSE);
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string swizzleStr;
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int elemNdx = 0; elemNdx < m_outValueRange.getType().getNumElements(); elemNdx++)
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		swizzleStr += swizzleSet[m_swizzle[elemNdx]];
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_child->tokenize(state, str);
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::DOT << Token(swizzleStr.c_str());
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat SwizzleOp::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!state.getProgramParameters().useSwizzle)
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getPrecedence() < swizzlePrecedence)
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!valueRange.getType().isFloatOrVec()	&&
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!valueRange.getType().isIntOrVec()		&&
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		!valueRange.getType().isBoolOrVec())
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int availableLevels = state.getShaderParameters().maxExpressionDepth - state.getExpressionDepth();
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Swizzle + Constructor + Values
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (availableLevels < 3)
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 1.0f;
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SwizzleOp::evaluate (ExecutionContext& execCtx)
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_child->evaluate(execCtx);
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecConstValueAccess	inValue		= m_child->getValue();
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecValueAccess			outValue	= m_value.getValue(m_outValueRange.getType());
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int outElemNdx = 0; outElemNdx < outValue.getType().getNumElements(); outElemNdx++)
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int inElemNdx = m_swizzle[outElemNdx];
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		outValue.component(outElemNdx) = inValue.component(inElemNdx).value();
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int countSamplers (const VariableManager& varManager, VariableType::Type samplerType)
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int numSamplers = 0;
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsSamplerEntry::Iterator	i		= varManager.getBegin(IsSamplerEntry(samplerType));
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IsSamplerEntry::Iterator	end		= varManager.getEnd(IsSamplerEntry(samplerType));
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (; i != end; i++)
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		numSamplers += 1;
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return numSamplers;
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexLookup::TexLookup (GeneratorState& state, ConstValueRangeAccess valueRange)
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_type			(TYPE_LAST)
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_coordExpr		(DE_NULL)
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_lodBiasExpr		(DE_NULL)
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_valueType		(VariableType::TYPE_FLOAT, 4)
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_value			(m_valueType)
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(valueRange.getType() == VariableType(VariableType::TYPE_FLOAT, 4));
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(valueRange); // Texture output value range is constant.
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Select type.
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Type> typeCandidates;
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getShaderParameters().useTexture2D)
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typeCandidates.push_back(TYPE_TEXTURE2D);
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typeCandidates.push_back(TYPE_TEXTURE2D_LOD);
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typeCandidates.push_back(TYPE_TEXTURE2D_PROJ);
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typeCandidates.push_back(TYPE_TEXTURE2D_PROJ_LOD);
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getShaderParameters().useTextureCube)
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typeCandidates.push_back(TYPE_TEXTURECUBE);
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typeCandidates.push_back(TYPE_TEXTURECUBE_LOD);
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_type = state.getRandom().choose<Type>(typeCandidates.begin(), typeCandidates.end());
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Select or allocate sampler.
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VariableType::Type samplerType = VariableType::TYPE_LAST;
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_type)
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURE2D:
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURE2D_LOD:
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURE2D_PROJ:
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURE2D_PROJ_LOD:
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			samplerType = VariableType::TYPE_SAMPLER_2D;
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURECUBE:
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURECUBE_LOD:
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			samplerType = VariableType::TYPE_SAMPLER_CUBE;
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		sampler2DCount		= countSamplers(state.getVariableManager(), VariableType::TYPE_SAMPLER_2D);
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		samplerCubeCount	= countSamplers(state.getVariableManager(), VariableType::TYPE_SAMPLER_CUBE);
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	canAllocSampler		= sampler2DCount + samplerCubeCount < state.getShaderParameters().maxSamplers;
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	hasSampler			= samplerType == VariableType::TYPE_SAMPLER_2D ? (sampler2DCount > 0) : (samplerCubeCount > 0);
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	allocSampler		= !hasSampler || (canAllocSampler && state.getRandom().getBool());
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (allocSampler)
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Variable* sampler = state.getVariableManager().allocate(VariableType(samplerType, 1));
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.getVariableManager().setStorage(sampler, Variable::STORAGE_UNIFORM); // Samplers are always uniforms.
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_sampler = sampler;
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_sampler = state.getRandom().choose<const ValueEntry*>(state.getVariableManager().getBegin(IsSamplerEntry(samplerType)),
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															    state.getVariableManager().getEnd(IsSamplerEntry(samplerType)))->getVariable();
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexLookup::~TexLookup (void)
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_coordExpr;
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_lodBiasExpr;
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryExpression* TexLookup::createNextChild (GeneratorState& state)
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool hasLodBias		= m_type == TYPE_TEXTURE2D_LOD ||
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						  m_type == TYPE_TEXTURE2D_PROJ_LOD ||
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						  m_type == TYPE_TEXTURECUBE_LOD;
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLodBias && !m_lodBiasExpr)
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ValueRange lodRange(VariableType(VariableType::TYPE_FLOAT, 1));
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setInfiniteRange(lodRange); // Any value is valid.
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_lodBiasExpr = Expression::createRandom(state, lodRange);
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_lodBiasExpr;
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_coordExpr)
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_type == TYPE_TEXTURECUBE || m_type == TYPE_TEXTURECUBE_LOD)
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Make sure major axis selection can be done.
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int majorAxisNdx = state.getRandom().getInt(0, 2);
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ValueRange coordRange(VariableType(VariableType::TYPE_FLOAT, 3));
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < 3; ndx++)
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (ndx == majorAxisNdx)
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					bool neg = state.getRandom().getBool();
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					coordRange.getMin().component(ndx) = neg ? -4.0f	: 2.25f;
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					coordRange.getMax().component(ndx) = neg ? -2.25f	: 4.0f;
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					coordRange.getMin().component(ndx) = -2.0f;
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					coordRange.getMax().component(ndx) =  2.0f;
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordExpr = Expression::createRandom(state, coordRange);
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool	isProj				= m_type == TYPE_TEXTURE2D_PROJ || m_type == TYPE_TEXTURE2D_PROJ_LOD;
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		coordScalarSize		= isProj ? 3 : 2;
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ValueRange coordRange(VariableType(VariableType::TYPE_FLOAT, coordScalarSize));
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setInfiniteRange(coordRange); // Initialize base range with -inf..inf
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isProj)
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// w coordinate must be something sane, and not 0.
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool neg = state.getRandom().getBool();
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				coordRange.getMin().component(2) = neg ? -4.0f  : 0.25f;
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				coordRange.getMax().component(2) = neg ? -0.25f : 4.0f;
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_coordExpr = Expression::createRandom(state, coordRange);
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_coordExpr);
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_coordExpr;
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_NULL; // Done.
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TexLookup::tokenize (GeneratorState& state, TokenStream& str) const
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool isVertex = state.getShader().getType() == Shader::TYPE_VERTEX;
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getProgramParameters().version == VERSION_300)
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_type)
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURE2D:			str << "texture";										break;
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURE2D_LOD:		str << (isVertex ? "textureLod" : "texture");			break;
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURE2D_PROJ:		str << "textureProj";									break;
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURE2D_PROJ_LOD:	str << (isVertex ? "textureProjLod" : "textureProj");	break;
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURECUBE:			str << "texture";										break;
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURECUBE_LOD:		str << (isVertex ? "textureLod" : "texture");			break;
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(DE_FALSE);
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_type)
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURE2D:			str << "texture2D";											break;
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURE2D_LOD:		str << (isVertex ? "texture2DLod" : "texture2D");			break;
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURE2D_PROJ:		str << "texture2DProj";										break;
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURE2D_PROJ_LOD:	str << (isVertex ? "texture2DProjLod" : "texture2DProj");	break;
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURECUBE:			str << "textureCube";										break;
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TYPE_TEXTURECUBE_LOD:		str << (isVertex ? "textureCubeLod" : "textureCube");		break;
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(DE_FALSE);
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::LEFT_PAREN;
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << m_sampler->getName();
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::COMMA;
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordExpr->tokenize(state, str);
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_lodBiasExpr)
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << Token::COMMA;
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_lodBiasExpr->tokenize(state, str);
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << Token::RIGHT_PAREN;
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat TexLookup::getWeight (const GeneratorState& state, ConstValueRangeAccess valueRange)
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getShaderParameters().texLookupBaseWeight <= 0.0f)
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int availableLevels = state.getShaderParameters().maxExpressionDepth - state.getExpressionDepth();
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Lookup + Constructor + Values
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (availableLevels < 3)
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (state.getExpressionFlags() & (CONST_EXPR|NO_VAR_ALLOCATION))
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (valueRange.getType() != VariableType(VariableType::TYPE_FLOAT, 4))
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ValueRange texOutputRange(VariableType(VariableType::TYPE_FLOAT, 4));
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < 4; ndx++)
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texOutputRange.getMin().component(ndx) = 0.0f;
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texOutputRange.getMax().component(ndx) = 1.0f;
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!valueRange.isSupersetOf(texOutputRange))
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0.0f;
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return state.getShaderParameters().texLookupBaseWeight;
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TexLookup::evaluate (ExecutionContext& execCtx)
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Evaluate coord and bias.
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_coordExpr->evaluate(execCtx);
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_lodBiasExpr)
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_lodBiasExpr->evaluate(execCtx);
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecConstValueAccess	coords	= m_coordExpr->getValue();
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ExecValueAccess			dst		= m_value.getValue(m_valueType);
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (m_type)
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURE2D:
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Sampler2D& tex = execCtx.getSampler2D(m_sampler);
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < EXEC_VEC_WIDTH; i++)
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		s	= coords.component(0).asFloat(i);
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		t	= coords.component(1).asFloat(i);
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4	p	= tex.sample(s, t, 0.0f);
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int comp = 0; comp < 4; comp++)
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.component(comp).asFloat(i) = p[comp];
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURE2D_LOD:
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ExecConstValueAccess	lod		= m_lodBiasExpr->getValue();
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Sampler2D&		tex		= execCtx.getSampler2D(m_sampler);
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < EXEC_VEC_WIDTH; i++)
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		s	= coords.component(0).asFloat(i);
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		t	= coords.component(1).asFloat(i);
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		l	= lod.component(0).asFloat(i);
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4	p	= tex.sample(s, t, l);
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int comp = 0; comp < 4; comp++)
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.component(comp).asFloat(i) = p[comp];
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURE2D_PROJ:
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Sampler2D& tex = execCtx.getSampler2D(m_sampler);
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < EXEC_VEC_WIDTH; i++)
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		s	= coords.component(0).asFloat(i);
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		t	= coords.component(1).asFloat(i);
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		w	= coords.component(2).asFloat(i);
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4	p	= tex.sample(s/w, t/w, 0.0f);
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int comp = 0; comp < 4; comp++)
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.component(comp).asFloat(i) = p[comp];
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURE2D_PROJ_LOD:
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ExecConstValueAccess	lod		= m_lodBiasExpr->getValue();
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Sampler2D&		tex		= execCtx.getSampler2D(m_sampler);
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < EXEC_VEC_WIDTH; i++)
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		s	= coords.component(0).asFloat(i);
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		t	= coords.component(1).asFloat(i);
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		w	= coords.component(2).asFloat(i);
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		l	= lod.component(0).asFloat(i);
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4	p	= tex.sample(s/w, t/w, l);
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int comp = 0; comp < 4; comp++)
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.component(comp).asFloat(i) = p[comp];
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURECUBE:
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const SamplerCube& tex = execCtx.getSamplerCube(m_sampler);
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < EXEC_VEC_WIDTH; i++)
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		s	= coords.component(0).asFloat(i);
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		t	= coords.component(1).asFloat(i);
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		r	= coords.component(2).asFloat(i);
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4	p	= tex.sample(s, t, r, 0.0f);
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int comp = 0; comp < 4; comp++)
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.component(comp).asFloat(i) = p[comp];
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_TEXTURECUBE_LOD:
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ExecConstValueAccess	lod		= m_lodBiasExpr->getValue();
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const SamplerCube&		tex		= execCtx.getSamplerCube(m_sampler);
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < EXEC_VEC_WIDTH; i++)
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		s	= coords.component(0).asFloat(i);
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		t	= coords.component(1).asFloat(i);
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		r	= coords.component(2).asFloat(i);
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float		l	= lod.component(0).asFloat(i);
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::Vec4	p	= tex.sample(s, t, r, l);
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int comp = 0; comp < 4; comp++)
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.component(comp).asFloat(i) = p[comp];
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // rsg
1740