Merge "x11: Fix deadlock" into nougat-cts-dev am: 34b869eeea
[platform/upstream/VK-GL-CTS.git] / framework / randomshaders / rsgVariableValue.hpp
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