xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcUniformBlockCase.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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, uint32_t flags);
72     VarType(const VarType &elementType, int arraySize);
73     explicit VarType(const StructType *structPtr);
74     ~VarType(void);
75 
isBasicType(void) const76     bool isBasicType(void) const
77     {
78         return m_type == TYPE_BASIC;
79     }
isArrayType(void) const80     bool isArrayType(void) const
81     {
82         return m_type == TYPE_ARRAY;
83     }
isStructType(void) const84     bool isStructType(void) const
85     {
86         return m_type == TYPE_STRUCT;
87     }
88 
getFlags(void) const89     uint32_t getFlags(void) const
90     {
91         return m_flags;
92     }
getBasicType(void) const93     glu::DataType getBasicType(void) const
94     {
95         return m_data.basicType;
96     }
97 
getElementType(void) const98     const VarType &getElementType(void) const
99     {
100         return *m_data.array.elementType;
101     }
getArraySize(void) const102     int getArraySize(void) const
103     {
104         return m_data.array.size;
105     }
106 
getStruct(void) const107     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     uint32_t m_flags;
126     union Data
127     {
128         glu::DataType basicType;
129         struct
130         {
131             VarType *elementType;
132             int size;
133         } array;
134         const StructType *structPtr;
135 
Data(void)136         Data(void)
137         {
138             array.elementType = DE_NULL;
139             array.size        = 0;
140         }
141     } m_data;
142 };
143 
144 class StructMember
145 {
146 public:
StructMember(const char * name,const VarType & type,uint32_t flags)147     StructMember(const char *name, const VarType &type, uint32_t flags) : m_name(name), m_type(type), m_flags(flags)
148     {
149     }
StructMember(void)150     StructMember(void) : m_flags(0)
151     {
152     }
153 
getName(void) const154     const char *getName(void) const
155     {
156         return m_name.c_str();
157     }
getType(void) const158     const VarType &getType(void) const
159     {
160         return m_type;
161     }
getFlags(void) const162     uint32_t getFlags(void) const
163     {
164         return m_flags;
165     }
166 
167 private:
168     std::string m_name;
169     VarType m_type;
170     uint32_t m_flags;
171 };
172 
173 class StructType
174 {
175 public:
176     typedef std::vector<StructMember>::iterator Iterator;
177     typedef std::vector<StructMember>::const_iterator ConstIterator;
178 
StructType(const char * typeName)179     StructType(const char *typeName) : m_typeName(typeName)
180     {
181     }
~StructType(void)182     ~StructType(void)
183     {
184     }
185 
getTypeName(void) const186     const char *getTypeName(void) const
187     {
188         return m_typeName.empty() ? DE_NULL : m_typeName.c_str();
189     }
190 
begin(void)191     inline Iterator begin(void)
192     {
193         return m_members.begin();
194     }
begin(void) const195     inline ConstIterator begin(void) const
196     {
197         return m_members.begin();
198     }
end(void)199     inline Iterator end(void)
200     {
201         return m_members.end();
202     }
end(void) const203     inline ConstIterator end(void) const
204     {
205         return m_members.end();
206     }
207 
208     void addMember(const char *name, const VarType &type, uint32_t flags = 0);
209 
210 private:
211     std::string m_typeName;
212     std::vector<StructMember> m_members;
213 };
214 
215 class Uniform
216 {
217 public:
218     Uniform(const char *name, const VarType &type, uint32_t flags = 0);
219 
getName(void) const220     const char *getName(void) const
221     {
222         return m_name.c_str();
223     }
getType(void) const224     const VarType &getType(void) const
225     {
226         return m_type;
227     }
getFlags(void) const228     uint32_t getFlags(void) const
229     {
230         return m_flags;
231     }
232 
233 private:
234     std::string m_name;
235     VarType m_type;
236     uint32_t m_flags;
237 };
238 
239 class UniformBlock
240 {
241 public:
242     typedef std::vector<Uniform>::iterator Iterator;
243     typedef std::vector<Uniform>::const_iterator ConstIterator;
244 
245     UniformBlock(const char *blockName);
246 
getBlockName(void) const247     const char *getBlockName(void) const
248     {
249         return m_blockName.c_str();
250     }
getInstanceName(void) const251     const char *getInstanceName(void) const
252     {
253         return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();
254     }
isArray(void) const255     bool isArray(void) const
256     {
257         return m_arraySize > 0;
258     }
getArraySize(void) const259     int getArraySize(void) const
260     {
261         return m_arraySize;
262     }
getFlags(void) const263     uint32_t getFlags(void) const
264     {
265         return m_flags;
266     }
267 
setInstanceName(const char * name)268     void setInstanceName(const char *name)
269     {
270         m_instanceName = name;
271     }
setFlags(uint32_t flags)272     void setFlags(uint32_t flags)
273     {
274         m_flags = flags;
275     }
setArraySize(int arraySize)276     void setArraySize(int arraySize)
277     {
278         m_arraySize = arraySize;
279     }
addUniform(const Uniform & uniform)280     void addUniform(const Uniform &uniform)
281     {
282         m_uniforms.push_back(uniform);
283     }
284 
begin(void)285     inline Iterator begin(void)
286     {
287         return m_uniforms.begin();
288     }
begin(void) const289     inline ConstIterator begin(void) const
290     {
291         return m_uniforms.begin();
292     }
end(void)293     inline Iterator end(void)
294     {
295         return m_uniforms.end();
296     }
end(void) const297     inline ConstIterator end(void) const
298     {
299         return m_uniforms.end();
300     }
301 
302 private:
303     std::string m_blockName;
304     std::string m_instanceName;
305     std::vector<Uniform> m_uniforms;
306     int m_arraySize; //!< Array size or 0 if not interface block array.
307     uint32_t m_flags;
308 };
309 
310 class ShaderInterface
311 {
312 public:
313     ShaderInterface(void);
314     ~ShaderInterface(void);
315 
316     StructType &allocStruct(const char *name);
317     const StructType *findStruct(const char *name) const;
318     void getNamedStructs(std::vector<const StructType *> &structs) const;
319 
320     UniformBlock &allocBlock(const char *name);
321 
getNumUniformBlocks(void) const322     int getNumUniformBlocks(void) const
323     {
324         return (int)m_uniformBlocks.size();
325     }
getUniformBlock(int ndx) const326     const UniformBlock &getUniformBlock(int ndx) const
327     {
328         return *m_uniformBlocks[ndx];
329     }
330 
331 private:
332     std::vector<StructType *> m_structs;
333     std::vector<UniformBlock *> m_uniformBlocks;
334 };
335 
336 class UniformLayout;
337 
338 } // namespace ub
339 
340 class UniformBlockCase : public TestCase
341 {
342 public:
343     enum BufferMode
344     {
345         BUFFERMODE_SINGLE = 0, //!< Single buffer shared between uniform blocks.
346         BUFFERMODE_PER_BLOCK,  //!< Per-block buffers
347 
348         BUFFERMODE_LAST
349     };
350 
351     UniformBlockCase(Context &context, const char *name, const char *description, glu::GLSLVersion glslVersion,
352                      BufferMode bufferMode);
353     ~UniformBlockCase(void);
354 
355     IterateResult iterate(void);
356 
357 protected:
358     bool compareStd140Blocks(const ub::UniformLayout &refLayout, const ub::UniformLayout &cmpLayout) const;
359     bool compareSharedBlocks(const ub::UniformLayout &refLayout, const ub::UniformLayout &cmpLayout) const;
360     bool compareTypes(const ub::UniformLayout &refLayout, const ub::UniformLayout &cmpLayout) const;
361     bool checkLayoutIndices(const ub::UniformLayout &layout) const;
362     bool checkLayoutBounds(const ub::UniformLayout &layout) const;
363     bool checkIndexQueries(uint32_t program, const ub::UniformLayout &layout) const;
364 
365     bool render(glu::ShaderProgram &program) const;
366 
367     glu::GLSLVersion m_glslVersion;
368     BufferMode m_bufferMode;
369     ub::ShaderInterface m_interface;
370 };
371 
372 } // namespace deqp
373 
374 #endif // _GLCUNIFORMBLOCKCASE_HPP
375