xref: /aosp_15_r20/external/deqp/framework/randomshaders/rsgVariableValue.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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