Always apply flat qualifier to double inputs, same as int/uint
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcUniformBlockCase.hpp
1 #ifndef _GLCUNIFORMBLOCKCASE_HPP
2 #define _GLCUNIFORMBLOCKCASE_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2016 Google Inc.
8  * Copyright (c) 2016 The Khronos Group Inc.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */ /*!
23  * \file
24  * \brief Uniform block tests.
25  */ /*-------------------------------------------------------------------*/
26
27 #include "glcTestCase.hpp"
28 #include "gluShaderProgram.hpp"
29 #include "gluShaderUtil.hpp"
30 #include "tcuDefs.hpp"
31
32 namespace deqp
33 {
34
35 // Uniform block details.
36 namespace ub
37 {
38
39 enum UniformFlags
40 {
41         PRECISION_LOW   = (1 << 0),
42         PRECISION_MEDIUM = (1 << 1),
43         PRECISION_HIGH   = (1 << 2),
44         PRECISION_MASK   = PRECISION_LOW | PRECISION_MEDIUM | PRECISION_HIGH,
45
46         LAYOUT_SHARED           = (1 << 3),
47         LAYOUT_PACKED           = (1 << 4),
48         LAYOUT_STD140           = (1 << 5),
49         LAYOUT_ROW_MAJOR        = (1 << 6),
50         LAYOUT_COLUMN_MAJOR = (1 << 7), //!< \note Lack of both flags means column-major matrix.
51         LAYOUT_MASK                     = LAYOUT_SHARED | LAYOUT_PACKED | LAYOUT_STD140 | LAYOUT_ROW_MAJOR | LAYOUT_COLUMN_MAJOR,
52
53         DECLARE_VERTEX   = (1 << 8),
54         DECLARE_FRAGMENT = (1 << 9),
55         DECLARE_BOTH     = DECLARE_VERTEX | DECLARE_FRAGMENT,
56
57         UNUSED_VERTEX   = (1 << 10), //!< Uniform or struct member is not read in vertex shader.
58         UNUSED_FRAGMENT = (1 << 11), //!< Uniform or struct member is not read in fragment shader.
59         UNUSED_BOTH             = UNUSED_VERTEX | UNUSED_FRAGMENT
60 };
61
62 // \todo [2012-07-25 pyry] Use glu::VarType.
63
64 class StructType;
65
66 class VarType
67 {
68 public:
69         VarType(void);
70         VarType(const VarType& other);
71         VarType(glu::DataType basicType, deUint32 flags);
72         VarType(const VarType& elementType, int arraySize);
73         explicit VarType(const StructType* structPtr);
74         ~VarType(void);
75
76         bool isBasicType(void) const
77         {
78                 return m_type == TYPE_BASIC;
79         }
80         bool isArrayType(void) const
81         {
82                 return m_type == TYPE_ARRAY;
83         }
84         bool isStructType(void) const
85         {
86                 return m_type == TYPE_STRUCT;
87         }
88
89         deUint32 getFlags(void) const
90         {
91                 return m_flags;
92         }
93         glu::DataType getBasicType(void) const
94         {
95                 return m_data.basicType;
96         }
97
98         const VarType& getElementType(void) const
99         {
100                 return *m_data.array.elementType;
101         }
102         int getArraySize(void) const
103         {
104                 return m_data.array.size;
105         }
106
107         const StructType& getStruct(void) const
108         {
109                 return *m_data.structPtr;
110         }
111
112         VarType& operator=(const VarType& other);
113
114 private:
115         enum Type
116         {
117                 TYPE_BASIC,
118                 TYPE_ARRAY,
119                 TYPE_STRUCT,
120
121                 TYPE_LAST
122         };
123
124         Type     m_type;
125         deUint32 m_flags;
126         union Data {
127                 glu::DataType basicType;
128                 struct
129                 {
130                         VarType* elementType;
131                         int              size;
132                 } array;
133                 const StructType* structPtr;
134
135                 Data(void)
136                 {
137                         array.elementType = DE_NULL;
138                         array.size                = 0;
139                 };
140         } m_data;
141 };
142
143 class StructMember
144 {
145 public:
146         StructMember(const char* name, const VarType& type, deUint32 flags) : m_name(name), m_type(type), m_flags(flags)
147         {
148         }
149         StructMember(void) : m_flags(0)
150         {
151         }
152
153         const char* getName(void) const
154         {
155                 return m_name.c_str();
156         }
157         const VarType& getType(void) const
158         {
159                 return m_type;
160         }
161         deUint32 getFlags(void) const
162         {
163                 return m_flags;
164         }
165
166 private:
167         std::string m_name;
168         VarType         m_type;
169         deUint32        m_flags;
170 };
171
172 class StructType
173 {
174 public:
175         typedef std::vector<StructMember>::iterator               Iterator;
176         typedef std::vector<StructMember>::const_iterator ConstIterator;
177
178         StructType(const char* typeName) : m_typeName(typeName)
179         {
180         }
181         ~StructType(void)
182         {
183         }
184
185         const char* getTypeName(void) const
186         {
187                 return m_typeName.empty() ? DE_NULL : m_typeName.c_str();
188         }
189
190         inline Iterator begin(void)
191         {
192                 return m_members.begin();
193         }
194         inline ConstIterator begin(void) const
195         {
196                 return m_members.begin();
197         }
198         inline Iterator end(void)
199         {
200                 return m_members.end();
201         }
202         inline ConstIterator end(void) const
203         {
204                 return m_members.end();
205         }
206
207         void addMember(const char* name, const VarType& type, deUint32 flags = 0);
208
209 private:
210         std::string                               m_typeName;
211         std::vector<StructMember> m_members;
212 };
213
214 class Uniform
215 {
216 public:
217         Uniform(const char* name, const VarType& type, deUint32 flags = 0);
218
219         const char* getName(void) const
220         {
221                 return m_name.c_str();
222         }
223         const VarType& getType(void) const
224         {
225                 return m_type;
226         }
227         deUint32 getFlags(void) const
228         {
229                 return m_flags;
230         }
231
232 private:
233         std::string m_name;
234         VarType         m_type;
235         deUint32        m_flags;
236 };
237
238 class UniformBlock
239 {
240 public:
241         typedef std::vector<Uniform>::iterator           Iterator;
242         typedef std::vector<Uniform>::const_iterator ConstIterator;
243
244         UniformBlock(const char* blockName);
245
246         const char* getBlockName(void) const
247         {
248                 return m_blockName.c_str();
249         }
250         const char* getInstanceName(void) const
251         {
252                 return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();
253         }
254         bool isArray(void) const
255         {
256                 return m_arraySize > 0;
257         }
258         int getArraySize(void) const
259         {
260                 return m_arraySize;
261         }
262         deUint32 getFlags(void) const
263         {
264                 return m_flags;
265         }
266
267         void setInstanceName(const char* name)
268         {
269                 m_instanceName = name;
270         }
271         void setFlags(deUint32 flags)
272         {
273                 m_flags = flags;
274         }
275         void setArraySize(int arraySize)
276         {
277                 m_arraySize = arraySize;
278         }
279         void addUniform(const Uniform& uniform)
280         {
281                 m_uniforms.push_back(uniform);
282         }
283
284         inline Iterator begin(void)
285         {
286                 return m_uniforms.begin();
287         }
288         inline ConstIterator begin(void) const
289         {
290                 return m_uniforms.begin();
291         }
292         inline Iterator end(void)
293         {
294                 return m_uniforms.end();
295         }
296         inline ConstIterator end(void) const
297         {
298                 return m_uniforms.end();
299         }
300
301 private:
302         std::string                      m_blockName;
303         std::string                      m_instanceName;
304         std::vector<Uniform> m_uniforms;
305         int                                      m_arraySize; //!< Array size or 0 if not interface block array.
306         deUint32                         m_flags;
307 };
308
309 class ShaderInterface
310 {
311 public:
312         ShaderInterface(void);
313         ~ShaderInterface(void);
314
315         StructType& allocStruct(const char* name);
316         const StructType* findStruct(const char* name) const;
317         void getNamedStructs(std::vector<const StructType*>& structs) const;
318
319         UniformBlock& allocBlock(const char* name);
320
321         int getNumUniformBlocks(void) const
322         {
323                 return (int)m_uniformBlocks.size();
324         }
325         const UniformBlock& getUniformBlock(int ndx) const
326         {
327                 return *m_uniformBlocks[ndx];
328         }
329
330 private:
331         std::vector<StructType*>   m_structs;
332         std::vector<UniformBlock*> m_uniformBlocks;
333 };
334
335 class UniformLayout;
336
337 } // ub
338
339 class UniformBlockCase : public TestCase
340 {
341 public:
342         enum BufferMode
343         {
344                 BUFFERMODE_SINGLE = 0, //!< Single buffer shared between uniform blocks.
345                 BUFFERMODE_PER_BLOCK,  //!< Per-block buffers
346
347                 BUFFERMODE_LAST
348         };
349
350         UniformBlockCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion,
351                                          BufferMode bufferMode);
352         ~UniformBlockCase(void);
353
354         IterateResult iterate(void);
355
356 protected:
357         bool compareStd140Blocks(const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const;
358         bool compareSharedBlocks(const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const;
359         bool compareTypes(const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const;
360         bool checkLayoutIndices(const ub::UniformLayout& layout) const;
361         bool checkLayoutBounds(const ub::UniformLayout& layout) const;
362         bool checkIndexQueries(deUint32 program, const ub::UniformLayout& layout) const;
363
364         bool render(glu::ShaderProgram& program) const;
365
366         glu::GLSLVersion        m_glslVersion;
367         BufferMode                      m_bufferMode;
368         ub::ShaderInterface m_interface;
369 };
370
371 } // deqp
372
373 #endif // _GLCUNIFORMBLOCKCASE_HPP