Home | History | Annotate | Download | only in randomshaders
      1 #ifndef _RSGVARIABLEVALUE_HPP
      2 #define _RSGVARIABLEVALUE_HPP
      3 /*-------------------------------------------------------------------------
      4  * drawElements Quality Program Random Shader Generator
      5  * ----------------------------------------------------
      6  *
      7  * Copyright 2014 The Android Open Source Project
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  *//*!
     22  * \file
     23  * \brief Variable Value class.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "rsgDefs.hpp"
     27 #include "rsgVariableType.hpp"
     28 #include "rsgVariable.hpp"
     29 #include "tcuVector.hpp"
     30 
     31 #include <algorithm>
     32 
     33 namespace rsg
     34 {
     35 
     36 union Scalar
     37 {
     38 	int		intVal;
     39 	float	floatVal;
     40 	bool	boolVal;
     41 
     42 	Scalar (void)		: intVal	(0) {}
     43 	Scalar (float v)	: floatVal	(v) {}
     44 	Scalar (int v)		: intVal	(v) {}
     45 	Scalar (bool v)		: boolVal	(v) {}
     46 
     47 	// Bit-exact compare
     48 	bool operator== (Scalar other) const { return intVal == other.intVal; }
     49 	bool operator!= (Scalar other) const { return intVal != other.intVal; }
     50 
     51 	template <typename T> static Scalar min	(void);
     52 	template <typename T> static Scalar max	(void);
     53 
     54 	template <typename T> T		as (void) const;
     55 	template <typename T> T&	as (void);
     56 };
     57 DE_STATIC_ASSERT(sizeof(Scalar) == sizeof(deUint32));
     58 
     59 template <> inline Scalar Scalar::min<float>	(void)	{ return Scalar((int)0xff800000);	}
     60 template <> inline Scalar Scalar::max<float>	(void)	{ return Scalar((int)0x7f800000);	}
     61 template <> inline Scalar Scalar::min<int>		(void)	{ return Scalar((int)0x80000000);	}
     62 template <> inline Scalar Scalar::max<int>		(void)	{ return Scalar((int)0x7fffffff);	}
     63 template <> inline Scalar Scalar::min<bool>		(void)	{ return Scalar(false);				}
     64 template <> inline Scalar Scalar::max<bool>		(void)	{ return Scalar(true);				}
     65 
     66 template <> inline float	Scalar::as<float>	(void) const	{ return floatVal;	}
     67 template <> inline float&	Scalar::as<float>	(void)			{ return floatVal;	}
     68 template <> inline int		Scalar::as<int>		(void) const	{ return intVal;	}
     69 template <> inline int&		Scalar::as<int>		(void)			{ return intVal;	}
     70 template <> inline bool		Scalar::as<bool>	(void) const	{ return boolVal;	}
     71 template <> inline bool&	Scalar::as<bool>	(void)			{ return boolVal;	}
     72 
     73 template <int Stride>
     74 class StridedValueRead
     75 {
     76 public:
     77 								StridedValueRead		(const VariableType& type, const Scalar* value) : m_type(type), m_value(value) {}
     78 
     79 	const VariableType&			getType					(void) const			{ return m_type;	}
     80 	const Scalar*				getValuePtr				(void) const			{ return m_value;	}
     81 
     82 private:
     83 	const VariableType&			m_type;
     84 	const Scalar*				m_value;
     85 };
     86 
     87 template <int Stride>
     88 class ConstStridedValueAccess
     89 {
     90 public:
     91 								ConstStridedValueAccess	(void) : m_type(DE_NULL), m_value(DE_NULL) {}
     92 								ConstStridedValueAccess	(const VariableType& type, const Scalar* valuePtr) : m_type(&type), m_value(const_cast<Scalar*>(valuePtr)) {}
     93 
     94 	const VariableType&			getType					(void) const			{ return *m_type;			}
     95 
     96 	// Read-only access
     97 	ConstStridedValueAccess		component				(int compNdx) const		{ return ConstStridedValueAccess(getType().getElementType(), m_value + Stride*compNdx);													}
     98 	ConstStridedValueAccess		arrayElement			(int elementNdx) const	{ return ConstStridedValueAccess(getType().getElementType(), m_value + Stride*getType().getElementScalarOffset(elementNdx));				}
     99 	ConstStridedValueAccess		member					(int memberNdx) const	{ return ConstStridedValueAccess(getType().getMembers()[memberNdx].getType(), m_value + Stride*getType().getMemberScalarOffset(memberNdx));	}
    100 
    101 	float						asFloat					(void) const			{ DE_STATIC_ASSERT(Stride == 1); return m_value->floatVal;	}
    102 	int							asInt					(void) const			{ DE_STATIC_ASSERT(Stride == 1); return m_value->intVal;	}
    103 	bool						asBool					(void) const			{ DE_STATIC_ASSERT(Stride == 1); return m_value->boolVal;	}
    104 	Scalar						asScalar				(void) const			{ DE_STATIC_ASSERT(Stride == 1); return *m_value;			}
    105 
    106 	float						asFloat					(int ndx) const			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return m_value[ndx].floatVal;	}
    107 	int							asInt					(int ndx) const			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return m_value[ndx].intVal;	}
    108 	bool						asBool					(int ndx) const			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return m_value[ndx].boolVal;	}
    109 	Scalar						asScalar				(int ndx) const			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return m_value[ndx];			}
    110 
    111 	template <typename T>
    112 	T							as						(int ndx) const			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].template as<T>();	}
    113 
    114 	// For assignment: b = a.value()
    115 	StridedValueRead<Stride>	value					(void) const			{ return StridedValueRead<Stride>(getType(), m_value);		}
    116 
    117 protected:
    118 	const VariableType*			m_type;
    119 	Scalar*						m_value;	// \note Non-const internal pointer is used so that ValueAccess can extend this class with RW access
    120 };
    121 
    122 template <int Stride>
    123 class StridedValueAccess : public ConstStridedValueAccess<Stride>
    124 {
    125 public:
    126 								StridedValueAccess	(void) {}
    127 								StridedValueAccess	(const VariableType& type, Scalar* valuePtr) : ConstStridedValueAccess<Stride>(type, valuePtr) {}
    128 
    129 	// Read-write access
    130 	StridedValueAccess			component			(int compNdx)		{ return StridedValueAccess(this->getType().getElementType(), this->m_value + Stride*compNdx);													}
    131 	StridedValueAccess			arrayElement		(int elementNdx)	{ return StridedValueAccess(this->getType().getElementType(), this->m_value + Stride*this->getType().getElementScalarOffset(elementNdx));					}
    132 	StridedValueAccess			member				(int memberNdx)		{ return StridedValueAccess(this->getType().getMembers()[memberNdx].getType(), this->m_value + Stride*this->getType().getMemberScalarOffset(memberNdx));	}
    133 
    134 	float&						asFloat				(void)				{ DE_STATIC_ASSERT(Stride == 1); return this->m_value->floatVal;	}
    135 	int&						asInt				(void)				{ DE_STATIC_ASSERT(Stride == 1); return this->m_value->intVal;		}
    136 	bool&						asBool				(void)				{ DE_STATIC_ASSERT(Stride == 1); return this->m_value->boolVal;		}
    137 	Scalar&						asScalar			(void)				{ DE_STATIC_ASSERT(Stride == 1); return *this->m_value;				}
    138 
    139 	float&						asFloat				(int ndx)			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].floatVal;	}
    140 	int&						asInt				(int ndx)			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].intVal;		}
    141 	bool&						asBool				(int ndx)			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].boolVal;		}
    142 	Scalar&						asScalar			(int ndx)			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx];				}
    143 
    144 	template <typename T>
    145 	T&							as					(int ndx)			{ DE_ASSERT(de::inBounds(ndx, 0, Stride)); return this->m_value[ndx].template as<T>();		}
    146 
    147 	template <int SrcStride>
    148 	StridedValueAccess&			operator=			(const StridedValueRead<SrcStride>& value);
    149 
    150 	// Helpers, work only in Stride == 1 case
    151 	template <int Size>
    152 	StridedValueAccess&			operator=			(const tcu::Vector<float, Size>& vec);
    153 	StridedValueAccess&			operator=			(float floatVal)	{ asFloat()		= floatVal;	return *this;	}
    154 	StridedValueAccess&			operator=			(int intVal)		{ asInt()		= intVal;	return *this;	}
    155 	StridedValueAccess&			operator=			(bool boolVal)		{ asBool()		= boolVal;	return *this;	}
    156 	StridedValueAccess&			operator=			(Scalar val)		{ asScalar()	= val;		return *this;	}
    157 };
    158 
    159 template <int Stride>
    160 template <int SrcStride>
    161 StridedValueAccess<Stride>& StridedValueAccess<Stride>::operator= (const StridedValueRead<SrcStride>& valueRead)
    162 {
    163 	DE_STATIC_ASSERT(SrcStride == Stride || SrcStride == 1);
    164 	DE_ASSERT(this->getType() == valueRead.getType());
    165 
    166 	int scalarSize = this->getType().getScalarSize();
    167 
    168 	if (scalarSize == 0)
    169 		return *this; // Happens when void value range is copied
    170 
    171 	if (Stride == SrcStride)
    172 		std::copy(valueRead.getValuePtr(), valueRead.getValuePtr() + scalarSize*Stride, this->m_value);
    173 	else
    174 	{
    175 		for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
    176 			std::fill(this->m_value + scalarNdx*Stride, this->m_value + (scalarNdx+1)*Stride, valueRead.getValuePtr()[scalarNdx]);
    177 	}
    178 
    179 	return *this;
    180 }
    181 
    182 template <int Stride>
    183 template <int Size>
    184 StridedValueAccess<Stride>& StridedValueAccess<Stride>::operator= (const tcu::Vector<float, Size>& vec)
    185 {
    186 	DE_ASSERT(this->getType() == VariableType(VariableType::TYPE_FLOAT, Size));
    187 	for (int comp = 0; comp < 4; comp++)
    188 		component(comp).asFloat() = vec.getPtr()[comp];
    189 
    190 	return *this;
    191 }
    192 
    193 // Typedefs for stride == 1 case
    194 typedef ConstStridedValueAccess<1>	ConstValueAccess;
    195 typedef StridedValueAccess<1>		ValueAccess;
    196 
    197 class ConstValueRangeAccess
    198 {
    199 public:
    200 								ConstValueRangeAccess	(void) : m_type(DE_NULL), m_min(DE_NULL), m_max(DE_NULL) {}
    201 								ConstValueRangeAccess	(const VariableType& type, const Scalar* minVal, const Scalar* maxVal) : m_type(&type), m_min(const_cast<Scalar*>(minVal)), m_max(const_cast<Scalar*>(maxVal)) {}
    202 
    203 	const VariableType&			getType					(void) const	{ return *m_type;							}
    204 	ConstValueAccess			getMin					(void) const	{ return ConstValueAccess(*m_type, m_min);	}
    205 	ConstValueAccess			getMax					(void) const	{ return ConstValueAccess(*m_type, m_max);	}
    206 
    207 	// Read-only access
    208 	ConstValueRangeAccess		component				(int compNdx) const;
    209 	ConstValueRangeAccess		arrayElement			(int elementNdx) const;
    210 	ConstValueRangeAccess		member					(int memberNdx) const;
    211 
    212 	// Set operations - tests condition for all elements
    213 	bool						intersects				(const ConstValueRangeAccess& other) const;
    214 	bool						isSupersetOf			(const ConstValueRangeAccess& other) const;
    215 	bool						isSubsetOf				(const ConstValueRangeAccess& other) const;
    216 
    217 protected:
    218 	const VariableType*			m_type;
    219 	Scalar*						m_min;	// \note See note in ConstValueAccess
    220 	Scalar*						m_max;
    221 };
    222 
    223 inline ConstValueRangeAccess ConstValueRangeAccess::component (int compNdx) const
    224 {
    225 	return ConstValueRangeAccess(m_type->getElementType(), m_min + compNdx, m_max + compNdx);
    226 }
    227 
    228 inline ConstValueRangeAccess ConstValueRangeAccess::arrayElement (int elementNdx) const
    229 {
    230 	int offset = m_type->getElementScalarOffset(elementNdx);
    231 	return ConstValueRangeAccess(m_type->getElementType(), m_min + offset, m_max + offset);
    232 }
    233 
    234 inline ConstValueRangeAccess ConstValueRangeAccess::member (int memberNdx) const
    235 {
    236 	int offset = m_type->getMemberScalarOffset(memberNdx);
    237 	return ConstValueRangeAccess(m_type->getMembers()[memberNdx].getType(), m_min + offset, m_max + offset);
    238 }
    239 
    240 class ValueRangeAccess : public ConstValueRangeAccess
    241 {
    242 public:
    243 								ValueRangeAccess		(const VariableType& type, Scalar* minVal, Scalar* maxVal) : ConstValueRangeAccess(type, minVal, maxVal) {}
    244 
    245 	// Read-write access
    246 	ValueAccess					getMin					(void) { return ValueAccess(*m_type, m_min);	}
    247 	ValueAccess					getMax					(void) { return ValueAccess(*m_type, m_max);	}
    248 
    249 	ValueRangeAccess			component				(int compNdx);
    250 	ValueRangeAccess			arrayElement			(int elementNdx);
    251 	ValueRangeAccess			member					(int memberNdx);
    252 };
    253 
    254 inline ValueRangeAccess ValueRangeAccess::component (int compNdx)
    255 {
    256 	return ValueRangeAccess(m_type->getElementType(), m_min + compNdx, m_max + compNdx);
    257 }
    258 
    259 inline ValueRangeAccess ValueRangeAccess::arrayElement (int elementNdx)
    260 {
    261 	int offset = m_type->getElementScalarOffset(elementNdx);
    262 	return ValueRangeAccess(m_type->getElementType(), m_min + offset, m_max + offset);
    263 }
    264 
    265 inline ValueRangeAccess ValueRangeAccess::member (int memberNdx)
    266 {
    267 	int offset = m_type->getMemberScalarOffset(memberNdx);
    268 	return ValueRangeAccess(m_type->getMembers()[memberNdx].getType(), m_min + offset, m_max + offset);
    269 }
    270 
    271 class ValueRange
    272 {
    273 public:
    274 								ValueRange			(const VariableType& type);
    275 								ValueRange			(const VariableType& type, const ConstValueAccess& minVal, const ConstValueAccess& maxVal);
    276 								ValueRange			(const VariableType& type, const Scalar* minVal, const Scalar* maxVal);
    277 								ValueRange			(ConstValueRangeAccess other);
    278 								~ValueRange			(void);
    279 
    280 	const VariableType&			getType				(void) const	{ return m_type;								}
    281 
    282 	ValueAccess					getMin				(void)			{ return ValueAccess(m_type, getMinPtr());		}
    283 	ValueAccess					getMax				(void)			{ return ValueAccess(m_type, getMaxPtr());		}
    284 
    285 	ConstValueAccess			getMin				(void) const	{ return ConstValueAccess(m_type, getMinPtr());	}
    286 	ConstValueAccess			getMax				(void) const	{ return ConstValueAccess(m_type, getMaxPtr());	}
    287 
    288 	ValueRangeAccess			asAccess			(void)			{ return ValueRangeAccess(m_type, getMinPtr(), getMaxPtr());		}
    289 	ConstValueRangeAccess		asAccess			(void) const	{ return ConstValueRangeAccess(m_type, getMinPtr(), getMaxPtr());	}
    290 
    291 	operator ConstValueRangeAccess					(void) const	{ return asAccess();							}
    292 	operator ValueRangeAccess						(void)			{ return asAccess();							}
    293 
    294 	static void					computeIntersection	(ValueRangeAccess dst, const ConstValueRangeAccess& a, const ConstValueRangeAccess& b);
    295 	static void					computeIntersection	(ValueRange& dst, const ConstValueRangeAccess& a, const ConstValueRangeAccess& b);
    296 
    297 private:
    298 	const Scalar*				getMinPtr			(void) const	{ return m_min.empty() ? DE_NULL : &m_min[0];	}
    299 	const Scalar*				getMaxPtr			(void) const	{ return m_max.empty() ? DE_NULL : &m_max[0];	}
    300 
    301 	Scalar*						getMinPtr			(void)			{ return m_min.empty() ? DE_NULL : &m_min[0];	}
    302 	Scalar*						getMaxPtr			(void)			{ return m_max.empty() ? DE_NULL : &m_max[0];	}
    303 
    304 	VariableType				m_type;
    305 	std::vector<Scalar>			m_min;
    306 	std::vector<Scalar>			m_max;
    307 };
    308 
    309 template <int Stride>
    310 class ValueStorage
    311 {
    312 public:
    313 										ValueStorage		(void);
    314 										ValueStorage		(const VariableType& type);
    315 
    316 	void								setStorage			(const VariableType& type);
    317 
    318 	StridedValueAccess<Stride>			getValue			(const VariableType& type)			{ return StridedValueAccess<Stride>(type, &m_value[0]);			}
    319 	ConstStridedValueAccess<Stride>		getValue			(const VariableType& type) const	{ return ConstStridedValueAccess<Stride>(type, &m_value[0]);	}
    320 
    321 private:
    322 										ValueStorage		(const ValueStorage& other);
    323 	ValueStorage						operator=			(const ValueStorage& other);
    324 
    325 	std::vector<Scalar>					m_value;
    326 };
    327 
    328 template <int Stride>
    329 ValueStorage<Stride>::ValueStorage (void)
    330 {
    331 }
    332 
    333 template <int Stride>
    334 ValueStorage<Stride>::ValueStorage (const VariableType& type)
    335 {
    336 	setStorage(type);
    337 }
    338 
    339 template <int Stride>
    340 void ValueStorage<Stride>::setStorage (const VariableType& type)
    341 {
    342 	m_value.resize(type.getScalarSize() * Stride);
    343 }
    344 
    345 class VariableValue
    346 {
    347 public:
    348 							VariableValue		(const Variable* variable) : m_variable(variable), m_storage(m_variable->getType()) {}
    349 							~VariableValue		(void) {}
    350 
    351 	const Variable*			getVariable			(void) const	{ return m_variable;								}
    352 	ValueAccess				getValue			(void)			{ return m_storage.getValue(m_variable->getType());	}
    353 	ConstValueAccess		getValue			(void) const	{ return m_storage.getValue(m_variable->getType());	}
    354 
    355 							VariableValue		(const VariableValue& other);
    356 	VariableValue&			operator=			(const VariableValue& other);
    357 
    358 private:
    359 	const VariableType&		getType				(void) const	{ return m_variable->getType();						}
    360 
    361 	const Variable*			m_variable;
    362 	ValueStorage<1>			m_storage;
    363 };
    364 
    365 } // rsg
    366 
    367 #endif // _RSGVARIABLEVALUE_HPP
    368