• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 	deUint32 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 	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 
Data(void)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:
StructMember(const char * name,const VarType & type,deUint32 flags)146 	StructMember(const char* name, const VarType& type, deUint32 flags) : m_name(name), m_type(type), m_flags(flags)
147 	{
148 	}
StructMember(void)149 	StructMember(void) : m_flags(0)
150 	{
151 	}
152 
getName(void) const153 	const char* getName(void) const
154 	{
155 		return m_name.c_str();
156 	}
getType(void) const157 	const VarType& getType(void) const
158 	{
159 		return m_type;
160 	}
getFlags(void) const161 	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 
StructType(const char * typeName)178 	StructType(const char* typeName) : m_typeName(typeName)
179 	{
180 	}
~StructType(void)181 	~StructType(void)
182 	{
183 	}
184 
getTypeName(void) const185 	const char* getTypeName(void) const
186 	{
187 		return m_typeName.empty() ? DE_NULL : m_typeName.c_str();
188 	}
189 
begin(void)190 	inline Iterator begin(void)
191 	{
192 		return m_members.begin();
193 	}
begin(void) const194 	inline ConstIterator begin(void) const
195 	{
196 		return m_members.begin();
197 	}
end(void)198 	inline Iterator end(void)
199 	{
200 		return m_members.end();
201 	}
end(void) const202 	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 
getName(void) const219 	const char* getName(void) const
220 	{
221 		return m_name.c_str();
222 	}
getType(void) const223 	const VarType& getType(void) const
224 	{
225 		return m_type;
226 	}
getFlags(void) const227 	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 
getBlockName(void) const246 	const char* getBlockName(void) const
247 	{
248 		return m_blockName.c_str();
249 	}
getInstanceName(void) const250 	const char* getInstanceName(void) const
251 	{
252 		return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();
253 	}
isArray(void) const254 	bool isArray(void) const
255 	{
256 		return m_arraySize > 0;
257 	}
getArraySize(void) const258 	int getArraySize(void) const
259 	{
260 		return m_arraySize;
261 	}
getFlags(void) const262 	deUint32 getFlags(void) const
263 	{
264 		return m_flags;
265 	}
266 
setInstanceName(const char * name)267 	void setInstanceName(const char* name)
268 	{
269 		m_instanceName = name;
270 	}
setFlags(deUint32 flags)271 	void setFlags(deUint32 flags)
272 	{
273 		m_flags = flags;
274 	}
setArraySize(int arraySize)275 	void setArraySize(int arraySize)
276 	{
277 		m_arraySize = arraySize;
278 	}
addUniform(const Uniform & uniform)279 	void addUniform(const Uniform& uniform)
280 	{
281 		m_uniforms.push_back(uniform);
282 	}
283 
begin(void)284 	inline Iterator begin(void)
285 	{
286 		return m_uniforms.begin();
287 	}
begin(void) const288 	inline ConstIterator begin(void) const
289 	{
290 		return m_uniforms.begin();
291 	}
end(void)292 	inline Iterator end(void)
293 	{
294 		return m_uniforms.end();
295 	}
end(void) const296 	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 
getNumUniformBlocks(void) const321 	int getNumUniformBlocks(void) const
322 	{
323 		return (int)m_uniformBlocks.size();
324 	}
getUniformBlock(int ndx) const325 	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
374