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
Scalar(void)42 Scalar(void) : intVal(0)
43 {
44 }
Scalar(float v)45 Scalar(float v) : floatVal(v)
46 {
47 }
Scalar(int v)48 Scalar(int v) : intVal(v)
49 {
50 }
Scalar(bool v)51 Scalar(bool v) : boolVal(v)
52 {
53 }
54
55 // Bit-exact compare
operator ==(Scalar other) const56 bool operator==(Scalar other) const
57 {
58 return intVal == other.intVal;
59 }
operator !=(Scalar other) const60 bool operator!=(Scalar other) const
61 {
62 return intVal != other.intVal;
63 }
64
65 template <typename T>
66 static Scalar min(void);
67 template <typename T>
68 static Scalar max(void);
69
70 template <typename T>
71 T as(void) const;
72 template <typename T>
73 T &as(void);
74 };
75 DE_STATIC_ASSERT(sizeof(Scalar) == sizeof(uint32_t));
76
77 template <>
min(void)78 inline Scalar Scalar::min<float>(void)
79 {
80 return Scalar((int)0xff800000);
81 }
82 template <>
max(void)83 inline Scalar Scalar::max<float>(void)
84 {
85 return Scalar((int)0x7f800000);
86 }
87 template <>
min(void)88 inline Scalar Scalar::min<int>(void)
89 {
90 return Scalar((int)0x80000000);
91 }
92 template <>
max(void)93 inline Scalar Scalar::max<int>(void)
94 {
95 return Scalar((int)0x7fffffff);
96 }
97 template <>
min(void)98 inline Scalar Scalar::min<bool>(void)
99 {
100 return Scalar(false);
101 }
102 template <>
max(void)103 inline Scalar Scalar::max<bool>(void)
104 {
105 return Scalar(true);
106 }
107
108 template <>
as(void) const109 inline float Scalar::as<float>(void) const
110 {
111 return floatVal;
112 }
113 template <>
as(void)114 inline float &Scalar::as<float>(void)
115 {
116 return floatVal;
117 }
118 template <>
as(void) const119 inline int Scalar::as<int>(void) const
120 {
121 return intVal;
122 }
123 template <>
as(void)124 inline int &Scalar::as<int>(void)
125 {
126 return intVal;
127 }
128 template <>
as(void) const129 inline bool Scalar::as<bool>(void) const
130 {
131 return boolVal;
132 }
133 template <>
as(void)134 inline bool &Scalar::as<bool>(void)
135 {
136 return boolVal;
137 }
138
139 template <int Stride>
140 class StridedValueRead
141 {
142 public:
StridedValueRead(const VariableType & type,const Scalar * value)143 StridedValueRead(const VariableType &type, const Scalar *value) : m_type(type), m_value(value)
144 {
145 }
146
getType(void) const147 const VariableType &getType(void) const
148 {
149 return m_type;
150 }
getValuePtr(void) const151 const Scalar *getValuePtr(void) const
152 {
153 return m_value;
154 }
155
156 private:
157 const VariableType &m_type;
158 const Scalar *m_value;
159 };
160
161 template <int Stride>
162 class ConstStridedValueAccess
163 {
164 public:
ConstStridedValueAccess(void)165 ConstStridedValueAccess(void) : m_type(DE_NULL), m_value(DE_NULL)
166 {
167 }
ConstStridedValueAccess(const VariableType & type,const Scalar * valuePtr)168 ConstStridedValueAccess(const VariableType &type, const Scalar *valuePtr)
169 : m_type(&type)
170 , m_value(const_cast<Scalar *>(valuePtr))
171 {
172 }
173
getType(void) const174 const VariableType &getType(void) const
175 {
176 return *m_type;
177 }
178
179 // Read-only access
component(int compNdx) const180 ConstStridedValueAccess component(int compNdx) const
181 {
182 return ConstStridedValueAccess(getType().getElementType(), m_value + Stride * compNdx);
183 }
arrayElement(int elementNdx) const184 ConstStridedValueAccess arrayElement(int elementNdx) const
185 {
186 return ConstStridedValueAccess(getType().getElementType(),
187 m_value + Stride * getType().getElementScalarOffset(elementNdx));
188 }
member(int memberNdx) const189 ConstStridedValueAccess member(int memberNdx) const
190 {
191 return ConstStridedValueAccess(getType().getMembers()[memberNdx].getType(),
192 m_value + Stride * getType().getMemberScalarOffset(memberNdx));
193 }
194
asFloat(void) const195 float asFloat(void) const
196 {
197 DE_STATIC_ASSERT(Stride == 1);
198 return m_value->floatVal;
199 }
asInt(void) const200 int asInt(void) const
201 {
202 DE_STATIC_ASSERT(Stride == 1);
203 return m_value->intVal;
204 }
asBool(void) const205 bool asBool(void) const
206 {
207 DE_STATIC_ASSERT(Stride == 1);
208 return m_value->boolVal;
209 }
asScalar(void) const210 Scalar asScalar(void) const
211 {
212 DE_STATIC_ASSERT(Stride == 1);
213 return *m_value;
214 }
215
asFloat(int ndx) const216 float asFloat(int ndx) const
217 {
218 DE_ASSERT(de::inBounds(ndx, 0, Stride));
219 return m_value[ndx].floatVal;
220 }
asInt(int ndx) const221 int asInt(int ndx) const
222 {
223 DE_ASSERT(de::inBounds(ndx, 0, Stride));
224 return m_value[ndx].intVal;
225 }
asBool(int ndx) const226 bool asBool(int ndx) const
227 {
228 DE_ASSERT(de::inBounds(ndx, 0, Stride));
229 return m_value[ndx].boolVal;
230 }
asScalar(int ndx) const231 Scalar asScalar(int ndx) const
232 {
233 DE_ASSERT(de::inBounds(ndx, 0, Stride));
234 return m_value[ndx];
235 }
236
237 template <typename T>
as(int ndx) const238 T as(int ndx) const
239 {
240 DE_ASSERT(de::inBounds(ndx, 0, Stride));
241 return this->m_value[ndx].template as<T>();
242 }
243
244 // For assignment: b = a.value()
value(void) const245 StridedValueRead<Stride> value(void) const
246 {
247 return StridedValueRead<Stride>(getType(), m_value);
248 }
249
250 protected:
251 const VariableType *m_type;
252 Scalar
253 *m_value; // \note Non-const internal pointer is used so that ValueAccess can extend this class with RW access
254 };
255
256 template <int Stride>
257 class StridedValueAccess : public ConstStridedValueAccess<Stride>
258 {
259 public:
StridedValueAccess(void)260 StridedValueAccess(void)
261 {
262 }
StridedValueAccess(const VariableType & type,Scalar * valuePtr)263 StridedValueAccess(const VariableType &type, Scalar *valuePtr) : ConstStridedValueAccess<Stride>(type, valuePtr)
264 {
265 }
266
267 // Read-write access
component(int compNdx)268 StridedValueAccess component(int compNdx)
269 {
270 return StridedValueAccess(this->getType().getElementType(), this->m_value + Stride * compNdx);
271 }
arrayElement(int elementNdx)272 StridedValueAccess arrayElement(int elementNdx)
273 {
274 return StridedValueAccess(this->getType().getElementType(),
275 this->m_value + Stride * this->getType().getElementScalarOffset(elementNdx));
276 }
member(int memberNdx)277 StridedValueAccess member(int memberNdx)
278 {
279 return StridedValueAccess(this->getType().getMembers()[memberNdx].getType(),
280 this->m_value + Stride * this->getType().getMemberScalarOffset(memberNdx));
281 }
282
asFloat(void)283 float &asFloat(void)
284 {
285 DE_STATIC_ASSERT(Stride == 1);
286 return this->m_value->floatVal;
287 }
asInt(void)288 int &asInt(void)
289 {
290 DE_STATIC_ASSERT(Stride == 1);
291 return this->m_value->intVal;
292 }
asBool(void)293 bool &asBool(void)
294 {
295 DE_STATIC_ASSERT(Stride == 1);
296 return this->m_value->boolVal;
297 }
asScalar(void)298 Scalar &asScalar(void)
299 {
300 DE_STATIC_ASSERT(Stride == 1);
301 return *this->m_value;
302 }
303
asFloat(int ndx)304 float &asFloat(int ndx)
305 {
306 DE_ASSERT(de::inBounds(ndx, 0, Stride));
307 return this->m_value[ndx].floatVal;
308 }
asInt(int ndx)309 int &asInt(int ndx)
310 {
311 DE_ASSERT(de::inBounds(ndx, 0, Stride));
312 return this->m_value[ndx].intVal;
313 }
asBool(int ndx)314 bool &asBool(int ndx)
315 {
316 DE_ASSERT(de::inBounds(ndx, 0, Stride));
317 return this->m_value[ndx].boolVal;
318 }
asScalar(int ndx)319 Scalar &asScalar(int ndx)
320 {
321 DE_ASSERT(de::inBounds(ndx, 0, Stride));
322 return this->m_value[ndx];
323 }
324
325 template <typename T>
as(int ndx)326 T &as(int ndx)
327 {
328 DE_ASSERT(de::inBounds(ndx, 0, Stride));
329 return this->m_value[ndx].template as<T>();
330 }
331
332 template <int SrcStride>
333 StridedValueAccess &operator=(const StridedValueRead<SrcStride> &value);
334
335 // Helpers, work only in Stride == 1 case
336 template <int Size>
337 StridedValueAccess &operator=(const tcu::Vector<float, Size> &vec);
operator =(float floatVal)338 StridedValueAccess &operator=(float floatVal)
339 {
340 asFloat() = floatVal;
341 return *this;
342 }
operator =(int intVal)343 StridedValueAccess &operator=(int intVal)
344 {
345 asInt() = intVal;
346 return *this;
347 }
operator =(bool boolVal)348 StridedValueAccess &operator=(bool boolVal)
349 {
350 asBool() = boolVal;
351 return *this;
352 }
operator =(Scalar val)353 StridedValueAccess &operator=(Scalar val)
354 {
355 asScalar() = val;
356 return *this;
357 }
358 };
359
360 template <int Stride>
361 template <int SrcStride>
operator =(const StridedValueRead<SrcStride> & valueRead)362 StridedValueAccess<Stride> &StridedValueAccess<Stride>::operator=(const StridedValueRead<SrcStride> &valueRead)
363 {
364 DE_STATIC_ASSERT(SrcStride == Stride || SrcStride == 1);
365 DE_ASSERT(this->getType() == valueRead.getType());
366
367 int scalarSize = this->getType().getScalarSize();
368
369 if (scalarSize == 0)
370 return *this; // Happens when void value range is copied
371
372 if (Stride == SrcStride)
373 std::copy(valueRead.getValuePtr(), valueRead.getValuePtr() + scalarSize * Stride, this->m_value);
374 else
375 {
376 for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
377 std::fill(this->m_value + scalarNdx * Stride, this->m_value + (scalarNdx + 1) * Stride,
378 valueRead.getValuePtr()[scalarNdx]);
379 }
380
381 return *this;
382 }
383
384 template <int Stride>
385 template <int Size>
operator =(const tcu::Vector<float,Size> & vec)386 StridedValueAccess<Stride> &StridedValueAccess<Stride>::operator=(const tcu::Vector<float, Size> &vec)
387 {
388 DE_ASSERT(this->getType() == VariableType(VariableType::TYPE_FLOAT, Size));
389 for (int comp = 0; comp < 4; comp++)
390 component(comp).asFloat() = vec.getPtr()[comp];
391
392 return *this;
393 }
394
395 // Typedefs for stride == 1 case
396 typedef ConstStridedValueAccess<1> ConstValueAccess;
397 typedef StridedValueAccess<1> ValueAccess;
398
399 class ConstValueRangeAccess
400 {
401 public:
ConstValueRangeAccess(void)402 ConstValueRangeAccess(void) : m_type(DE_NULL), m_min(DE_NULL), m_max(DE_NULL)
403 {
404 }
ConstValueRangeAccess(const VariableType & type,const Scalar * minVal,const Scalar * maxVal)405 ConstValueRangeAccess(const VariableType &type, const Scalar *minVal, const Scalar *maxVal)
406 : m_type(&type)
407 , m_min(const_cast<Scalar *>(minVal))
408 , m_max(const_cast<Scalar *>(maxVal))
409 {
410 }
411
getType(void) const412 const VariableType &getType(void) const
413 {
414 return *m_type;
415 }
getMin(void) const416 ConstValueAccess getMin(void) const
417 {
418 return ConstValueAccess(*m_type, m_min);
419 }
getMax(void) const420 ConstValueAccess getMax(void) const
421 {
422 return ConstValueAccess(*m_type, m_max);
423 }
424
425 // Read-only access
426 ConstValueRangeAccess component(int compNdx) const;
427 ConstValueRangeAccess arrayElement(int elementNdx) const;
428 ConstValueRangeAccess member(int memberNdx) const;
429
430 // Set operations - tests condition for all elements
431 bool intersects(const ConstValueRangeAccess &other) const;
432 bool isSupersetOf(const ConstValueRangeAccess &other) const;
433 bool isSubsetOf(const ConstValueRangeAccess &other) const;
434
435 protected:
436 const VariableType *m_type;
437 Scalar *m_min; // \note See note in ConstValueAccess
438 Scalar *m_max;
439 };
440
component(int compNdx) const441 inline ConstValueRangeAccess ConstValueRangeAccess::component(int compNdx) const
442 {
443 return ConstValueRangeAccess(m_type->getElementType(), m_min + compNdx, m_max + compNdx);
444 }
445
arrayElement(int elementNdx) const446 inline ConstValueRangeAccess ConstValueRangeAccess::arrayElement(int elementNdx) const
447 {
448 int offset = m_type->getElementScalarOffset(elementNdx);
449 return ConstValueRangeAccess(m_type->getElementType(), m_min + offset, m_max + offset);
450 }
451
member(int memberNdx) const452 inline ConstValueRangeAccess ConstValueRangeAccess::member(int memberNdx) const
453 {
454 int offset = m_type->getMemberScalarOffset(memberNdx);
455 return ConstValueRangeAccess(m_type->getMembers()[memberNdx].getType(), m_min + offset, m_max + offset);
456 }
457
458 class ValueRangeAccess : public ConstValueRangeAccess
459 {
460 public:
ValueRangeAccess(const VariableType & type,Scalar * minVal,Scalar * maxVal)461 ValueRangeAccess(const VariableType &type, Scalar *minVal, Scalar *maxVal)
462 : ConstValueRangeAccess(type, minVal, maxVal)
463 {
464 }
465
466 // Read-write access
getMin(void)467 ValueAccess getMin(void)
468 {
469 return ValueAccess(*m_type, m_min);
470 }
getMax(void)471 ValueAccess getMax(void)
472 {
473 return ValueAccess(*m_type, m_max);
474 }
475
476 ValueRangeAccess component(int compNdx);
477 ValueRangeAccess arrayElement(int elementNdx);
478 ValueRangeAccess member(int memberNdx);
479 };
480
component(int compNdx)481 inline ValueRangeAccess ValueRangeAccess::component(int compNdx)
482 {
483 return ValueRangeAccess(m_type->getElementType(), m_min + compNdx, m_max + compNdx);
484 }
485
arrayElement(int elementNdx)486 inline ValueRangeAccess ValueRangeAccess::arrayElement(int elementNdx)
487 {
488 int offset = m_type->getElementScalarOffset(elementNdx);
489 return ValueRangeAccess(m_type->getElementType(), m_min + offset, m_max + offset);
490 }
491
member(int memberNdx)492 inline ValueRangeAccess ValueRangeAccess::member(int memberNdx)
493 {
494 int offset = m_type->getMemberScalarOffset(memberNdx);
495 return ValueRangeAccess(m_type->getMembers()[memberNdx].getType(), m_min + offset, m_max + offset);
496 }
497
498 class ValueRange
499 {
500 public:
501 ValueRange(const VariableType &type);
502 ValueRange(const VariableType &type, const ConstValueAccess &minVal, const ConstValueAccess &maxVal);
503 ValueRange(const VariableType &type, const Scalar *minVal, const Scalar *maxVal);
504 ValueRange(ConstValueRangeAccess other);
505 ~ValueRange(void);
506
getType(void) const507 const VariableType &getType(void) const
508 {
509 return m_type;
510 }
511
getMin(void)512 ValueAccess getMin(void)
513 {
514 return ValueAccess(m_type, getMinPtr());
515 }
getMax(void)516 ValueAccess getMax(void)
517 {
518 return ValueAccess(m_type, getMaxPtr());
519 }
520
getMin(void) const521 ConstValueAccess getMin(void) const
522 {
523 return ConstValueAccess(m_type, getMinPtr());
524 }
getMax(void) const525 ConstValueAccess getMax(void) const
526 {
527 return ConstValueAccess(m_type, getMaxPtr());
528 }
529
asAccess(void)530 ValueRangeAccess asAccess(void)
531 {
532 return ValueRangeAccess(m_type, getMinPtr(), getMaxPtr());
533 }
asAccess(void) const534 ConstValueRangeAccess asAccess(void) const
535 {
536 return ConstValueRangeAccess(m_type, getMinPtr(), getMaxPtr());
537 }
538
operator ConstValueRangeAccess(void) const539 operator ConstValueRangeAccess(void) const
540 {
541 return asAccess();
542 }
operator ValueRangeAccess(void)543 operator ValueRangeAccess(void)
544 {
545 return asAccess();
546 }
547
548 static void computeIntersection(ValueRangeAccess dst, const ConstValueRangeAccess &a,
549 const ConstValueRangeAccess &b);
550 static void computeIntersection(ValueRange &dst, const ConstValueRangeAccess &a, const ConstValueRangeAccess &b);
551
552 private:
getMinPtr(void) const553 const Scalar *getMinPtr(void) const
554 {
555 return m_min.empty() ? DE_NULL : &m_min[0];
556 }
getMaxPtr(void) const557 const Scalar *getMaxPtr(void) const
558 {
559 return m_max.empty() ? DE_NULL : &m_max[0];
560 }
561
getMinPtr(void)562 Scalar *getMinPtr(void)
563 {
564 return m_min.empty() ? DE_NULL : &m_min[0];
565 }
getMaxPtr(void)566 Scalar *getMaxPtr(void)
567 {
568 return m_max.empty() ? DE_NULL : &m_max[0];
569 }
570
571 VariableType m_type;
572 std::vector<Scalar> m_min;
573 std::vector<Scalar> m_max;
574 };
575
576 template <int Stride>
577 class ValueStorage
578 {
579 public:
580 ValueStorage(void);
581 ValueStorage(const VariableType &type);
582
583 void setStorage(const VariableType &type);
584
getValue(const VariableType & type)585 StridedValueAccess<Stride> getValue(const VariableType &type)
586 {
587 return StridedValueAccess<Stride>(type, &m_value[0]);
588 }
getValue(const VariableType & type) const589 ConstStridedValueAccess<Stride> getValue(const VariableType &type) const
590 {
591 return ConstStridedValueAccess<Stride>(type, &m_value[0]);
592 }
593
594 private:
595 ValueStorage(const ValueStorage &other);
596 ValueStorage operator=(const ValueStorage &other);
597
598 std::vector<Scalar> m_value;
599 };
600
601 template <int Stride>
ValueStorage(void)602 ValueStorage<Stride>::ValueStorage(void)
603 {
604 }
605
606 template <int Stride>
ValueStorage(const VariableType & type)607 ValueStorage<Stride>::ValueStorage(const VariableType &type)
608 {
609 setStorage(type);
610 }
611
612 template <int Stride>
setStorage(const VariableType & type)613 void ValueStorage<Stride>::setStorage(const VariableType &type)
614 {
615 m_value.resize(type.getScalarSize() * Stride);
616 }
617
618 class VariableValue
619 {
620 public:
VariableValue(const Variable * variable)621 VariableValue(const Variable *variable) : m_variable(variable), m_storage(m_variable->getType())
622 {
623 }
~VariableValue(void)624 ~VariableValue(void)
625 {
626 }
627
getVariable(void) const628 const Variable *getVariable(void) const
629 {
630 return m_variable;
631 }
getValue(void)632 ValueAccess getValue(void)
633 {
634 return m_storage.getValue(m_variable->getType());
635 }
getValue(void) const636 ConstValueAccess getValue(void) const
637 {
638 return m_storage.getValue(m_variable->getType());
639 }
640
641 VariableValue(const VariableValue &other);
642 VariableValue &operator=(const VariableValue &other);
643
644 private:
getType(void) const645 const VariableType &getType(void) const
646 {
647 return m_variable->getType();
648 }
649
650 const Variable *m_variable;
651 ValueStorage<1> m_storage;
652 };
653
654 } // namespace rsg
655
656 #endif // _RSGVARIABLEVALUE_HPP
657