Home | History | Annotate | Download | only in common
      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
    374