Home | History | Annotate | Download | only in glshared
      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, deUint32 flags);
     77 						VarType			(const VarType& elementType, int arraySize);
     78 	explicit			VarType			(const StructType* structPtr);
     79 						~VarType		(void);
     80 
     81 	bool				isBasicType		(void) const	{ return m_type == TYPE_BASIC;	}
     82 	bool				isArrayType		(void) const	{ return m_type == TYPE_ARRAY;	}
     83 	bool				isStructType	(void) const	{ return m_type == TYPE_STRUCT;	}
     84 
     85 	deUint32			getFlags		(void) const	{ return m_flags;					}
     86 	glu::DataType		getBasicType	(void) const	{ return m_data.basicType;			}
     87 
     88 	const VarType&		getElementType	(void) const	{ return *m_data.array.elementType;	}
     89 	int					getArraySize	(void) const	{ return m_data.array.size;			}
     90 
     91 	const StructType&	getStruct		(void) const	{ return *m_data.structPtr;			}
     92 
     93 	VarType&			operator=		(const VarType& other);
     94 
     95 private:
     96 	enum Type
     97 	{
     98 		TYPE_BASIC,
     99 		TYPE_ARRAY,
    100 		TYPE_STRUCT,
    101 
    102 		TYPE_LAST
    103 	};
    104 
    105 	Type				m_type;
    106 	deUint32			m_flags;
    107 	union Data
    108 	{
    109 		glu::DataType		basicType;
    110 		struct
    111 		{
    112 			VarType*		elementType;
    113 			int				size;
    114 		} array;
    115 		const StructType*	structPtr;
    116 
    117 		Data (void)
    118 		{
    119 			array.elementType	= DE_NULL;
    120 			array.size			= 0;
    121 		};
    122 	} m_data;
    123 };
    124 
    125 class StructMember
    126 {
    127 public:
    128 						StructMember	(const char* name, const VarType& type, deUint32 flags) : m_name(name), m_type(type), m_flags(flags) {}
    129 						StructMember	(void) : m_flags(0) {}
    130 
    131 	const char*			getName			(void) const { return m_name.c_str();	}
    132 	const VarType&		getType			(void) const { return m_type;			}
    133 	deUint32			getFlags		(void) const { return m_flags;			}
    134 
    135 private:
    136 	std::string			m_name;
    137 	VarType				m_type;
    138 	deUint32			m_flags;
    139 };
    140 
    141 class StructType
    142 {
    143 public:
    144 	typedef std::vector<StructMember>::iterator			Iterator;
    145 	typedef std::vector<StructMember>::const_iterator	ConstIterator;
    146 
    147 								StructType		(const char* typeName) : m_typeName(typeName) {}
    148 								~StructType		(void) {}
    149 
    150 	const char*					getTypeName		(void) const	{ return m_typeName.empty() ? DE_NULL : m_typeName.c_str();	}
    151 
    152 	inline Iterator				begin			(void)			{ return m_members.begin();		}
    153 	inline ConstIterator		begin			(void) const	{ return m_members.begin();		}
    154 	inline Iterator				end				(void)			{ return m_members.end();		}
    155 	inline ConstIterator		end				(void) const	{ return m_members.end();		}
    156 
    157 	void						addMember		(const char* name, const VarType& type, deUint32 flags = 0);
    158 
    159 private:
    160 	std::string					m_typeName;
    161 	std::vector<StructMember>	m_members;
    162 };
    163 
    164 class Uniform
    165 {
    166 public:
    167 					Uniform			(const char* name, const VarType& type, deUint32 flags = 0);
    168 
    169 	const char*		getName			(void) const { return m_name.c_str();	}
    170 	const VarType&	getType			(void) const { return m_type;			}
    171 	deUint32		getFlags		(void) const { return m_flags;			}
    172 
    173 private:
    174 	std::string		m_name;
    175 	VarType			m_type;
    176 	deUint32		m_flags;
    177 };
    178 
    179 class UniformBlock
    180 {
    181 public:
    182 	typedef std::vector<Uniform>::iterator			Iterator;
    183 	typedef std::vector<Uniform>::const_iterator	ConstIterator;
    184 
    185 							UniformBlock		(const char* blockName);
    186 
    187 	const char*				getBlockName		(void) const { return m_blockName.c_str();		}
    188 	const char*				getInstanceName		(void) const { return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();	}
    189 	bool					isArray				(void) const { return m_arraySize > 0;			}
    190 	int						getArraySize		(void) const { return m_arraySize;				}
    191 	deUint32				getFlags			(void) const { return m_flags;					}
    192 
    193 	void					setInstanceName		(const char* name)			{ m_instanceName = name;			}
    194 	void					setFlags			(deUint32 flags)			{ m_flags = flags;					}
    195 	void					setArraySize		(int arraySize)				{ m_arraySize = arraySize;			}
    196 	void					addUniform			(const Uniform& uniform)	{ m_uniforms.push_back(uniform);	}
    197 
    198 	inline Iterator			begin				(void)			{ return m_uniforms.begin();	}
    199 	inline ConstIterator	begin				(void) const	{ return m_uniforms.begin();	}
    200 	inline Iterator			end					(void)			{ return m_uniforms.end();		}
    201 	inline ConstIterator	end					(void) const	{ return m_uniforms.end();		}
    202 
    203 private:
    204 	std::string				m_blockName;
    205 	std::string				m_instanceName;
    206 	std::vector<Uniform>	m_uniforms;
    207 	int						m_arraySize;	//!< Array size or 0 if not interface block array.
    208 	deUint32				m_flags;
    209 };
    210 
    211 class ShaderInterface
    212 {
    213 public:
    214 								ShaderInterface			(void);
    215 								~ShaderInterface		(void);
    216 
    217 	StructType&					allocStruct				(const char* name);
    218 	const StructType*			findStruct				(const char* name) const;
    219 	void						getNamedStructs			(std::vector<const StructType*>& structs) const;
    220 
    221 	UniformBlock&				allocBlock				(const char* name);
    222 
    223 	int							getNumUniformBlocks		(void) const	{ return (int)m_uniformBlocks.size();	}
    224 	const UniformBlock&			getUniformBlock			(int ndx) const	{ return *m_uniformBlocks[ndx];			}
    225 
    226 private:
    227 	std::vector<StructType*>	m_structs;
    228 	std::vector<UniformBlock*>	m_uniformBlocks;
    229 };
    230 
    231 class UniformLayout;
    232 
    233 } // ub
    234 
    235 class UniformBlockCase : public tcu::TestCase
    236 {
    237 public:
    238 	enum BufferMode
    239 	{
    240 		BUFFERMODE_SINGLE = 0,	//!< Single buffer shared between uniform blocks.
    241 		BUFFERMODE_PER_BLOCK,	//!< Per-block buffers
    242 
    243 		BUFFERMODE_LAST
    244 	};
    245 
    246 								UniformBlockCase			(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, glu::GLSLVersion glslVersion, BufferMode bufferMode);
    247 								~UniformBlockCase			(void);
    248 
    249 	IterateResult				iterate						(void);
    250 
    251 protected:
    252 	bool						compareStd140Blocks			(const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const;
    253 	bool						compareSharedBlocks			(const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const;
    254 	bool						compareTypes				(const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const;
    255 	bool						checkLayoutIndices			(const ub::UniformLayout& layout) const;
    256 	bool						checkLayoutBounds			(const ub::UniformLayout& layout) const;
    257 	bool						checkIndexQueries			(deUint32 program, const ub::UniformLayout& layout) const;
    258 
    259 	bool						render						(deUint32 program) const;
    260 
    261 	glu::RenderContext&			m_renderCtx;
    262 	glu::GLSLVersion			m_glslVersion;
    263 	BufferMode					m_bufferMode;
    264 	ub::ShaderInterface			m_interface;
    265 };
    266 
    267 } // gls
    268 } // deqp
    269 
    270 #endif // _GLSUNIFORMBLOCKCASE_HPP
    271