xref: /aosp_15_r20/external/deqp/modules/glshared/glsUniformBlockCase.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _GLSUNIFORMBLOCKCASE_HPP
2 #define _GLSUNIFORMBLOCKCASE_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program OpenGL (ES) Module
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 Uniform block tests.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "tcuDefs.hpp"
27 #include "tcuTestCase.hpp"
28 #include "gluShaderUtil.hpp"
29 
30 namespace glu
31 {
32 class RenderContext;
33 }
34 
35 namespace deqp
36 {
37 namespace gls
38 {
39 
40 // Uniform block details.
41 namespace ub
42 {
43 
44 enum UniformFlags
45 {
46     PRECISION_LOW    = (1 << 0),
47     PRECISION_MEDIUM = (1 << 1),
48     PRECISION_HIGH   = (1 << 2),
49     PRECISION_MASK   = PRECISION_LOW | PRECISION_MEDIUM | PRECISION_HIGH,
50 
51     LAYOUT_SHARED       = (1 << 3),
52     LAYOUT_PACKED       = (1 << 4),
53     LAYOUT_STD140       = (1 << 5),
54     LAYOUT_ROW_MAJOR    = (1 << 6),
55     LAYOUT_COLUMN_MAJOR = (1 << 7), //!< \note Lack of both flags means column-major matrix.
56     LAYOUT_MASK         = LAYOUT_SHARED | LAYOUT_PACKED | LAYOUT_STD140 | LAYOUT_ROW_MAJOR | LAYOUT_COLUMN_MAJOR,
57 
58     DECLARE_VERTEX   = (1 << 8),
59     DECLARE_FRAGMENT = (1 << 9),
60     DECLARE_BOTH     = DECLARE_VERTEX | DECLARE_FRAGMENT,
61 
62     UNUSED_VERTEX   = (1 << 10), //!< Uniform or struct member is not read in vertex shader.
63     UNUSED_FRAGMENT = (1 << 11), //!< Uniform or struct member is not read in fragment shader.
64     UNUSED_BOTH     = UNUSED_VERTEX | UNUSED_FRAGMENT
65 };
66 
67 // \todo [2012-07-25 pyry] Use glu::VarType.
68 
69 class StructType;
70 
71 class VarType
72 {
73 public:
74     VarType(void);
75     VarType(const VarType &other);
76     VarType(glu::DataType basicType, uint32_t flags);
77     VarType(const VarType &elementType, int arraySize);
78     explicit VarType(const StructType *structPtr, uint32_t flags = 0u);
79     ~VarType(void);
80 
isBasicType(void) const81     bool isBasicType(void) const
82     {
83         return m_type == TYPE_BASIC;
84     }
isArrayType(void) const85     bool isArrayType(void) const
86     {
87         return m_type == TYPE_ARRAY;
88     }
isStructType(void) const89     bool isStructType(void) const
90     {
91         return m_type == TYPE_STRUCT;
92     }
93 
getFlags(void) const94     uint32_t getFlags(void) const
95     {
96         return m_flags;
97     }
getBasicType(void) const98     glu::DataType getBasicType(void) const
99     {
100         return m_data.basicType;
101     }
102 
getElementType(void) const103     const VarType &getElementType(void) const
104     {
105         return *m_data.array.elementType;
106     }
getArraySize(void) const107     int getArraySize(void) const
108     {
109         return m_data.array.size;
110     }
111 
getStruct(void) const112     const StructType &getStruct(void) const
113     {
114         return *m_data.structPtr;
115     }
116 
117     VarType &operator=(const VarType &other);
118 
119 private:
120     enum Type
121     {
122         TYPE_BASIC,
123         TYPE_ARRAY,
124         TYPE_STRUCT,
125 
126         TYPE_LAST
127     };
128 
129     Type m_type;
130     uint32_t m_flags;
131     union Data
132     {
133         glu::DataType basicType;
134         struct
135         {
136             VarType *elementType;
137             int size;
138         } array;
139         const StructType *structPtr;
140 
Data(void)141         Data(void)
142         {
143             array.elementType = DE_NULL;
144             array.size        = 0;
145         }
146     } m_data;
147 };
148 
149 class StructMember
150 {
151 public:
StructMember(const char * name,const VarType & type,uint32_t flags)152     StructMember(const char *name, const VarType &type, uint32_t flags) : m_name(name), m_type(type), m_flags(flags)
153     {
154     }
StructMember(void)155     StructMember(void) : m_flags(0)
156     {
157     }
158 
getName(void) const159     const char *getName(void) const
160     {
161         return m_name.c_str();
162     }
getType(void) const163     const VarType &getType(void) const
164     {
165         return m_type;
166     }
getFlags(void) const167     uint32_t getFlags(void) const
168     {
169         return m_flags;
170     }
171 
172 private:
173     std::string m_name;
174     VarType m_type;
175     uint32_t m_flags;
176 };
177 
178 class StructType
179 {
180 public:
181     typedef std::vector<StructMember>::iterator Iterator;
182     typedef std::vector<StructMember>::const_iterator ConstIterator;
183 
StructType(const char * typeName)184     StructType(const char *typeName) : m_typeName(typeName)
185     {
186     }
~StructType(void)187     ~StructType(void)
188     {
189     }
190 
getTypeName(void) const191     const char *getTypeName(void) const
192     {
193         return m_typeName.empty() ? DE_NULL : m_typeName.c_str();
194     }
195 
begin(void)196     inline Iterator begin(void)
197     {
198         return m_members.begin();
199     }
begin(void) const200     inline ConstIterator begin(void) const
201     {
202         return m_members.begin();
203     }
end(void)204     inline Iterator end(void)
205     {
206         return m_members.end();
207     }
end(void) const208     inline ConstIterator end(void) const
209     {
210         return m_members.end();
211     }
212 
213     void addMember(const char *name, const VarType &type, uint32_t flags = 0);
214 
215 private:
216     std::string m_typeName;
217     std::vector<StructMember> m_members;
218 };
219 
220 class Uniform
221 {
222 public:
223     Uniform(const char *name, const VarType &type, uint32_t flags = 0);
224 
getName(void) const225     const char *getName(void) const
226     {
227         return m_name.c_str();
228     }
getType(void) const229     const VarType &getType(void) const
230     {
231         return m_type;
232     }
getFlags(void) const233     uint32_t getFlags(void) const
234     {
235         return m_flags;
236     }
237 
238 private:
239     std::string m_name;
240     VarType m_type;
241     uint32_t m_flags;
242 };
243 
244 class UniformBlock
245 {
246 public:
247     typedef std::vector<Uniform>::iterator Iterator;
248     typedef std::vector<Uniform>::const_iterator ConstIterator;
249 
250     UniformBlock(const char *blockName);
251 
getBlockName(void) const252     const char *getBlockName(void) const
253     {
254         return m_blockName.c_str();
255     }
getInstanceName(void) const256     const char *getInstanceName(void) const
257     {
258         return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();
259     }
isArray(void) const260     bool isArray(void) const
261     {
262         return m_arraySize > 0;
263     }
getArraySize(void) const264     int getArraySize(void) const
265     {
266         return m_arraySize;
267     }
getFlags(void) const268     uint32_t getFlags(void) const
269     {
270         return m_flags;
271     }
272 
setInstanceName(const char * name)273     void setInstanceName(const char *name)
274     {
275         m_instanceName = name;
276     }
setFlags(uint32_t flags)277     void setFlags(uint32_t flags)
278     {
279         m_flags = flags;
280     }
setArraySize(int arraySize)281     void setArraySize(int arraySize)
282     {
283         m_arraySize = arraySize;
284     }
addUniform(const Uniform & uniform)285     void addUniform(const Uniform &uniform)
286     {
287         m_uniforms.push_back(uniform);
288     }
289 
begin(void)290     inline Iterator begin(void)
291     {
292         return m_uniforms.begin();
293     }
begin(void) const294     inline ConstIterator begin(void) const
295     {
296         return m_uniforms.begin();
297     }
end(void)298     inline Iterator end(void)
299     {
300         return m_uniforms.end();
301     }
end(void) const302     inline ConstIterator end(void) const
303     {
304         return m_uniforms.end();
305     }
306 
307 private:
308     std::string m_blockName;
309     std::string m_instanceName;
310     std::vector<Uniform> m_uniforms;
311     int m_arraySize; //!< Array size or 0 if not interface block array.
312     uint32_t m_flags;
313 };
314 
315 class ShaderInterface
316 {
317 public:
318     ShaderInterface(void);
319     ~ShaderInterface(void);
320 
321     StructType &allocStruct(const char *name);
322     const StructType *findStruct(const char *name) const;
323     void getNamedStructs(std::vector<const StructType *> &structs) const;
324 
325     UniformBlock &allocBlock(const char *name);
326 
getNumUniformBlocks(void) const327     int getNumUniformBlocks(void) const
328     {
329         return (int)m_uniformBlocks.size();
330     }
getUniformBlock(int ndx) const331     const UniformBlock &getUniformBlock(int ndx) const
332     {
333         return *m_uniformBlocks[ndx];
334     }
335 
336 private:
337     std::vector<StructType *> m_structs;
338     std::vector<UniformBlock *> m_uniformBlocks;
339 };
340 
341 class UniformLayout;
342 
343 } // namespace ub
344 
345 class UniformBlockCase : public tcu::TestCase
346 {
347 public:
348     enum BufferMode
349     {
350         BUFFERMODE_SINGLE = 0, //!< Single buffer shared between uniform blocks.
351         BUFFERMODE_PER_BLOCK,  //!< Per-block buffers
352 
353         BUFFERMODE_LAST
354     };
355 
356     UniformBlockCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name,
357                      const char *description, glu::GLSLVersion glslVersion, BufferMode bufferMode);
358     ~UniformBlockCase(void);
359 
360     IterateResult iterate(void);
361 
362 protected:
363     bool compareStd140Blocks(const ub::UniformLayout &refLayout, const ub::UniformLayout &cmpLayout) const;
364     bool compareSharedBlocks(const ub::UniformLayout &refLayout, const ub::UniformLayout &cmpLayout) const;
365     bool compareTypes(const ub::UniformLayout &refLayout, const ub::UniformLayout &cmpLayout) const;
366     bool checkLayoutIndices(const ub::UniformLayout &layout) const;
367     bool checkLayoutBounds(const ub::UniformLayout &layout) const;
368     bool checkIndexQueries(uint32_t program, const ub::UniformLayout &layout) const;
369 
370     bool render(uint32_t program) const;
371 
372     glu::RenderContext &m_renderCtx;
373     glu::GLSLVersion m_glslVersion;
374     BufferMode m_bufferMode;
375     ub::ShaderInterface m_interface;
376 };
377 
378 } // namespace gls
379 } // namespace deqp
380 
381 #endif // _GLSUNIFORMBLOCKCASE_HPP
382