1 #ifndef _ES31FSSBOLAYOUTCASE_HPP
2 #define _ES31FSSBOLAYOUTCASE_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program OpenGL ES 3.1 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 SSBO layout tests.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "tcuDefs.hpp"
27 #include "tcuTestCase.hpp"
28 #include "gluShaderUtil.hpp"
29 #include "gluVarType.hpp"
30 
31 namespace glu
32 {
33 class RenderContext;
34 }
35 
36 namespace deqp
37 {
38 namespace gles31
39 {
40 
41 // Buffer block details.
42 namespace bb
43 {
44 
45 enum BufferVarFlags
46 {
47 	LAYOUT_SHARED		= (1<<0),
48 	LAYOUT_PACKED		= (1<<1),
49 	LAYOUT_STD140		= (1<<2),
50 	LAYOUT_STD430		= (1<<3),
51 	LAYOUT_ROW_MAJOR	= (1<<4),
52 	LAYOUT_COLUMN_MAJOR	= (1<<5),	//!< \note Lack of both flags means column-major matrix.
53 	LAYOUT_MASK			= LAYOUT_SHARED|LAYOUT_PACKED|LAYOUT_STD140|LAYOUT_STD430|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR,
54 
55 	// \todo [2013-10-14 pyry] Investigate adding these.
56 /*	QUALIFIER_COHERENT	= (1<<6),
57 	QUALIFIER_VOLATILE	= (1<<7),
58 	QUALIFIER_RESTRICT	= (1<<8),
59 	QUALIFIER_READONLY	= (1<<9),
60 	QUALIFIER_WRITEONLY	= (1<<10),*/
61 
62 	ACCESS_READ			= (1<<11),	//!< Buffer variable is read in the shader.
63 	ACCESS_WRITE		= (1<<12),	//!< Buffer variable is written in the shader.
64 };
65 
66 class BufferVar
67 {
68 public:
69 						BufferVar		(const char* name, const glu::VarType& type, deUint32 flags);
70 
getName(void) const71 	const char*			getName			(void) const { return m_name.c_str();	}
getType(void) const72 	const glu::VarType&	getType			(void) const { return m_type;			}
getFlags(void) const73 	deUint32			getFlags		(void) const { return m_flags;			}
74 
75 private:
76 	std::string			m_name;
77 	glu::VarType		m_type;
78 	deUint32			m_flags;
79 };
80 
81 class BufferBlock
82 {
83 public:
84 	typedef std::vector<BufferVar>::iterator		iterator;
85 	typedef std::vector<BufferVar>::const_iterator	const_iterator;
86 
87 							BufferBlock				(const char* blockName);
88 
getBlockName(void) const89 	const char*				getBlockName			(void) const { return m_blockName.c_str();		}
getInstanceName(void) const90 	const char*				getInstanceName			(void) const { return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str();	}
isArray(void) const91 	bool					isArray					(void) const { return m_arraySize > 0;			}
getArraySize(void) const92 	int						getArraySize			(void) const { return m_arraySize;				}
getFlags(void) const93 	deUint32				getFlags				(void) const { return m_flags;					}
94 
setInstanceName(const char * name)95 	void					setInstanceName			(const char* name)			{ m_instanceName = name;			}
setFlags(deUint32 flags)96 	void					setFlags				(deUint32 flags)			{ m_flags = flags;					}
addMember(const BufferVar & var)97 	void					addMember				(const BufferVar& var)		{ m_variables.push_back(var);		}
98 	void					setArraySize			(int arraySize);
99 
getLastUnsizedArraySize(int instanceNdx) const100 	int						getLastUnsizedArraySize	(int instanceNdx) const		{ return m_lastUnsizedArraySizes[instanceNdx];	}
setLastUnsizedArraySize(int instanceNdx,int size)101 	void					setLastUnsizedArraySize	(int instanceNdx, int size)	{ m_lastUnsizedArraySizes[instanceNdx] = size;	}
102 
begin(void)103 	inline iterator			begin					(void)			{ return m_variables.begin();	}
begin(void) const104 	inline const_iterator	begin					(void) const	{ return m_variables.begin();	}
end(void)105 	inline iterator			end						(void)			{ return m_variables.end();		}
end(void) const106 	inline const_iterator	end						(void) const	{ return m_variables.end();		}
107 
108 private:
109 	std::string				m_blockName;
110 	std::string				m_instanceName;
111 	std::vector<BufferVar>	m_variables;
112 	int						m_arraySize;				//!< Array size or 0 if not interface block array.
113 	std::vector<int>		m_lastUnsizedArraySizes;	//!< Sizes of last unsized array element, can be different per instance.
114 	deUint32				m_flags;
115 };
116 
117 class ShaderInterface
118 {
119 public:
120 									ShaderInterface			(void);
121 									~ShaderInterface		(void);
122 
123 	glu::StructType&				allocStruct				(const char* name);
124 	const glu::StructType*			findStruct				(const char* name) const;
125 	void							getNamedStructs			(std::vector<const glu::StructType*>& structs) const;
126 
127 	BufferBlock&					allocBlock				(const char* name);
128 
getNumBlocks(void) const129 	int								getNumBlocks			(void) const	{ return (int)m_bufferBlocks.size();	}
getBlock(int ndx) const130 	const BufferBlock&				getBlock				(int ndx) const	{ return *m_bufferBlocks[ndx];			}
131 
132 private:
133 									ShaderInterface			(const ShaderInterface&);
134 	ShaderInterface&				operator=				(const ShaderInterface&);
135 
136 	std::vector<glu::StructType*>	m_structs;
137 	std::vector<BufferBlock*>		m_bufferBlocks;
138 };
139 
140 class BufferLayout;
141 
142 } // bb
143 
144 class SSBOLayoutCase : public tcu::TestCase
145 {
146 public:
147 	enum BufferMode
148 	{
149 		BUFFERMODE_SINGLE = 0,	//!< Single buffer shared between uniform blocks.
150 		BUFFERMODE_PER_BLOCK,	//!< Per-block buffers
151 
152 		BUFFERMODE_LAST
153 	};
154 
155 								SSBOLayoutCase				(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, glu::GLSLVersion glslVersion, BufferMode bufferMode);
156 								~SSBOLayoutCase				(void);
157 
158 	IterateResult				iterate						(void);
159 
160 protected:
161 	bool						compareStdBlocks			(const bb::BufferLayout& refLayout, const bb::BufferLayout& cmpLayout) const;
162 	bool						compareSharedBlocks			(const bb::BufferLayout& refLayout, const bb::BufferLayout& cmpLayout) const;
163 	bool						compareTypes				(const bb::BufferLayout& refLayout, const bb::BufferLayout& cmpLayout) const;
164 	bool						checkLayoutIndices			(const bb::BufferLayout& layout) const;
165 	bool						checkLayoutBounds			(const bb::BufferLayout& layout) const;
166 	bool						checkIndexQueries			(deUint32 program, const bb::BufferLayout& layout) const;
167 
168 	bool						execute						(deUint32 program);
169 
170 	glu::RenderContext&			m_renderCtx;
171 	glu::GLSLVersion			m_glslVersion;
172 	BufferMode					m_bufferMode;
173 	bb::ShaderInterface			m_interface;
174 
175 private:
176 								SSBOLayoutCase				(const SSBOLayoutCase&);
177 	SSBOLayoutCase&				operator=					(const SSBOLayoutCase&);
178 };
179 
180 } // gles31
181 } // deqp
182 
183 #endif // _ES31FSSBOLAYOUTCASE_HPP
184