1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.1 Module
3e5c31af7Sopenharmony_ci * -------------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Program interface query tests.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es31fProgramInterfaceQueryTests.hpp"
25e5c31af7Sopenharmony_ci#include "es31fProgramInterfaceQueryTestCase.hpp"
26e5c31af7Sopenharmony_ci#include "es31fProgramInterfaceDefinition.hpp"
27e5c31af7Sopenharmony_ci#include "es31fProgramInterfaceDefinitionUtil.hpp"
28e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
29e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
30e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
31e5c31af7Sopenharmony_ci#include "gluVarTypeUtil.hpp"
32e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp"
33e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
34e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
35e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
36e5c31af7Sopenharmony_ci#include "deRandom.hpp"
37e5c31af7Sopenharmony_ci#include "deString.h"
38e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
39e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp"
40e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp"
41e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp"
42e5c31af7Sopenharmony_ci#include "deArrayUtil.hpp"
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_ci#include <set>
45e5c31af7Sopenharmony_ci#include <map>
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_cinamespace deqp
48e5c31af7Sopenharmony_ci{
49e5c31af7Sopenharmony_cinamespace gles31
50e5c31af7Sopenharmony_ci{
51e5c31af7Sopenharmony_cinamespace Functional
52e5c31af7Sopenharmony_ci{
53e5c31af7Sopenharmony_cinamespace
54e5c31af7Sopenharmony_ci{
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_cistatic int getTypeSize (glu::DataType type)
57e5c31af7Sopenharmony_ci{
58e5c31af7Sopenharmony_ci	if (type == glu::TYPE_FLOAT)
59e5c31af7Sopenharmony_ci		return 4;
60e5c31af7Sopenharmony_ci	else if (type == glu::TYPE_INT || type == glu::TYPE_UINT)
61e5c31af7Sopenharmony_ci		return 4;
62e5c31af7Sopenharmony_ci	else if (type == glu::TYPE_BOOL)
63e5c31af7Sopenharmony_ci		return 4; // uint
64e5c31af7Sopenharmony_ci
65e5c31af7Sopenharmony_ci	DE_ASSERT(false);
66e5c31af7Sopenharmony_ci	return 0;
67e5c31af7Sopenharmony_ci}
68e5c31af7Sopenharmony_ci
69e5c31af7Sopenharmony_cistatic int getVarTypeSize (const glu::VarType& type)
70e5c31af7Sopenharmony_ci{
71e5c31af7Sopenharmony_ci	if (type.isBasicType())
72e5c31af7Sopenharmony_ci		return glu::getDataTypeScalarSize(type.getBasicType()) * getTypeSize(glu::getDataTypeScalarType(type.getBasicType()));
73e5c31af7Sopenharmony_ci	else if (type.isStructType())
74e5c31af7Sopenharmony_ci	{
75e5c31af7Sopenharmony_ci		int size = 0;
76e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
77e5c31af7Sopenharmony_ci			size += getVarTypeSize(type.getStructPtr()->getMember(ndx).getType());
78e5c31af7Sopenharmony_ci		return size;
79e5c31af7Sopenharmony_ci	}
80e5c31af7Sopenharmony_ci	else if (type.isArrayType())
81e5c31af7Sopenharmony_ci	{
82e5c31af7Sopenharmony_ci		if (type.getArraySize() == glu::VarType::UNSIZED_ARRAY)
83e5c31af7Sopenharmony_ci			return getVarTypeSize(type.getElementType());
84e5c31af7Sopenharmony_ci		else
85e5c31af7Sopenharmony_ci			return type.getArraySize() * getVarTypeSize(type.getElementType());
86e5c31af7Sopenharmony_ci	}
87e5c31af7Sopenharmony_ci	else
88e5c31af7Sopenharmony_ci	{
89e5c31af7Sopenharmony_ci		DE_ASSERT(false);
90e5c31af7Sopenharmony_ci		return 0;
91e5c31af7Sopenharmony_ci	}
92e5c31af7Sopenharmony_ci}
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_cistatic std::string convertGLTypeNameToTestName (const char* glName)
95e5c31af7Sopenharmony_ci{
96e5c31af7Sopenharmony_ci	// vectors and matrices are fine as is
97e5c31af7Sopenharmony_ci	{
98e5c31af7Sopenharmony_ci		if (deStringBeginsWith(glName, "vec")  == DE_TRUE ||
99e5c31af7Sopenharmony_ci			deStringBeginsWith(glName, "ivec") == DE_TRUE ||
100e5c31af7Sopenharmony_ci			deStringBeginsWith(glName, "uvec") == DE_TRUE ||
101e5c31af7Sopenharmony_ci			deStringBeginsWith(glName, "bvec") == DE_TRUE ||
102e5c31af7Sopenharmony_ci			deStringBeginsWith(glName, "mat")  == DE_TRUE)
103e5c31af7Sopenharmony_ci			return std::string(glName);
104e5c31af7Sopenharmony_ci	}
105e5c31af7Sopenharmony_ci
106e5c31af7Sopenharmony_ci	// convert camel case to use underscore
107e5c31af7Sopenharmony_ci	{
108e5c31af7Sopenharmony_ci		std::ostringstream	buf;
109e5c31af7Sopenharmony_ci		std::istringstream	name					(glName);
110e5c31af7Sopenharmony_ci		bool				mergeNextToken			= false;
111e5c31af7Sopenharmony_ci		bool				previousTokenWasDigit	= false;
112e5c31af7Sopenharmony_ci
113e5c31af7Sopenharmony_ci		while (!name.eof())
114e5c31af7Sopenharmony_ci		{
115e5c31af7Sopenharmony_ci			std::ostringstream token;
116e5c31af7Sopenharmony_ci
117e5c31af7Sopenharmony_ci			while (name.peek() != EOF)
118e5c31af7Sopenharmony_ci			{
119e5c31af7Sopenharmony_ci				if ((de::isDigit((char)name.peek()) || de::isUpper((char)name.peek())) && token.tellp())
120e5c31af7Sopenharmony_ci					break;
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ci				token << de::toLower((char)name.get());
123e5c31af7Sopenharmony_ci			}
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ci			if (buf.str().empty() || mergeNextToken)
126e5c31af7Sopenharmony_ci				buf << token.str();
127e5c31af7Sopenharmony_ci			else
128e5c31af7Sopenharmony_ci				buf << '_' << token.str();
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_ci			// Single char causes next char to be merged (don't split initialisms or acronyms) unless it is 'D' after a number (split to ..._2d_acronym_aa
131e5c31af7Sopenharmony_ci			mergeNextToken = false;
132e5c31af7Sopenharmony_ci			if (token.tellp() == (std::streamoff)1)
133e5c31af7Sopenharmony_ci			{
134e5c31af7Sopenharmony_ci				if (!previousTokenWasDigit || token.str()[0] != 'd')
135e5c31af7Sopenharmony_ci					mergeNextToken = true;
136e5c31af7Sopenharmony_ci
137e5c31af7Sopenharmony_ci				previousTokenWasDigit = de::isDigit(token.str()[0]);
138e5c31af7Sopenharmony_ci			}
139e5c31af7Sopenharmony_ci			else
140e5c31af7Sopenharmony_ci				previousTokenWasDigit = false;
141e5c31af7Sopenharmony_ci		}
142e5c31af7Sopenharmony_ci
143e5c31af7Sopenharmony_ci		return buf.str();
144e5c31af7Sopenharmony_ci	}
145e5c31af7Sopenharmony_ci}
146e5c31af7Sopenharmony_ci
147e5c31af7Sopenharmony_cistatic glw::GLenum getProgramInterfaceGLEnum (ProgramInterface interface)
148e5c31af7Sopenharmony_ci{
149e5c31af7Sopenharmony_ci	static const glw::GLenum s_enums[] =
150e5c31af7Sopenharmony_ci	{
151e5c31af7Sopenharmony_ci		GL_UNIFORM,						// PROGRAMINTERFACE_UNIFORM
152e5c31af7Sopenharmony_ci		GL_UNIFORM_BLOCK,				// PROGRAMINTERFACE_UNIFORM_BLOCK
153e5c31af7Sopenharmony_ci		GL_ATOMIC_COUNTER_BUFFER,		// PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER
154e5c31af7Sopenharmony_ci		GL_PROGRAM_INPUT,				// PROGRAMINTERFACE_PROGRAM_INPUT
155e5c31af7Sopenharmony_ci		GL_PROGRAM_OUTPUT,				// PROGRAMINTERFACE_PROGRAM_OUTPUT
156e5c31af7Sopenharmony_ci		GL_TRANSFORM_FEEDBACK_VARYING,	// PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING
157e5c31af7Sopenharmony_ci		GL_BUFFER_VARIABLE,				// PROGRAMINTERFACE_BUFFER_VARIABLE
158e5c31af7Sopenharmony_ci		GL_SHADER_STORAGE_BLOCK,		// PROGRAMINTERFACE_SHADER_STORAGE_BLOCK
159e5c31af7Sopenharmony_ci	};
160e5c31af7Sopenharmony_ci
161e5c31af7Sopenharmony_ci	return de::getSizedArrayElement<PROGRAMINTERFACE_LAST>(s_enums, interface);
162e5c31af7Sopenharmony_ci}
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_cistatic glu::ShaderType getShaderMaskFirstStage (deUint32 mask)
165e5c31af7Sopenharmony_ci{
166e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_COMPUTE))
167e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_COMPUTE;
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_VERTEX))
170e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_VERTEX;
171e5c31af7Sopenharmony_ci
172e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
173e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_TESSELLATION_CONTROL;
174e5c31af7Sopenharmony_ci
175e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
176e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_TESSELLATION_EVALUATION;
177e5c31af7Sopenharmony_ci
178e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
179e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_GEOMETRY;
180e5c31af7Sopenharmony_ci
181e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
182e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_FRAGMENT;
183e5c31af7Sopenharmony_ci
184e5c31af7Sopenharmony_ci	DE_ASSERT(false);
185e5c31af7Sopenharmony_ci	return glu::SHADERTYPE_LAST;
186e5c31af7Sopenharmony_ci}
187e5c31af7Sopenharmony_ci
188e5c31af7Sopenharmony_cistatic glu::ShaderType getShaderMaskLastStage (deUint32 mask)
189e5c31af7Sopenharmony_ci{
190e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
191e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_FRAGMENT;
192e5c31af7Sopenharmony_ci
193e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
194e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_GEOMETRY;
195e5c31af7Sopenharmony_ci
196e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
197e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_TESSELLATION_EVALUATION;
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
200e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_TESSELLATION_CONTROL;
201e5c31af7Sopenharmony_ci
202e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_VERTEX))
203e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_VERTEX;
204e5c31af7Sopenharmony_ci
205e5c31af7Sopenharmony_ci	if (mask & (1u << glu::SHADERTYPE_COMPUTE))
206e5c31af7Sopenharmony_ci		return glu::SHADERTYPE_COMPUTE;
207e5c31af7Sopenharmony_ci
208e5c31af7Sopenharmony_ci	DE_ASSERT(false);
209e5c31af7Sopenharmony_ci	return glu::SHADERTYPE_LAST;
210e5c31af7Sopenharmony_ci}
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_cistatic bool checkSupport(Context& ctx)
213e5c31af7Sopenharmony_ci{
214e5c31af7Sopenharmony_ci	auto ctxType = ctx.getRenderContext().getType();
215e5c31af7Sopenharmony_ci	return contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
216e5c31af7Sopenharmony_ci		   contextSupports(ctxType, glu::ApiType::core(4, 5));
217e5c31af7Sopenharmony_ci}
218e5c31af7Sopenharmony_ci
219e5c31af7Sopenharmony_cistatic std::string specializeShader(Context& context, const char* code)
220e5c31af7Sopenharmony_ci{
221e5c31af7Sopenharmony_ci	const glu::GLSLVersion				glslVersion			= glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
222e5c31af7Sopenharmony_ci	std::map<std::string, std::string>	specializationMap;
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_ci	specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_ci	return tcu::StringTemplate(code).specialize(specializationMap);
227e5c31af7Sopenharmony_ci}
228e5c31af7Sopenharmony_ci
229e5c31af7Sopenharmony_cinamespace ResourceDefinition
230e5c31af7Sopenharmony_ci{
231e5c31af7Sopenharmony_ci
232e5c31af7Sopenharmony_ciclass Node
233e5c31af7Sopenharmony_ci{
234e5c31af7Sopenharmony_cipublic:
235e5c31af7Sopenharmony_ci	enum NodeType
236e5c31af7Sopenharmony_ci	{
237e5c31af7Sopenharmony_ci		TYPE_PROGRAM = 0,
238e5c31af7Sopenharmony_ci		TYPE_SHADER,
239e5c31af7Sopenharmony_ci		TYPE_DEFAULT_BLOCK,
240e5c31af7Sopenharmony_ci		TYPE_VARIABLE,
241e5c31af7Sopenharmony_ci		TYPE_INTERFACE_BLOCK,
242e5c31af7Sopenharmony_ci		TYPE_ARRAY_ELEMENT,
243e5c31af7Sopenharmony_ci		TYPE_STRUCT_MEMBER,
244e5c31af7Sopenharmony_ci		TYPE_STORAGE_QUALIFIER,
245e5c31af7Sopenharmony_ci		TYPE_LAYOUT_QUALIFIER,
246e5c31af7Sopenharmony_ci		TYPE_SHADER_SET,
247e5c31af7Sopenharmony_ci		TYPE_INTERPOLATION_QUALIFIER,
248e5c31af7Sopenharmony_ci		TYPE_TRANSFORM_FEEDBACK_TARGET,
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci		TYPE_LAST
251e5c31af7Sopenharmony_ci	};
252e5c31af7Sopenharmony_ci
253e5c31af7Sopenharmony_ci	typedef de::SharedPtr<const Node> SharedPtr;
254e5c31af7Sopenharmony_ci
255e5c31af7Sopenharmony_ci							Node				(NodeType type, const SharedPtr& enclosingNode) : m_type(type), m_enclosingNode(enclosingNode) { DE_ASSERT(type < TYPE_LAST); }
256e5c31af7Sopenharmony_ci	virtual					~Node				(void) { }
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_ci	inline const Node*		getEnclosingNode	(void) const					{ return m_enclosingNode.get();	}
259e5c31af7Sopenharmony_ci	inline NodeType			getType				(void) const					{ return m_type;				}
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_ciprivate:
262e5c31af7Sopenharmony_ci	const NodeType			m_type;
263e5c31af7Sopenharmony_ci	const SharedPtr			m_enclosingNode;
264e5c31af7Sopenharmony_ci};
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ciclass Program : public Node
267e5c31af7Sopenharmony_ci{
268e5c31af7Sopenharmony_cipublic:
269e5c31af7Sopenharmony_ci	Program (bool separable = false)
270e5c31af7Sopenharmony_ci		: Node			(TYPE_PROGRAM, SharedPtr())
271e5c31af7Sopenharmony_ci		, m_separable	(separable)
272e5c31af7Sopenharmony_ci	{
273e5c31af7Sopenharmony_ci	}
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci	const bool m_separable;
276e5c31af7Sopenharmony_ci};
277e5c31af7Sopenharmony_ci
278e5c31af7Sopenharmony_ciclass Shader : public Node
279e5c31af7Sopenharmony_ci{
280e5c31af7Sopenharmony_cipublic:
281e5c31af7Sopenharmony_ci	Shader (const SharedPtr& enclosingNode, glu::ShaderType type, glu::GLSLVersion version)
282e5c31af7Sopenharmony_ci		: Node		(TYPE_SHADER, enclosingNode)
283e5c31af7Sopenharmony_ci		, m_type	(type)
284e5c31af7Sopenharmony_ci		, m_version	(version)
285e5c31af7Sopenharmony_ci	{
286e5c31af7Sopenharmony_ci		DE_ASSERT(enclosingNode->getType() == TYPE_PROGRAM);
287e5c31af7Sopenharmony_ci		DE_ASSERT(type < glu::SHADERTYPE_LAST);
288e5c31af7Sopenharmony_ci	}
289e5c31af7Sopenharmony_ci
290e5c31af7Sopenharmony_ci	const glu::ShaderType	m_type;
291e5c31af7Sopenharmony_ci	const glu::GLSLVersion	m_version;
292e5c31af7Sopenharmony_ci};
293e5c31af7Sopenharmony_ci
294e5c31af7Sopenharmony_ciclass DefaultBlock : public Node
295e5c31af7Sopenharmony_ci{
296e5c31af7Sopenharmony_cipublic:
297e5c31af7Sopenharmony_ci	DefaultBlock (const SharedPtr& enclosing)
298e5c31af7Sopenharmony_ci		: Node(TYPE_DEFAULT_BLOCK, enclosing)
299e5c31af7Sopenharmony_ci	{
300e5c31af7Sopenharmony_ci		// enclosed by the shader
301e5c31af7Sopenharmony_ci		DE_ASSERT(enclosing->getType() == TYPE_SHADER		||
302e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_SHADER_SET);
303e5c31af7Sopenharmony_ci	}
304e5c31af7Sopenharmony_ci};
305e5c31af7Sopenharmony_ci
306e5c31af7Sopenharmony_ciclass StorageQualifier : public Node
307e5c31af7Sopenharmony_ci{
308e5c31af7Sopenharmony_cipublic:
309e5c31af7Sopenharmony_ci	StorageQualifier (const SharedPtr& enclosing, glu::Storage storage)
310e5c31af7Sopenharmony_ci		: Node		(TYPE_STORAGE_QUALIFIER, enclosing)
311e5c31af7Sopenharmony_ci		, m_storage	(storage)
312e5c31af7Sopenharmony_ci	{
313e5c31af7Sopenharmony_ci		// not a part of any block
314e5c31af7Sopenharmony_ci		DE_ASSERT(enclosing->getType() == TYPE_DEFAULT_BLOCK);
315e5c31af7Sopenharmony_ci	}
316e5c31af7Sopenharmony_ci
317e5c31af7Sopenharmony_ci	const glu::Storage	m_storage;
318e5c31af7Sopenharmony_ci};
319e5c31af7Sopenharmony_ci
320e5c31af7Sopenharmony_ciclass Variable : public Node
321e5c31af7Sopenharmony_ci{
322e5c31af7Sopenharmony_cipublic:
323e5c31af7Sopenharmony_ci	Variable (const SharedPtr& enclosing, glu::DataType dataType)
324e5c31af7Sopenharmony_ci		: Node			(TYPE_VARIABLE, enclosing)
325e5c31af7Sopenharmony_ci		, m_dataType	(dataType)
326e5c31af7Sopenharmony_ci	{
327e5c31af7Sopenharmony_ci		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
328e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
329e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
330e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERFACE_BLOCK			||
331e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_ARRAY_ELEMENT			||
332e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_STRUCT_MEMBER			||
333e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
334e5c31af7Sopenharmony_ci	}
335e5c31af7Sopenharmony_ci
336e5c31af7Sopenharmony_ci	const glu::DataType	m_dataType;
337e5c31af7Sopenharmony_ci};
338e5c31af7Sopenharmony_ci
339e5c31af7Sopenharmony_ciclass InterfaceBlock : public Node
340e5c31af7Sopenharmony_ci{
341e5c31af7Sopenharmony_cipublic:
342e5c31af7Sopenharmony_ci	InterfaceBlock (const SharedPtr& enclosing, bool named)
343e5c31af7Sopenharmony_ci		: Node		(TYPE_INTERFACE_BLOCK, enclosing)
344e5c31af7Sopenharmony_ci		, m_named	(named)
345e5c31af7Sopenharmony_ci	{
346e5c31af7Sopenharmony_ci		// Must be storage qualified
347e5c31af7Sopenharmony_ci		const Node* storageNode = enclosing.get();
348e5c31af7Sopenharmony_ci		while (storageNode->getType() == TYPE_ARRAY_ELEMENT ||
349e5c31af7Sopenharmony_ci			   storageNode->getType() == TYPE_LAYOUT_QUALIFIER)
350e5c31af7Sopenharmony_ci		{
351e5c31af7Sopenharmony_ci			storageNode = storageNode->getEnclosingNode();
352e5c31af7Sopenharmony_ci		}
353e5c31af7Sopenharmony_ci
354e5c31af7Sopenharmony_ci		DE_ASSERT(storageNode->getType() == TYPE_STORAGE_QUALIFIER);
355e5c31af7Sopenharmony_ci		DE_UNREF(storageNode);
356e5c31af7Sopenharmony_ci	}
357e5c31af7Sopenharmony_ci
358e5c31af7Sopenharmony_ci	const bool	m_named;
359e5c31af7Sopenharmony_ci};
360e5c31af7Sopenharmony_ci
361e5c31af7Sopenharmony_ciclass ArrayElement : public Node
362e5c31af7Sopenharmony_ci{
363e5c31af7Sopenharmony_cipublic:
364e5c31af7Sopenharmony_ci	ArrayElement (const SharedPtr& enclosing, int arraySize = DEFAULT_SIZE)
365e5c31af7Sopenharmony_ci		: Node			(TYPE_ARRAY_ELEMENT, enclosing)
366e5c31af7Sopenharmony_ci		, m_arraySize	(arraySize)
367e5c31af7Sopenharmony_ci	{
368e5c31af7Sopenharmony_ci		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
369e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
370e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
371e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERFACE_BLOCK			||
372e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_ARRAY_ELEMENT			||
373e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_STRUCT_MEMBER			||
374e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
375e5c31af7Sopenharmony_ci	}
376e5c31af7Sopenharmony_ci
377e5c31af7Sopenharmony_ci	const int m_arraySize;
378e5c31af7Sopenharmony_ci
379e5c31af7Sopenharmony_ci	enum
380e5c31af7Sopenharmony_ci	{
381e5c31af7Sopenharmony_ci		DEFAULT_SIZE	= -1,
382e5c31af7Sopenharmony_ci		UNSIZED_ARRAY	= -2,
383e5c31af7Sopenharmony_ci	};
384e5c31af7Sopenharmony_ci};
385e5c31af7Sopenharmony_ci
386e5c31af7Sopenharmony_ciclass StructMember : public Node
387e5c31af7Sopenharmony_ci{
388e5c31af7Sopenharmony_cipublic:
389e5c31af7Sopenharmony_ci	StructMember (const SharedPtr& enclosing)
390e5c31af7Sopenharmony_ci		: Node(TYPE_STRUCT_MEMBER, enclosing)
391e5c31af7Sopenharmony_ci	{
392e5c31af7Sopenharmony_ci		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
393e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
394e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
395e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERFACE_BLOCK			||
396e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_ARRAY_ELEMENT			||
397e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_STRUCT_MEMBER			||
398e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
399e5c31af7Sopenharmony_ci	}
400e5c31af7Sopenharmony_ci};
401e5c31af7Sopenharmony_ci
402e5c31af7Sopenharmony_ciclass LayoutQualifier : public Node
403e5c31af7Sopenharmony_ci{
404e5c31af7Sopenharmony_cipublic:
405e5c31af7Sopenharmony_ci	LayoutQualifier (const SharedPtr& enclosing, const glu::Layout& layout)
406e5c31af7Sopenharmony_ci		: Node		(TYPE_LAYOUT_QUALIFIER, enclosing)
407e5c31af7Sopenharmony_ci		, m_layout	(layout)
408e5c31af7Sopenharmony_ci	{
409e5c31af7Sopenharmony_ci		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
410e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
411e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
412e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_DEFAULT_BLOCK			||
413e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERFACE_BLOCK);
414e5c31af7Sopenharmony_ci	}
415e5c31af7Sopenharmony_ci
416e5c31af7Sopenharmony_ci	const glu::Layout m_layout;
417e5c31af7Sopenharmony_ci};
418e5c31af7Sopenharmony_ci
419e5c31af7Sopenharmony_ciclass InterpolationQualifier : public Node
420e5c31af7Sopenharmony_ci{
421e5c31af7Sopenharmony_cipublic:
422e5c31af7Sopenharmony_ci	InterpolationQualifier (const SharedPtr& enclosing, const glu::Interpolation& interpolation)
423e5c31af7Sopenharmony_ci		: Node				(TYPE_INTERPOLATION_QUALIFIER, enclosing)
424e5c31af7Sopenharmony_ci		, m_interpolation	(interpolation)
425e5c31af7Sopenharmony_ci	{
426e5c31af7Sopenharmony_ci		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
427e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
428e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
429e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_DEFAULT_BLOCK			||
430e5c31af7Sopenharmony_ci				  enclosing->getType() == TYPE_INTERFACE_BLOCK);
431e5c31af7Sopenharmony_ci	}
432e5c31af7Sopenharmony_ci
433e5c31af7Sopenharmony_ci	const glu::Interpolation m_interpolation;
434e5c31af7Sopenharmony_ci};
435e5c31af7Sopenharmony_ci
436e5c31af7Sopenharmony_ciclass ShaderSet : public Node
437e5c31af7Sopenharmony_ci{
438e5c31af7Sopenharmony_cipublic:
439e5c31af7Sopenharmony_ci				ShaderSet			(const SharedPtr& enclosing, glu::GLSLVersion version);
440e5c31af7Sopenharmony_ci				ShaderSet			(const SharedPtr& enclosing, glu::GLSLVersion version, deUint32 stagesPresentBits, deUint32 stagesReferencingBits);
441e5c31af7Sopenharmony_ci
442e5c31af7Sopenharmony_ci	void		setStage			(glu::ShaderType type, bool referencing);
443e5c31af7Sopenharmony_ci	bool		isStagePresent		(glu::ShaderType stage) const;
444e5c31af7Sopenharmony_ci	bool		isStageReferencing	(glu::ShaderType stage) const;
445e5c31af7Sopenharmony_ci
446e5c31af7Sopenharmony_ci	deUint32	getReferencingMask	(void) const;
447e5c31af7Sopenharmony_ci
448e5c31af7Sopenharmony_ci	const glu::GLSLVersion	m_version;
449e5c31af7Sopenharmony_ciprivate:
450e5c31af7Sopenharmony_ci	bool		m_stagePresent[glu::SHADERTYPE_LAST];
451e5c31af7Sopenharmony_ci	bool		m_stageReferencing[glu::SHADERTYPE_LAST];
452e5c31af7Sopenharmony_ci};
453e5c31af7Sopenharmony_ci
454e5c31af7Sopenharmony_ciShaderSet::ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version)
455e5c31af7Sopenharmony_ci	: Node		(TYPE_SHADER_SET, enclosing)
456e5c31af7Sopenharmony_ci	, m_version	(version)
457e5c31af7Sopenharmony_ci{
458e5c31af7Sopenharmony_ci	DE_ASSERT(enclosing->getType() == TYPE_PROGRAM);
459e5c31af7Sopenharmony_ci
460e5c31af7Sopenharmony_ci	deMemset(m_stagePresent, 0, sizeof(m_stagePresent));
461e5c31af7Sopenharmony_ci	deMemset(m_stageReferencing, 0, sizeof(m_stageReferencing));
462e5c31af7Sopenharmony_ci}
463e5c31af7Sopenharmony_ci
464e5c31af7Sopenharmony_ciShaderSet::ShaderSet (const SharedPtr&	enclosing,
465e5c31af7Sopenharmony_ci					  glu::GLSLVersion	version,
466e5c31af7Sopenharmony_ci					  deUint32			stagesPresentBits,
467e5c31af7Sopenharmony_ci					  deUint32			stagesReferencingBits)
468e5c31af7Sopenharmony_ci	: Node		(TYPE_SHADER_SET, enclosing)
469e5c31af7Sopenharmony_ci	, m_version	(version)
470e5c31af7Sopenharmony_ci{
471e5c31af7Sopenharmony_ci	for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
472e5c31af7Sopenharmony_ci	{
473e5c31af7Sopenharmony_ci		const deUint32	stageMask			= (1u << stageNdx);
474e5c31af7Sopenharmony_ci		const bool		stagePresent		= (stagesPresentBits & stageMask) != 0;
475e5c31af7Sopenharmony_ci		const bool		stageReferencing	= (stagesReferencingBits & stageMask) != 0;
476e5c31af7Sopenharmony_ci
477e5c31af7Sopenharmony_ci		DE_ASSERT(stagePresent || !stageReferencing);
478e5c31af7Sopenharmony_ci
479e5c31af7Sopenharmony_ci		m_stagePresent[stageNdx]		= stagePresent;
480e5c31af7Sopenharmony_ci		m_stageReferencing[stageNdx]	= stageReferencing;
481e5c31af7Sopenharmony_ci	}
482e5c31af7Sopenharmony_ci}
483e5c31af7Sopenharmony_ci
484e5c31af7Sopenharmony_civoid ShaderSet::setStage (glu::ShaderType type, bool referencing)
485e5c31af7Sopenharmony_ci{
486e5c31af7Sopenharmony_ci	DE_ASSERT(type < glu::SHADERTYPE_LAST);
487e5c31af7Sopenharmony_ci	m_stagePresent[type] = true;
488e5c31af7Sopenharmony_ci	m_stageReferencing[type] = referencing;
489e5c31af7Sopenharmony_ci}
490e5c31af7Sopenharmony_ci
491e5c31af7Sopenharmony_cibool ShaderSet::isStagePresent (glu::ShaderType stage) const
492e5c31af7Sopenharmony_ci{
493e5c31af7Sopenharmony_ci	DE_ASSERT(stage < glu::SHADERTYPE_LAST);
494e5c31af7Sopenharmony_ci	return m_stagePresent[stage];
495e5c31af7Sopenharmony_ci}
496e5c31af7Sopenharmony_ci
497e5c31af7Sopenharmony_cibool ShaderSet::isStageReferencing (glu::ShaderType stage) const
498e5c31af7Sopenharmony_ci{
499e5c31af7Sopenharmony_ci	DE_ASSERT(stage < glu::SHADERTYPE_LAST);
500e5c31af7Sopenharmony_ci	return m_stageReferencing[stage];
501e5c31af7Sopenharmony_ci}
502e5c31af7Sopenharmony_ci
503e5c31af7Sopenharmony_cideUint32 ShaderSet::getReferencingMask (void) const
504e5c31af7Sopenharmony_ci{
505e5c31af7Sopenharmony_ci	deUint32 mask = 0;
506e5c31af7Sopenharmony_ci	for (deUint32 stage = 0; stage < glu::SHADERTYPE_LAST; ++stage)
507e5c31af7Sopenharmony_ci	{
508e5c31af7Sopenharmony_ci		if (m_stageReferencing[stage])
509e5c31af7Sopenharmony_ci			mask |= (1u << stage);
510e5c31af7Sopenharmony_ci	}
511e5c31af7Sopenharmony_ci	return mask;
512e5c31af7Sopenharmony_ci}
513e5c31af7Sopenharmony_ci
514e5c31af7Sopenharmony_ciclass TransformFeedbackTarget : public Node
515e5c31af7Sopenharmony_ci{
516e5c31af7Sopenharmony_cipublic:
517e5c31af7Sopenharmony_ci	TransformFeedbackTarget (const SharedPtr& enclosing, const char* builtinVarName = DE_NULL)
518e5c31af7Sopenharmony_ci		: Node				(TYPE_TRANSFORM_FEEDBACK_TARGET, enclosing)
519e5c31af7Sopenharmony_ci		, m_builtinVarName	(builtinVarName)
520e5c31af7Sopenharmony_ci	{
521e5c31af7Sopenharmony_ci	}
522e5c31af7Sopenharmony_ci
523e5c31af7Sopenharmony_ci	const char* const m_builtinVarName;
524e5c31af7Sopenharmony_ci};
525e5c31af7Sopenharmony_ci
526e5c31af7Sopenharmony_ci} // ResourceDefinition
527e5c31af7Sopenharmony_ci
528e5c31af7Sopenharmony_cistatic glu::Precision getDataTypeDefaultPrecision (const glu::DataType& type)
529e5c31af7Sopenharmony_ci{
530e5c31af7Sopenharmony_ci	if (glu::isDataTypeBoolOrBVec(type))
531e5c31af7Sopenharmony_ci		return glu::PRECISION_LAST;
532e5c31af7Sopenharmony_ci	else if (glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type))
533e5c31af7Sopenharmony_ci		return glu::PRECISION_HIGHP;
534e5c31af7Sopenharmony_ci	else if (glu::isDataTypeSampler(type))
535e5c31af7Sopenharmony_ci		return glu::PRECISION_HIGHP;
536e5c31af7Sopenharmony_ci	else if (glu::isDataTypeImage(type))
537e5c31af7Sopenharmony_ci		return glu::PRECISION_HIGHP;
538e5c31af7Sopenharmony_ci	else if (type == glu::TYPE_UINT_ATOMIC_COUNTER)
539e5c31af7Sopenharmony_ci		return glu::PRECISION_HIGHP;
540e5c31af7Sopenharmony_ci
541e5c31af7Sopenharmony_ci	DE_ASSERT(false);
542e5c31af7Sopenharmony_ci	return glu::PRECISION_LAST;
543e5c31af7Sopenharmony_ci}
544e5c31af7Sopenharmony_ci
545e5c31af7Sopenharmony_cistatic de::MovePtr<ProgramInterfaceDefinition::Program>	generateProgramDefinitionFromResource (const ResourceDefinition::Node* resource)
546e5c31af7Sopenharmony_ci{
547e5c31af7Sopenharmony_ci	de::MovePtr<ProgramInterfaceDefinition::Program>	program	(new ProgramInterfaceDefinition::Program());
548e5c31af7Sopenharmony_ci	const ResourceDefinition::Node*						head	= resource;
549e5c31af7Sopenharmony_ci
550e5c31af7Sopenharmony_ci	if (head->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
551e5c31af7Sopenharmony_ci	{
552e5c31af7Sopenharmony_ci		DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
553e5c31af7Sopenharmony_ci
554e5c31af7Sopenharmony_ci		enum BindingType
555e5c31af7Sopenharmony_ci		{
556e5c31af7Sopenharmony_ci			BINDING_VARIABLE,
557e5c31af7Sopenharmony_ci			BINDING_INTERFACE_BLOCK,
558e5c31af7Sopenharmony_ci			BINDING_DEFAULT_BLOCK
559e5c31af7Sopenharmony_ci		};
560e5c31af7Sopenharmony_ci
561e5c31af7Sopenharmony_ci		int											structNdx				= 0;
562e5c31af7Sopenharmony_ci		int											autoAssignArraySize		= 0;
563e5c31af7Sopenharmony_ci		const glu::DataType							basicType				= static_cast<const ResourceDefinition::Variable*>(resource)->m_dataType;
564e5c31af7Sopenharmony_ci		BindingType									boundObject				= BINDING_VARIABLE;
565e5c31af7Sopenharmony_ci		glu::VariableDeclaration					variable				(glu::VarType(basicType, getDataTypeDefaultPrecision(basicType)), "target");
566e5c31af7Sopenharmony_ci		glu::InterfaceBlock							interfaceBlock;
567e5c31af7Sopenharmony_ci		ProgramInterfaceDefinition::DefaultBlock	defaultBlock;
568e5c31af7Sopenharmony_ci		std::vector<std::string>					feedbackTargetVaryingPath;
569e5c31af7Sopenharmony_ci		bool										feedbackTargetSet		= false;
570e5c31af7Sopenharmony_ci
571e5c31af7Sopenharmony_ci		// image specific
572e5c31af7Sopenharmony_ci		if (glu::isDataTypeImage(basicType))
573e5c31af7Sopenharmony_ci		{
574e5c31af7Sopenharmony_ci			variable.memoryAccessQualifierBits |= glu::MEMORYACCESSQUALIFIER_READONLY_BIT;
575e5c31af7Sopenharmony_ci			variable.layout.binding = 1;
576e5c31af7Sopenharmony_ci
577e5c31af7Sopenharmony_ci			if (basicType >= glu::TYPE_IMAGE_2D && basicType <= glu::TYPE_IMAGE_3D)
578e5c31af7Sopenharmony_ci				variable.layout.format = glu::FORMATLAYOUT_RGBA8;
579e5c31af7Sopenharmony_ci			else if (basicType >= glu::TYPE_INT_IMAGE_2D && basicType <= glu::TYPE_INT_IMAGE_3D)
580e5c31af7Sopenharmony_ci				variable.layout.format = glu::FORMATLAYOUT_RGBA8I;
581e5c31af7Sopenharmony_ci			else if (basicType >= glu::TYPE_UINT_IMAGE_2D && basicType <= glu::TYPE_UINT_IMAGE_3D)
582e5c31af7Sopenharmony_ci				variable.layout.format = glu::FORMATLAYOUT_RGBA8UI;
583e5c31af7Sopenharmony_ci			else
584e5c31af7Sopenharmony_ci				DE_ASSERT(false);
585e5c31af7Sopenharmony_ci		}
586e5c31af7Sopenharmony_ci
587e5c31af7Sopenharmony_ci		// atomic counter specific
588e5c31af7Sopenharmony_ci		if (basicType == glu::TYPE_UINT_ATOMIC_COUNTER)
589e5c31af7Sopenharmony_ci			variable.layout.binding = 1;
590e5c31af7Sopenharmony_ci
591e5c31af7Sopenharmony_ci		for (head = head->getEnclosingNode(); head; head = head->getEnclosingNode())
592e5c31af7Sopenharmony_ci		{
593e5c31af7Sopenharmony_ci			if (head->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
594e5c31af7Sopenharmony_ci			{
595e5c31af7Sopenharmony_ci				const ResourceDefinition::StorageQualifier* qualifier = static_cast<const ResourceDefinition::StorageQualifier*>(head);
596e5c31af7Sopenharmony_ci
597e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(head));
598e5c31af7Sopenharmony_ci
599e5c31af7Sopenharmony_ci				if (boundObject == BINDING_VARIABLE)
600e5c31af7Sopenharmony_ci				{
601e5c31af7Sopenharmony_ci					DE_ASSERT(variable.storage == glu::STORAGE_LAST);
602e5c31af7Sopenharmony_ci					variable.storage = qualifier->m_storage;
603e5c31af7Sopenharmony_ci				}
604e5c31af7Sopenharmony_ci				else if (boundObject == BINDING_INTERFACE_BLOCK)
605e5c31af7Sopenharmony_ci				{
606e5c31af7Sopenharmony_ci					DE_ASSERT(interfaceBlock.storage == glu::STORAGE_LAST);
607e5c31af7Sopenharmony_ci					interfaceBlock.storage = qualifier->m_storage;
608e5c31af7Sopenharmony_ci				}
609e5c31af7Sopenharmony_ci				else
610e5c31af7Sopenharmony_ci					DE_ASSERT(false);
611e5c31af7Sopenharmony_ci			}
612e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_LAYOUT_QUALIFIER)
613e5c31af7Sopenharmony_ci			{
614e5c31af7Sopenharmony_ci				const ResourceDefinition::LayoutQualifier*	qualifier		= static_cast<const ResourceDefinition::LayoutQualifier*>(head);
615e5c31af7Sopenharmony_ci				glu::Layout*								targetLayout	= DE_NULL;
616e5c31af7Sopenharmony_ci
617e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::LayoutQualifier*>(head));
618e5c31af7Sopenharmony_ci
619e5c31af7Sopenharmony_ci				if (boundObject == BINDING_VARIABLE)
620e5c31af7Sopenharmony_ci					targetLayout = &variable.layout;
621e5c31af7Sopenharmony_ci				else if (boundObject == BINDING_INTERFACE_BLOCK)
622e5c31af7Sopenharmony_ci					targetLayout = &interfaceBlock.layout;
623e5c31af7Sopenharmony_ci				else
624e5c31af7Sopenharmony_ci					DE_ASSERT(false);
625e5c31af7Sopenharmony_ci
626e5c31af7Sopenharmony_ci				if (qualifier->m_layout.location != -1)
627e5c31af7Sopenharmony_ci					targetLayout->location = qualifier->m_layout.location;
628e5c31af7Sopenharmony_ci
629e5c31af7Sopenharmony_ci				if (qualifier->m_layout.binding != -1)
630e5c31af7Sopenharmony_ci					targetLayout->binding = qualifier->m_layout.binding;
631e5c31af7Sopenharmony_ci
632e5c31af7Sopenharmony_ci				if (qualifier->m_layout.offset != -1)
633e5c31af7Sopenharmony_ci					targetLayout->offset = qualifier->m_layout.offset;
634e5c31af7Sopenharmony_ci
635e5c31af7Sopenharmony_ci				if (qualifier->m_layout.format != glu::FORMATLAYOUT_LAST)
636e5c31af7Sopenharmony_ci					targetLayout->format = qualifier->m_layout.format;
637e5c31af7Sopenharmony_ci
638e5c31af7Sopenharmony_ci				if (qualifier->m_layout.matrixOrder != glu::MATRIXORDER_LAST)
639e5c31af7Sopenharmony_ci					targetLayout->matrixOrder = qualifier->m_layout.matrixOrder;
640e5c31af7Sopenharmony_ci			}
641e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_INTERPOLATION_QUALIFIER)
642e5c31af7Sopenharmony_ci			{
643e5c31af7Sopenharmony_ci				const ResourceDefinition::InterpolationQualifier* qualifier = static_cast<const ResourceDefinition::InterpolationQualifier*>(head);
644e5c31af7Sopenharmony_ci
645e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::InterpolationQualifier*>(head));
646e5c31af7Sopenharmony_ci
647e5c31af7Sopenharmony_ci				if (boundObject == BINDING_VARIABLE)
648e5c31af7Sopenharmony_ci					variable.interpolation = qualifier->m_interpolation;
649e5c31af7Sopenharmony_ci				else
650e5c31af7Sopenharmony_ci					DE_ASSERT(false);
651e5c31af7Sopenharmony_ci			}
652e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
653e5c31af7Sopenharmony_ci			{
654e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(head));
655e5c31af7Sopenharmony_ci
656e5c31af7Sopenharmony_ci				const ResourceDefinition::ArrayElement*	arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(head);
657e5c31af7Sopenharmony_ci				int										arraySize;
658e5c31af7Sopenharmony_ci
659e5c31af7Sopenharmony_ci				// Vary array size per level
660e5c31af7Sopenharmony_ci				if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::DEFAULT_SIZE)
661e5c31af7Sopenharmony_ci				{
662e5c31af7Sopenharmony_ci					if (--autoAssignArraySize <= 1)
663e5c31af7Sopenharmony_ci						autoAssignArraySize = 3;
664e5c31af7Sopenharmony_ci
665e5c31af7Sopenharmony_ci					arraySize = autoAssignArraySize;
666e5c31af7Sopenharmony_ci				}
667e5c31af7Sopenharmony_ci				else if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY)
668e5c31af7Sopenharmony_ci					arraySize = glu::VarType::UNSIZED_ARRAY;
669e5c31af7Sopenharmony_ci				else
670e5c31af7Sopenharmony_ci					arraySize = arrayElement->m_arraySize;
671e5c31af7Sopenharmony_ci
672e5c31af7Sopenharmony_ci				if (boundObject == BINDING_VARIABLE)
673e5c31af7Sopenharmony_ci					variable.varType = glu::VarType(variable.varType, arraySize);
674e5c31af7Sopenharmony_ci				else if (boundObject == BINDING_INTERFACE_BLOCK)
675e5c31af7Sopenharmony_ci					interfaceBlock.dimensions.push_back(arraySize);
676e5c31af7Sopenharmony_ci				else
677e5c31af7Sopenharmony_ci					DE_ASSERT(false);
678e5c31af7Sopenharmony_ci
679e5c31af7Sopenharmony_ci				if (feedbackTargetSet)
680e5c31af7Sopenharmony_ci					feedbackTargetVaryingPath.back().append("[0]");
681e5c31af7Sopenharmony_ci			}
682e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
683e5c31af7Sopenharmony_ci			{
684e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::StructMember*>(head));
685e5c31af7Sopenharmony_ci				DE_ASSERT(boundObject == BINDING_VARIABLE);
686e5c31af7Sopenharmony_ci
687e5c31af7Sopenharmony_ci				// Struct members cannot contain any qualifiers except precision
688e5c31af7Sopenharmony_ci				DE_ASSERT(variable.interpolation == glu::INTERPOLATION_LAST);
689e5c31af7Sopenharmony_ci				DE_ASSERT(variable.layout == glu::Layout());
690e5c31af7Sopenharmony_ci				DE_ASSERT(variable.memoryAccessQualifierBits == 0);
691e5c31af7Sopenharmony_ci				DE_ASSERT(variable.storage == glu::STORAGE_LAST);
692e5c31af7Sopenharmony_ci
693e5c31af7Sopenharmony_ci				{
694e5c31af7Sopenharmony_ci					glu::StructType* structPtr = new glu::StructType(("StructType" + de::toString(structNdx++)).c_str());
695e5c31af7Sopenharmony_ci					structPtr->addMember(variable.name.c_str(), variable.varType);
696e5c31af7Sopenharmony_ci
697e5c31af7Sopenharmony_ci					variable = glu::VariableDeclaration(glu::VarType(structPtr), "target");
698e5c31af7Sopenharmony_ci				}
699e5c31af7Sopenharmony_ci
700e5c31af7Sopenharmony_ci				if (feedbackTargetSet)
701e5c31af7Sopenharmony_ci					feedbackTargetVaryingPath.push_back("target");
702e5c31af7Sopenharmony_ci			}
703e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
704e5c31af7Sopenharmony_ci			{
705e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::InterfaceBlock*>(head));
706e5c31af7Sopenharmony_ci				DE_ASSERT(boundObject == BINDING_VARIABLE);
707e5c31af7Sopenharmony_ci
708e5c31af7Sopenharmony_ci				const bool named = static_cast<const ResourceDefinition::InterfaceBlock*>(head)->m_named;
709e5c31af7Sopenharmony_ci
710e5c31af7Sopenharmony_ci				boundObject = BINDING_INTERFACE_BLOCK;
711e5c31af7Sopenharmony_ci
712e5c31af7Sopenharmony_ci				interfaceBlock.interfaceName = "TargetInterface";
713e5c31af7Sopenharmony_ci				interfaceBlock.instanceName = (named) ? ("targetInstance") : ("");
714e5c31af7Sopenharmony_ci				interfaceBlock.variables.push_back(variable);
715e5c31af7Sopenharmony_ci
716e5c31af7Sopenharmony_ci				if (feedbackTargetSet && !interfaceBlock.instanceName.empty())
717e5c31af7Sopenharmony_ci					feedbackTargetVaryingPath.push_back(interfaceBlock.interfaceName);
718e5c31af7Sopenharmony_ci			}
719e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
720e5c31af7Sopenharmony_ci			{
721e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::DefaultBlock*>(head));
722e5c31af7Sopenharmony_ci				DE_ASSERT(boundObject == BINDING_VARIABLE || boundObject == BINDING_INTERFACE_BLOCK);
723e5c31af7Sopenharmony_ci
724e5c31af7Sopenharmony_ci				if (boundObject == BINDING_VARIABLE)
725e5c31af7Sopenharmony_ci					defaultBlock.variables.push_back(variable);
726e5c31af7Sopenharmony_ci				else if (boundObject == BINDING_INTERFACE_BLOCK)
727e5c31af7Sopenharmony_ci					defaultBlock.interfaceBlocks.push_back(interfaceBlock);
728e5c31af7Sopenharmony_ci				else
729e5c31af7Sopenharmony_ci					DE_ASSERT(false);
730e5c31af7Sopenharmony_ci
731e5c31af7Sopenharmony_ci				boundObject = BINDING_DEFAULT_BLOCK;
732e5c31af7Sopenharmony_ci			}
733e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
734e5c31af7Sopenharmony_ci			{
735e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
736e5c31af7Sopenharmony_ci
737e5c31af7Sopenharmony_ci				const ResourceDefinition::Shader*	shaderDef	= static_cast<const ResourceDefinition::Shader*>(head);
738e5c31af7Sopenharmony_ci				ProgramInterfaceDefinition::Shader* shader		= program->addShader(shaderDef->m_type, shaderDef->m_version);
739e5c31af7Sopenharmony_ci
740e5c31af7Sopenharmony_ci				shader->getDefaultBlock() = defaultBlock;
741e5c31af7Sopenharmony_ci			}
742e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
743e5c31af7Sopenharmony_ci			{
744e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
745e5c31af7Sopenharmony_ci
746e5c31af7Sopenharmony_ci				const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
747e5c31af7Sopenharmony_ci
748e5c31af7Sopenharmony_ci				for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
749e5c31af7Sopenharmony_ci				{
750e5c31af7Sopenharmony_ci					if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
751e5c31af7Sopenharmony_ci					{
752e5c31af7Sopenharmony_ci						ProgramInterfaceDefinition::Shader* shader = program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
753e5c31af7Sopenharmony_ci
754e5c31af7Sopenharmony_ci						if (shaderDef->isStageReferencing((glu::ShaderType)shaderType))
755e5c31af7Sopenharmony_ci							shader->getDefaultBlock() = defaultBlock;
756e5c31af7Sopenharmony_ci					}
757e5c31af7Sopenharmony_ci				}
758e5c31af7Sopenharmony_ci			}
759e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
760e5c31af7Sopenharmony_ci			{
761e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
762e5c31af7Sopenharmony_ci
763e5c31af7Sopenharmony_ci				const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
764e5c31af7Sopenharmony_ci
765e5c31af7Sopenharmony_ci				program->setSeparable(programDef->m_separable);
766e5c31af7Sopenharmony_ci
767e5c31af7Sopenharmony_ci				DE_ASSERT(feedbackTargetSet == !feedbackTargetVaryingPath.empty());
768e5c31af7Sopenharmony_ci				if (!feedbackTargetVaryingPath.empty())
769e5c31af7Sopenharmony_ci				{
770e5c31af7Sopenharmony_ci					std::ostringstream buf;
771e5c31af7Sopenharmony_ci
772e5c31af7Sopenharmony_ci					for (std::vector<std::string>::reverse_iterator it = feedbackTargetVaryingPath.rbegin(); it != feedbackTargetVaryingPath.rend(); ++it)
773e5c31af7Sopenharmony_ci					{
774e5c31af7Sopenharmony_ci						if (it != feedbackTargetVaryingPath.rbegin())
775e5c31af7Sopenharmony_ci							buf << ".";
776e5c31af7Sopenharmony_ci						buf << *it;
777e5c31af7Sopenharmony_ci					}
778e5c31af7Sopenharmony_ci
779e5c31af7Sopenharmony_ci					program->addTransformFeedbackVarying(buf.str());
780e5c31af7Sopenharmony_ci					program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
781e5c31af7Sopenharmony_ci				}
782e5c31af7Sopenharmony_ci				break;
783e5c31af7Sopenharmony_ci			}
784e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
785e5c31af7Sopenharmony_ci			{
786e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
787e5c31af7Sopenharmony_ci
788e5c31af7Sopenharmony_ci				const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
789e5c31af7Sopenharmony_ci
790e5c31af7Sopenharmony_ci				DE_ASSERT(feedbackTarget->m_builtinVarName == DE_NULL);
791e5c31af7Sopenharmony_ci				DE_UNREF(feedbackTarget);
792e5c31af7Sopenharmony_ci
793e5c31af7Sopenharmony_ci				feedbackTargetSet = true;
794e5c31af7Sopenharmony_ci				feedbackTargetVaryingPath.push_back(variable.name);
795e5c31af7Sopenharmony_ci			}
796e5c31af7Sopenharmony_ci			else
797e5c31af7Sopenharmony_ci			{
798e5c31af7Sopenharmony_ci				DE_ASSERT(DE_FALSE);
799e5c31af7Sopenharmony_ci				break;
800e5c31af7Sopenharmony_ci			}
801e5c31af7Sopenharmony_ci		}
802e5c31af7Sopenharmony_ci	}
803e5c31af7Sopenharmony_ci	else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK ||
804e5c31af7Sopenharmony_ci			 head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
805e5c31af7Sopenharmony_ci	{
806e5c31af7Sopenharmony_ci		const char* feedbackTargetVaryingName = DE_NULL;
807e5c31af7Sopenharmony_ci
808e5c31af7Sopenharmony_ci		// empty default block
809e5c31af7Sopenharmony_ci
810e5c31af7Sopenharmony_ci		for (; head; head = head->getEnclosingNode())
811e5c31af7Sopenharmony_ci		{
812e5c31af7Sopenharmony_ci			if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
813e5c31af7Sopenharmony_ci			{
814e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));
815e5c31af7Sopenharmony_ci
816e5c31af7Sopenharmony_ci				const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);
817e5c31af7Sopenharmony_ci
818e5c31af7Sopenharmony_ci				program->addShader(shaderDef->m_type, shaderDef->m_version);
819e5c31af7Sopenharmony_ci			}
820e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
821e5c31af7Sopenharmony_ci			{
822e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));
823e5c31af7Sopenharmony_ci
824e5c31af7Sopenharmony_ci				const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);
825e5c31af7Sopenharmony_ci
826e5c31af7Sopenharmony_ci				for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
827e5c31af7Sopenharmony_ci					if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
828e5c31af7Sopenharmony_ci						program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
829e5c31af7Sopenharmony_ci			}
830e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
831e5c31af7Sopenharmony_ci			{
832e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));
833e5c31af7Sopenharmony_ci
834e5c31af7Sopenharmony_ci				const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);
835e5c31af7Sopenharmony_ci
836e5c31af7Sopenharmony_ci				program->setSeparable(programDef->m_separable);
837e5c31af7Sopenharmony_ci				if (feedbackTargetVaryingName)
838e5c31af7Sopenharmony_ci				{
839e5c31af7Sopenharmony_ci					program->addTransformFeedbackVarying(std::string(feedbackTargetVaryingName));
840e5c31af7Sopenharmony_ci					program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
841e5c31af7Sopenharmony_ci				}
842e5c31af7Sopenharmony_ci				break;
843e5c31af7Sopenharmony_ci			}
844e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
845e5c31af7Sopenharmony_ci			{
846e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));
847e5c31af7Sopenharmony_ci
848e5c31af7Sopenharmony_ci				const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);
849e5c31af7Sopenharmony_ci
850e5c31af7Sopenharmony_ci				DE_ASSERT(feedbackTarget->m_builtinVarName != DE_NULL);
851e5c31af7Sopenharmony_ci
852e5c31af7Sopenharmony_ci				feedbackTargetVaryingName = feedbackTarget->m_builtinVarName;
853e5c31af7Sopenharmony_ci			}
854e5c31af7Sopenharmony_ci			else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
855e5c31af7Sopenharmony_ci			{
856e5c31af7Sopenharmony_ci			}
857e5c31af7Sopenharmony_ci			else
858e5c31af7Sopenharmony_ci			{
859e5c31af7Sopenharmony_ci				DE_ASSERT(DE_FALSE);
860e5c31af7Sopenharmony_ci				break;
861e5c31af7Sopenharmony_ci			}
862e5c31af7Sopenharmony_ci		}
863e5c31af7Sopenharmony_ci	}
864e5c31af7Sopenharmony_ci
865e5c31af7Sopenharmony_ci	if (program->hasStage(glu::SHADERTYPE_GEOMETRY))
866e5c31af7Sopenharmony_ci		program->setGeometryNumOutputVertices(1);
867e5c31af7Sopenharmony_ci	if (program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
868e5c31af7Sopenharmony_ci		program->setTessellationNumOutputPatchVertices(1);
869e5c31af7Sopenharmony_ci
870e5c31af7Sopenharmony_ci	return program;
871e5c31af7Sopenharmony_ci}
872e5c31af7Sopenharmony_ci
873e5c31af7Sopenharmony_cistatic void checkAndLogProgram (const glu::ShaderProgram& program, const ProgramInterfaceDefinition::Program* programDefinition, const glw::Functions& gl, tcu::TestLog& log)
874e5c31af7Sopenharmony_ci{
875e5c31af7Sopenharmony_ci	const tcu::ScopedLogSection section(log, "Program", "Program");
876e5c31af7Sopenharmony_ci
877e5c31af7Sopenharmony_ci	log << program;
878e5c31af7Sopenharmony_ci	if (!program.isOk())
879e5c31af7Sopenharmony_ci	{
880e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << "Program build failed, checking if program exceeded implementation limits" << tcu::TestLog::EndMessage;
881e5c31af7Sopenharmony_ci		checkProgramResourceUsage(programDefinition, gl, log);
882e5c31af7Sopenharmony_ci
883e5c31af7Sopenharmony_ci		// within limits
884e5c31af7Sopenharmony_ci		throw tcu::TestError("could not build program");
885e5c31af7Sopenharmony_ci	}
886e5c31af7Sopenharmony_ci}
887e5c31af7Sopenharmony_ci
888e5c31af7Sopenharmony_ci// Resource list query case
889e5c31af7Sopenharmony_ci
890e5c31af7Sopenharmony_ciclass ResourceListTestCase : public TestCase
891e5c31af7Sopenharmony_ci{
892e5c31af7Sopenharmony_cipublic:
893e5c31af7Sopenharmony_ci												ResourceListTestCase		(Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name = DE_NULL);
894e5c31af7Sopenharmony_ci												~ResourceListTestCase		(void);
895e5c31af7Sopenharmony_ci
896e5c31af7Sopenharmony_ciprotected:
897e5c31af7Sopenharmony_ci	void										init						(void);
898e5c31af7Sopenharmony_ci	void										deinit						(void);
899e5c31af7Sopenharmony_ci	IterateResult								iterate						(void);
900e5c31af7Sopenharmony_ci
901e5c31af7Sopenharmony_ci	void										queryResourceList			(std::vector<std::string>& dst, glw::GLuint program);
902e5c31af7Sopenharmony_ci	bool										verifyResourceList			(const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources);
903e5c31af7Sopenharmony_ci	bool										verifyResourceIndexQuery	(const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program);
904e5c31af7Sopenharmony_ci	bool										verifyMaxNameLength			(const std::vector<std::string>& referenceResourceList, glw::GLuint program);
905e5c31af7Sopenharmony_ci
906e5c31af7Sopenharmony_ci	static std::string							genTestCaseName				(ProgramInterface interface, const ResourceDefinition::Node*);
907e5c31af7Sopenharmony_ci	static bool									isArrayedInterface			(ProgramInterface interface, deUint32 stageBits);
908e5c31af7Sopenharmony_ci
909e5c31af7Sopenharmony_ci	const ProgramInterface						m_programInterface;
910e5c31af7Sopenharmony_ci	ResourceDefinition::Node::SharedPtr			m_targetResource;
911e5c31af7Sopenharmony_ci	ProgramInterfaceDefinition::Program*		m_programDefinition;
912e5c31af7Sopenharmony_ci};
913e5c31af7Sopenharmony_ci
914e5c31af7Sopenharmony_ciResourceListTestCase::ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name)
915e5c31af7Sopenharmony_ci	: TestCase				(context, (name == DE_NULL) ? (genTestCaseName(interface, targetResource.get()).c_str()) : (name), "")
916e5c31af7Sopenharmony_ci	, m_programInterface	(interface)
917e5c31af7Sopenharmony_ci	, m_targetResource		(targetResource)
918e5c31af7Sopenharmony_ci	, m_programDefinition	(DE_NULL)
919e5c31af7Sopenharmony_ci{
920e5c31af7Sopenharmony_ci	// GL_ATOMIC_COUNTER_BUFFER: no resource names
921e5c31af7Sopenharmony_ci	DE_ASSERT(m_programInterface != PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER);
922e5c31af7Sopenharmony_ci}
923e5c31af7Sopenharmony_ci
924e5c31af7Sopenharmony_ciResourceListTestCase::~ResourceListTestCase (void)
925e5c31af7Sopenharmony_ci{
926e5c31af7Sopenharmony_ci	deinit();
927e5c31af7Sopenharmony_ci}
928e5c31af7Sopenharmony_ci
929e5c31af7Sopenharmony_civoid ResourceListTestCase::init (void)
930e5c31af7Sopenharmony_ci{
931e5c31af7Sopenharmony_ci	m_programDefinition	= generateProgramDefinitionFromResource(m_targetResource.get()).release();
932e5c31af7Sopenharmony_ci	const bool supportsES32orGL45 = checkSupport(m_context);
933e5c31af7Sopenharmony_ci
934e5c31af7Sopenharmony_ci	if ((m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION)) &&
935e5c31af7Sopenharmony_ci		!supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
936e5c31af7Sopenharmony_ci	{
937e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
938e5c31af7Sopenharmony_ci	}
939e5c31af7Sopenharmony_ci	if (m_programDefinition->hasStage(glu::SHADERTYPE_GEOMETRY) &&
940e5c31af7Sopenharmony_ci		!supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
941e5c31af7Sopenharmony_ci	{
942e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
943e5c31af7Sopenharmony_ci	}
944e5c31af7Sopenharmony_ci	if (programContainsIOBlocks(m_programDefinition) &&
945e5c31af7Sopenharmony_ci		!supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_io_blocks"))
946e5c31af7Sopenharmony_ci	{
947e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_shader_io_blocks extension");
948e5c31af7Sopenharmony_ci	}
949e5c31af7Sopenharmony_ci}
950e5c31af7Sopenharmony_ci
951e5c31af7Sopenharmony_civoid ResourceListTestCase::deinit (void)
952e5c31af7Sopenharmony_ci{
953e5c31af7Sopenharmony_ci	m_targetResource.clear();
954e5c31af7Sopenharmony_ci
955e5c31af7Sopenharmony_ci	delete m_programDefinition;
956e5c31af7Sopenharmony_ci	m_programDefinition = DE_NULL;
957e5c31af7Sopenharmony_ci}
958e5c31af7Sopenharmony_ci
959e5c31af7Sopenharmony_ciResourceListTestCase::IterateResult ResourceListTestCase::iterate (void)
960e5c31af7Sopenharmony_ci{
961e5c31af7Sopenharmony_ci	const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
962e5c31af7Sopenharmony_ci
963e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
964e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
965e5c31af7Sopenharmony_ci
966e5c31af7Sopenharmony_ci	// Check resource list
967e5c31af7Sopenharmony_ci	{
968e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "ResourceList", "Resource list");
969e5c31af7Sopenharmony_ci		std::vector<std::string>	resourceList;
970e5c31af7Sopenharmony_ci		std::vector<std::string>	expectedResources;
971e5c31af7Sopenharmony_ci
972e5c31af7Sopenharmony_ci		queryResourceList(resourceList, program.getProgram());
973e5c31af7Sopenharmony_ci		expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
974e5c31af7Sopenharmony_ci
975e5c31af7Sopenharmony_ci		// verify the list and the expected list match
976e5c31af7Sopenharmony_ci
977e5c31af7Sopenharmony_ci		if (!verifyResourceList(resourceList, expectedResources))
978e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
979e5c31af7Sopenharmony_ci
980e5c31af7Sopenharmony_ci		// verify GetProgramResourceIndex() matches the indices of the list
981e5c31af7Sopenharmony_ci
982e5c31af7Sopenharmony_ci		if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
983e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
984e5c31af7Sopenharmony_ci
985e5c31af7Sopenharmony_ci		// Verify MAX_NAME_LENGTH
986e5c31af7Sopenharmony_ci		if (!verifyMaxNameLength(resourceList, program.getProgram()))
987e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
988e5c31af7Sopenharmony_ci	}
989e5c31af7Sopenharmony_ci
990e5c31af7Sopenharmony_ci	return STOP;
991e5c31af7Sopenharmony_ci}
992e5c31af7Sopenharmony_ci
993e5c31af7Sopenharmony_civoid ResourceListTestCase::queryResourceList (std::vector<std::string>& dst, glw::GLuint program)
994e5c31af7Sopenharmony_ci{
995e5c31af7Sopenharmony_ci	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
996e5c31af7Sopenharmony_ci	const glw::GLenum		programInterface	= getProgramInterfaceGLEnum(m_programInterface);
997e5c31af7Sopenharmony_ci	glw::GLint				numActiveResources	= 0;
998e5c31af7Sopenharmony_ci	glw::GLint				maxNameLength		= 0;
999e5c31af7Sopenharmony_ci	std::vector<char>		buffer;
1000e5c31af7Sopenharmony_ci
1001e5c31af7Sopenharmony_ci	m_testCtx.getLog() << tcu::TestLog::Message << "Querying " << glu::getProgramInterfaceName(programInterface) << " interface:" << tcu::TestLog::EndMessage;
1002e5c31af7Sopenharmony_ci
1003e5c31af7Sopenharmony_ci	gl.getProgramInterfaceiv(program, programInterface, GL_ACTIVE_RESOURCES, &numActiveResources);
1004e5c31af7Sopenharmony_ci	gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1005e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1006e5c31af7Sopenharmony_ci
1007e5c31af7Sopenharmony_ci	m_testCtx.getLog()	<< tcu::TestLog::Message
1008e5c31af7Sopenharmony_ci						<< "\tGL_ACTIVE_RESOURCES = " << numActiveResources << "\n"
1009e5c31af7Sopenharmony_ci						<< "\tGL_MAX_NAME_LENGTH = " << maxNameLength
1010e5c31af7Sopenharmony_ci						<< tcu::TestLog::EndMessage;
1011e5c31af7Sopenharmony_ci
1012e5c31af7Sopenharmony_ci	m_testCtx.getLog() << tcu::TestLog::Message << "Querying all active resources" << tcu::TestLog::EndMessage;
1013e5c31af7Sopenharmony_ci
1014e5c31af7Sopenharmony_ci	buffer.resize(maxNameLength+1, '\0');
1015e5c31af7Sopenharmony_ci
1016e5c31af7Sopenharmony_ci	for (int resourceNdx = 0; resourceNdx < numActiveResources; ++resourceNdx)
1017e5c31af7Sopenharmony_ci	{
1018e5c31af7Sopenharmony_ci		glw::GLint written = 0;
1019e5c31af7Sopenharmony_ci
1020e5c31af7Sopenharmony_ci		gl.getProgramResourceName(program, programInterface, resourceNdx, maxNameLength, &written, &buffer[0]);
1021e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1022e5c31af7Sopenharmony_ci
1023e5c31af7Sopenharmony_ci		dst.push_back(std::string(&buffer[0], written));
1024e5c31af7Sopenharmony_ci	}
1025e5c31af7Sopenharmony_ci}
1026e5c31af7Sopenharmony_ci
1027e5c31af7Sopenharmony_cibool ResourceListTestCase::verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources)
1028e5c31af7Sopenharmony_ci{
1029e5c31af7Sopenharmony_ci	bool error = false;
1030e5c31af7Sopenharmony_ci
1031e5c31af7Sopenharmony_ci	// Log and compare resource lists
1032e5c31af7Sopenharmony_ci
1033e5c31af7Sopenharmony_ci	m_testCtx.getLog() << tcu::TestLog::Message << "GL returned resources:" << tcu::TestLog::EndMessage;
1034e5c31af7Sopenharmony_ci
1035e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1036e5c31af7Sopenharmony_ci	{
1037e5c31af7Sopenharmony_ci		// unusedZero is a uniform that may be added by
1038e5c31af7Sopenharmony_ci		// generateProgramInterfaceProgramSources.  Omit it here to avoid
1039e5c31af7Sopenharmony_ci		// confusion about the output.
1040e5c31af7Sopenharmony_ci		if (resourceList[ndx] != getUnusedZeroUniformName())
1041e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << resourceList[ndx] << tcu::TestLog::EndMessage;
1042e5c31af7Sopenharmony_ci	}
1043e5c31af7Sopenharmony_ci
1044e5c31af7Sopenharmony_ci	m_testCtx.getLog() << tcu::TestLog::Message << "Expected list of resources:" << tcu::TestLog::EndMessage;
1045e5c31af7Sopenharmony_ci
1046e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1047e5c31af7Sopenharmony_ci		m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1048e5c31af7Sopenharmony_ci
1049e5c31af7Sopenharmony_ci	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying resource list contents." << tcu::TestLog::EndMessage;
1050e5c31af7Sopenharmony_ci
1051e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
1052e5c31af7Sopenharmony_ci	{
1053e5c31af7Sopenharmony_ci		if (!de::contains(resourceList.begin(), resourceList.end(), expectedResources[ndx]))
1054e5c31af7Sopenharmony_ci		{
1055e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list did not contain active resource " << expectedResources[ndx] << tcu::TestLog::EndMessage;
1056e5c31af7Sopenharmony_ci			error = true;
1057e5c31af7Sopenharmony_ci		}
1058e5c31af7Sopenharmony_ci	}
1059e5c31af7Sopenharmony_ci
1060e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1061e5c31af7Sopenharmony_ci	{
1062e5c31af7Sopenharmony_ci		if (!de::contains(expectedResources.begin(), expectedResources.end(), resourceList[ndx]))
1063e5c31af7Sopenharmony_ci		{
1064e5c31af7Sopenharmony_ci			// Ignore all builtin variables or the variable unusedZero,
1065e5c31af7Sopenharmony_ci			// mismatch causes errors otherwise.  unusedZero is a uniform that
1066e5c31af7Sopenharmony_ci			// may be added by generateProgramInterfaceProgramSources.
1067e5c31af7Sopenharmony_ci			if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == DE_FALSE &&
1068e5c31af7Sopenharmony_ci				resourceList[ndx] != getUnusedZeroUniformName())
1069e5c31af7Sopenharmony_ci			{
1070e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list contains unexpected resource name " << resourceList[ndx] << tcu::TestLog::EndMessage;
1071e5c31af7Sopenharmony_ci				error = true;
1072e5c31af7Sopenharmony_ci			}
1073e5c31af7Sopenharmony_ci			else
1074e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Note, resource list contains unknown built-in " << resourceList[ndx] << ". This variable is ignored." << tcu::TestLog::EndMessage;
1075e5c31af7Sopenharmony_ci		}
1076e5c31af7Sopenharmony_ci	}
1077e5c31af7Sopenharmony_ci
1078e5c31af7Sopenharmony_ci	return !error;
1079e5c31af7Sopenharmony_ci}
1080e5c31af7Sopenharmony_ci
1081e5c31af7Sopenharmony_cibool ResourceListTestCase::verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program)
1082e5c31af7Sopenharmony_ci{
1083e5c31af7Sopenharmony_ci	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
1084e5c31af7Sopenharmony_ci	const glw::GLenum		programInterface	= getProgramInterfaceGLEnum(m_programInterface);
1085e5c31af7Sopenharmony_ci	bool					error				= false;
1086e5c31af7Sopenharmony_ci
1087e5c31af7Sopenharmony_ci	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying GetProgramResourceIndex returns correct indices for resource names." << tcu::TestLog::EndMessage;
1088e5c31af7Sopenharmony_ci
1089e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1090e5c31af7Sopenharmony_ci	{
1091e5c31af7Sopenharmony_ci		const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, referenceResources[ndx].c_str());
1092e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1093e5c31af7Sopenharmony_ci
1094e5c31af7Sopenharmony_ci		if (index == GL_INVALID_INDEX)
1095e5c31af7Sopenharmony_ci		{
1096e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1097e5c31af7Sopenharmony_ci			error = true;
1098e5c31af7Sopenharmony_ci		}
1099e5c31af7Sopenharmony_ci		else if ((int)index >= (int)resourceList.size())
1100e5c31af7Sopenharmony_ci		{
1101e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1102e5c31af7Sopenharmony_ci			error = true;
1103e5c31af7Sopenharmony_ci		}
1104e5c31af7Sopenharmony_ci		else if (resourceList[index] != referenceResources[ndx])
1105e5c31af7Sopenharmony_ci		{
1106e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index (index = " << index << ") of another resource (" << resourceList[index] << ")." << tcu::TestLog::EndMessage;
1107e5c31af7Sopenharmony_ci			error = true;
1108e5c31af7Sopenharmony_ci		}
1109e5c31af7Sopenharmony_ci	}
1110e5c31af7Sopenharmony_ci
1111e5c31af7Sopenharmony_ci	// Query for "name" should match "name[0]" except for XFB
1112e5c31af7Sopenharmony_ci
1113e5c31af7Sopenharmony_ci	if (m_programInterface != PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING)
1114e5c31af7Sopenharmony_ci	{
1115e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
1116e5c31af7Sopenharmony_ci		{
1117e5c31af7Sopenharmony_ci			if (de::endsWith(referenceResources[ndx], "[0]"))
1118e5c31af7Sopenharmony_ci			{
1119e5c31af7Sopenharmony_ci				const std::string	queryString	= referenceResources[ndx].substr(0, referenceResources[ndx].length()-3);
1120e5c31af7Sopenharmony_ci				const glw::GLuint	index		= gl.getProgramResourceIndex(program, programInterface, queryString.c_str());
1121e5c31af7Sopenharmony_ci				GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1122e5c31af7Sopenharmony_ci
1123e5c31af7Sopenharmony_ci				if (index == GL_INVALID_INDEX)
1124e5c31af7Sopenharmony_ci				{
1125e5c31af7Sopenharmony_ci					m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
1126e5c31af7Sopenharmony_ci					error = true;
1127e5c31af7Sopenharmony_ci				}
1128e5c31af7Sopenharmony_ci				else if ((int)index >= (int)resourceList.size())
1129e5c31af7Sopenharmony_ci				{
1130e5c31af7Sopenharmony_ci					m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
1131e5c31af7Sopenharmony_ci					error = true;
1132e5c31af7Sopenharmony_ci				}
1133e5c31af7Sopenharmony_ci				else if (resourceList[index] != queryString + "[0]")
1134e5c31af7Sopenharmony_ci				{
1135e5c31af7Sopenharmony_ci					m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" got index (index = " << index << ") of another resource (\"" << resourceList[index] << "\")." << tcu::TestLog::EndMessage;
1136e5c31af7Sopenharmony_ci					error = true;
1137e5c31af7Sopenharmony_ci				}
1138e5c31af7Sopenharmony_ci			}
1139e5c31af7Sopenharmony_ci		}
1140e5c31af7Sopenharmony_ci	}
1141e5c31af7Sopenharmony_ci
1142e5c31af7Sopenharmony_ci	return !error;
1143e5c31af7Sopenharmony_ci}
1144e5c31af7Sopenharmony_ci
1145e5c31af7Sopenharmony_cibool ResourceListTestCase::verifyMaxNameLength (const std::vector<std::string>& resourceList, glw::GLuint program)
1146e5c31af7Sopenharmony_ci{
1147e5c31af7Sopenharmony_ci	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
1148e5c31af7Sopenharmony_ci	const glw::GLenum		programInterface		= getProgramInterfaceGLEnum(m_programInterface);
1149e5c31af7Sopenharmony_ci	glw::GLint				maxNameLength			= 0;
1150e5c31af7Sopenharmony_ci	glw::GLint				expectedMaxNameLength	= 0;
1151e5c31af7Sopenharmony_ci
1152e5c31af7Sopenharmony_ci	gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
1153e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
1154e5c31af7Sopenharmony_ci
1155e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
1156e5c31af7Sopenharmony_ci		expectedMaxNameLength = de::max(expectedMaxNameLength, (int)resourceList[ndx].size() + 1);
1157e5c31af7Sopenharmony_ci
1158e5c31af7Sopenharmony_ci	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying MAX_NAME_LENGTH, expecting " << expectedMaxNameLength << " (i.e. consistent with the queried resource list)" << tcu::TestLog::EndMessage;
1159e5c31af7Sopenharmony_ci
1160e5c31af7Sopenharmony_ci	if (expectedMaxNameLength != maxNameLength)
1161e5c31af7Sopenharmony_ci	{
1162e5c31af7Sopenharmony_ci		m_testCtx.getLog() << tcu::TestLog::Message << "Error, got " << maxNameLength << tcu::TestLog::EndMessage;
1163e5c31af7Sopenharmony_ci		return false;
1164e5c31af7Sopenharmony_ci	}
1165e5c31af7Sopenharmony_ci
1166e5c31af7Sopenharmony_ci	return true;
1167e5c31af7Sopenharmony_ci}
1168e5c31af7Sopenharmony_ci
1169e5c31af7Sopenharmony_cistd::string ResourceListTestCase::genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node* root)
1170e5c31af7Sopenharmony_ci{
1171e5c31af7Sopenharmony_ci	bool				isImplicitlySizedArray	= false;
1172e5c31af7Sopenharmony_ci	bool				hasVariable				= false;
1173e5c31af7Sopenharmony_ci	bool				accumulateName			= true;
1174e5c31af7Sopenharmony_ci	std::string			buf						= "var";
1175e5c31af7Sopenharmony_ci	std::string			prefix;
1176e5c31af7Sopenharmony_ci
1177e5c31af7Sopenharmony_ci	for (const ResourceDefinition::Node* node = root; node; node = node->getEnclosingNode())
1178e5c31af7Sopenharmony_ci	{
1179e5c31af7Sopenharmony_ci		switch (node->getType())
1180e5c31af7Sopenharmony_ci		{
1181e5c31af7Sopenharmony_ci			case ResourceDefinition::Node::TYPE_VARIABLE:
1182e5c31af7Sopenharmony_ci			{
1183e5c31af7Sopenharmony_ci				hasVariable = true;
1184e5c31af7Sopenharmony_ci				break;
1185e5c31af7Sopenharmony_ci			}
1186e5c31af7Sopenharmony_ci
1187e5c31af7Sopenharmony_ci			case ResourceDefinition::Node::TYPE_STRUCT_MEMBER:
1188e5c31af7Sopenharmony_ci			{
1189e5c31af7Sopenharmony_ci				if (accumulateName)
1190e5c31af7Sopenharmony_ci					buf += "_struct";
1191e5c31af7Sopenharmony_ci				break;
1192e5c31af7Sopenharmony_ci			}
1193e5c31af7Sopenharmony_ci
1194e5c31af7Sopenharmony_ci			case ResourceDefinition::Node::TYPE_ARRAY_ELEMENT:
1195e5c31af7Sopenharmony_ci			{
1196e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(node));
1197e5c31af7Sopenharmony_ci				const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(node);
1198e5c31af7Sopenharmony_ci
1199e5c31af7Sopenharmony_ci				isImplicitlySizedArray = (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY);
1200e5c31af7Sopenharmony_ci
1201e5c31af7Sopenharmony_ci				if (accumulateName)
1202e5c31af7Sopenharmony_ci					buf += "_array";
1203e5c31af7Sopenharmony_ci				break;
1204e5c31af7Sopenharmony_ci			}
1205e5c31af7Sopenharmony_ci
1206e5c31af7Sopenharmony_ci			case ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER:
1207e5c31af7Sopenharmony_ci			{
1208e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1209e5c31af7Sopenharmony_ci				const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1210e5c31af7Sopenharmony_ci
1211e5c31af7Sopenharmony_ci				if (storageDef->m_storage == glu::STORAGE_PATCH_IN ||
1212e5c31af7Sopenharmony_ci					storageDef->m_storage == glu::STORAGE_PATCH_OUT)
1213e5c31af7Sopenharmony_ci				{
1214e5c31af7Sopenharmony_ci					if (accumulateName)
1215e5c31af7Sopenharmony_ci						prefix += "patch_";
1216e5c31af7Sopenharmony_ci				}
1217e5c31af7Sopenharmony_ci				break;
1218e5c31af7Sopenharmony_ci			}
1219e5c31af7Sopenharmony_ci
1220e5c31af7Sopenharmony_ci			case ResourceDefinition::Node::TYPE_SHADER:
1221e5c31af7Sopenharmony_ci			case ResourceDefinition::Node::TYPE_SHADER_SET:
1222e5c31af7Sopenharmony_ci			{
1223e5c31af7Sopenharmony_ci				bool arrayedInterface;
1224e5c31af7Sopenharmony_ci
1225e5c31af7Sopenharmony_ci				if (node->getType() == ResourceDefinition::Node::TYPE_SHADER)
1226e5c31af7Sopenharmony_ci				{
1227e5c31af7Sopenharmony_ci					DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(node));
1228e5c31af7Sopenharmony_ci					const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(node);
1229e5c31af7Sopenharmony_ci
1230e5c31af7Sopenharmony_ci					arrayedInterface = isArrayedInterface(interface, (1u << shaderDef->m_type));
1231e5c31af7Sopenharmony_ci				}
1232e5c31af7Sopenharmony_ci				else
1233e5c31af7Sopenharmony_ci				{
1234e5c31af7Sopenharmony_ci					DE_ASSERT(node->getType() == ResourceDefinition::Node::TYPE_SHADER_SET);
1235e5c31af7Sopenharmony_ci					DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(node));
1236e5c31af7Sopenharmony_ci					const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(node);
1237e5c31af7Sopenharmony_ci
1238e5c31af7Sopenharmony_ci					arrayedInterface = isArrayedInterface(interface, shaderDef->getReferencingMask());
1239e5c31af7Sopenharmony_ci				}
1240e5c31af7Sopenharmony_ci
1241e5c31af7Sopenharmony_ci				if (arrayedInterface && isImplicitlySizedArray)
1242e5c31af7Sopenharmony_ci				{
1243e5c31af7Sopenharmony_ci					// omit implicit arrayness from name, i.e. remove trailing "_array"
1244e5c31af7Sopenharmony_ci					DE_ASSERT(de::endsWith(buf, "_array"));
1245e5c31af7Sopenharmony_ci					buf = buf.substr(0, buf.length() - 6);
1246e5c31af7Sopenharmony_ci				}
1247e5c31af7Sopenharmony_ci
1248e5c31af7Sopenharmony_ci				break;
1249e5c31af7Sopenharmony_ci			}
1250e5c31af7Sopenharmony_ci
1251e5c31af7Sopenharmony_ci			case ResourceDefinition::Node::TYPE_INTERFACE_BLOCK:
1252e5c31af7Sopenharmony_ci			{
1253e5c31af7Sopenharmony_ci				accumulateName = false;
1254e5c31af7Sopenharmony_ci				break;
1255e5c31af7Sopenharmony_ci			}
1256e5c31af7Sopenharmony_ci
1257e5c31af7Sopenharmony_ci			default:
1258e5c31af7Sopenharmony_ci				break;
1259e5c31af7Sopenharmony_ci		}
1260e5c31af7Sopenharmony_ci	}
1261e5c31af7Sopenharmony_ci
1262e5c31af7Sopenharmony_ci	if (!hasVariable)
1263e5c31af7Sopenharmony_ci		return prefix + "empty";
1264e5c31af7Sopenharmony_ci	else
1265e5c31af7Sopenharmony_ci		return prefix + buf;
1266e5c31af7Sopenharmony_ci}
1267e5c31af7Sopenharmony_ci
1268e5c31af7Sopenharmony_cibool ResourceListTestCase::isArrayedInterface (ProgramInterface interface, deUint32 stageBits)
1269e5c31af7Sopenharmony_ci{
1270e5c31af7Sopenharmony_ci	if (interface == PROGRAMINTERFACE_PROGRAM_INPUT)
1271e5c31af7Sopenharmony_ci	{
1272e5c31af7Sopenharmony_ci		const glu::ShaderType firstStage = getShaderMaskFirstStage(stageBits);
1273e5c31af7Sopenharmony_ci		return	firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL		||
1274e5c31af7Sopenharmony_ci				firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION	||
1275e5c31af7Sopenharmony_ci				firstStage == glu::SHADERTYPE_GEOMETRY;
1276e5c31af7Sopenharmony_ci	}
1277e5c31af7Sopenharmony_ci	else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT)
1278e5c31af7Sopenharmony_ci	{
1279e5c31af7Sopenharmony_ci		const glu::ShaderType lastStage = getShaderMaskLastStage(stageBits);
1280e5c31af7Sopenharmony_ci		return	lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL;
1281e5c31af7Sopenharmony_ci	}
1282e5c31af7Sopenharmony_ci	return false;
1283e5c31af7Sopenharmony_ci}
1284e5c31af7Sopenharmony_ci
1285e5c31af7Sopenharmony_ci// Resouce property query case
1286e5c31af7Sopenharmony_ci
1287e5c31af7Sopenharmony_ciclass ResourceTestCase : public ProgramInterfaceQueryTestCase
1288e5c31af7Sopenharmony_ci{
1289e5c31af7Sopenharmony_cipublic:
1290e5c31af7Sopenharmony_ci															ResourceTestCase			(Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name = DE_NULL);
1291e5c31af7Sopenharmony_ci															~ResourceTestCase			(void);
1292e5c31af7Sopenharmony_ci
1293e5c31af7Sopenharmony_ciprivate:
1294e5c31af7Sopenharmony_ci	void													init						(void);
1295e5c31af7Sopenharmony_ci	void													deinit						(void);
1296e5c31af7Sopenharmony_ci	const ProgramInterfaceDefinition::Program*				getProgramDefinition		(void) const;
1297e5c31af7Sopenharmony_ci	std::vector<std::string>								getQueryTargetResources		(void) const;
1298e5c31af7Sopenharmony_ci
1299e5c31af7Sopenharmony_ci	static std::string										genTestCaseName				(const ResourceDefinition::Node*);
1300e5c31af7Sopenharmony_ci	static std::string										genMultilineDescription		(const ResourceDefinition::Node*);
1301e5c31af7Sopenharmony_ci
1302e5c31af7Sopenharmony_ci	ResourceDefinition::Node::SharedPtr						m_targetResource;
1303e5c31af7Sopenharmony_ci	ProgramInterfaceDefinition::Program*					m_program;
1304e5c31af7Sopenharmony_ci	std::vector<std::string>								m_targetResources;
1305e5c31af7Sopenharmony_ci};
1306e5c31af7Sopenharmony_ci
1307e5c31af7Sopenharmony_ciResourceTestCase::ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name)
1308e5c31af7Sopenharmony_ci	: ProgramInterfaceQueryTestCase	(context, (name == DE_NULL) ? (genTestCaseName(targetResource.get()).c_str()) : (name), "", queryTarget)
1309e5c31af7Sopenharmony_ci	, m_targetResource				(targetResource)
1310e5c31af7Sopenharmony_ci	, m_program						(DE_NULL)
1311e5c31af7Sopenharmony_ci{
1312e5c31af7Sopenharmony_ci}
1313e5c31af7Sopenharmony_ci
1314e5c31af7Sopenharmony_ciResourceTestCase::~ResourceTestCase (void)
1315e5c31af7Sopenharmony_ci{
1316e5c31af7Sopenharmony_ci	deinit();
1317e5c31af7Sopenharmony_ci}
1318e5c31af7Sopenharmony_ci
1319e5c31af7Sopenharmony_civoid ResourceTestCase::init (void)
1320e5c31af7Sopenharmony_ci{
1321e5c31af7Sopenharmony_ci	m_testCtx.getLog()
1322e5c31af7Sopenharmony_ci		<< tcu::TestLog::Message
1323e5c31af7Sopenharmony_ci		<< genMultilineDescription(m_targetResource.get())
1324e5c31af7Sopenharmony_ci		<< tcu::TestLog::EndMessage;
1325e5c31af7Sopenharmony_ci
1326e5c31af7Sopenharmony_ci	// Program
1327e5c31af7Sopenharmony_ci	{
1328e5c31af7Sopenharmony_ci		// Generate interface with target resource
1329e5c31af7Sopenharmony_ci		m_program = generateProgramDefinitionFromResource(m_targetResource.get()).release();
1330e5c31af7Sopenharmony_ci		m_targetResources = getProgramInterfaceResourceList(m_program, getTargetInterface());
1331e5c31af7Sopenharmony_ci	}
1332e5c31af7Sopenharmony_ci}
1333e5c31af7Sopenharmony_ci
1334e5c31af7Sopenharmony_civoid ResourceTestCase::deinit (void)
1335e5c31af7Sopenharmony_ci{
1336e5c31af7Sopenharmony_ci	m_targetResource.clear();
1337e5c31af7Sopenharmony_ci
1338e5c31af7Sopenharmony_ci	delete m_program;
1339e5c31af7Sopenharmony_ci	m_program = DE_NULL;
1340e5c31af7Sopenharmony_ci
1341e5c31af7Sopenharmony_ci	m_targetResources = std::vector<std::string>();
1342e5c31af7Sopenharmony_ci}
1343e5c31af7Sopenharmony_ci
1344e5c31af7Sopenharmony_ciconst ProgramInterfaceDefinition::Program* ResourceTestCase::getProgramDefinition (void) const
1345e5c31af7Sopenharmony_ci{
1346e5c31af7Sopenharmony_ci	return m_program;
1347e5c31af7Sopenharmony_ci}
1348e5c31af7Sopenharmony_ci
1349e5c31af7Sopenharmony_cistd::vector<std::string> ResourceTestCase::getQueryTargetResources (void) const
1350e5c31af7Sopenharmony_ci{
1351e5c31af7Sopenharmony_ci	return m_targetResources;
1352e5c31af7Sopenharmony_ci}
1353e5c31af7Sopenharmony_ci
1354e5c31af7Sopenharmony_cistd::string ResourceTestCase::genTestCaseName (const ResourceDefinition::Node* resource)
1355e5c31af7Sopenharmony_ci{
1356e5c31af7Sopenharmony_ci	if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1357e5c31af7Sopenharmony_ci	{
1358e5c31af7Sopenharmony_ci		DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1359e5c31af7Sopenharmony_ci
1360e5c31af7Sopenharmony_ci		const ResourceDefinition::Variable* variable = static_cast<const ResourceDefinition::Variable*>(resource);
1361e5c31af7Sopenharmony_ci
1362e5c31af7Sopenharmony_ci		return convertGLTypeNameToTestName(glu::getDataTypeName(variable->m_dataType));
1363e5c31af7Sopenharmony_ci	}
1364e5c31af7Sopenharmony_ci
1365e5c31af7Sopenharmony_ci	DE_ASSERT(false);
1366e5c31af7Sopenharmony_ci	return "";
1367e5c31af7Sopenharmony_ci}
1368e5c31af7Sopenharmony_ci
1369e5c31af7Sopenharmony_cistd::string ResourceTestCase::genMultilineDescription (const ResourceDefinition::Node* resource)
1370e5c31af7Sopenharmony_ci{
1371e5c31af7Sopenharmony_ci	if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
1372e5c31af7Sopenharmony_ci	{
1373e5c31af7Sopenharmony_ci		DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));
1374e5c31af7Sopenharmony_ci
1375e5c31af7Sopenharmony_ci		const ResourceDefinition::Variable*	varDef				= static_cast<const ResourceDefinition::Variable*>(resource);
1376e5c31af7Sopenharmony_ci		std::ostringstream					buf;
1377e5c31af7Sopenharmony_ci		std::ostringstream					structureDescriptor;
1378e5c31af7Sopenharmony_ci		std::string							uniformType;
1379e5c31af7Sopenharmony_ci
1380e5c31af7Sopenharmony_ci		for (const ResourceDefinition::Node* node = resource; node; node = node->getEnclosingNode())
1381e5c31af7Sopenharmony_ci		{
1382e5c31af7Sopenharmony_ci			if (node->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
1383e5c31af7Sopenharmony_ci			{
1384e5c31af7Sopenharmony_ci				DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
1385e5c31af7Sopenharmony_ci
1386e5c31af7Sopenharmony_ci				const ResourceDefinition::StorageQualifier*	storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);
1387e5c31af7Sopenharmony_ci
1388e5c31af7Sopenharmony_ci				uniformType = std::string(" ") + glu::getStorageName(storageDef->m_storage);
1389e5c31af7Sopenharmony_ci				structureDescriptor << "\n\tdeclared as \"" << glu::getStorageName(storageDef->m_storage) << "\"";
1390e5c31af7Sopenharmony_ci			}
1391e5c31af7Sopenharmony_ci
1392e5c31af7Sopenharmony_ci			if (node->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
1393e5c31af7Sopenharmony_ci				structureDescriptor << "\n\tarray";
1394e5c31af7Sopenharmony_ci
1395e5c31af7Sopenharmony_ci			if (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
1396e5c31af7Sopenharmony_ci				structureDescriptor << "\n\tin a struct";
1397e5c31af7Sopenharmony_ci
1398e5c31af7Sopenharmony_ci			if (node->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
1399e5c31af7Sopenharmony_ci				structureDescriptor << "\n\tin the default block";
1400e5c31af7Sopenharmony_ci
1401e5c31af7Sopenharmony_ci			if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
1402e5c31af7Sopenharmony_ci				structureDescriptor << "\n\tin an interface block";
1403e5c31af7Sopenharmony_ci		}
1404e5c31af7Sopenharmony_ci
1405e5c31af7Sopenharmony_ci		buf	<< "Querying properties of " << glu::getDataTypeName(varDef->m_dataType) << uniformType << " variable.\n"
1406e5c31af7Sopenharmony_ci			<< "Variable is:\n"
1407e5c31af7Sopenharmony_ci			<< "\t" << glu::getDataTypeName(varDef->m_dataType)
1408e5c31af7Sopenharmony_ci			<< structureDescriptor.str();
1409e5c31af7Sopenharmony_ci
1410e5c31af7Sopenharmony_ci		return buf.str();
1411e5c31af7Sopenharmony_ci	}
1412e5c31af7Sopenharmony_ci	else if (resource->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
1413e5c31af7Sopenharmony_ci	{
1414e5c31af7Sopenharmony_ci		DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource));
1415e5c31af7Sopenharmony_ci
1416e5c31af7Sopenharmony_ci		const ResourceDefinition::TransformFeedbackTarget* xfbDef = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource);
1417e5c31af7Sopenharmony_ci
1418e5c31af7Sopenharmony_ci		DE_ASSERT(xfbDef->m_builtinVarName);
1419e5c31af7Sopenharmony_ci
1420e5c31af7Sopenharmony_ci		return std::string("Querying properties of a builtin variable ") + xfbDef->m_builtinVarName;
1421e5c31af7Sopenharmony_ci	}
1422e5c31af7Sopenharmony_ci
1423e5c31af7Sopenharmony_ci	DE_ASSERT(false);
1424e5c31af7Sopenharmony_ci	return "";
1425e5c31af7Sopenharmony_ci}
1426e5c31af7Sopenharmony_ci
1427e5c31af7Sopenharmony_ciclass ResourceNameBufferLimitCase : public TestCase
1428e5c31af7Sopenharmony_ci{
1429e5c31af7Sopenharmony_cipublic:
1430e5c31af7Sopenharmony_ci					ResourceNameBufferLimitCase		(Context& context, const char* name, const char* description);
1431e5c31af7Sopenharmony_ci					~ResourceNameBufferLimitCase	(void);
1432e5c31af7Sopenharmony_ci
1433e5c31af7Sopenharmony_ciprivate:
1434e5c31af7Sopenharmony_ci	IterateResult	iterate							(void);
1435e5c31af7Sopenharmony_ci};
1436e5c31af7Sopenharmony_ci
1437e5c31af7Sopenharmony_ciResourceNameBufferLimitCase::ResourceNameBufferLimitCase (Context& context, const char* name, const char* description)
1438e5c31af7Sopenharmony_ci	: TestCase(context, name, description)
1439e5c31af7Sopenharmony_ci{
1440e5c31af7Sopenharmony_ci}
1441e5c31af7Sopenharmony_ci
1442e5c31af7Sopenharmony_ciResourceNameBufferLimitCase::~ResourceNameBufferLimitCase (void)
1443e5c31af7Sopenharmony_ci{
1444e5c31af7Sopenharmony_ci}
1445e5c31af7Sopenharmony_ci
1446e5c31af7Sopenharmony_ciResourceNameBufferLimitCase::IterateResult ResourceNameBufferLimitCase::iterate (void)
1447e5c31af7Sopenharmony_ci{
1448e5c31af7Sopenharmony_ci	static const char* const computeSource =	"${GLSL_VERSION_DECL}\n"
1449e5c31af7Sopenharmony_ci												"layout(local_size_x = 1) in;\n"
1450e5c31af7Sopenharmony_ci												"uniform highp int u_uniformWithALongName;\n"
1451e5c31af7Sopenharmony_ci												"writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1452e5c31af7Sopenharmony_ci												"void main ()\n"
1453e5c31af7Sopenharmony_ci												"{\n"
1454e5c31af7Sopenharmony_ci												"	b_output_int = u_uniformWithALongName;\n"
1455e5c31af7Sopenharmony_ci												"}\n";
1456e5c31af7Sopenharmony_ci
1457e5c31af7Sopenharmony_ci	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
1458e5c31af7Sopenharmony_ci	const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, computeSource)));
1459e5c31af7Sopenharmony_ci	glw::GLuint					uniformIndex;
1460e5c31af7Sopenharmony_ci
1461e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1462e5c31af7Sopenharmony_ci
1463e5c31af7Sopenharmony_ci	// Log program
1464e5c31af7Sopenharmony_ci	{
1465e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1466e5c31af7Sopenharmony_ci
1467e5c31af7Sopenharmony_ci		m_testCtx.getLog() << program;
1468e5c31af7Sopenharmony_ci		if (!program.isOk())
1469e5c31af7Sopenharmony_ci			throw tcu::TestError("could not build program");
1470e5c31af7Sopenharmony_ci	}
1471e5c31af7Sopenharmony_ci
1472e5c31af7Sopenharmony_ci	uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniformWithALongName");
1473e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1474e5c31af7Sopenharmony_ci
1475e5c31af7Sopenharmony_ci	if (uniformIndex == GL_INVALID_INDEX)
1476e5c31af7Sopenharmony_ci		throw tcu::TestError("Uniform u_uniformWithALongName resource index was GL_INVALID_INDEX");
1477e5c31af7Sopenharmony_ci
1478e5c31af7Sopenharmony_ci	// Query with different sized buffers, len("u_uniformWithALongName") == 22
1479e5c31af7Sopenharmony_ci
1480e5c31af7Sopenharmony_ci	{
1481e5c31af7Sopenharmony_ci		static const struct
1482e5c31af7Sopenharmony_ci		{
1483e5c31af7Sopenharmony_ci			const char*	description;
1484e5c31af7Sopenharmony_ci			int			querySize;
1485e5c31af7Sopenharmony_ci			bool		returnLength;
1486e5c31af7Sopenharmony_ci		} querySizes[] =
1487e5c31af7Sopenharmony_ci		{
1488e5c31af7Sopenharmony_ci			{ "Query to larger buffer",										24,		true	},
1489e5c31af7Sopenharmony_ci			{ "Query to buffer the same size",								23,		true	},
1490e5c31af7Sopenharmony_ci			{ "Query to one byte too small buffer",							22,		true	},
1491e5c31af7Sopenharmony_ci			{ "Query to one byte buffer",									1,		true	},
1492e5c31af7Sopenharmony_ci			{ "Query to zero sized buffer",									0,		true	},
1493e5c31af7Sopenharmony_ci			{ "Query to one byte too small buffer, null length argument",	22,		false	},
1494e5c31af7Sopenharmony_ci			{ "Query to one byte buffer, null length argument",				1,		false	},
1495e5c31af7Sopenharmony_ci			{ "Query to zero sized buffer, null length argument",			0,		false	},
1496e5c31af7Sopenharmony_ci		};
1497e5c31af7Sopenharmony_ci
1498e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1499e5c31af7Sopenharmony_ci		{
1500e5c31af7Sopenharmony_ci			const tcu::ScopedLogSection			section				(m_testCtx.getLog(), "Query", querySizes[ndx].description);
1501e5c31af7Sopenharmony_ci			const int							uniformNameLen		= 22;
1502e5c31af7Sopenharmony_ci			const int							expectedWriteLen	= (querySizes[ndx].querySize != 0) ? (de::min(uniformNameLen, (querySizes[ndx].querySize - 1))) : (0);
1503e5c31af7Sopenharmony_ci			char								buffer				[26];
1504e5c31af7Sopenharmony_ci			glw::GLsizei						written				= -1;
1505e5c31af7Sopenharmony_ci
1506e5c31af7Sopenharmony_ci			// One byte for guard
1507e5c31af7Sopenharmony_ci			DE_ASSERT((int)sizeof(buffer) > querySizes[ndx].querySize);
1508e5c31af7Sopenharmony_ci
1509e5c31af7Sopenharmony_ci			deMemset(buffer, 'x', sizeof(buffer));
1510e5c31af7Sopenharmony_ci
1511e5c31af7Sopenharmony_ci			if (querySizes[ndx].querySize)
1512e5c31af7Sopenharmony_ci				m_testCtx.getLog()
1513e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1514e5c31af7Sopenharmony_ci					<< "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1515e5c31af7Sopenharmony_ci					<< ", expecting query to write " << expectedWriteLen << " bytes followed by a null terminator"
1516e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
1517e5c31af7Sopenharmony_ci			else
1518e5c31af7Sopenharmony_ci				m_testCtx.getLog()
1519e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1520e5c31af7Sopenharmony_ci					<< "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
1521e5c31af7Sopenharmony_ci					<< ", expecting query to write 0 bytes"
1522e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
1523e5c31af7Sopenharmony_ci
1524e5c31af7Sopenharmony_ci			gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].querySize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), buffer);
1525e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");
1526e5c31af7Sopenharmony_ci
1527e5c31af7Sopenharmony_ci			if (querySizes[ndx].returnLength && written != expectedWriteLen)
1528e5c31af7Sopenharmony_ci			{
1529e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1530e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1531e5c31af7Sopenharmony_ci			}
1532e5c31af7Sopenharmony_ci			else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen] != 0)
1533e5c31af7Sopenharmony_ci			{
1534e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected null terminator at " << expectedWriteLen << ", got dec=" << (int)buffer[expectedWriteLen] << tcu::TestLog::EndMessage;
1535e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Missing null terminator");
1536e5c31af7Sopenharmony_ci			}
1537e5c31af7Sopenharmony_ci			else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen+1] != 'x')
1538e5c31af7Sopenharmony_ci			{
1539e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen+1) << " was modified, got dec=" << (int)buffer[expectedWriteLen+1] << tcu::TestLog::EndMessage;
1540e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1541e5c31af7Sopenharmony_ci			}
1542e5c31af7Sopenharmony_ci			else if (querySizes[ndx].querySize == 0 && buffer[0] != 'x')
1543e5c31af7Sopenharmony_ci			{
1544e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was 0 but buffer contents were modified. At index 0 got dec=" << (int)buffer[0] << tcu::TestLog::EndMessage;
1545e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents were modified");
1546e5c31af7Sopenharmony_ci			}
1547e5c31af7Sopenharmony_ci		}
1548e5c31af7Sopenharmony_ci	}
1549e5c31af7Sopenharmony_ci
1550e5c31af7Sopenharmony_ci	return STOP;
1551e5c31af7Sopenharmony_ci}
1552e5c31af7Sopenharmony_ci
1553e5c31af7Sopenharmony_ciclass ResourceQueryBufferLimitCase : public TestCase
1554e5c31af7Sopenharmony_ci{
1555e5c31af7Sopenharmony_cipublic:
1556e5c31af7Sopenharmony_ci					ResourceQueryBufferLimitCase	(Context& context, const char* name, const char* description);
1557e5c31af7Sopenharmony_ci					~ResourceQueryBufferLimitCase	(void);
1558e5c31af7Sopenharmony_ci
1559e5c31af7Sopenharmony_ciprivate:
1560e5c31af7Sopenharmony_ci	IterateResult	iterate							(void);
1561e5c31af7Sopenharmony_ci};
1562e5c31af7Sopenharmony_ci
1563e5c31af7Sopenharmony_ciResourceQueryBufferLimitCase::ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description)
1564e5c31af7Sopenharmony_ci	: TestCase(context, name, description)
1565e5c31af7Sopenharmony_ci{
1566e5c31af7Sopenharmony_ci}
1567e5c31af7Sopenharmony_ci
1568e5c31af7Sopenharmony_ciResourceQueryBufferLimitCase::~ResourceQueryBufferLimitCase (void)
1569e5c31af7Sopenharmony_ci{
1570e5c31af7Sopenharmony_ci}
1571e5c31af7Sopenharmony_ci
1572e5c31af7Sopenharmony_ciResourceQueryBufferLimitCase::IterateResult ResourceQueryBufferLimitCase::iterate (void)
1573e5c31af7Sopenharmony_ci{
1574e5c31af7Sopenharmony_ci	static const char* const computeSource =	"${GLSL_VERSION_DECL}\n"
1575e5c31af7Sopenharmony_ci												"layout(local_size_x = 1) in;\n"
1576e5c31af7Sopenharmony_ci												"uniform highp int u_uniform;\n"
1577e5c31af7Sopenharmony_ci												"writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
1578e5c31af7Sopenharmony_ci												"void main ()\n"
1579e5c31af7Sopenharmony_ci												"{\n"
1580e5c31af7Sopenharmony_ci												"	b_output_int = u_uniform;\n"
1581e5c31af7Sopenharmony_ci												"}\n";
1582e5c31af7Sopenharmony_ci
1583e5c31af7Sopenharmony_ci	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
1584e5c31af7Sopenharmony_ci	const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, computeSource)));
1585e5c31af7Sopenharmony_ci	glw::GLuint					uniformIndex;
1586e5c31af7Sopenharmony_ci
1587e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1588e5c31af7Sopenharmony_ci
1589e5c31af7Sopenharmony_ci	// Log program
1590e5c31af7Sopenharmony_ci	{
1591e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");
1592e5c31af7Sopenharmony_ci
1593e5c31af7Sopenharmony_ci		m_testCtx.getLog() << program;
1594e5c31af7Sopenharmony_ci		if (!program.isOk())
1595e5c31af7Sopenharmony_ci			throw tcu::TestError("could not build program");
1596e5c31af7Sopenharmony_ci	}
1597e5c31af7Sopenharmony_ci
1598e5c31af7Sopenharmony_ci	uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniform");
1599e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1600e5c31af7Sopenharmony_ci
1601e5c31af7Sopenharmony_ci	if (uniformIndex == GL_INVALID_INDEX)
1602e5c31af7Sopenharmony_ci		throw tcu::TestError("Uniform u_uniform resource index was GL_INVALID_INDEX");
1603e5c31af7Sopenharmony_ci
1604e5c31af7Sopenharmony_ci	// Query uniform properties
1605e5c31af7Sopenharmony_ci
1606e5c31af7Sopenharmony_ci	{
1607e5c31af7Sopenharmony_ci		static const struct
1608e5c31af7Sopenharmony_ci		{
1609e5c31af7Sopenharmony_ci			const char*	description;
1610e5c31af7Sopenharmony_ci			int			numProps;
1611e5c31af7Sopenharmony_ci			int			bufferSize;
1612e5c31af7Sopenharmony_ci			bool		returnLength;
1613e5c31af7Sopenharmony_ci		} querySizes[] =
1614e5c31af7Sopenharmony_ci		{
1615e5c31af7Sopenharmony_ci			{ "Query to a larger buffer",							2, 3, true	},
1616e5c31af7Sopenharmony_ci			{ "Query to too small a buffer",						3, 2, true	},
1617e5c31af7Sopenharmony_ci			{ "Query to zero sized buffer",							3, 0, true	},
1618e5c31af7Sopenharmony_ci			{ "Query to a larger buffer, null length argument",		2, 3, false	},
1619e5c31af7Sopenharmony_ci			{ "Query to too small a buffer, null length argument",	3, 2, false	},
1620e5c31af7Sopenharmony_ci			{ "Query to zero sized buffer, null length argument",	3, 0, false	},
1621e5c31af7Sopenharmony_ci		};
1622e5c31af7Sopenharmony_ci
1623e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
1624e5c31af7Sopenharmony_ci		{
1625e5c31af7Sopenharmony_ci			const tcu::ScopedLogSection		section				(m_testCtx.getLog(), "QueryToLarger", querySizes[ndx].description);
1626e5c31af7Sopenharmony_ci			const glw::GLenum				props[]				= { GL_LOCATION, GL_LOCATION, GL_LOCATION };
1627e5c31af7Sopenharmony_ci			const int						expectedWriteLen	= de::min(querySizes[ndx].bufferSize, querySizes[ndx].numProps);
1628e5c31af7Sopenharmony_ci			int								params[]			= { 255, 255, 255, 255 };
1629e5c31af7Sopenharmony_ci			glw::GLsizei					written				= -1;
1630e5c31af7Sopenharmony_ci
1631e5c31af7Sopenharmony_ci			DE_ASSERT(querySizes[ndx].numProps <= DE_LENGTH_OF_ARRAY(props));
1632e5c31af7Sopenharmony_ci			DE_ASSERT(querySizes[ndx].bufferSize < DE_LENGTH_OF_ARRAY(params)); // leave at least one element for overflow detection
1633e5c31af7Sopenharmony_ci
1634e5c31af7Sopenharmony_ci			m_testCtx.getLog()
1635e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
1636e5c31af7Sopenharmony_ci				<< "Querying " << querySizes[ndx].numProps << " uniform prop(s) to a buffer with size " << querySizes[ndx].bufferSize << ". Expecting query to return " << expectedWriteLen << " prop(s)"
1637e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
1638e5c31af7Sopenharmony_ci
1639e5c31af7Sopenharmony_ci			gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].numProps, props, querySizes[ndx].bufferSize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), params);
1640e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query program resources");
1641e5c31af7Sopenharmony_ci
1642e5c31af7Sopenharmony_ci			if (querySizes[ndx].returnLength && written != expectedWriteLen)
1643e5c31af7Sopenharmony_ci			{
1644e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
1645e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
1646e5c31af7Sopenharmony_ci			}
1647e5c31af7Sopenharmony_ci			else if (params[expectedWriteLen] != 255)
1648e5c31af7Sopenharmony_ci			{
1649e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen) << " was modified. Was 255 before call, got dec=" << params[expectedWriteLen] << tcu::TestLog::EndMessage;
1650e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
1651e5c31af7Sopenharmony_ci			}
1652e5c31af7Sopenharmony_ci		}
1653e5c31af7Sopenharmony_ci	}
1654e5c31af7Sopenharmony_ci
1655e5c31af7Sopenharmony_ci	return STOP;
1656e5c31af7Sopenharmony_ci}
1657e5c31af7Sopenharmony_ci
1658e5c31af7Sopenharmony_ciclass InterfaceBlockBaseCase : public TestCase
1659e5c31af7Sopenharmony_ci{
1660e5c31af7Sopenharmony_cipublic:
1661e5c31af7Sopenharmony_ci	enum CaseType
1662e5c31af7Sopenharmony_ci	{
1663e5c31af7Sopenharmony_ci		CASE_NAMED_BLOCK = 0,
1664e5c31af7Sopenharmony_ci		CASE_UNNAMED_BLOCK,
1665e5c31af7Sopenharmony_ci		CASE_BLOCK_ARRAY,
1666e5c31af7Sopenharmony_ci
1667e5c31af7Sopenharmony_ci		CASE_LAST
1668e5c31af7Sopenharmony_ci	};
1669e5c31af7Sopenharmony_ci
1670e5c31af7Sopenharmony_ci											InterfaceBlockBaseCase		(Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1671e5c31af7Sopenharmony_ci											~InterfaceBlockBaseCase		(void);
1672e5c31af7Sopenharmony_ci
1673e5c31af7Sopenharmony_ciprivate:
1674e5c31af7Sopenharmony_ci	void									init						(void);
1675e5c31af7Sopenharmony_ci	void									deinit						(void);
1676e5c31af7Sopenharmony_ci
1677e5c31af7Sopenharmony_ciprotected:
1678e5c31af7Sopenharmony_ci	const glu::Storage						m_storage;
1679e5c31af7Sopenharmony_ci	const CaseType							m_caseType;
1680e5c31af7Sopenharmony_ci	ProgramInterfaceDefinition::Program*	m_program;
1681e5c31af7Sopenharmony_ci};
1682e5c31af7Sopenharmony_ci
1683e5c31af7Sopenharmony_ciInterfaceBlockBaseCase::InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1684e5c31af7Sopenharmony_ci	: TestCase		(context, name, description)
1685e5c31af7Sopenharmony_ci	, m_storage		(storage)
1686e5c31af7Sopenharmony_ci	, m_caseType	(caseType)
1687e5c31af7Sopenharmony_ci	, m_program		(DE_NULL)
1688e5c31af7Sopenharmony_ci{
1689e5c31af7Sopenharmony_ci	DE_ASSERT(storage == glu::STORAGE_UNIFORM || storage == glu::STORAGE_BUFFER);
1690e5c31af7Sopenharmony_ci}
1691e5c31af7Sopenharmony_ci
1692e5c31af7Sopenharmony_ciInterfaceBlockBaseCase::~InterfaceBlockBaseCase (void)
1693e5c31af7Sopenharmony_ci{
1694e5c31af7Sopenharmony_ci	deinit();
1695e5c31af7Sopenharmony_ci}
1696e5c31af7Sopenharmony_ci
1697e5c31af7Sopenharmony_civoid InterfaceBlockBaseCase::init (void)
1698e5c31af7Sopenharmony_ci{
1699e5c31af7Sopenharmony_ci	const glu::GLSLVersion				glslVersion	= glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
1700e5c31af7Sopenharmony_ci	ProgramInterfaceDefinition::Shader*	shader;
1701e5c31af7Sopenharmony_ci
1702e5c31af7Sopenharmony_ci	m_program = new ProgramInterfaceDefinition::Program();
1703e5c31af7Sopenharmony_ci	shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glslVersion);
1704e5c31af7Sopenharmony_ci
1705e5c31af7Sopenharmony_ci	// PrecedingInterface
1706e5c31af7Sopenharmony_ci	{
1707e5c31af7Sopenharmony_ci		glu::InterfaceBlock precedingInterfaceBlock;
1708e5c31af7Sopenharmony_ci
1709e5c31af7Sopenharmony_ci		precedingInterfaceBlock.interfaceName	= "PrecedingInterface";
1710e5c31af7Sopenharmony_ci		precedingInterfaceBlock.layout.binding	= 0;
1711e5c31af7Sopenharmony_ci		precedingInterfaceBlock.storage			= m_storage;
1712e5c31af7Sopenharmony_ci		precedingInterfaceBlock.instanceName	= "precedingInstance";
1713e5c31af7Sopenharmony_ci
1714e5c31af7Sopenharmony_ci		precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "precedingMember"));
1715e5c31af7Sopenharmony_ci
1716e5c31af7Sopenharmony_ci		// Unsized array type
1717e5c31af7Sopenharmony_ci		if (m_storage == glu::STORAGE_BUFFER)
1718e5c31af7Sopenharmony_ci			precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "precedingMemberUnsizedArray"));
1719e5c31af7Sopenharmony_ci		else
1720e5c31af7Sopenharmony_ci			precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2), "precedingMemberArray"));
1721e5c31af7Sopenharmony_ci
1722e5c31af7Sopenharmony_ci		shader->getDefaultBlock().interfaceBlocks.push_back(precedingInterfaceBlock);
1723e5c31af7Sopenharmony_ci	}
1724e5c31af7Sopenharmony_ci
1725e5c31af7Sopenharmony_ci	// TargetInterface
1726e5c31af7Sopenharmony_ci	{
1727e5c31af7Sopenharmony_ci		glu::InterfaceBlock targetInterfaceBlock;
1728e5c31af7Sopenharmony_ci
1729e5c31af7Sopenharmony_ci		targetInterfaceBlock.interfaceName	= "TargetInterface";
1730e5c31af7Sopenharmony_ci		targetInterfaceBlock.layout.binding	= 1;
1731e5c31af7Sopenharmony_ci		targetInterfaceBlock.storage		= m_storage;
1732e5c31af7Sopenharmony_ci
1733e5c31af7Sopenharmony_ci		if (m_caseType == CASE_UNNAMED_BLOCK)
1734e5c31af7Sopenharmony_ci			targetInterfaceBlock.instanceName = "";
1735e5c31af7Sopenharmony_ci		else
1736e5c31af7Sopenharmony_ci			targetInterfaceBlock.instanceName = "targetInstance";
1737e5c31af7Sopenharmony_ci
1738e5c31af7Sopenharmony_ci		if (m_caseType == CASE_BLOCK_ARRAY)
1739e5c31af7Sopenharmony_ci			targetInterfaceBlock.dimensions.push_back(2);
1740e5c31af7Sopenharmony_ci
1741e5c31af7Sopenharmony_ci		// Basic type
1742e5c31af7Sopenharmony_ci		{
1743e5c31af7Sopenharmony_ci			targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "blockMemberBasic"));
1744e5c31af7Sopenharmony_ci		}
1745e5c31af7Sopenharmony_ci
1746e5c31af7Sopenharmony_ci		// Array type
1747e5c31af7Sopenharmony_ci		{
1748e5c31af7Sopenharmony_ci			targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 3), "blockMemberArray"));
1749e5c31af7Sopenharmony_ci		}
1750e5c31af7Sopenharmony_ci
1751e5c31af7Sopenharmony_ci		// Struct type
1752e5c31af7Sopenharmony_ci		{
1753e5c31af7Sopenharmony_ci			glu::StructType* structPtr = new glu::StructType("StructType");
1754e5c31af7Sopenharmony_ci			structPtr->addMember("structMemberBasic", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
1755e5c31af7Sopenharmony_ci			structPtr->addMember("structMemberArray", glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2));
1756e5c31af7Sopenharmony_ci
1757e5c31af7Sopenharmony_ci			targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(structPtr), 2), "blockMemberStruct"));
1758e5c31af7Sopenharmony_ci		}
1759e5c31af7Sopenharmony_ci
1760e5c31af7Sopenharmony_ci		// Unsized array type
1761e5c31af7Sopenharmony_ci		if (m_storage == glu::STORAGE_BUFFER)
1762e5c31af7Sopenharmony_ci			targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "blockMemberUnsizedArray"));
1763e5c31af7Sopenharmony_ci
1764e5c31af7Sopenharmony_ci		shader->getDefaultBlock().interfaceBlocks.push_back(targetInterfaceBlock);
1765e5c31af7Sopenharmony_ci	}
1766e5c31af7Sopenharmony_ci
1767e5c31af7Sopenharmony_ci	// TrailingInterface
1768e5c31af7Sopenharmony_ci	{
1769e5c31af7Sopenharmony_ci		glu::InterfaceBlock trailingInterfaceBlock;
1770e5c31af7Sopenharmony_ci
1771e5c31af7Sopenharmony_ci		trailingInterfaceBlock.interfaceName	= "TrailingInterface";
1772e5c31af7Sopenharmony_ci		trailingInterfaceBlock.layout.binding	= 3;
1773e5c31af7Sopenharmony_ci		trailingInterfaceBlock.storage			= m_storage;
1774e5c31af7Sopenharmony_ci		trailingInterfaceBlock.instanceName		= "trailingInstance";
1775e5c31af7Sopenharmony_ci		trailingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "trailingMember"));
1776e5c31af7Sopenharmony_ci
1777e5c31af7Sopenharmony_ci		shader->getDefaultBlock().interfaceBlocks.push_back(trailingInterfaceBlock);
1778e5c31af7Sopenharmony_ci	}
1779e5c31af7Sopenharmony_ci
1780e5c31af7Sopenharmony_ci	DE_ASSERT(m_program->isValid());
1781e5c31af7Sopenharmony_ci}
1782e5c31af7Sopenharmony_ci
1783e5c31af7Sopenharmony_civoid InterfaceBlockBaseCase::deinit (void)
1784e5c31af7Sopenharmony_ci{
1785e5c31af7Sopenharmony_ci	delete m_program;
1786e5c31af7Sopenharmony_ci	m_program = DE_NULL;
1787e5c31af7Sopenharmony_ci}
1788e5c31af7Sopenharmony_ci
1789e5c31af7Sopenharmony_ciclass InterfaceBlockActiveVariablesTestCase : public InterfaceBlockBaseCase
1790e5c31af7Sopenharmony_ci{
1791e5c31af7Sopenharmony_cipublic:
1792e5c31af7Sopenharmony_ci											InterfaceBlockActiveVariablesTestCase	(Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
1793e5c31af7Sopenharmony_ci
1794e5c31af7Sopenharmony_ciprivate:
1795e5c31af7Sopenharmony_ci	IterateResult							iterate									(void);
1796e5c31af7Sopenharmony_ci};
1797e5c31af7Sopenharmony_ci
1798e5c31af7Sopenharmony_ciInterfaceBlockActiveVariablesTestCase::InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
1799e5c31af7Sopenharmony_ci	: InterfaceBlockBaseCase(context, name, description, storage, caseType)
1800e5c31af7Sopenharmony_ci{
1801e5c31af7Sopenharmony_ci}
1802e5c31af7Sopenharmony_ci
1803e5c31af7Sopenharmony_ciInterfaceBlockActiveVariablesTestCase::IterateResult InterfaceBlockActiveVariablesTestCase::iterate (void)
1804e5c31af7Sopenharmony_ci{
1805e5c31af7Sopenharmony_ci	const ProgramInterface			programInterface				= (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
1806e5c31af7Sopenharmony_ci																	  (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
1807e5c31af7Sopenharmony_ci																	  (PROGRAMINTERFACE_LAST);
1808e5c31af7Sopenharmony_ci	const glw::GLenum				programGLInterfaceValue			= getProgramInterfaceGLEnum(programInterface);
1809e5c31af7Sopenharmony_ci	const glw::GLenum				programMemberInterfaceValue		= (m_storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM) :
1810e5c31af7Sopenharmony_ci																	  (m_storage == glu::STORAGE_BUFFER) ? (GL_BUFFER_VARIABLE) :
1811e5c31af7Sopenharmony_ci																	  (0);
1812e5c31af7Sopenharmony_ci	const std::vector<std::string>	blockNames						= getProgramInterfaceResourceList(m_program, programInterface);
1813e5c31af7Sopenharmony_ci	glu::ShaderProgram				program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
1814e5c31af7Sopenharmony_ci	int								expectedMaxNumActiveVariables	= 0;
1815e5c31af7Sopenharmony_ci
1816e5c31af7Sopenharmony_ci	DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
1817e5c31af7Sopenharmony_ci
1818e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1819e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1820e5c31af7Sopenharmony_ci
1821e5c31af7Sopenharmony_ci	// Verify all blocks
1822e5c31af7Sopenharmony_ci
1823e5c31af7Sopenharmony_ci	for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
1824e5c31af7Sopenharmony_ci	{
1825e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section				(m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
1826e5c31af7Sopenharmony_ci		const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
1827e5c31af7Sopenharmony_ci		const glw::GLuint			resourceNdx			= gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
1828e5c31af7Sopenharmony_ci		glw::GLint					numActiveResources;
1829e5c31af7Sopenharmony_ci		std::vector<std::string>	activeResourceNames;
1830e5c31af7Sopenharmony_ci
1831e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
1832e5c31af7Sopenharmony_ci
1833e5c31af7Sopenharmony_ci		if (resourceNdx == GL_INVALID_INDEX)
1834e5c31af7Sopenharmony_ci		{
1835e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
1836e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
1837e5c31af7Sopenharmony_ci			continue;
1838e5c31af7Sopenharmony_ci		}
1839e5c31af7Sopenharmony_ci
1840e5c31af7Sopenharmony_ci		// query block information
1841e5c31af7Sopenharmony_ci
1842e5c31af7Sopenharmony_ci		{
1843e5c31af7Sopenharmony_ci			const glw::GLenum	props[]			= { GL_NUM_ACTIVE_VARIABLES };
1844e5c31af7Sopenharmony_ci			glw::GLint			retBuffer[2]	= { -1, -1 };
1845e5c31af7Sopenharmony_ci			glw::GLint			written			= -1;
1846e5c31af7Sopenharmony_ci
1847e5c31af7Sopenharmony_ci			gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, 1, &written, retBuffer);
1848e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NUM_ACTIVE_VARIABLES");
1849e5c31af7Sopenharmony_ci
1850e5c31af7Sopenharmony_ci			numActiveResources = retBuffer[0];
1851e5c31af7Sopenharmony_ci			expectedMaxNumActiveVariables = de::max(expectedMaxNumActiveVariables, numActiveResources);
1852e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "NUM_ACTIVE_VARIABLES = " << numActiveResources << tcu::TestLog::EndMessage;
1853e5c31af7Sopenharmony_ci
1854e5c31af7Sopenharmony_ci			if (written == -1 || retBuffer[0] == -1)
1855e5c31af7Sopenharmony_ci			{
1856e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES did not return a value" << tcu::TestLog::EndMessage;
1857e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES failed");
1858e5c31af7Sopenharmony_ci				continue;
1859e5c31af7Sopenharmony_ci			}
1860e5c31af7Sopenharmony_ci			else if (retBuffer[1] != -1)
1861e5c31af7Sopenharmony_ci			{
1862e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES returned too many values" << tcu::TestLog::EndMessage;
1863e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES returned too many values");
1864e5c31af7Sopenharmony_ci				continue;
1865e5c31af7Sopenharmony_ci			}
1866e5c31af7Sopenharmony_ci			else if (retBuffer[0] < 0)
1867e5c31af7Sopenharmony_ci			{
1868e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, NUM_ACTIVE_VARIABLES < 0" << tcu::TestLog::EndMessage;
1869e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES < 0");
1870e5c31af7Sopenharmony_ci				continue;
1871e5c31af7Sopenharmony_ci			}
1872e5c31af7Sopenharmony_ci		}
1873e5c31af7Sopenharmony_ci
1874e5c31af7Sopenharmony_ci		// query block variable information
1875e5c31af7Sopenharmony_ci
1876e5c31af7Sopenharmony_ci		{
1877e5c31af7Sopenharmony_ci			const glw::GLenum			props[]					= { GL_ACTIVE_VARIABLES };
1878e5c31af7Sopenharmony_ci			std::vector<glw::GLint>		activeVariableIndices	(numActiveResources + 1, -1);	// Allocate one extra trailing to detect wrong write lengths
1879e5c31af7Sopenharmony_ci			glw::GLint					written					= -1;
1880e5c31af7Sopenharmony_ci
1881e5c31af7Sopenharmony_ci			gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, (glw::GLsizei)activeVariableIndices.size(), &written, &activeVariableIndices[0]);
1882e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_VARIABLES");
1883e5c31af7Sopenharmony_ci
1884e5c31af7Sopenharmony_ci			if (written == -1)
1885e5c31af7Sopenharmony_ci			{
1886e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return any values" << tcu::TestLog::EndMessage;
1887e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES failed");
1888e5c31af7Sopenharmony_ci				continue;
1889e5c31af7Sopenharmony_ci			}
1890e5c31af7Sopenharmony_ci			else if (written != numActiveResources)
1891e5c31af7Sopenharmony_ci			{
1892e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
1893e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned invalid number of values");
1894e5c31af7Sopenharmony_ci				continue;
1895e5c31af7Sopenharmony_ci			}
1896e5c31af7Sopenharmony_ci			else if (activeVariableIndices.back() != -1)
1897e5c31af7Sopenharmony_ci			{
1898e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_ACTIVE_VARIABLES query return buffer trailing guard value was modified, getProgramResourceiv returned more than NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
1899e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned too many values");
1900e5c31af7Sopenharmony_ci				continue;
1901e5c31af7Sopenharmony_ci			}
1902e5c31af7Sopenharmony_ci
1903e5c31af7Sopenharmony_ci			// log indices
1904e5c31af7Sopenharmony_ci			{
1905e5c31af7Sopenharmony_ci				tcu::MessageBuilder builder(&m_testCtx.getLog());
1906e5c31af7Sopenharmony_ci
1907e5c31af7Sopenharmony_ci				builder << "Active variable indices: {";
1908e5c31af7Sopenharmony_ci				for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1909e5c31af7Sopenharmony_ci				{
1910e5c31af7Sopenharmony_ci					if (varNdx)
1911e5c31af7Sopenharmony_ci						builder << ", ";
1912e5c31af7Sopenharmony_ci					builder << activeVariableIndices[varNdx];
1913e5c31af7Sopenharmony_ci				}
1914e5c31af7Sopenharmony_ci				builder << "}" << tcu::TestLog::EndMessage;
1915e5c31af7Sopenharmony_ci			}
1916e5c31af7Sopenharmony_ci
1917e5c31af7Sopenharmony_ci			// collect names
1918e5c31af7Sopenharmony_ci
1919e5c31af7Sopenharmony_ci			activeResourceNames.resize(numActiveResources);
1920e5c31af7Sopenharmony_ci
1921e5c31af7Sopenharmony_ci			for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1922e5c31af7Sopenharmony_ci			{
1923e5c31af7Sopenharmony_ci				const glw::GLenum	nameProp	= GL_NAME_LENGTH;
1924e5c31af7Sopenharmony_ci				glw::GLint			nameLength	= -1;
1925e5c31af7Sopenharmony_ci				std::vector<char>	nameBuffer;
1926e5c31af7Sopenharmony_ci
1927e5c31af7Sopenharmony_ci				written = -1;
1928e5c31af7Sopenharmony_ci				gl.getProgramResourceiv(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], 1, &nameProp, 1, &written, &nameLength);
1929e5c31af7Sopenharmony_ci				GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NAME_LENGTH");
1930e5c31af7Sopenharmony_ci
1931e5c31af7Sopenharmony_ci				if (nameLength <= 0 || written <= 0)
1932e5c31af7Sopenharmony_ci				{
1933e5c31af7Sopenharmony_ci					m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_NAME_LENGTH query failed" << tcu::TestLog::EndMessage;
1934e5c31af7Sopenharmony_ci					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
1935e5c31af7Sopenharmony_ci					continue;
1936e5c31af7Sopenharmony_ci				}
1937e5c31af7Sopenharmony_ci
1938e5c31af7Sopenharmony_ci				nameBuffer.resize(nameLength + 2, 'X'); // allocate more than required
1939e5c31af7Sopenharmony_ci				written = -1;
1940e5c31af7Sopenharmony_ci				gl.getProgramResourceName(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], nameLength+1, &written, &nameBuffer[0]);
1941e5c31af7Sopenharmony_ci				GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceName");
1942e5c31af7Sopenharmony_ci
1943e5c31af7Sopenharmony_ci				if (written <= 0)
1944e5c31af7Sopenharmony_ci				{
1945e5c31af7Sopenharmony_ci					m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, no data written" << tcu::TestLog::EndMessage;
1946e5c31af7Sopenharmony_ci					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1947e5c31af7Sopenharmony_ci					continue;
1948e5c31af7Sopenharmony_ci				}
1949e5c31af7Sopenharmony_ci				else if (written > nameLength)
1950e5c31af7Sopenharmony_ci				{
1951e5c31af7Sopenharmony_ci					m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, query returned too much data" << tcu::TestLog::EndMessage;
1952e5c31af7Sopenharmony_ci					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
1953e5c31af7Sopenharmony_ci					continue;
1954e5c31af7Sopenharmony_ci				}
1955e5c31af7Sopenharmony_ci
1956e5c31af7Sopenharmony_ci				activeResourceNames[varNdx] = std::string(&nameBuffer[0], written);
1957e5c31af7Sopenharmony_ci			}
1958e5c31af7Sopenharmony_ci
1959e5c31af7Sopenharmony_ci			// log collected names
1960e5c31af7Sopenharmony_ci			{
1961e5c31af7Sopenharmony_ci				tcu::MessageBuilder builder(&m_testCtx.getLog());
1962e5c31af7Sopenharmony_ci
1963e5c31af7Sopenharmony_ci				builder << "Active variables:\n";
1964e5c31af7Sopenharmony_ci				for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
1965e5c31af7Sopenharmony_ci					builder << "\t" << activeResourceNames[varNdx] << "\n";
1966e5c31af7Sopenharmony_ci				builder << tcu::TestLog::EndMessage;
1967e5c31af7Sopenharmony_ci			}
1968e5c31af7Sopenharmony_ci		}
1969e5c31af7Sopenharmony_ci
1970e5c31af7Sopenharmony_ci		// verify names
1971e5c31af7Sopenharmony_ci		{
1972e5c31af7Sopenharmony_ci			glu::InterfaceBlock*		block		= DE_NULL;
1973e5c31af7Sopenharmony_ci			const std::string			blockName	= glu::parseVariableName(blockNames[blockNdx].c_str());
1974e5c31af7Sopenharmony_ci			std::vector<std::string>	referenceList;
1975e5c31af7Sopenharmony_ci
1976e5c31af7Sopenharmony_ci			for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
1977e5c31af7Sopenharmony_ci			{
1978e5c31af7Sopenharmony_ci				if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName)
1979e5c31af7Sopenharmony_ci				{
1980e5c31af7Sopenharmony_ci					block = &m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx];
1981e5c31af7Sopenharmony_ci					break;
1982e5c31af7Sopenharmony_ci				}
1983e5c31af7Sopenharmony_ci			}
1984e5c31af7Sopenharmony_ci
1985e5c31af7Sopenharmony_ci			if (!block)
1986e5c31af7Sopenharmony_ci				throw tcu::InternalError("could not find block referenced in the reference resource list");
1987e5c31af7Sopenharmony_ci
1988e5c31af7Sopenharmony_ci			// generate reference list
1989e5c31af7Sopenharmony_ci
1990e5c31af7Sopenharmony_ci			referenceList = getProgramInterfaceBlockMemberResourceList(*block);
1991e5c31af7Sopenharmony_ci			{
1992e5c31af7Sopenharmony_ci				tcu::MessageBuilder builder(&m_testCtx.getLog());
1993e5c31af7Sopenharmony_ci
1994e5c31af7Sopenharmony_ci				builder << "Expected variable names:\n";
1995e5c31af7Sopenharmony_ci				for (int varNdx = 0; varNdx < (int)referenceList.size(); ++varNdx)
1996e5c31af7Sopenharmony_ci					builder << "\t" << referenceList[varNdx] << "\n";
1997e5c31af7Sopenharmony_ci				builder << tcu::TestLog::EndMessage;
1998e5c31af7Sopenharmony_ci			}
1999e5c31af7Sopenharmony_ci
2000e5c31af7Sopenharmony_ci			// compare lists
2001e5c31af7Sopenharmony_ci			{
2002e5c31af7Sopenharmony_ci				bool listsIdentical = true;
2003e5c31af7Sopenharmony_ci
2004e5c31af7Sopenharmony_ci				for (int ndx = 0; ndx < (int)referenceList.size(); ++ndx)
2005e5c31af7Sopenharmony_ci				{
2006e5c31af7Sopenharmony_ci					if (!de::contains(activeResourceNames.begin(), activeResourceNames.end(), referenceList[ndx]))
2007e5c31af7Sopenharmony_ci					{
2008e5c31af7Sopenharmony_ci						m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list did not contain active variable " << referenceList[ndx] << tcu::TestLog::EndMessage;
2009e5c31af7Sopenharmony_ci						listsIdentical = false;
2010e5c31af7Sopenharmony_ci					}
2011e5c31af7Sopenharmony_ci				}
2012e5c31af7Sopenharmony_ci
2013e5c31af7Sopenharmony_ci				for (int ndx = 0; ndx < (int)activeResourceNames.size(); ++ndx)
2014e5c31af7Sopenharmony_ci				{
2015e5c31af7Sopenharmony_ci					if (!de::contains(referenceList.begin(), referenceList.end(), activeResourceNames[ndx]))
2016e5c31af7Sopenharmony_ci					{
2017e5c31af7Sopenharmony_ci						m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list contains unexpected resource \"" << activeResourceNames[ndx] << "\"" << tcu::TestLog::EndMessage;
2018e5c31af7Sopenharmony_ci						listsIdentical = false;
2019e5c31af7Sopenharmony_ci					}
2020e5c31af7Sopenharmony_ci				}
2021e5c31af7Sopenharmony_ci
2022e5c31af7Sopenharmony_ci				if (listsIdentical)
2023e5c31af7Sopenharmony_ci					m_testCtx.getLog() << tcu::TestLog::Message << "Lists identical" << tcu::TestLog::EndMessage;
2024e5c31af7Sopenharmony_ci				else
2025e5c31af7Sopenharmony_ci				{
2026e5c31af7Sopenharmony_ci					m_testCtx.getLog() << tcu::TestLog::Message << "Error, invalid active variable list" << tcu::TestLog::EndMessage;
2027e5c31af7Sopenharmony_ci					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid active variable list");
2028e5c31af7Sopenharmony_ci					continue;
2029e5c31af7Sopenharmony_ci				}
2030e5c31af7Sopenharmony_ci			}
2031e5c31af7Sopenharmony_ci		}
2032e5c31af7Sopenharmony_ci	}
2033e5c31af7Sopenharmony_ci
2034e5c31af7Sopenharmony_ci	// Max num active variables
2035e5c31af7Sopenharmony_ci	{
2036e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection	section					(m_testCtx.getLog(), "MaxNumActiveVariables", "MAX_NUM_ACTIVE_VARIABLES");
2037e5c31af7Sopenharmony_ci		const glw::Functions&		gl						= m_context.getRenderContext().getFunctions();
2038e5c31af7Sopenharmony_ci		glw::GLint					maxNumActiveVariables	= -1;
2039e5c31af7Sopenharmony_ci
2040e5c31af7Sopenharmony_ci		gl.getProgramInterfaceiv(program.getProgram(), programGLInterfaceValue, GL_MAX_NUM_ACTIVE_VARIABLES, &maxNumActiveVariables);
2041e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "query MAX_NUM_ACTIVE_VARIABLES");
2042e5c31af7Sopenharmony_ci
2043e5c31af7Sopenharmony_ci		m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES = " << maxNumActiveVariables << tcu::TestLog::EndMessage;
2044e5c31af7Sopenharmony_ci
2045e5c31af7Sopenharmony_ci		if (expectedMaxNumActiveVariables != maxNumActiveVariables)
2046e5c31af7Sopenharmony_ci		{
2047e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected MAX_NUM_ACTIVE_VARIABLES" << tcu::TestLog::EndMessage;
2048e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected MAX_NUM_ACTIVE_VARIABLES");
2049e5c31af7Sopenharmony_ci		}
2050e5c31af7Sopenharmony_ci		else
2051e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES valid" << tcu::TestLog::EndMessage;
2052e5c31af7Sopenharmony_ci	}
2053e5c31af7Sopenharmony_ci
2054e5c31af7Sopenharmony_ci	return STOP;
2055e5c31af7Sopenharmony_ci}
2056e5c31af7Sopenharmony_ci
2057e5c31af7Sopenharmony_ciclass InterfaceBlockDataSizeTestCase : public InterfaceBlockBaseCase
2058e5c31af7Sopenharmony_ci{
2059e5c31af7Sopenharmony_cipublic:
2060e5c31af7Sopenharmony_ci											InterfaceBlockDataSizeTestCase	(Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
2061e5c31af7Sopenharmony_ci
2062e5c31af7Sopenharmony_ciprivate:
2063e5c31af7Sopenharmony_ci	IterateResult							iterate							(void);
2064e5c31af7Sopenharmony_ci	int										getBlockMinDataSize				(const std::string& blockName) const;
2065e5c31af7Sopenharmony_ci	int										getBlockMinDataSize				(const glu::InterfaceBlock& block) const;
2066e5c31af7Sopenharmony_ci};
2067e5c31af7Sopenharmony_ci
2068e5c31af7Sopenharmony_ciInterfaceBlockDataSizeTestCase::InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
2069e5c31af7Sopenharmony_ci	: InterfaceBlockBaseCase(context, name, description, storage, caseType)
2070e5c31af7Sopenharmony_ci{
2071e5c31af7Sopenharmony_ci}
2072e5c31af7Sopenharmony_ci
2073e5c31af7Sopenharmony_ciInterfaceBlockDataSizeTestCase::IterateResult InterfaceBlockDataSizeTestCase::iterate (void)
2074e5c31af7Sopenharmony_ci{
2075e5c31af7Sopenharmony_ci	const ProgramInterface			programInterface		= (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
2076e5c31af7Sopenharmony_ci															  (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
2077e5c31af7Sopenharmony_ci															  (PROGRAMINTERFACE_LAST);
2078e5c31af7Sopenharmony_ci	const glw::GLenum				programGLInterfaceValue	= getProgramInterfaceGLEnum(programInterface);
2079e5c31af7Sopenharmony_ci	const std::vector<std::string>	blockNames				= getProgramInterfaceResourceList(m_program, programInterface);
2080e5c31af7Sopenharmony_ci	glu::ShaderProgram				program					(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2081e5c31af7Sopenharmony_ci
2082e5c31af7Sopenharmony_ci	DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
2083e5c31af7Sopenharmony_ci
2084e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2085e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2086e5c31af7Sopenharmony_ci
2087e5c31af7Sopenharmony_ci	// Verify all blocks
2088e5c31af7Sopenharmony_ci	for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
2089e5c31af7Sopenharmony_ci	{
2090e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section				(m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
2091e5c31af7Sopenharmony_ci		const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
2092e5c31af7Sopenharmony_ci		const glw::GLuint			resourceNdx			= gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
2093e5c31af7Sopenharmony_ci		const int					expectedMinDataSize	= getBlockMinDataSize(blockNames[blockNdx]);
2094e5c31af7Sopenharmony_ci		glw::GLint					queryDataSize		= -1;
2095e5c31af7Sopenharmony_ci
2096e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
2097e5c31af7Sopenharmony_ci
2098e5c31af7Sopenharmony_ci		if (resourceNdx == GL_INVALID_INDEX)
2099e5c31af7Sopenharmony_ci		{
2100e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
2101e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
2102e5c31af7Sopenharmony_ci			continue;
2103e5c31af7Sopenharmony_ci		}
2104e5c31af7Sopenharmony_ci
2105e5c31af7Sopenharmony_ci		// query
2106e5c31af7Sopenharmony_ci		{
2107e5c31af7Sopenharmony_ci			const glw::GLenum prop = GL_BUFFER_DATA_SIZE;
2108e5c31af7Sopenharmony_ci
2109e5c31af7Sopenharmony_ci			gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, 1, &prop, 1, DE_NULL, &queryDataSize);
2110e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query resource BUFFER_DATA_SIZE");
2111e5c31af7Sopenharmony_ci		}
2112e5c31af7Sopenharmony_ci
2113e5c31af7Sopenharmony_ci		m_testCtx.getLog()
2114e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message
2115e5c31af7Sopenharmony_ci			<< "BUFFER_DATA_SIZE = " << queryDataSize << "\n"
2116e5c31af7Sopenharmony_ci			<< "Buffer data size with tight packing: " << expectedMinDataSize
2117e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2118e5c31af7Sopenharmony_ci
2119e5c31af7Sopenharmony_ci		if (queryDataSize < expectedMinDataSize)
2120e5c31af7Sopenharmony_ci		{
2121e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was less than minimum buffer data size" << tcu::TestLog::EndMessage;
2122e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer data size invalid");
2123e5c31af7Sopenharmony_ci			continue;
2124e5c31af7Sopenharmony_ci		}
2125e5c31af7Sopenharmony_ci		else
2126e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size valid" << tcu::TestLog::EndMessage;
2127e5c31af7Sopenharmony_ci	}
2128e5c31af7Sopenharmony_ci
2129e5c31af7Sopenharmony_ci	return STOP;
2130e5c31af7Sopenharmony_ci}
2131e5c31af7Sopenharmony_ci
2132e5c31af7Sopenharmony_ciint InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const std::string& blockFullName) const
2133e5c31af7Sopenharmony_ci{
2134e5c31af7Sopenharmony_ci	const std::string blockName = glu::parseVariableName(blockFullName.c_str());
2135e5c31af7Sopenharmony_ci
2136e5c31af7Sopenharmony_ci	for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
2137e5c31af7Sopenharmony_ci	{
2138e5c31af7Sopenharmony_ci		if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName &&
2139e5c31af7Sopenharmony_ci			m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].storage == m_storage)
2140e5c31af7Sopenharmony_ci			return getBlockMinDataSize(m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx]);
2141e5c31af7Sopenharmony_ci	}
2142e5c31af7Sopenharmony_ci
2143e5c31af7Sopenharmony_ci	DE_ASSERT(false);
2144e5c31af7Sopenharmony_ci	return -1;
2145e5c31af7Sopenharmony_ci}
2146e5c31af7Sopenharmony_ci
2147e5c31af7Sopenharmony_ciclass AtomicCounterCase : public TestCase
2148e5c31af7Sopenharmony_ci{
2149e5c31af7Sopenharmony_cipublic:
2150e5c31af7Sopenharmony_ci											AtomicCounterCase			(Context& context, const char* name, const char* description);
2151e5c31af7Sopenharmony_ci											~AtomicCounterCase			(void);
2152e5c31af7Sopenharmony_ci
2153e5c31af7Sopenharmony_ciprivate:
2154e5c31af7Sopenharmony_ci	void									init						(void);
2155e5c31af7Sopenharmony_ci	void									deinit						(void);
2156e5c31af7Sopenharmony_ci
2157e5c31af7Sopenharmony_ciprotected:
2158e5c31af7Sopenharmony_ci	int										getNumAtomicCounterBuffers	(void) const;
2159e5c31af7Sopenharmony_ci	int										getMaxNumActiveVariables	(void) const;
2160e5c31af7Sopenharmony_ci	int										getBufferVariableCount		(int binding) const;
2161e5c31af7Sopenharmony_ci	int										getBufferMinimumDataSize	(int binding) const;
2162e5c31af7Sopenharmony_ci
2163e5c31af7Sopenharmony_ci	ProgramInterfaceDefinition::Program*	m_program;
2164e5c31af7Sopenharmony_ci};
2165e5c31af7Sopenharmony_ci
2166e5c31af7Sopenharmony_ciAtomicCounterCase::AtomicCounterCase (Context& context, const char* name, const char* description)
2167e5c31af7Sopenharmony_ci	: TestCase	(context, name, description)
2168e5c31af7Sopenharmony_ci	, m_program	(DE_NULL)
2169e5c31af7Sopenharmony_ci{
2170e5c31af7Sopenharmony_ci}
2171e5c31af7Sopenharmony_ci
2172e5c31af7Sopenharmony_ciAtomicCounterCase::~AtomicCounterCase (void)
2173e5c31af7Sopenharmony_ci{
2174e5c31af7Sopenharmony_ci	deinit();
2175e5c31af7Sopenharmony_ci}
2176e5c31af7Sopenharmony_ci
2177e5c31af7Sopenharmony_civoid AtomicCounterCase::init (void)
2178e5c31af7Sopenharmony_ci{
2179e5c31af7Sopenharmony_ci	ProgramInterfaceDefinition::Shader* shader;
2180e5c31af7Sopenharmony_ci	glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2181e5c31af7Sopenharmony_ci
2182e5c31af7Sopenharmony_ci	m_program = new ProgramInterfaceDefinition::Program();
2183e5c31af7Sopenharmony_ci	shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glslVersion);
2184e5c31af7Sopenharmony_ci
2185e5c31af7Sopenharmony_ci	{
2186e5c31af7Sopenharmony_ci		glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter1", glu::STORAGE_UNIFORM);
2187e5c31af7Sopenharmony_ci		decl.layout.binding = 1;
2188e5c31af7Sopenharmony_ci		shader->getDefaultBlock().variables.push_back(decl);
2189e5c31af7Sopenharmony_ci	}
2190e5c31af7Sopenharmony_ci	{
2191e5c31af7Sopenharmony_ci		glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter2", glu::STORAGE_UNIFORM);
2192e5c31af7Sopenharmony_ci		decl.layout.binding = 1;
2193e5c31af7Sopenharmony_ci		decl.layout.offset = 8;
2194e5c31af7Sopenharmony_ci
2195e5c31af7Sopenharmony_ci		shader->getDefaultBlock().variables.push_back(decl);
2196e5c31af7Sopenharmony_ci	}
2197e5c31af7Sopenharmony_ci	{
2198e5c31af7Sopenharmony_ci		glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding2_counter1", glu::STORAGE_UNIFORM);
2199e5c31af7Sopenharmony_ci		decl.layout.binding = 2;
2200e5c31af7Sopenharmony_ci		shader->getDefaultBlock().variables.push_back(decl);
2201e5c31af7Sopenharmony_ci	}
2202e5c31af7Sopenharmony_ci
2203e5c31af7Sopenharmony_ci	DE_ASSERT(m_program->isValid());
2204e5c31af7Sopenharmony_ci}
2205e5c31af7Sopenharmony_ci
2206e5c31af7Sopenharmony_civoid AtomicCounterCase::deinit (void)
2207e5c31af7Sopenharmony_ci{
2208e5c31af7Sopenharmony_ci	delete m_program;
2209e5c31af7Sopenharmony_ci	m_program = DE_NULL;
2210e5c31af7Sopenharmony_ci}
2211e5c31af7Sopenharmony_ci
2212e5c31af7Sopenharmony_ciint AtomicCounterCase::getNumAtomicCounterBuffers (void) const
2213e5c31af7Sopenharmony_ci{
2214e5c31af7Sopenharmony_ci	std::set<int> buffers;
2215e5c31af7Sopenharmony_ci
2216e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2217e5c31af7Sopenharmony_ci	{
2218e5c31af7Sopenharmony_ci		if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2219e5c31af7Sopenharmony_ci			glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2220e5c31af7Sopenharmony_ci		{
2221e5c31af7Sopenharmony_ci			buffers.insert(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding);
2222e5c31af7Sopenharmony_ci		}
2223e5c31af7Sopenharmony_ci	}
2224e5c31af7Sopenharmony_ci
2225e5c31af7Sopenharmony_ci	return (int)buffers.size();
2226e5c31af7Sopenharmony_ci}
2227e5c31af7Sopenharmony_ci
2228e5c31af7Sopenharmony_ciint AtomicCounterCase::getMaxNumActiveVariables (void) const
2229e5c31af7Sopenharmony_ci{
2230e5c31af7Sopenharmony_ci	int					maxVars			= 0;
2231e5c31af7Sopenharmony_ci	std::map<int,int>	numBufferVars;
2232e5c31af7Sopenharmony_ci
2233e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2234e5c31af7Sopenharmony_ci	{
2235e5c31af7Sopenharmony_ci		if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2236e5c31af7Sopenharmony_ci			glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
2237e5c31af7Sopenharmony_ci		{
2238e5c31af7Sopenharmony_ci			const int binding = m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding;
2239e5c31af7Sopenharmony_ci
2240e5c31af7Sopenharmony_ci			if (numBufferVars.find(binding) == numBufferVars.end())
2241e5c31af7Sopenharmony_ci				numBufferVars[binding] = 1;
2242e5c31af7Sopenharmony_ci			else
2243e5c31af7Sopenharmony_ci				++numBufferVars[binding];
2244e5c31af7Sopenharmony_ci		}
2245e5c31af7Sopenharmony_ci	}
2246e5c31af7Sopenharmony_ci
2247e5c31af7Sopenharmony_ci	for (std::map<int,int>::const_iterator it = numBufferVars.begin(); it != numBufferVars.end(); ++it)
2248e5c31af7Sopenharmony_ci		maxVars = de::max(maxVars, it->second);
2249e5c31af7Sopenharmony_ci
2250e5c31af7Sopenharmony_ci	return maxVars;
2251e5c31af7Sopenharmony_ci}
2252e5c31af7Sopenharmony_ci
2253e5c31af7Sopenharmony_ciint AtomicCounterCase::getBufferVariableCount (int binding) const
2254e5c31af7Sopenharmony_ci{
2255e5c31af7Sopenharmony_ci	int numVars = 0;
2256e5c31af7Sopenharmony_ci
2257e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2258e5c31af7Sopenharmony_ci	{
2259e5c31af7Sopenharmony_ci		if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2260e5c31af7Sopenharmony_ci			glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2261e5c31af7Sopenharmony_ci			m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2262e5c31af7Sopenharmony_ci			++numVars;
2263e5c31af7Sopenharmony_ci	}
2264e5c31af7Sopenharmony_ci
2265e5c31af7Sopenharmony_ci	return numVars;
2266e5c31af7Sopenharmony_ci}
2267e5c31af7Sopenharmony_ci
2268e5c31af7Sopenharmony_ciint AtomicCounterCase::getBufferMinimumDataSize (int binding) const
2269e5c31af7Sopenharmony_ci{
2270e5c31af7Sopenharmony_ci	int minSize			= -1;
2271e5c31af7Sopenharmony_ci	int currentOffset	= 0;
2272e5c31af7Sopenharmony_ci
2273e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
2274e5c31af7Sopenharmony_ci	{
2275e5c31af7Sopenharmony_ci		if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
2276e5c31af7Sopenharmony_ci			glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
2277e5c31af7Sopenharmony_ci			m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
2278e5c31af7Sopenharmony_ci		{
2279e5c31af7Sopenharmony_ci			const int thisOffset = (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset != -1) ? (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset) : (currentOffset);
2280e5c31af7Sopenharmony_ci			currentOffset = thisOffset + 4;
2281e5c31af7Sopenharmony_ci
2282e5c31af7Sopenharmony_ci			minSize = de::max(minSize, thisOffset + 4);
2283e5c31af7Sopenharmony_ci		}
2284e5c31af7Sopenharmony_ci	}
2285e5c31af7Sopenharmony_ci
2286e5c31af7Sopenharmony_ci	return minSize;
2287e5c31af7Sopenharmony_ci}
2288e5c31af7Sopenharmony_ci
2289e5c31af7Sopenharmony_ciclass AtomicCounterResourceListCase : public AtomicCounterCase
2290e5c31af7Sopenharmony_ci{
2291e5c31af7Sopenharmony_cipublic:
2292e5c31af7Sopenharmony_ci						AtomicCounterResourceListCase	(Context& context, const char* name, const char* description);
2293e5c31af7Sopenharmony_ci
2294e5c31af7Sopenharmony_ciprivate:
2295e5c31af7Sopenharmony_ci	IterateResult		iterate							(void);
2296e5c31af7Sopenharmony_ci};
2297e5c31af7Sopenharmony_ci
2298e5c31af7Sopenharmony_ciAtomicCounterResourceListCase::AtomicCounterResourceListCase (Context& context, const char* name, const char* description)
2299e5c31af7Sopenharmony_ci	: AtomicCounterCase(context, name, description)
2300e5c31af7Sopenharmony_ci{
2301e5c31af7Sopenharmony_ci}
2302e5c31af7Sopenharmony_ci
2303e5c31af7Sopenharmony_ciAtomicCounterResourceListCase::IterateResult AtomicCounterResourceListCase::iterate (void)
2304e5c31af7Sopenharmony_ci{
2305e5c31af7Sopenharmony_ci	const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2306e5c31af7Sopenharmony_ci
2307e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2308e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2309e5c31af7Sopenharmony_ci
2310e5c31af7Sopenharmony_ci	{
2311e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection		section						(m_testCtx.getLog(), "ActiveResources", "ACTIVE_RESOURCES");
2312e5c31af7Sopenharmony_ci		const glw::Functions&			gl							= m_context.getRenderContext().getFunctions();
2313e5c31af7Sopenharmony_ci		glw::GLint						numActiveResources			= -1;
2314e5c31af7Sopenharmony_ci		const int						numExpectedActiveResources	= 2; // 2 buffer bindings
2315e5c31af7Sopenharmony_ci
2316e5c31af7Sopenharmony_ci		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying ACTIVE_RESOURCES, expecting " << numExpectedActiveResources << tcu::TestLog::EndMessage;
2317e5c31af7Sopenharmony_ci
2318e5c31af7Sopenharmony_ci		gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources);
2319e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_RESOURCES");
2320e5c31af7Sopenharmony_ci
2321e5c31af7Sopenharmony_ci		m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage;
2322e5c31af7Sopenharmony_ci
2323e5c31af7Sopenharmony_ci		if (numActiveResources != numExpectedActiveResources)
2324e5c31af7Sopenharmony_ci		{
2325e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected ACTIVE_RESOURCES" << tcu::TestLog::EndMessage;
2326e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_RESOURCES");
2327e5c31af7Sopenharmony_ci		}
2328e5c31af7Sopenharmony_ci		else
2329e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES valid" << tcu::TestLog::EndMessage;
2330e5c31af7Sopenharmony_ci	}
2331e5c31af7Sopenharmony_ci
2332e5c31af7Sopenharmony_ci	return STOP;
2333e5c31af7Sopenharmony_ci}
2334e5c31af7Sopenharmony_ci
2335e5c31af7Sopenharmony_ciclass AtomicCounterActiveVariablesCase : public AtomicCounterCase
2336e5c31af7Sopenharmony_ci{
2337e5c31af7Sopenharmony_cipublic:
2338e5c31af7Sopenharmony_ci					AtomicCounterActiveVariablesCase	(Context& context, const char* name, const char* description);
2339e5c31af7Sopenharmony_ci
2340e5c31af7Sopenharmony_ciprivate:
2341e5c31af7Sopenharmony_ci	IterateResult	iterate								(void);
2342e5c31af7Sopenharmony_ci};
2343e5c31af7Sopenharmony_ci
2344e5c31af7Sopenharmony_ciAtomicCounterActiveVariablesCase::AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description)
2345e5c31af7Sopenharmony_ci	: AtomicCounterCase(context, name, description)
2346e5c31af7Sopenharmony_ci{
2347e5c31af7Sopenharmony_ci}
2348e5c31af7Sopenharmony_ci
2349e5c31af7Sopenharmony_ciAtomicCounterActiveVariablesCase::IterateResult AtomicCounterActiveVariablesCase::iterate (void)
2350e5c31af7Sopenharmony_ci{
2351e5c31af7Sopenharmony_ci	const glw::Functions&		gl								= m_context.getRenderContext().getFunctions();
2352e5c31af7Sopenharmony_ci	const glu::ShaderProgram	program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2353e5c31af7Sopenharmony_ci	const int					numAtomicBuffers				= getNumAtomicCounterBuffers();
2354e5c31af7Sopenharmony_ci	const int					expectedMaxNumActiveVariables	= getMaxNumActiveVariables();
2355e5c31af7Sopenharmony_ci
2356e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2357e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2358e5c31af7Sopenharmony_ci
2359e5c31af7Sopenharmony_ci	// check active variables
2360e5c31af7Sopenharmony_ci	{
2361e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection	section						(m_testCtx.getLog(), "Interface", "ATOMIC_COUNTER_BUFFER interface");
2362e5c31af7Sopenharmony_ci		glw::GLint					queryActiveResources		= -1;
2363e5c31af7Sopenharmony_ci		glw::GLint					queryMaxNumActiveVariables	= -1;
2364e5c31af7Sopenharmony_ci
2365e5c31af7Sopenharmony_ci		gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &queryActiveResources);
2366e5c31af7Sopenharmony_ci		gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &queryMaxNumActiveVariables);
2367e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");
2368e5c31af7Sopenharmony_ci
2369e5c31af7Sopenharmony_ci		m_testCtx.getLog()
2370e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message
2371e5c31af7Sopenharmony_ci			<< "GL_ACTIVE_RESOURCES = " << queryActiveResources << "\n"
2372e5c31af7Sopenharmony_ci			<< "GL_MAX_NUM_ACTIVE_VARIABLES = " << queryMaxNumActiveVariables << "\n"
2373e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2374e5c31af7Sopenharmony_ci
2375e5c31af7Sopenharmony_ci		if (queryActiveResources != numAtomicBuffers)
2376e5c31af7Sopenharmony_ci		{
2377e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_ACTIVE_RESOURCES, expected " << numAtomicBuffers << tcu::TestLog::EndMessage;
2378e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_ACTIVE_RESOURCES");
2379e5c31af7Sopenharmony_ci		}
2380e5c31af7Sopenharmony_ci
2381e5c31af7Sopenharmony_ci		if (queryMaxNumActiveVariables != expectedMaxNumActiveVariables)
2382e5c31af7Sopenharmony_ci		{
2383e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_MAX_NUM_ACTIVE_VARIABLES, expected " << expectedMaxNumActiveVariables << tcu::TestLog::EndMessage;
2384e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_MAX_NUM_ACTIVE_VARIABLES");
2385e5c31af7Sopenharmony_ci		}
2386e5c31af7Sopenharmony_ci	}
2387e5c31af7Sopenharmony_ci
2388e5c31af7Sopenharmony_ci	// Check each buffer
2389e5c31af7Sopenharmony_ci	for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2390e5c31af7Sopenharmony_ci	{
2391e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2392e5c31af7Sopenharmony_ci		std::vector<glw::GLint>		activeVariables;
2393e5c31af7Sopenharmony_ci		std::vector<std::string>	memberNames;
2394e5c31af7Sopenharmony_ci
2395e5c31af7Sopenharmony_ci		// Find active variables
2396e5c31af7Sopenharmony_ci		{
2397e5c31af7Sopenharmony_ci			const glw::GLenum	numActiveVariablesProp	= GL_NUM_ACTIVE_VARIABLES;
2398e5c31af7Sopenharmony_ci			const glw::GLenum	activeVariablesProp		= GL_ACTIVE_VARIABLES;
2399e5c31af7Sopenharmony_ci			glw::GLint			numActiveVariables		= -2;
2400e5c31af7Sopenharmony_ci			glw::GLint			written					= -1;
2401e5c31af7Sopenharmony_ci
2402e5c31af7Sopenharmony_ci			gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &numActiveVariablesProp, 1, &written, &numActiveVariables);
2403e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query num active variables");
2404e5c31af7Sopenharmony_ci
2405e5c31af7Sopenharmony_ci			if (numActiveVariables <= 0)
2406e5c31af7Sopenharmony_ci			{
2407e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected NUM_ACTIVE_VARIABLES: " << numActiveVariables  << tcu::TestLog::EndMessage;
2408e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected NUM_ACTIVE_VARIABLES");
2409e5c31af7Sopenharmony_ci				continue;
2410e5c31af7Sopenharmony_ci			}
2411e5c31af7Sopenharmony_ci
2412e5c31af7Sopenharmony_ci			if (written <= 0)
2413e5c31af7Sopenharmony_ci			{
2414e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for NUM_ACTIVE_VARIABLES returned no values" << tcu::TestLog::EndMessage;
2415e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES query failed");
2416e5c31af7Sopenharmony_ci				continue;
2417e5c31af7Sopenharmony_ci			}
2418e5c31af7Sopenharmony_ci
2419e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_ACTIVE_VARIABLES = " << numActiveVariables << tcu::TestLog::EndMessage;
2420e5c31af7Sopenharmony_ci
2421e5c31af7Sopenharmony_ci			written = -1;
2422e5c31af7Sopenharmony_ci			activeVariables.resize(numActiveVariables + 1, -2);
2423e5c31af7Sopenharmony_ci
2424e5c31af7Sopenharmony_ci			gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &activeVariablesProp, numActiveVariables, &written, &activeVariables[0]);
2425e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query active variables");
2426e5c31af7Sopenharmony_ci
2427e5c31af7Sopenharmony_ci			if (written != numActiveVariables)
2428e5c31af7Sopenharmony_ci			{
2429e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected number of ACTIVE_VARIABLES, NUM_ACTIVE_VARIABLES = " << numActiveVariables << ", query returned " << written << " values" << tcu::TestLog::EndMessage;
2430e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_VARIABLES");
2431e5c31af7Sopenharmony_ci				continue;
2432e5c31af7Sopenharmony_ci			}
2433e5c31af7Sopenharmony_ci
2434e5c31af7Sopenharmony_ci			if (activeVariables.back() != -2)
2435e5c31af7Sopenharmony_ci			{
2436e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for ACTIVE_VARIABLES wrote over target buffer bounds" << tcu::TestLog::EndMessage;
2437e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "ACTIVE_VARIABLES query failed");
2438e5c31af7Sopenharmony_ci				continue;
2439e5c31af7Sopenharmony_ci			}
2440e5c31af7Sopenharmony_ci
2441e5c31af7Sopenharmony_ci			activeVariables.pop_back();
2442e5c31af7Sopenharmony_ci		}
2443e5c31af7Sopenharmony_ci
2444e5c31af7Sopenharmony_ci		// log indices
2445e5c31af7Sopenharmony_ci		{
2446e5c31af7Sopenharmony_ci			tcu::MessageBuilder builder(&m_testCtx.getLog());
2447e5c31af7Sopenharmony_ci
2448e5c31af7Sopenharmony_ci			builder << "Active variable indices: {";
2449e5c31af7Sopenharmony_ci			for (int varNdx = 0; varNdx < (int)activeVariables.size(); ++varNdx)
2450e5c31af7Sopenharmony_ci			{
2451e5c31af7Sopenharmony_ci				if (varNdx)
2452e5c31af7Sopenharmony_ci					builder << ", ";
2453e5c31af7Sopenharmony_ci				builder << activeVariables[varNdx];
2454e5c31af7Sopenharmony_ci			}
2455e5c31af7Sopenharmony_ci			builder << "}" << tcu::TestLog::EndMessage;
2456e5c31af7Sopenharmony_ci		}
2457e5c31af7Sopenharmony_ci
2458e5c31af7Sopenharmony_ci		// collect member names
2459e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < (int)activeVariables.size(); ++ndx)
2460e5c31af7Sopenharmony_ci		{
2461e5c31af7Sopenharmony_ci			const glw::GLenum	nameLengthProp	= GL_NAME_LENGTH;
2462e5c31af7Sopenharmony_ci			glw::GLint			nameLength		= -1;
2463e5c31af7Sopenharmony_ci			glw::GLint			written			= -1;
2464e5c31af7Sopenharmony_ci			std::vector<char>	nameBuf;
2465e5c31af7Sopenharmony_ci
2466e5c31af7Sopenharmony_ci			gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, activeVariables[ndx], 1, &nameLengthProp, 1, &written, &nameLength);
2467e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name length");
2468e5c31af7Sopenharmony_ci
2469e5c31af7Sopenharmony_ci			if (written <= 0 || nameLength == -1)
2470e5c31af7Sopenharmony_ci			{
2471e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for GL_NAME_LENGTH returned no values" << tcu::TestLog::EndMessage;
2472e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
2473e5c31af7Sopenharmony_ci				continue;
2474e5c31af7Sopenharmony_ci			}
2475e5c31af7Sopenharmony_ci
2476e5c31af7Sopenharmony_ci			nameBuf.resize(nameLength + 2, 'X'); // +2 to tolerate potential off-by-ones in some implementations, name queries will check these cases better
2477e5c31af7Sopenharmony_ci			written = -1;
2478e5c31af7Sopenharmony_ci
2479e5c31af7Sopenharmony_ci			gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, activeVariables[ndx], (int)nameBuf.size(), &written, &nameBuf[0]);
2480e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name");
2481e5c31af7Sopenharmony_ci
2482e5c31af7Sopenharmony_ci			if (written <= 0)
2483e5c31af7Sopenharmony_ci			{
2484e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource name returned no name" << tcu::TestLog::EndMessage;
2485e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Name query failed");
2486e5c31af7Sopenharmony_ci				continue;
2487e5c31af7Sopenharmony_ci			}
2488e5c31af7Sopenharmony_ci
2489e5c31af7Sopenharmony_ci			memberNames.push_back(std::string(&nameBuf[0], written));
2490e5c31af7Sopenharmony_ci		}
2491e5c31af7Sopenharmony_ci
2492e5c31af7Sopenharmony_ci		// log names
2493e5c31af7Sopenharmony_ci		{
2494e5c31af7Sopenharmony_ci			tcu::MessageBuilder builder(&m_testCtx.getLog());
2495e5c31af7Sopenharmony_ci
2496e5c31af7Sopenharmony_ci			builder << "Active variables:\n";
2497e5c31af7Sopenharmony_ci			for (int varNdx = 0; varNdx < (int)memberNames.size(); ++varNdx)
2498e5c31af7Sopenharmony_ci			{
2499e5c31af7Sopenharmony_ci				builder << "\t" << memberNames[varNdx] << "\n";
2500e5c31af7Sopenharmony_ci			}
2501e5c31af7Sopenharmony_ci			builder << tcu::TestLog::EndMessage;
2502e5c31af7Sopenharmony_ci		}
2503e5c31af7Sopenharmony_ci
2504e5c31af7Sopenharmony_ci		// check names are all in the same buffer
2505e5c31af7Sopenharmony_ci		{
2506e5c31af7Sopenharmony_ci			bool bindingsValid = true;
2507e5c31af7Sopenharmony_ci
2508e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying names" << tcu::TestLog::EndMessage;
2509e5c31af7Sopenharmony_ci
2510e5c31af7Sopenharmony_ci			for (int nameNdx = 0; nameNdx < (int)memberNames.size(); ++nameNdx)
2511e5c31af7Sopenharmony_ci			{
2512e5c31af7Sopenharmony_ci				int prevBinding = -1;
2513e5c31af7Sopenharmony_ci
2514e5c31af7Sopenharmony_ci				for (int varNdx = 0; varNdx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++varNdx)
2515e5c31af7Sopenharmony_ci				{
2516e5c31af7Sopenharmony_ci					if (m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].name == memberNames[nameNdx])
2517e5c31af7Sopenharmony_ci					{
2518e5c31af7Sopenharmony_ci						const int varBinding = m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].layout.binding;
2519e5c31af7Sopenharmony_ci
2520e5c31af7Sopenharmony_ci						if (prevBinding == -1 || prevBinding == varBinding)
2521e5c31af7Sopenharmony_ci							prevBinding = varBinding;
2522e5c31af7Sopenharmony_ci						else
2523e5c31af7Sopenharmony_ci							bindingsValid = false;
2524e5c31af7Sopenharmony_ci					}
2525e5c31af7Sopenharmony_ci				}
2526e5c31af7Sopenharmony_ci
2527e5c31af7Sopenharmony_ci				if (prevBinding == -1)
2528e5c31af7Sopenharmony_ci				{
2529e5c31af7Sopenharmony_ci					m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find variable with name \"" << memberNames[nameNdx] << "\"" << tcu::TestLog::EndMessage;
2530e5c31af7Sopenharmony_ci					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable name invalid");
2531e5c31af7Sopenharmony_ci				}
2532e5c31af7Sopenharmony_ci				else if (getBufferVariableCount(prevBinding) != (int)memberNames.size())
2533e5c31af7Sopenharmony_ci				{
2534e5c31af7Sopenharmony_ci					m_testCtx.getLog()
2535e5c31af7Sopenharmony_ci						<< tcu::TestLog::Message
2536e5c31af7Sopenharmony_ci						<< "Error, unexpected variable count for binding " << prevBinding
2537e5c31af7Sopenharmony_ci						<< ". Expected " << getBufferVariableCount(prevBinding) << ", got " << (int)memberNames.size()
2538e5c31af7Sopenharmony_ci						<< tcu::TestLog::EndMessage;
2539e5c31af7Sopenharmony_ci					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable names invalid");
2540e5c31af7Sopenharmony_ci				}
2541e5c31af7Sopenharmony_ci			}
2542e5c31af7Sopenharmony_ci
2543e5c31af7Sopenharmony_ci			if (!bindingsValid)
2544e5c31af7Sopenharmony_ci			{
2545e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, all resource do not share the same buffer" << tcu::TestLog::EndMessage;
2546e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Active variables invalid");
2547e5c31af7Sopenharmony_ci				continue;
2548e5c31af7Sopenharmony_ci			}
2549e5c31af7Sopenharmony_ci		}
2550e5c31af7Sopenharmony_ci	}
2551e5c31af7Sopenharmony_ci
2552e5c31af7Sopenharmony_ci	return STOP;
2553e5c31af7Sopenharmony_ci}
2554e5c31af7Sopenharmony_ci
2555e5c31af7Sopenharmony_ciclass AtomicCounterBufferBindingCase : public AtomicCounterCase
2556e5c31af7Sopenharmony_ci{
2557e5c31af7Sopenharmony_cipublic:
2558e5c31af7Sopenharmony_ci					AtomicCounterBufferBindingCase		(Context& context, const char* name, const char* description);
2559e5c31af7Sopenharmony_ci
2560e5c31af7Sopenharmony_ciprivate:
2561e5c31af7Sopenharmony_ci	IterateResult	iterate								(void);
2562e5c31af7Sopenharmony_ci};
2563e5c31af7Sopenharmony_ci
2564e5c31af7Sopenharmony_ciAtomicCounterBufferBindingCase::AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description)
2565e5c31af7Sopenharmony_ci	: AtomicCounterCase(context, name, description)
2566e5c31af7Sopenharmony_ci{
2567e5c31af7Sopenharmony_ci}
2568e5c31af7Sopenharmony_ci
2569e5c31af7Sopenharmony_ciAtomicCounterBufferBindingCase::IterateResult AtomicCounterBufferBindingCase::iterate (void)
2570e5c31af7Sopenharmony_ci{
2571e5c31af7Sopenharmony_ci	const glw::Functions&		gl								= m_context.getRenderContext().getFunctions();
2572e5c31af7Sopenharmony_ci	const glu::ShaderProgram	program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2573e5c31af7Sopenharmony_ci	const int					numAtomicBuffers				= getNumAtomicCounterBuffers();
2574e5c31af7Sopenharmony_ci
2575e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2576e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2577e5c31af7Sopenharmony_ci
2578e5c31af7Sopenharmony_ci	// check every buffer
2579e5c31af7Sopenharmony_ci	for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2580e5c31af7Sopenharmony_ci	{
2581e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2582e5c31af7Sopenharmony_ci		const glw::GLenum			bufferBindingProp	= GL_BUFFER_BINDING;
2583e5c31af7Sopenharmony_ci		glw::GLint					bufferBinding		= -1;
2584e5c31af7Sopenharmony_ci		glw::GLint					written				= -1;
2585e5c31af7Sopenharmony_ci
2586e5c31af7Sopenharmony_ci		gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &bufferBindingProp, 1, &written, &bufferBinding);
2587e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2588e5c31af7Sopenharmony_ci
2589e5c31af7Sopenharmony_ci		if (written <= 0)
2590e5c31af7Sopenharmony_ci		{
2591e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for BUFFER_BINDING returned no values." << tcu::TestLog::EndMessage;
2592e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "BUFFER_BINDING query failed");
2593e5c31af7Sopenharmony_ci		}
2594e5c31af7Sopenharmony_ci
2595e5c31af7Sopenharmony_ci		m_testCtx.getLog() << tcu::TestLog::Message << "GL_BUFFER_BINDING = " << bufferBinding << tcu::TestLog::EndMessage;
2596e5c31af7Sopenharmony_ci
2597e5c31af7Sopenharmony_ci		// no such buffer binding?
2598e5c31af7Sopenharmony_ci		if (getBufferVariableCount(bufferBinding) == 0)
2599e5c31af7Sopenharmony_ci		{
2600e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << bufferBinding << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2601e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2602e5c31af7Sopenharmony_ci		}
2603e5c31af7Sopenharmony_ci	}
2604e5c31af7Sopenharmony_ci
2605e5c31af7Sopenharmony_ci	return STOP;
2606e5c31af7Sopenharmony_ci}
2607e5c31af7Sopenharmony_ci
2608e5c31af7Sopenharmony_ciclass AtomicCounterBufferDataSizeCase : public AtomicCounterCase
2609e5c31af7Sopenharmony_ci{
2610e5c31af7Sopenharmony_cipublic:
2611e5c31af7Sopenharmony_ci					AtomicCounterBufferDataSizeCase		(Context& context, const char* name, const char* description);
2612e5c31af7Sopenharmony_ci
2613e5c31af7Sopenharmony_ciprivate:
2614e5c31af7Sopenharmony_ci	IterateResult	iterate								(void);
2615e5c31af7Sopenharmony_ci};
2616e5c31af7Sopenharmony_ci
2617e5c31af7Sopenharmony_ciAtomicCounterBufferDataSizeCase::AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description)
2618e5c31af7Sopenharmony_ci	: AtomicCounterCase(context, name, description)
2619e5c31af7Sopenharmony_ci{
2620e5c31af7Sopenharmony_ci}
2621e5c31af7Sopenharmony_ci
2622e5c31af7Sopenharmony_ciAtomicCounterBufferDataSizeCase::IterateResult AtomicCounterBufferDataSizeCase::iterate (void)
2623e5c31af7Sopenharmony_ci{
2624e5c31af7Sopenharmony_ci	const glw::Functions&		gl								= m_context.getRenderContext().getFunctions();
2625e5c31af7Sopenharmony_ci	const glu::ShaderProgram	program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
2626e5c31af7Sopenharmony_ci	const int					numAtomicBuffers				= getNumAtomicCounterBuffers();
2627e5c31af7Sopenharmony_ci
2628e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2629e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
2630e5c31af7Sopenharmony_ci
2631e5c31af7Sopenharmony_ci	// check every buffer
2632e5c31af7Sopenharmony_ci	for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
2633e5c31af7Sopenharmony_ci	{
2634e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
2635e5c31af7Sopenharmony_ci		const glw::GLenum			props[]				= { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE };
2636e5c31af7Sopenharmony_ci		glw::GLint					values[]			= { -1, -1 };
2637e5c31af7Sopenharmony_ci		glw::GLint					written				= -1;
2638e5c31af7Sopenharmony_ci		int							bufferMinDataSize;
2639e5c31af7Sopenharmony_ci
2640e5c31af7Sopenharmony_ci		gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, DE_LENGTH_OF_ARRAY(props), props, DE_LENGTH_OF_ARRAY(values), &written, values);
2641e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2642e5c31af7Sopenharmony_ci
2643e5c31af7Sopenharmony_ci		if (written != 2)
2644e5c31af7Sopenharmony_ci		{
2645e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for (BUFFER_BINDING, BUFFER_DATA_SIZE) returned " << written << " value(s)." << tcu::TestLog::EndMessage;
2646e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2647e5c31af7Sopenharmony_ci			continue;
2648e5c31af7Sopenharmony_ci		}
2649e5c31af7Sopenharmony_ci
2650e5c31af7Sopenharmony_ci		m_testCtx.getLog()
2651e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message
2652e5c31af7Sopenharmony_ci			<< "GL_BUFFER_BINDING = " << values[0] << "\n"
2653e5c31af7Sopenharmony_ci			<< "GL_BUFFER_DATA_SIZE = " << values[1]
2654e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2655e5c31af7Sopenharmony_ci
2656e5c31af7Sopenharmony_ci		bufferMinDataSize = getBufferMinimumDataSize(values[0]);
2657e5c31af7Sopenharmony_ci		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying data size, expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;
2658e5c31af7Sopenharmony_ci
2659e5c31af7Sopenharmony_ci		// no such buffer binding?
2660e5c31af7Sopenharmony_ci		if (bufferMinDataSize == -1)
2661e5c31af7Sopenharmony_ci		{
2662e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << values[0] << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
2663e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2664e5c31af7Sopenharmony_ci		}
2665e5c31af7Sopenharmony_ci		else if (values[1] < bufferMinDataSize)
2666e5c31af7Sopenharmony_ci		{
2667e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_DATA_SIZE = " << values[1] << ", expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;
2668e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
2669e5c31af7Sopenharmony_ci		}
2670e5c31af7Sopenharmony_ci		else
2671e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Data size valid" << tcu::TestLog::EndMessage;
2672e5c31af7Sopenharmony_ci	}
2673e5c31af7Sopenharmony_ci
2674e5c31af7Sopenharmony_ci	return STOP;
2675e5c31af7Sopenharmony_ci}
2676e5c31af7Sopenharmony_ci
2677e5c31af7Sopenharmony_ciclass AtomicCounterReferencedByCase : public TestCase
2678e5c31af7Sopenharmony_ci{
2679e5c31af7Sopenharmony_cipublic:
2680e5c31af7Sopenharmony_ci											AtomicCounterReferencedByCase	(Context&		context,
2681e5c31af7Sopenharmony_ci																			 const char*	name,
2682e5c31af7Sopenharmony_ci																			 const char*	description,
2683e5c31af7Sopenharmony_ci																			 bool			separable,
2684e5c31af7Sopenharmony_ci																			 deUint32		presentStagesMask,
2685e5c31af7Sopenharmony_ci																			 deUint32		activeStagesMask);
2686e5c31af7Sopenharmony_ci											~AtomicCounterReferencedByCase	(void);
2687e5c31af7Sopenharmony_ci
2688e5c31af7Sopenharmony_ciprivate:
2689e5c31af7Sopenharmony_ci	void									init							(void);
2690e5c31af7Sopenharmony_ci	void									deinit							(void);
2691e5c31af7Sopenharmony_ci	IterateResult							iterate							(void);
2692e5c31af7Sopenharmony_ci
2693e5c31af7Sopenharmony_ci	const bool								m_separable;
2694e5c31af7Sopenharmony_ci	const deUint32							m_presentStagesMask;
2695e5c31af7Sopenharmony_ci	const deUint32							m_activeStagesMask;
2696e5c31af7Sopenharmony_ci	ProgramInterfaceDefinition::Program*	m_program;
2697e5c31af7Sopenharmony_ci};
2698e5c31af7Sopenharmony_ci
2699e5c31af7Sopenharmony_ciAtomicCounterReferencedByCase::AtomicCounterReferencedByCase (Context&		context,
2700e5c31af7Sopenharmony_ci															  const char*	name,
2701e5c31af7Sopenharmony_ci															  const char*	description,
2702e5c31af7Sopenharmony_ci															  bool			separable,
2703e5c31af7Sopenharmony_ci															  deUint32		presentStagesMask,
2704e5c31af7Sopenharmony_ci															  deUint32		activeStagesMask)
2705e5c31af7Sopenharmony_ci	: TestCase				(context, name, description)
2706e5c31af7Sopenharmony_ci	, m_separable			(separable)
2707e5c31af7Sopenharmony_ci	, m_presentStagesMask	(presentStagesMask)
2708e5c31af7Sopenharmony_ci	, m_activeStagesMask	(activeStagesMask)
2709e5c31af7Sopenharmony_ci	, m_program				(DE_NULL)
2710e5c31af7Sopenharmony_ci{
2711e5c31af7Sopenharmony_ci	DE_ASSERT((activeStagesMask & presentStagesMask) == activeStagesMask);
2712e5c31af7Sopenharmony_ci}
2713e5c31af7Sopenharmony_ci
2714e5c31af7Sopenharmony_ciAtomicCounterReferencedByCase::~AtomicCounterReferencedByCase (void)
2715e5c31af7Sopenharmony_ci{
2716e5c31af7Sopenharmony_ci	deinit();
2717e5c31af7Sopenharmony_ci}
2718e5c31af7Sopenharmony_ci
2719e5c31af7Sopenharmony_civoid AtomicCounterReferencedByCase::init (void)
2720e5c31af7Sopenharmony_ci{
2721e5c31af7Sopenharmony_ci	const deUint32				geometryMask		= (1 << glu::SHADERTYPE_GEOMETRY);
2722e5c31af7Sopenharmony_ci	const deUint32				tessellationMask	= (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);
2723e5c31af7Sopenharmony_ci	glu::VariableDeclaration	atomicVar			(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "targetCounter", glu::STORAGE_UNIFORM);
2724e5c31af7Sopenharmony_ci	const glu::GLSLVersion		glslVersion			= glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2725e5c31af7Sopenharmony_ci	const bool					supportsES32orGL45	= checkSupport(m_context);
2726e5c31af7Sopenharmony_ci
2727e5c31af7Sopenharmony_ci	if ((m_presentStagesMask & tessellationMask) != 0 && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2728e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2729e5c31af7Sopenharmony_ci	if ((m_presentStagesMask & geometryMask) != 0 && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2730e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2731e5c31af7Sopenharmony_ci
2732e5c31af7Sopenharmony_ci	atomicVar.layout.binding = 1;
2733e5c31af7Sopenharmony_ci
2734e5c31af7Sopenharmony_ci	m_program = new ProgramInterfaceDefinition::Program();
2735e5c31af7Sopenharmony_ci	m_program->setSeparable(m_separable);
2736e5c31af7Sopenharmony_ci
2737e5c31af7Sopenharmony_ci	for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
2738e5c31af7Sopenharmony_ci	{
2739e5c31af7Sopenharmony_ci		if (m_activeStagesMask & (1 << shaderType))
2740e5c31af7Sopenharmony_ci			m_program->addShader((glu::ShaderType)shaderType, glslVersion)->getDefaultBlock().variables.push_back(atomicVar);
2741e5c31af7Sopenharmony_ci		else if (m_presentStagesMask & (1 << shaderType))
2742e5c31af7Sopenharmony_ci			m_program->addShader((glu::ShaderType)shaderType, glslVersion);
2743e5c31af7Sopenharmony_ci	}
2744e5c31af7Sopenharmony_ci
2745e5c31af7Sopenharmony_ci	if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2746e5c31af7Sopenharmony_ci		m_program->setGeometryNumOutputVertices(1);
2747e5c31af7Sopenharmony_ci	if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2748e5c31af7Sopenharmony_ci		m_program->setTessellationNumOutputPatchVertices(1);
2749e5c31af7Sopenharmony_ci
2750e5c31af7Sopenharmony_ci	DE_ASSERT(m_program->isValid());
2751e5c31af7Sopenharmony_ci}
2752e5c31af7Sopenharmony_ci
2753e5c31af7Sopenharmony_civoid AtomicCounterReferencedByCase::deinit (void)
2754e5c31af7Sopenharmony_ci{
2755e5c31af7Sopenharmony_ci	delete m_program;
2756e5c31af7Sopenharmony_ci	m_program = DE_NULL;
2757e5c31af7Sopenharmony_ci}
2758e5c31af7Sopenharmony_ci
2759e5c31af7Sopenharmony_ciAtomicCounterReferencedByCase::IterateResult AtomicCounterReferencedByCase::iterate (void)
2760e5c31af7Sopenharmony_ci{
2761e5c31af7Sopenharmony_ci	const glu::RenderContext& rc = m_context.getRenderContext();
2762e5c31af7Sopenharmony_ci	const bool isES32orGL45 = glu::contextSupports(rc.getType(), glu::ApiType::es(3, 2)) ||
2763e5c31af7Sopenharmony_ci							  glu::contextSupports(rc.getType(), glu::ApiType::core(4, 5));
2764e5c31af7Sopenharmony_ci
2765e5c31af7Sopenharmony_ci	const struct
2766e5c31af7Sopenharmony_ci	{
2767e5c31af7Sopenharmony_ci		glw::GLenum		propName;
2768e5c31af7Sopenharmony_ci		glu::ShaderType	shaderType;
2769e5c31af7Sopenharmony_ci		const char*		extension;
2770e5c31af7Sopenharmony_ci	} targetProps[] =
2771e5c31af7Sopenharmony_ci	{
2772e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_VERTEX_SHADER,			glu::SHADERTYPE_VERTEX,						DE_NULL												},
2773e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_FRAGMENT_SHADER,			glu::SHADERTYPE_FRAGMENT,					DE_NULL												},
2774e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_COMPUTE_SHADER,			glu::SHADERTYPE_COMPUTE,					DE_NULL												},
2775e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_TESS_CONTROL_SHADER,		glu::SHADERTYPE_TESSELLATION_CONTROL,		(isES32orGL45 ? DE_NULL : "GL_EXT_tessellation_shader")	},
2776e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_TESS_EVALUATION_SHADER,	glu::SHADERTYPE_TESSELLATION_EVALUATION,	(isES32orGL45 ? DE_NULL : "GL_EXT_tessellation_shader")	},
2777e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_GEOMETRY_SHADER,			glu::SHADERTYPE_GEOMETRY,					(isES32orGL45 ? DE_NULL : "GL_EXT_geometry_shader")		},
2778e5c31af7Sopenharmony_ci	};
2779e5c31af7Sopenharmony_ci
2780e5c31af7Sopenharmony_ci	const glw::Functions&		gl			= rc.getFunctions();
2781e5c31af7Sopenharmony_ci	const glu::ShaderProgram	program		(rc, generateProgramInterfaceProgramSources(m_program));
2782e5c31af7Sopenharmony_ci
2783e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2784e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_program, rc.getFunctions(), m_testCtx.getLog());
2785e5c31af7Sopenharmony_ci
2786e5c31af7Sopenharmony_ci	// check props
2787e5c31af7Sopenharmony_ci	for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
2788e5c31af7Sopenharmony_ci	{
2789e5c31af7Sopenharmony_ci		if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
2790e5c31af7Sopenharmony_ci		{
2791e5c31af7Sopenharmony_ci			const glw::GLenum	prop		= targetProps[propNdx].propName;
2792e5c31af7Sopenharmony_ci			const glw::GLint	expected	= ((m_activeStagesMask & (1 << targetProps[propNdx].shaderType)) != 0) ? (GL_TRUE) : (GL_FALSE);
2793e5c31af7Sopenharmony_ci			glw::GLint			value		= -1;
2794e5c31af7Sopenharmony_ci			glw::GLint			written		= -1;
2795e5c31af7Sopenharmony_ci
2796e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << glu::getBooleanName(expected) << tcu::TestLog::EndMessage;
2797e5c31af7Sopenharmony_ci
2798e5c31af7Sopenharmony_ci			gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, 0, 1, &prop, 1, &written, &value);
2799e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
2800e5c31af7Sopenharmony_ci
2801e5c31af7Sopenharmony_ci			if (written != 1)
2802e5c31af7Sopenharmony_ci			{
2803e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
2804e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
2805e5c31af7Sopenharmony_ci				continue;
2806e5c31af7Sopenharmony_ci			}
2807e5c31af7Sopenharmony_ci
2808e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
2809e5c31af7Sopenharmony_ci
2810e5c31af7Sopenharmony_ci			if (value != expected)
2811e5c31af7Sopenharmony_ci			{
2812e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
2813e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
2814e5c31af7Sopenharmony_ci				continue;
2815e5c31af7Sopenharmony_ci			}
2816e5c31af7Sopenharmony_ci		}
2817e5c31af7Sopenharmony_ci	}
2818e5c31af7Sopenharmony_ci
2819e5c31af7Sopenharmony_ci	return STOP;
2820e5c31af7Sopenharmony_ci}
2821e5c31af7Sopenharmony_ci
2822e5c31af7Sopenharmony_ciclass ProgramInputOutputReferencedByCase : public TestCase
2823e5c31af7Sopenharmony_ci{
2824e5c31af7Sopenharmony_cipublic:
2825e5c31af7Sopenharmony_ci	enum CaseType
2826e5c31af7Sopenharmony_ci	{
2827e5c31af7Sopenharmony_ci		CASE_VERTEX_FRAGMENT = 0,
2828e5c31af7Sopenharmony_ci		CASE_VERTEX_GEO_FRAGMENT,
2829e5c31af7Sopenharmony_ci		CASE_VERTEX_TESS_FRAGMENT,
2830e5c31af7Sopenharmony_ci		CASE_VERTEX_TESS_GEO_FRAGMENT,
2831e5c31af7Sopenharmony_ci
2832e5c31af7Sopenharmony_ci		CASE_SEPARABLE_VERTEX,
2833e5c31af7Sopenharmony_ci		CASE_SEPARABLE_FRAGMENT,
2834e5c31af7Sopenharmony_ci		CASE_SEPARABLE_GEOMETRY,
2835e5c31af7Sopenharmony_ci		CASE_SEPARABLE_TESS_CTRL,
2836e5c31af7Sopenharmony_ci		CASE_SEPARABLE_TESS_EVAL,
2837e5c31af7Sopenharmony_ci
2838e5c31af7Sopenharmony_ci		CASE_LAST
2839e5c31af7Sopenharmony_ci	};
2840e5c31af7Sopenharmony_ci											ProgramInputOutputReferencedByCase	(Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType);
2841e5c31af7Sopenharmony_ci											~ProgramInputOutputReferencedByCase	(void);
2842e5c31af7Sopenharmony_ci
2843e5c31af7Sopenharmony_ciprivate:
2844e5c31af7Sopenharmony_ci	void									init								(void);
2845e5c31af7Sopenharmony_ci	void									deinit								(void);
2846e5c31af7Sopenharmony_ci	IterateResult							iterate								(void);
2847e5c31af7Sopenharmony_ci
2848e5c31af7Sopenharmony_ci	const CaseType							m_caseType;
2849e5c31af7Sopenharmony_ci	const glu::Storage						m_targetStorage;
2850e5c31af7Sopenharmony_ci	ProgramInterfaceDefinition::Program*	m_program;
2851e5c31af7Sopenharmony_ci};
2852e5c31af7Sopenharmony_ci
2853e5c31af7Sopenharmony_ciProgramInputOutputReferencedByCase::ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType)
2854e5c31af7Sopenharmony_ci	: TestCase				(context, name, description)
2855e5c31af7Sopenharmony_ci	, m_caseType			(caseType)
2856e5c31af7Sopenharmony_ci	, m_targetStorage		(targetStorage)
2857e5c31af7Sopenharmony_ci	, m_program				(DE_NULL)
2858e5c31af7Sopenharmony_ci{
2859e5c31af7Sopenharmony_ci	DE_ASSERT(caseType < CASE_LAST);
2860e5c31af7Sopenharmony_ci}
2861e5c31af7Sopenharmony_ci
2862e5c31af7Sopenharmony_ciProgramInputOutputReferencedByCase::~ProgramInputOutputReferencedByCase (void)
2863e5c31af7Sopenharmony_ci{
2864e5c31af7Sopenharmony_ci	deinit();
2865e5c31af7Sopenharmony_ci}
2866e5c31af7Sopenharmony_ci
2867e5c31af7Sopenharmony_civoid ProgramInputOutputReferencedByCase::init (void)
2868e5c31af7Sopenharmony_ci{
2869e5c31af7Sopenharmony_ci	const bool hasTessellationShader =	(m_caseType == CASE_VERTEX_TESS_FRAGMENT)		||
2870e5c31af7Sopenharmony_ci										(m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)	||
2871e5c31af7Sopenharmony_ci										(m_caseType == CASE_SEPARABLE_TESS_CTRL)		||
2872e5c31af7Sopenharmony_ci										(m_caseType == CASE_SEPARABLE_TESS_EVAL);
2873e5c31af7Sopenharmony_ci	const bool hasGeometryShader =		(m_caseType == CASE_VERTEX_GEO_FRAGMENT)		||
2874e5c31af7Sopenharmony_ci										(m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)	||
2875e5c31af7Sopenharmony_ci										(m_caseType == CASE_SEPARABLE_GEOMETRY);
2876e5c31af7Sopenharmony_ci	const bool supportsES32orGL45 =		checkSupport(m_context);
2877e5c31af7Sopenharmony_ci
2878e5c31af7Sopenharmony_ci	if (hasTessellationShader && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
2879e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
2880e5c31af7Sopenharmony_ci	if (hasGeometryShader && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
2881e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
2882e5c31af7Sopenharmony_ci
2883e5c31af7Sopenharmony_ci	glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
2884e5c31af7Sopenharmony_ci	m_program = new ProgramInterfaceDefinition::Program();
2885e5c31af7Sopenharmony_ci
2886e5c31af7Sopenharmony_ci	if (m_caseType == CASE_SEPARABLE_VERTEX		||
2887e5c31af7Sopenharmony_ci		m_caseType == CASE_SEPARABLE_FRAGMENT	||
2888e5c31af7Sopenharmony_ci		m_caseType == CASE_SEPARABLE_GEOMETRY	||
2889e5c31af7Sopenharmony_ci		m_caseType == CASE_SEPARABLE_TESS_CTRL	||
2890e5c31af7Sopenharmony_ci		m_caseType == CASE_SEPARABLE_TESS_EVAL)
2891e5c31af7Sopenharmony_ci	{
2892e5c31af7Sopenharmony_ci		const bool						isInputCase			= (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
2893e5c31af7Sopenharmony_ci		const bool						perPatchStorage		= (m_targetStorage == glu::STORAGE_PATCH_IN || m_targetStorage == glu::STORAGE_PATCH_OUT);
2894e5c31af7Sopenharmony_ci		const char*						varName				= (isInputCase) ? ("shaderInput") : ("shaderOutput");
2895e5c31af7Sopenharmony_ci		const glu::VariableDeclaration	targetDecl			(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), varName, m_targetStorage);
2896e5c31af7Sopenharmony_ci		const glu::ShaderType			shaderType			= (m_caseType == CASE_SEPARABLE_VERTEX)		? (glu::SHADERTYPE_VERTEX)
2897e5c31af7Sopenharmony_ci															: (m_caseType == CASE_SEPARABLE_FRAGMENT)	? (glu::SHADERTYPE_FRAGMENT)
2898e5c31af7Sopenharmony_ci															: (m_caseType == CASE_SEPARABLE_GEOMETRY)	? (glu::SHADERTYPE_GEOMETRY)
2899e5c31af7Sopenharmony_ci															: (m_caseType == CASE_SEPARABLE_TESS_CTRL)	? (glu::SHADERTYPE_TESSELLATION_CONTROL)
2900e5c31af7Sopenharmony_ci															: (m_caseType == CASE_SEPARABLE_TESS_EVAL)	? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
2901e5c31af7Sopenharmony_ci															:											  (glu::SHADERTYPE_LAST);
2902e5c31af7Sopenharmony_ci		const bool						arrayedInterface	= (isInputCase) ? ((shaderType == glu::SHADERTYPE_GEOMETRY)					||
2903e5c31af7Sopenharmony_ci																			   (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)		||
2904e5c31af7Sopenharmony_ci																			   (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION))
2905e5c31af7Sopenharmony_ci																			: (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL);
2906e5c31af7Sopenharmony_ci
2907e5c31af7Sopenharmony_ci		m_program->setSeparable(true);
2908e5c31af7Sopenharmony_ci
2909e5c31af7Sopenharmony_ci		if (arrayedInterface && !perPatchStorage)
2910e5c31af7Sopenharmony_ci		{
2911e5c31af7Sopenharmony_ci			const glu::VariableDeclaration targetDeclArr(glu::VarType(targetDecl.varType, glu::VarType::UNSIZED_ARRAY), varName, m_targetStorage);
2912e5c31af7Sopenharmony_ci			m_program->addShader(shaderType, glslVersion)->getDefaultBlock().variables.push_back(targetDeclArr);
2913e5c31af7Sopenharmony_ci		}
2914e5c31af7Sopenharmony_ci		else
2915e5c31af7Sopenharmony_ci		{
2916e5c31af7Sopenharmony_ci			m_program->addShader(shaderType, glslVersion)->getDefaultBlock().variables.push_back(targetDecl);
2917e5c31af7Sopenharmony_ci		}
2918e5c31af7Sopenharmony_ci	}
2919e5c31af7Sopenharmony_ci	else if (m_caseType == CASE_VERTEX_FRAGMENT			||
2920e5c31af7Sopenharmony_ci			 m_caseType == CASE_VERTEX_GEO_FRAGMENT		||
2921e5c31af7Sopenharmony_ci			 m_caseType == CASE_VERTEX_TESS_FRAGMENT	||
2922e5c31af7Sopenharmony_ci			 m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2923e5c31af7Sopenharmony_ci	{
2924e5c31af7Sopenharmony_ci		ProgramInterfaceDefinition::Shader*	vertex		= m_program->addShader(glu::SHADERTYPE_VERTEX, glslVersion);
2925e5c31af7Sopenharmony_ci		ProgramInterfaceDefinition::Shader*	fragment	= m_program->addShader(glu::SHADERTYPE_FRAGMENT, glslVersion);
2926e5c31af7Sopenharmony_ci
2927e5c31af7Sopenharmony_ci		m_program->setSeparable(false);
2928e5c31af7Sopenharmony_ci
2929e5c31af7Sopenharmony_ci		vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2930e5c31af7Sopenharmony_ci																			   "shaderInput",
2931e5c31af7Sopenharmony_ci																			   glu::STORAGE_IN));
2932e5c31af7Sopenharmony_ci		vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2933e5c31af7Sopenharmony_ci																			   "shaderOutput",
2934e5c31af7Sopenharmony_ci																			   glu::STORAGE_OUT,
2935e5c31af7Sopenharmony_ci																			   glu::INTERPOLATION_LAST,
2936e5c31af7Sopenharmony_ci																			   glu::Layout(1)));
2937e5c31af7Sopenharmony_ci
2938e5c31af7Sopenharmony_ci		fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2939e5c31af7Sopenharmony_ci																				 "shaderOutput",
2940e5c31af7Sopenharmony_ci																				 glu::STORAGE_OUT,
2941e5c31af7Sopenharmony_ci																				 glu::INTERPOLATION_LAST,
2942e5c31af7Sopenharmony_ci																				 glu::Layout(0)));
2943e5c31af7Sopenharmony_ci		fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2944e5c31af7Sopenharmony_ci																				 "shaderInput",
2945e5c31af7Sopenharmony_ci																				 glu::STORAGE_IN,
2946e5c31af7Sopenharmony_ci																				 glu::INTERPOLATION_LAST,
2947e5c31af7Sopenharmony_ci																				 glu::Layout(1)));
2948e5c31af7Sopenharmony_ci
2949e5c31af7Sopenharmony_ci		if (m_caseType == CASE_VERTEX_TESS_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2950e5c31af7Sopenharmony_ci		{
2951e5c31af7Sopenharmony_ci			ProgramInterfaceDefinition::Shader* tessCtrl = m_program->addShader(glu::SHADERTYPE_TESSELLATION_CONTROL, glslVersion);
2952e5c31af7Sopenharmony_ci			ProgramInterfaceDefinition::Shader* tessEval = m_program->addShader(glu::SHADERTYPE_TESSELLATION_EVALUATION, glslVersion);
2953e5c31af7Sopenharmony_ci
2954e5c31af7Sopenharmony_ci			tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2955e5c31af7Sopenharmony_ci																					 "shaderInput",
2956e5c31af7Sopenharmony_ci																					 glu::STORAGE_IN,
2957e5c31af7Sopenharmony_ci																					 glu::INTERPOLATION_LAST,
2958e5c31af7Sopenharmony_ci																					 glu::Layout(1)));
2959e5c31af7Sopenharmony_ci			tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2960e5c31af7Sopenharmony_ci																					 "shaderOutput",
2961e5c31af7Sopenharmony_ci																					 glu::STORAGE_OUT,
2962e5c31af7Sopenharmony_ci																					 glu::INTERPOLATION_LAST,
2963e5c31af7Sopenharmony_ci																					 glu::Layout(1)));
2964e5c31af7Sopenharmony_ci
2965e5c31af7Sopenharmony_ci			tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2966e5c31af7Sopenharmony_ci																					 "shaderInput",
2967e5c31af7Sopenharmony_ci																					 glu::STORAGE_IN,
2968e5c31af7Sopenharmony_ci																					 glu::INTERPOLATION_LAST,
2969e5c31af7Sopenharmony_ci																					 glu::Layout(1)));
2970e5c31af7Sopenharmony_ci			tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2971e5c31af7Sopenharmony_ci																					 "shaderOutput",
2972e5c31af7Sopenharmony_ci																					 glu::STORAGE_OUT,
2973e5c31af7Sopenharmony_ci																					 glu::INTERPOLATION_LAST,
2974e5c31af7Sopenharmony_ci																					 glu::Layout(1)));
2975e5c31af7Sopenharmony_ci		}
2976e5c31af7Sopenharmony_ci
2977e5c31af7Sopenharmony_ci		if (m_caseType == CASE_VERTEX_GEO_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
2978e5c31af7Sopenharmony_ci		{
2979e5c31af7Sopenharmony_ci			ProgramInterfaceDefinition::Shader* geometry = m_program->addShader(glu::SHADERTYPE_GEOMETRY, glslVersion);
2980e5c31af7Sopenharmony_ci
2981e5c31af7Sopenharmony_ci			geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
2982e5c31af7Sopenharmony_ci																					 "shaderInput",
2983e5c31af7Sopenharmony_ci																					 glu::STORAGE_IN,
2984e5c31af7Sopenharmony_ci																					 glu::INTERPOLATION_LAST,
2985e5c31af7Sopenharmony_ci																					 glu::Layout(1)));
2986e5c31af7Sopenharmony_ci			geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
2987e5c31af7Sopenharmony_ci																					 "shaderOutput",
2988e5c31af7Sopenharmony_ci																					 glu::STORAGE_OUT,
2989e5c31af7Sopenharmony_ci																					 glu::INTERPOLATION_LAST,
2990e5c31af7Sopenharmony_ci																					 glu::Layout(1)));
2991e5c31af7Sopenharmony_ci		}
2992e5c31af7Sopenharmony_ci	}
2993e5c31af7Sopenharmony_ci	else
2994e5c31af7Sopenharmony_ci		DE_ASSERT(false);
2995e5c31af7Sopenharmony_ci
2996e5c31af7Sopenharmony_ci	if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
2997e5c31af7Sopenharmony_ci		m_program->setGeometryNumOutputVertices(1);
2998e5c31af7Sopenharmony_ci	if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
2999e5c31af7Sopenharmony_ci		m_program->setTessellationNumOutputPatchVertices(1);
3000e5c31af7Sopenharmony_ci
3001e5c31af7Sopenharmony_ci	DE_ASSERT(m_program->isValid());
3002e5c31af7Sopenharmony_ci}
3003e5c31af7Sopenharmony_ci
3004e5c31af7Sopenharmony_civoid ProgramInputOutputReferencedByCase::deinit (void)
3005e5c31af7Sopenharmony_ci{
3006e5c31af7Sopenharmony_ci	delete m_program;
3007e5c31af7Sopenharmony_ci	m_program = DE_NULL;
3008e5c31af7Sopenharmony_ci}
3009e5c31af7Sopenharmony_ci
3010e5c31af7Sopenharmony_ciProgramInputOutputReferencedByCase::IterateResult ProgramInputOutputReferencedByCase::iterate (void)
3011e5c31af7Sopenharmony_ci{
3012e5c31af7Sopenharmony_ci	static const struct
3013e5c31af7Sopenharmony_ci	{
3014e5c31af7Sopenharmony_ci		glw::GLenum		propName;
3015e5c31af7Sopenharmony_ci		glu::ShaderType	shaderType;
3016e5c31af7Sopenharmony_ci		const char*		extension;
3017e5c31af7Sopenharmony_ci	} targetProps[] =
3018e5c31af7Sopenharmony_ci	{
3019e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_VERTEX_SHADER,			glu::SHADERTYPE_VERTEX,						DE_NULL							},
3020e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_FRAGMENT_SHADER,			glu::SHADERTYPE_FRAGMENT,					DE_NULL							},
3021e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_COMPUTE_SHADER,			glu::SHADERTYPE_COMPUTE,					DE_NULL							},
3022e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_TESS_CONTROL_SHADER,		glu::SHADERTYPE_TESSELLATION_CONTROL,		"GL_EXT_tessellation_shader"	},
3023e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_TESS_EVALUATION_SHADER,	glu::SHADERTYPE_TESSELLATION_EVALUATION,	"GL_EXT_tessellation_shader"	},
3024e5c31af7Sopenharmony_ci		{ GL_REFERENCED_BY_GEOMETRY_SHADER,			glu::SHADERTYPE_GEOMETRY,					"GL_EXT_geometry_shader"		},
3025e5c31af7Sopenharmony_ci	};
3026e5c31af7Sopenharmony_ci
3027e5c31af7Sopenharmony_ci	const bool					isInputCase						= (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
3028e5c31af7Sopenharmony_ci	const glw::Functions&		gl								= m_context.getRenderContext().getFunctions();
3029e5c31af7Sopenharmony_ci	const glu::ShaderProgram	program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
3030e5c31af7Sopenharmony_ci	const std::string			targetResourceName				= (isInputCase) ? ("shaderInput") : ("shaderOutput");
3031e5c31af7Sopenharmony_ci	const glw::GLenum			programGLInterface				= (isInputCase) ? (GL_PROGRAM_INPUT) : (GL_PROGRAM_OUTPUT);
3032e5c31af7Sopenharmony_ci	glw::GLuint					resourceIndex;
3033e5c31af7Sopenharmony_ci
3034e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3035e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3036e5c31af7Sopenharmony_ci
3037e5c31af7Sopenharmony_ci	// find target resource index
3038e5c31af7Sopenharmony_ci
3039e5c31af7Sopenharmony_ci	resourceIndex = gl.getProgramResourceIndex(program.getProgram(), programGLInterface, targetResourceName.c_str());
3040e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");
3041e5c31af7Sopenharmony_ci
3042e5c31af7Sopenharmony_ci	if (resourceIndex == GL_INVALID_INDEX)
3043e5c31af7Sopenharmony_ci	{
3044e5c31af7Sopenharmony_ci		m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource \"" << targetResourceName << "\" index returned invalid index." << tcu::TestLog::EndMessage;
3045e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");
3046e5c31af7Sopenharmony_ci		return STOP;
3047e5c31af7Sopenharmony_ci	}
3048e5c31af7Sopenharmony_ci
3049e5c31af7Sopenharmony_ci	// check props
3050e5c31af7Sopenharmony_ci	for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
3051e5c31af7Sopenharmony_ci	{
3052e5c31af7Sopenharmony_ci		if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
3053e5c31af7Sopenharmony_ci		{
3054e5c31af7Sopenharmony_ci			const glw::GLenum	prop			= targetProps[propNdx].propName;
3055e5c31af7Sopenharmony_ci			const bool			expected		= (isInputCase) ? (targetProps[propNdx].shaderType == m_program->getFirstStage()) : (targetProps[propNdx].shaderType == m_program->getLastStage());
3056e5c31af7Sopenharmony_ci			glw::GLint			value			= -1;
3057e5c31af7Sopenharmony_ci			glw::GLint			written			= -1;
3058e5c31af7Sopenharmony_ci
3059e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << ((expected) ? ("TRUE") : ("FALSE")) << tcu::TestLog::EndMessage;
3060e5c31af7Sopenharmony_ci
3061e5c31af7Sopenharmony_ci			gl.getProgramResourceiv(program.getProgram(), programGLInterface, resourceIndex, 1, &prop, 1, &written, &value);
3062e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");
3063e5c31af7Sopenharmony_ci
3064e5c31af7Sopenharmony_ci			if (written != 1)
3065e5c31af7Sopenharmony_ci			{
3066e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
3067e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
3068e5c31af7Sopenharmony_ci				continue;
3069e5c31af7Sopenharmony_ci			}
3070e5c31af7Sopenharmony_ci
3071e5c31af7Sopenharmony_ci			m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;
3072e5c31af7Sopenharmony_ci
3073e5c31af7Sopenharmony_ci			if (value != ((expected) ? (GL_TRUE) : (GL_FALSE)))
3074e5c31af7Sopenharmony_ci			{
3075e5c31af7Sopenharmony_ci				m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
3076e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
3077e5c31af7Sopenharmony_ci				continue;
3078e5c31af7Sopenharmony_ci			}
3079e5c31af7Sopenharmony_ci		}
3080e5c31af7Sopenharmony_ci	}
3081e5c31af7Sopenharmony_ci
3082e5c31af7Sopenharmony_ci	return STOP;
3083e5c31af7Sopenharmony_ci}
3084e5c31af7Sopenharmony_ci
3085e5c31af7Sopenharmony_ciclass FeedbackResourceListTestCase : public ResourceListTestCase
3086e5c31af7Sopenharmony_ci{
3087e5c31af7Sopenharmony_cipublic:
3088e5c31af7Sopenharmony_ci											FeedbackResourceListTestCase	(Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name);
3089e5c31af7Sopenharmony_ci											~FeedbackResourceListTestCase	(void);
3090e5c31af7Sopenharmony_ci
3091e5c31af7Sopenharmony_ciprivate:
3092e5c31af7Sopenharmony_ci	IterateResult							iterate							(void);
3093e5c31af7Sopenharmony_ci};
3094e5c31af7Sopenharmony_ci
3095e5c31af7Sopenharmony_ciFeedbackResourceListTestCase::FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name)
3096e5c31af7Sopenharmony_ci	: ResourceListTestCase(context, resource, PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, name)
3097e5c31af7Sopenharmony_ci{
3098e5c31af7Sopenharmony_ci}
3099e5c31af7Sopenharmony_ci
3100e5c31af7Sopenharmony_ciFeedbackResourceListTestCase::~FeedbackResourceListTestCase (void)
3101e5c31af7Sopenharmony_ci{
3102e5c31af7Sopenharmony_ci	deinit();
3103e5c31af7Sopenharmony_ci}
3104e5c31af7Sopenharmony_ci
3105e5c31af7Sopenharmony_ciFeedbackResourceListTestCase::IterateResult FeedbackResourceListTestCase::iterate (void)
3106e5c31af7Sopenharmony_ci{
3107e5c31af7Sopenharmony_ci	const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));
3108e5c31af7Sopenharmony_ci
3109e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3110e5c31af7Sopenharmony_ci
3111e5c31af7Sopenharmony_ci	// Feedback varyings
3112e5c31af7Sopenharmony_ci	{
3113e5c31af7Sopenharmony_ci		tcu::MessageBuilder builder(&m_testCtx.getLog());
3114e5c31af7Sopenharmony_ci		builder << "Transform feedback varyings: {";
3115e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < (int)m_programDefinition->getTransformFeedbackVaryings().size(); ++ndx)
3116e5c31af7Sopenharmony_ci		{
3117e5c31af7Sopenharmony_ci			if (ndx)
3118e5c31af7Sopenharmony_ci				builder << ", ";
3119e5c31af7Sopenharmony_ci			builder << "\"" << m_programDefinition->getTransformFeedbackVaryings()[ndx] << "\"";
3120e5c31af7Sopenharmony_ci		}
3121e5c31af7Sopenharmony_ci		builder << "}" << tcu::TestLog::EndMessage;
3122e5c31af7Sopenharmony_ci	}
3123e5c31af7Sopenharmony_ci
3124e5c31af7Sopenharmony_ci	checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
3125e5c31af7Sopenharmony_ci
3126e5c31af7Sopenharmony_ci	// Check resource list
3127e5c31af7Sopenharmony_ci	{
3128e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "ResourceList", "Resource list");
3129e5c31af7Sopenharmony_ci		std::vector<std::string>	resourceList;
3130e5c31af7Sopenharmony_ci		std::vector<std::string>	expectedResources;
3131e5c31af7Sopenharmony_ci
3132e5c31af7Sopenharmony_ci		queryResourceList(resourceList, program.getProgram());
3133e5c31af7Sopenharmony_ci		expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);
3134e5c31af7Sopenharmony_ci
3135e5c31af7Sopenharmony_ci		// verify the list and the expected list match
3136e5c31af7Sopenharmony_ci
3137e5c31af7Sopenharmony_ci		if (!verifyResourceList(resourceList, expectedResources))
3138e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");
3139e5c31af7Sopenharmony_ci
3140e5c31af7Sopenharmony_ci		// verify GetProgramResourceIndex() matches the indices of the list
3141e5c31af7Sopenharmony_ci
3142e5c31af7Sopenharmony_ci		if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
3143e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");
3144e5c31af7Sopenharmony_ci
3145e5c31af7Sopenharmony_ci		// Verify MAX_NAME_LENGTH
3146e5c31af7Sopenharmony_ci		if (!verifyMaxNameLength(resourceList, program.getProgram()))
3147e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
3148e5c31af7Sopenharmony_ci	}
3149e5c31af7Sopenharmony_ci
3150e5c31af7Sopenharmony_ci	return STOP;
3151e5c31af7Sopenharmony_ci}
3152e5c31af7Sopenharmony_ci
3153e5c31af7Sopenharmony_ciint InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const glu::InterfaceBlock& block) const
3154e5c31af7Sopenharmony_ci{
3155e5c31af7Sopenharmony_ci	int dataSize = 0;
3156e5c31af7Sopenharmony_ci
3157e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
3158e5c31af7Sopenharmony_ci		dataSize += getVarTypeSize(block.variables[ndx].varType);
3159e5c31af7Sopenharmony_ci
3160e5c31af7Sopenharmony_ci	return dataSize;
3161e5c31af7Sopenharmony_ci}
3162e5c31af7Sopenharmony_ci
3163e5c31af7Sopenharmony_cistatic bool isDataTypeLayoutQualified (glu::DataType type)
3164e5c31af7Sopenharmony_ci{
3165e5c31af7Sopenharmony_ci	return glu::isDataTypeImage(type) || glu::isDataTypeAtomicCounter(type);
3166e5c31af7Sopenharmony_ci}
3167e5c31af7Sopenharmony_ci
3168e5c31af7Sopenharmony_cistatic void generateVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3169e5c31af7Sopenharmony_ci{
3170e5c31af7Sopenharmony_ci	static const struct
3171e5c31af7Sopenharmony_ci	{
3172e5c31af7Sopenharmony_ci		int				level;
3173e5c31af7Sopenharmony_ci		glu::DataType	dataType;
3174e5c31af7Sopenharmony_ci	} variableTypes[] =
3175e5c31af7Sopenharmony_ci	{
3176e5c31af7Sopenharmony_ci		{ 0,	glu::TYPE_FLOAT			},
3177e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_INT			},
3178e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_UINT			},
3179e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_BOOL			},
3180e5c31af7Sopenharmony_ci
3181e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_VEC2	},
3182e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_FLOAT_VEC3	},
3183e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_FLOAT_VEC4	},
3184e5c31af7Sopenharmony_ci
3185e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_VEC2		},
3186e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_INT_VEC3		},
3187e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_VEC4		},
3188e5c31af7Sopenharmony_ci
3189e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_VEC2		},
3190e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_UINT_VEC3		},
3191e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_VEC4		},
3192e5c31af7Sopenharmony_ci
3193e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_BOOL_VEC2		},
3194e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_BOOL_VEC3		},
3195e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_BOOL_VEC4		},
3196e5c31af7Sopenharmony_ci
3197e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT2	},
3198e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_MAT2X3	},
3199e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_MAT2X4	},
3200e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT3X2	},
3201e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT3	},
3202e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_MAT3X4	},
3203e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT4X2	},
3204e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_MAT4X3	},
3205e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT4	},
3206e5c31af7Sopenharmony_ci	};
3207e5c31af7Sopenharmony_ci
3208e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* group;
3209e5c31af7Sopenharmony_ci
3210e5c31af7Sopenharmony_ci	if (createTestGroup)
3211e5c31af7Sopenharmony_ci	{
3212e5c31af7Sopenharmony_ci		group = new tcu::TestCaseGroup(context.getTestContext(), "basic_type", "Basic variable");
3213e5c31af7Sopenharmony_ci		targetGroup->addChild(group);
3214e5c31af7Sopenharmony_ci	}
3215e5c31af7Sopenharmony_ci	else
3216e5c31af7Sopenharmony_ci		group = targetGroup;
3217e5c31af7Sopenharmony_ci
3218e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3219e5c31af7Sopenharmony_ci	{
3220e5c31af7Sopenharmony_ci		if (variableTypes[ndx].level <= expandLevel)
3221e5c31af7Sopenharmony_ci		{
3222e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3223e5c31af7Sopenharmony_ci			group->addChild(new ResourceTestCase(context, variable, queryTarget));
3224e5c31af7Sopenharmony_ci		}
3225e5c31af7Sopenharmony_ci	}
3226e5c31af7Sopenharmony_ci}
3227e5c31af7Sopenharmony_ci
3228e5c31af7Sopenharmony_cistatic void generateOpaqueTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
3229e5c31af7Sopenharmony_ci{
3230e5c31af7Sopenharmony_ci	static const struct
3231e5c31af7Sopenharmony_ci	{
3232e5c31af7Sopenharmony_ci		int				level;
3233e5c31af7Sopenharmony_ci		glu::DataType	dataType;
3234e5c31af7Sopenharmony_ci	} variableTypes[] =
3235e5c31af7Sopenharmony_ci	{
3236e5c31af7Sopenharmony_ci		{ 0,	glu::TYPE_SAMPLER_2D					},
3237e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_SAMPLER_CUBE					},
3238e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_SAMPLER_2D_ARRAY				},
3239e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_SAMPLER_3D					},
3240e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_SAMPLER_2D_SHADOW				},
3241e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_SAMPLER_CUBE_SHADOW			},
3242e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_SAMPLER_2D_ARRAY_SHADOW		},
3243e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_INT_SAMPLER_2D				},
3244e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_SAMPLER_CUBE				},
3245e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_SAMPLER_2D_ARRAY			},
3246e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_SAMPLER_3D				},
3247e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_UINT_SAMPLER_2D				},
3248e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_SAMPLER_CUBE				},
3249e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_SAMPLER_2D_ARRAY			},
3250e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_SAMPLER_3D				},
3251e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_SAMPLER_2D_MULTISAMPLE		},
3252e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE	},
3253e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE	},
3254e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_IMAGE_2D						},
3255e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_IMAGE_CUBE					},
3256e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_IMAGE_2D_ARRAY				},
3257e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_IMAGE_3D						},
3258e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_IMAGE_2D					},
3259e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_IMAGE_CUBE				},
3260e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_INT_IMAGE_2D_ARRAY			},
3261e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_IMAGE_3D					},
3262e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_UINT_IMAGE_2D					},
3263e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_IMAGE_CUBE				},
3264e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_IMAGE_2D_ARRAY			},
3265e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_IMAGE_3D					},
3266e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_UINT_ATOMIC_COUNTER			},
3267e5c31af7Sopenharmony_ci	};
3268e5c31af7Sopenharmony_ci
3269e5c31af7Sopenharmony_ci	bool isStructMember = false;
3270e5c31af7Sopenharmony_ci
3271e5c31af7Sopenharmony_ci	// Requirements
3272e5c31af7Sopenharmony_ci	for (const ResourceDefinition::Node* node = parentStructure.get(); node; node = node->getEnclosingNode())
3273e5c31af7Sopenharmony_ci	{
3274e5c31af7Sopenharmony_ci		// Don't insert inside a interface block
3275e5c31af7Sopenharmony_ci		if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3276e5c31af7Sopenharmony_ci			return;
3277e5c31af7Sopenharmony_ci
3278e5c31af7Sopenharmony_ci		isStructMember |= (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER);
3279e5c31af7Sopenharmony_ci	}
3280e5c31af7Sopenharmony_ci
3281e5c31af7Sopenharmony_ci	// Add cases
3282e5c31af7Sopenharmony_ci	{
3283e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* group;
3284e5c31af7Sopenharmony_ci
3285e5c31af7Sopenharmony_ci		if (createTestGroup)
3286e5c31af7Sopenharmony_ci		{
3287e5c31af7Sopenharmony_ci			group = new tcu::TestCaseGroup(context.getTestContext(), "opaque_type", "Opaque types");
3288e5c31af7Sopenharmony_ci			targetGroup->addChild(group);
3289e5c31af7Sopenharmony_ci		}
3290e5c31af7Sopenharmony_ci		else
3291e5c31af7Sopenharmony_ci			group = targetGroup;
3292e5c31af7Sopenharmony_ci
3293e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3294e5c31af7Sopenharmony_ci		{
3295e5c31af7Sopenharmony_ci			if (variableTypes[ndx].level > expandLevel)
3296e5c31af7Sopenharmony_ci				continue;
3297e5c31af7Sopenharmony_ci
3298e5c31af7Sopenharmony_ci			// Layout qualifiers are not allowed on struct members
3299e5c31af7Sopenharmony_ci			if (isDataTypeLayoutQualified(variableTypes[ndx].dataType) && isStructMember)
3300e5c31af7Sopenharmony_ci				continue;
3301e5c31af7Sopenharmony_ci
3302e5c31af7Sopenharmony_ci			{
3303e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
3304e5c31af7Sopenharmony_ci				group->addChild(new ResourceTestCase(context, variable, queryTarget));
3305e5c31af7Sopenharmony_ci			}
3306e5c31af7Sopenharmony_ci		}
3307e5c31af7Sopenharmony_ci	}
3308e5c31af7Sopenharmony_ci}
3309e5c31af7Sopenharmony_ci
3310e5c31af7Sopenharmony_cistatic void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3);
3311e5c31af7Sopenharmony_ci
3312e5c31af7Sopenharmony_cistatic void generateVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3)
3313e5c31af7Sopenharmony_ci{
3314e5c31af7Sopenharmony_ci	if (expandLevel > 0)
3315e5c31af7Sopenharmony_ci	{
3316e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
3317e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3318e5c31af7Sopenharmony_ci
3319e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
3320e5c31af7Sopenharmony_ci
3321e5c31af7Sopenharmony_ci		// Arrays of basic variables
3322e5c31af7Sopenharmony_ci		generateVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3323e5c31af7Sopenharmony_ci
3324e5c31af7Sopenharmony_ci		// Arrays of opaque types
3325e5c31af7Sopenharmony_ci		generateOpaqueTypeCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3326e5c31af7Sopenharmony_ci
3327e5c31af7Sopenharmony_ci		// Arrays of arrays
3328e5c31af7Sopenharmony_ci		generateVariableArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3329e5c31af7Sopenharmony_ci
3330e5c31af7Sopenharmony_ci		// Arrays of structs
3331e5c31af7Sopenharmony_ci		generateCompoundVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3332e5c31af7Sopenharmony_ci	}
3333e5c31af7Sopenharmony_ci}
3334e5c31af7Sopenharmony_ci
3335e5c31af7Sopenharmony_cistatic void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3336e5c31af7Sopenharmony_ci{
3337e5c31af7Sopenharmony_ci	if (expandLevel > 0)
3338e5c31af7Sopenharmony_ci	{
3339e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
3340e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3341e5c31af7Sopenharmony_ci
3342e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
3343e5c31af7Sopenharmony_ci
3344e5c31af7Sopenharmony_ci		// Struct containing basic variable
3345e5c31af7Sopenharmony_ci		generateVariableCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3346e5c31af7Sopenharmony_ci
3347e5c31af7Sopenharmony_ci		// Struct containing opaque types
3348e5c31af7Sopenharmony_ci		generateOpaqueTypeCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);
3349e5c31af7Sopenharmony_ci
3350e5c31af7Sopenharmony_ci		// Struct containing arrays
3351e5c31af7Sopenharmony_ci		generateVariableArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3352e5c31af7Sopenharmony_ci
3353e5c31af7Sopenharmony_ci		// Struct containing struct
3354e5c31af7Sopenharmony_ci		generateCompoundVariableCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3355e5c31af7Sopenharmony_ci	}
3356e5c31af7Sopenharmony_ci}
3357e5c31af7Sopenharmony_ci
3358e5c31af7Sopenharmony_ci// Resource list cases
3359e5c31af7Sopenharmony_ci
3360e5c31af7Sopenharmony_cienum BlockFlags
3361e5c31af7Sopenharmony_ci{
3362e5c31af7Sopenharmony_ci	BLOCKFLAG_DEFAULT	= 0x01,
3363e5c31af7Sopenharmony_ci	BLOCKFLAG_NAMED		= 0x02,
3364e5c31af7Sopenharmony_ci	BLOCKFLAG_UNNAMED	= 0x04,
3365e5c31af7Sopenharmony_ci	BLOCKFLAG_ARRAY		= 0x08,
3366e5c31af7Sopenharmony_ci
3367e5c31af7Sopenharmony_ci	BLOCKFLAG_ALL		= 0x0F
3368e5c31af7Sopenharmony_ci};
3369e5c31af7Sopenharmony_ci
3370e5c31af7Sopenharmony_cistatic void generateUniformCaseBlocks (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, deUint32 blockFlags, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const))
3371e5c31af7Sopenharmony_ci{
3372e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
3373e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr uniform		(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3374e5c31af7Sopenharmony_ci
3375e5c31af7Sopenharmony_ci	// .default_block
3376e5c31af7Sopenharmony_ci	if (blockFlags & BLOCKFLAG_DEFAULT)
3377e5c31af7Sopenharmony_ci	{
3378e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "default_block", "Default block");
3379e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
3380e5c31af7Sopenharmony_ci
3381e5c31af7Sopenharmony_ci		blockContentGenerator(context, uniform, blockGroup);
3382e5c31af7Sopenharmony_ci	}
3383e5c31af7Sopenharmony_ci
3384e5c31af7Sopenharmony_ci	// .named_block
3385e5c31af7Sopenharmony_ci	if (blockFlags & BLOCKFLAG_NAMED)
3386e5c31af7Sopenharmony_ci	{
3387e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, true));
3388e5c31af7Sopenharmony_ci
3389e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "named_block", "Named uniform block");
3390e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
3391e5c31af7Sopenharmony_ci
3392e5c31af7Sopenharmony_ci		blockContentGenerator(context, block, blockGroup);
3393e5c31af7Sopenharmony_ci	}
3394e5c31af7Sopenharmony_ci
3395e5c31af7Sopenharmony_ci	// .unnamed_block
3396e5c31af7Sopenharmony_ci	if (blockFlags & BLOCKFLAG_UNNAMED)
3397e5c31af7Sopenharmony_ci	{
3398e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, false));
3399e5c31af7Sopenharmony_ci
3400e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "unnamed_block", "Unnamed uniform block");
3401e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
3402e5c31af7Sopenharmony_ci
3403e5c31af7Sopenharmony_ci		blockContentGenerator(context, block, blockGroup);
3404e5c31af7Sopenharmony_ci	}
3405e5c31af7Sopenharmony_ci
3406e5c31af7Sopenharmony_ci	// .block_array
3407e5c31af7Sopenharmony_ci	if (blockFlags & BLOCKFLAG_ARRAY)
3408e5c31af7Sopenharmony_ci	{
3409e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(uniform));
3410e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
3411e5c31af7Sopenharmony_ci
3412e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "block_array", "Uniform block array");
3413e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
3414e5c31af7Sopenharmony_ci
3415e5c31af7Sopenharmony_ci		blockContentGenerator(context, block, blockGroup);
3416e5c31af7Sopenharmony_ci	}
3417e5c31af7Sopenharmony_ci}
3418e5c31af7Sopenharmony_ci
3419e5c31af7Sopenharmony_cistatic void generateBufferBackedResourceListBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, int depth)
3420e5c31af7Sopenharmony_ci{
3421e5c31af7Sopenharmony_ci	// variable
3422e5c31af7Sopenharmony_ci	{
3423e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT_VEC4));
3424e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceListTestCase(context, variable, interface));
3425e5c31af7Sopenharmony_ci	}
3426e5c31af7Sopenharmony_ci
3427e5c31af7Sopenharmony_ci	// struct
3428e5c31af7Sopenharmony_ci	if (depth > 0)
3429e5c31af7Sopenharmony_ci	{
3430e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3431e5c31af7Sopenharmony_ci		generateBufferBackedResourceListBlockContentCases(context, structMember, targetGroup, interface, depth - 1);
3432e5c31af7Sopenharmony_ci	}
3433e5c31af7Sopenharmony_ci
3434e5c31af7Sopenharmony_ci	// array
3435e5c31af7Sopenharmony_ci	if (depth > 0)
3436e5c31af7Sopenharmony_ci	{
3437e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3438e5c31af7Sopenharmony_ci		generateBufferBackedResourceListBlockContentCases(context, arrayElement, targetGroup, interface, depth - 1);
3439e5c31af7Sopenharmony_ci	}
3440e5c31af7Sopenharmony_ci}
3441e5c31af7Sopenharmony_ci
3442e5c31af7Sopenharmony_cistatic void generateBufferBackedVariableAggregateTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, ProgramResourcePropFlags targetProp, glu::DataType dataType, const std::string& nameSuffix, int depth)
3443e5c31af7Sopenharmony_ci{
3444e5c31af7Sopenharmony_ci	// variable
3445e5c31af7Sopenharmony_ci	{
3446e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, dataType));
3447e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, targetProp), ("var" + nameSuffix).c_str()));
3448e5c31af7Sopenharmony_ci	}
3449e5c31af7Sopenharmony_ci
3450e5c31af7Sopenharmony_ci	// struct
3451e5c31af7Sopenharmony_ci	if (depth > 0)
3452e5c31af7Sopenharmony_ci	{
3453e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
3454e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, structMember, targetGroup, interface, targetProp, dataType, "_struct" + nameSuffix, depth - 1);
3455e5c31af7Sopenharmony_ci	}
3456e5c31af7Sopenharmony_ci
3457e5c31af7Sopenharmony_ci	// array
3458e5c31af7Sopenharmony_ci	if (depth > 0)
3459e5c31af7Sopenharmony_ci	{
3460e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
3461e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, arrayElement, targetGroup, interface, targetProp, dataType, "_array" + nameSuffix, depth - 1);
3462e5c31af7Sopenharmony_ci	}
3463e5c31af7Sopenharmony_ci}
3464e5c31af7Sopenharmony_ci
3465e5c31af7Sopenharmony_cistatic void generateUniformResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3466e5c31af7Sopenharmony_ci{
3467e5c31af7Sopenharmony_ci	generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, 4);
3468e5c31af7Sopenharmony_ci}
3469e5c31af7Sopenharmony_ci
3470e5c31af7Sopenharmony_cistatic void generateUniformBlockArraySizeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3471e5c31af7Sopenharmony_ci{
3472e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_SIZE);
3473e5c31af7Sopenharmony_ci	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3474e5c31af7Sopenharmony_ci	const bool								namedNonArrayBlock	= isInterfaceBlock																					&&
3475e5c31af7Sopenharmony_ci																  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
3476e5c31af7Sopenharmony_ci																  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3477e5c31af7Sopenharmony_ci
3478e5c31af7Sopenharmony_ci	if (!isInterfaceBlock || namedNonArrayBlock)
3479e5c31af7Sopenharmony_ci	{
3480e5c31af7Sopenharmony_ci		// .types
3481e5c31af7Sopenharmony_ci		{
3482e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3483e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3484e5c31af7Sopenharmony_ci
3485e5c31af7Sopenharmony_ci			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3486e5c31af7Sopenharmony_ci			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3487e5c31af7Sopenharmony_ci		}
3488e5c31af7Sopenharmony_ci
3489e5c31af7Sopenharmony_ci		// aggregates
3490e5c31af7Sopenharmony_ci		{
3491e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3492e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3493e5c31af7Sopenharmony_ci
3494e5c31af7Sopenharmony_ci			generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 3);
3495e5c31af7Sopenharmony_ci		}
3496e5c31af7Sopenharmony_ci	}
3497e5c31af7Sopenharmony_ci	else
3498e5c31af7Sopenharmony_ci	{
3499e5c31af7Sopenharmony_ci		// aggregates
3500e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 2);
3501e5c31af7Sopenharmony_ci	}
3502e5c31af7Sopenharmony_ci}
3503e5c31af7Sopenharmony_ci
3504e5c31af7Sopenharmony_cistatic void generateBufferBackedArrayStrideTypeAggregateSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const std::string& namePrefix, ProgramInterface interface, glu::DataType type, int expandLevel)
3505e5c31af7Sopenharmony_ci{
3506e5c31af7Sopenharmony_ci	// case
3507e5c31af7Sopenharmony_ci	{
3508e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3509e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3510e5c31af7Sopenharmony_ci	}
3511e5c31af7Sopenharmony_ci
3512e5c31af7Sopenharmony_ci	if (expandLevel > 0)
3513e5c31af7Sopenharmony_ci	{
3514e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
3515e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
3516e5c31af7Sopenharmony_ci
3517e5c31af7Sopenharmony_ci		// _struct
3518e5c31af7Sopenharmony_ci		generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3519e5c31af7Sopenharmony_ci
3520e5c31af7Sopenharmony_ci		// _array
3521e5c31af7Sopenharmony_ci		generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3522e5c31af7Sopenharmony_ci	}
3523e5c31af7Sopenharmony_ci}
3524e5c31af7Sopenharmony_ci
3525e5c31af7Sopenharmony_cistatic void generateBufferBackedArrayStrideTypeAggregateCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, glu::DataType type, int expandLevel, bool includeBaseCase)
3526e5c31af7Sopenharmony_ci{
3527e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
3528e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
3529e5c31af7Sopenharmony_ci	const std::string							namePrefix		= glu::getDataTypeName(type);
3530e5c31af7Sopenharmony_ci
3531e5c31af7Sopenharmony_ci	if (expandLevel == 0 || includeBaseCase)
3532e5c31af7Sopenharmony_ci	{
3533e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
3534e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
3535e5c31af7Sopenharmony_ci	}
3536e5c31af7Sopenharmony_ci	if (expandLevel >= 1)
3537e5c31af7Sopenharmony_ci	{
3538e5c31af7Sopenharmony_ci		// _struct
3539e5c31af7Sopenharmony_ci		if (!glu::isDataTypeAtomicCounter(type))
3540e5c31af7Sopenharmony_ci			generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);
3541e5c31af7Sopenharmony_ci
3542e5c31af7Sopenharmony_ci		// _array
3543e5c31af7Sopenharmony_ci		generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
3544e5c31af7Sopenharmony_ci	}
3545e5c31af7Sopenharmony_ci}
3546e5c31af7Sopenharmony_ci
3547e5c31af7Sopenharmony_cistatic void generateUniformBlockArrayStrideContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3548e5c31af7Sopenharmony_ci{
3549e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_STRIDE);
3550e5c31af7Sopenharmony_ci	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3551e5c31af7Sopenharmony_ci	const bool								namedNonArrayBlock	= isInterfaceBlock																					&&
3552e5c31af7Sopenharmony_ci																  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
3553e5c31af7Sopenharmony_ci																  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3554e5c31af7Sopenharmony_ci
3555e5c31af7Sopenharmony_ci	if (!isInterfaceBlock || namedNonArrayBlock)
3556e5c31af7Sopenharmony_ci	{
3557e5c31af7Sopenharmony_ci		// .types
3558e5c31af7Sopenharmony_ci		{
3559e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3560e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3561e5c31af7Sopenharmony_ci
3562e5c31af7Sopenharmony_ci			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3563e5c31af7Sopenharmony_ci			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
3564e5c31af7Sopenharmony_ci		}
3565e5c31af7Sopenharmony_ci
3566e5c31af7Sopenharmony_ci		// .aggregates
3567e5c31af7Sopenharmony_ci		{
3568e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3569e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3570e5c31af7Sopenharmony_ci
3571e5c31af7Sopenharmony_ci			// .sampler_2d_*
3572e5c31af7Sopenharmony_ci			if (!isInterfaceBlock)
3573e5c31af7Sopenharmony_ci				generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_SAMPLER_2D, 1, false);
3574e5c31af7Sopenharmony_ci
3575e5c31af7Sopenharmony_ci			// .atomic_counter_*
3576e5c31af7Sopenharmony_ci			if (!isInterfaceBlock)
3577e5c31af7Sopenharmony_ci			{
3578e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr layout(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
3579e5c31af7Sopenharmony_ci				generateBufferBackedArrayStrideTypeAggregateCases(context, layout, blockGroup, queryTarget.interface, glu::TYPE_UINT_ATOMIC_COUNTER, 1, false);
3580e5c31af7Sopenharmony_ci			}
3581e5c31af7Sopenharmony_ci
3582e5c31af7Sopenharmony_ci			// .float_*
3583e5c31af7Sopenharmony_ci			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT, 2, false);
3584e5c31af7Sopenharmony_ci
3585e5c31af7Sopenharmony_ci			// .bool_*
3586e5c31af7Sopenharmony_ci			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL, 1, false);
3587e5c31af7Sopenharmony_ci
3588e5c31af7Sopenharmony_ci			// .bvec3_*
3589e5c31af7Sopenharmony_ci			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, 2, false);
3590e5c31af7Sopenharmony_ci
3591e5c31af7Sopenharmony_ci			// .vec3_*
3592e5c31af7Sopenharmony_ci			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC3, 2, false);
3593e5c31af7Sopenharmony_ci
3594e5c31af7Sopenharmony_ci			// .ivec2_*
3595e5c31af7Sopenharmony_ci			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_INT_VEC3, 2, false);
3596e5c31af7Sopenharmony_ci		}
3597e5c31af7Sopenharmony_ci	}
3598e5c31af7Sopenharmony_ci	else
3599e5c31af7Sopenharmony_ci	{
3600e5c31af7Sopenharmony_ci		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3601e5c31af7Sopenharmony_ci		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3602e5c31af7Sopenharmony_ci		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3603e5c31af7Sopenharmony_ci	}
3604e5c31af7Sopenharmony_ci}
3605e5c31af7Sopenharmony_ci
3606e5c31af7Sopenharmony_cistatic void generateUniformBlockLocationContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3607e5c31af7Sopenharmony_ci{
3608e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_LOCATION);
3609e5c31af7Sopenharmony_ci	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3610e5c31af7Sopenharmony_ci
3611e5c31af7Sopenharmony_ci	if (!isInterfaceBlock)
3612e5c31af7Sopenharmony_ci	{
3613e5c31af7Sopenharmony_ci		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3614e5c31af7Sopenharmony_ci		generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3615e5c31af7Sopenharmony_ci		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 2);
3616e5c31af7Sopenharmony_ci		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 2);
3617e5c31af7Sopenharmony_ci	}
3618e5c31af7Sopenharmony_ci	else
3619e5c31af7Sopenharmony_ci		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3620e5c31af7Sopenharmony_ci}
3621e5c31af7Sopenharmony_ci
3622e5c31af7Sopenharmony_cistatic void generateUniformBlockBlockIndexContents (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion)
3623e5c31af7Sopenharmony_ci{
3624e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
3625e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
3626e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
3627e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	uniform			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
3628e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	binding			(new ResourceDefinition::LayoutQualifier(uniform, glu::Layout(-1, 0)));
3629e5c31af7Sopenharmony_ci
3630e5c31af7Sopenharmony_ci	// .default_block
3631e5c31af7Sopenharmony_ci	{
3632e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(uniform, glu::TYPE_FLOAT_VEC4));
3633e5c31af7Sopenharmony_ci
3634e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "default_block"));
3635e5c31af7Sopenharmony_ci	}
3636e5c31af7Sopenharmony_ci
3637e5c31af7Sopenharmony_ci	// .named_block
3638e5c31af7Sopenharmony_ci	{
3639e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, true));
3640e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3641e5c31af7Sopenharmony_ci
3642e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
3643e5c31af7Sopenharmony_ci	}
3644e5c31af7Sopenharmony_ci
3645e5c31af7Sopenharmony_ci	// .unnamed_block
3646e5c31af7Sopenharmony_ci	{
3647e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, false));
3648e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3649e5c31af7Sopenharmony_ci
3650e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
3651e5c31af7Sopenharmony_ci	}
3652e5c31af7Sopenharmony_ci
3653e5c31af7Sopenharmony_ci	// .block_array
3654e5c31af7Sopenharmony_ci	{
3655e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(binding));
3656e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
3657e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
3658e5c31af7Sopenharmony_ci
3659e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
3660e5c31af7Sopenharmony_ci	}
3661e5c31af7Sopenharmony_ci}
3662e5c31af7Sopenharmony_ci
3663e5c31af7Sopenharmony_cistatic void generateUniformBlockAtomicCounterBufferIndexContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3664e5c31af7Sopenharmony_ci{
3665e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX);
3666e5c31af7Sopenharmony_ci	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3667e5c31af7Sopenharmony_ci
3668e5c31af7Sopenharmony_ci	if (!isInterfaceBlock)
3669e5c31af7Sopenharmony_ci	{
3670e5c31af7Sopenharmony_ci		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
3671e5c31af7Sopenharmony_ci		generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
3672e5c31af7Sopenharmony_ci
3673e5c31af7Sopenharmony_ci		// .array
3674e5c31af7Sopenharmony_ci		{
3675e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElement		(new ResourceDefinition::ArrayElement(parentStructure));
3676e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayArrayElement	(new ResourceDefinition::ArrayElement(arrayElement));
3677e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	variable			(new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3678e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	elementvariable		(new ResourceDefinition::Variable(arrayArrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3679e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup			= new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3680e5c31af7Sopenharmony_ci
3681e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3682e5c31af7Sopenharmony_ci
3683e5c31af7Sopenharmony_ci			blockGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "var_array"));
3684e5c31af7Sopenharmony_ci			blockGroup->addChild(new ResourceTestCase(context, elementvariable, queryTarget, "var_array_array"));
3685e5c31af7Sopenharmony_ci		}
3686e5c31af7Sopenharmony_ci	}
3687e5c31af7Sopenharmony_ci	else
3688e5c31af7Sopenharmony_ci		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
3689e5c31af7Sopenharmony_ci}
3690e5c31af7Sopenharmony_ci
3691e5c31af7Sopenharmony_cistatic void generateUniformBlockNameLengthContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3692e5c31af7Sopenharmony_ci{
3693e5c31af7Sopenharmony_ci	const bool	isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3694e5c31af7Sopenharmony_ci	const bool	namedNonArrayBlock	= isInterfaceBlock																					&&
3695e5c31af7Sopenharmony_ci									  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
3696e5c31af7Sopenharmony_ci									  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3697e5c31af7Sopenharmony_ci
3698e5c31af7Sopenharmony_ci	if (!isInterfaceBlock || namedNonArrayBlock)
3699e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
3700e5c31af7Sopenharmony_ci	else
3701e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 1);
3702e5c31af7Sopenharmony_ci}
3703e5c31af7Sopenharmony_ci
3704e5c31af7Sopenharmony_cistatic void generateUniformBlockTypeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3705e5c31af7Sopenharmony_ci{
3706e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_TYPE);
3707e5c31af7Sopenharmony_ci	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3708e5c31af7Sopenharmony_ci	const bool								namedNonArrayBlock	= isInterfaceBlock																					&&
3709e5c31af7Sopenharmony_ci																  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
3710e5c31af7Sopenharmony_ci																  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3711e5c31af7Sopenharmony_ci
3712e5c31af7Sopenharmony_ci	if (!isInterfaceBlock || namedNonArrayBlock)
3713e5c31af7Sopenharmony_ci	{
3714e5c31af7Sopenharmony_ci		// .types
3715e5c31af7Sopenharmony_ci		{
3716e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3717e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3718e5c31af7Sopenharmony_ci
3719e5c31af7Sopenharmony_ci			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3720e5c31af7Sopenharmony_ci			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3721e5c31af7Sopenharmony_ci		}
3722e5c31af7Sopenharmony_ci
3723e5c31af7Sopenharmony_ci		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3724e5c31af7Sopenharmony_ci		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3725e5c31af7Sopenharmony_ci
3726e5c31af7Sopenharmony_ci	}
3727e5c31af7Sopenharmony_ci	else
3728e5c31af7Sopenharmony_ci	{
3729e5c31af7Sopenharmony_ci		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3730e5c31af7Sopenharmony_ci		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3731e5c31af7Sopenharmony_ci		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3732e5c31af7Sopenharmony_ci	}
3733e5c31af7Sopenharmony_ci}
3734e5c31af7Sopenharmony_ci
3735e5c31af7Sopenharmony_cistatic void generateUniformBlockOffsetContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
3736e5c31af7Sopenharmony_ci{
3737e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_OFFSET);
3738e5c31af7Sopenharmony_ci	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
3739e5c31af7Sopenharmony_ci	const bool								namedNonArrayBlock	= isInterfaceBlock																					&&
3740e5c31af7Sopenharmony_ci																  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
3741e5c31af7Sopenharmony_ci																  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
3742e5c31af7Sopenharmony_ci
3743e5c31af7Sopenharmony_ci	if (!isInterfaceBlock)
3744e5c31af7Sopenharmony_ci	{
3745e5c31af7Sopenharmony_ci		// .types
3746e5c31af7Sopenharmony_ci		{
3747e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3748e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3749e5c31af7Sopenharmony_ci
3750e5c31af7Sopenharmony_ci			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3751e5c31af7Sopenharmony_ci			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3752e5c31af7Sopenharmony_ci		}
3753e5c31af7Sopenharmony_ci
3754e5c31af7Sopenharmony_ci		// .aggregates
3755e5c31af7Sopenharmony_ci		{
3756e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3757e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3758e5c31af7Sopenharmony_ci
3759e5c31af7Sopenharmony_ci			// .atomic_uint_struct
3760e5c31af7Sopenharmony_ci			// .atomic_uint_array
3761e5c31af7Sopenharmony_ci			{
3762e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr offset			(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, 4)));
3763e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr arrayElement		(new ResourceDefinition::ArrayElement(offset));
3764e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr elementVariable	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
3765e5c31af7Sopenharmony_ci
3766e5c31af7Sopenharmony_ci				blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "atomic_uint_array"));
3767e5c31af7Sopenharmony_ci			}
3768e5c31af7Sopenharmony_ci
3769e5c31af7Sopenharmony_ci			// .float_array
3770e5c31af7Sopenharmony_ci			// .float_struct
3771e5c31af7Sopenharmony_ci			{
3772e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr structMember		(new ResourceDefinition::StructMember(parentStructure));
3773e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr arrayElement		(new ResourceDefinition::ArrayElement(parentStructure));
3774e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr memberVariable	(new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3775e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr elementVariable	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3776e5c31af7Sopenharmony_ci
3777e5c31af7Sopenharmony_ci				blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3778e5c31af7Sopenharmony_ci				blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3779e5c31af7Sopenharmony_ci			}
3780e5c31af7Sopenharmony_ci		}
3781e5c31af7Sopenharmony_ci	}
3782e5c31af7Sopenharmony_ci	else if (namedNonArrayBlock)
3783e5c31af7Sopenharmony_ci	{
3784e5c31af7Sopenharmony_ci		// .types
3785e5c31af7Sopenharmony_ci		{
3786e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
3787e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3788e5c31af7Sopenharmony_ci
3789e5c31af7Sopenharmony_ci			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3790e5c31af7Sopenharmony_ci			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
3791e5c31af7Sopenharmony_ci		}
3792e5c31af7Sopenharmony_ci
3793e5c31af7Sopenharmony_ci		// .aggregates
3794e5c31af7Sopenharmony_ci		{
3795e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
3796e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
3797e5c31af7Sopenharmony_ci
3798e5c31af7Sopenharmony_ci			// .float_array
3799e5c31af7Sopenharmony_ci			// .float_struct
3800e5c31af7Sopenharmony_ci			{
3801e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr structMember		(new ResourceDefinition::StructMember(parentStructure));
3802e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr arrayElement		(new ResourceDefinition::StructMember(parentStructure));
3803e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr memberVariable	(new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
3804e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr elementVariable	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
3805e5c31af7Sopenharmony_ci
3806e5c31af7Sopenharmony_ci				blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
3807e5c31af7Sopenharmony_ci				blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
3808e5c31af7Sopenharmony_ci			}
3809e5c31af7Sopenharmony_ci		}
3810e5c31af7Sopenharmony_ci	}
3811e5c31af7Sopenharmony_ci	else
3812e5c31af7Sopenharmony_ci	{
3813e5c31af7Sopenharmony_ci		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3814e5c31af7Sopenharmony_ci		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
3815e5c31af7Sopenharmony_ci		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
3816e5c31af7Sopenharmony_ci	}
3817e5c31af7Sopenharmony_ci}
3818e5c31af7Sopenharmony_ci
3819e5c31af7Sopenharmony_cistatic void generateMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool createTestGroup = true, int expandLevel = 2)
3820e5c31af7Sopenharmony_ci{
3821e5c31af7Sopenharmony_ci	static const struct
3822e5c31af7Sopenharmony_ci	{
3823e5c31af7Sopenharmony_ci		int				priority;
3824e5c31af7Sopenharmony_ci		glu::DataType	type;
3825e5c31af7Sopenharmony_ci	} variableTypes[] =
3826e5c31af7Sopenharmony_ci	{
3827e5c31af7Sopenharmony_ci		{ 0,	glu::TYPE_FLOAT_MAT2	},
3828e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_FLOAT_MAT2X3	},
3829e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT2X4	},
3830e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT3X2	},
3831e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_FLOAT_MAT3	},
3832e5c31af7Sopenharmony_ci		{ 0,	glu::TYPE_FLOAT_MAT3X4	},
3833e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT4X2	},
3834e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_FLOAT_MAT4X3	},
3835e5c31af7Sopenharmony_ci		{ 0,	glu::TYPE_FLOAT_MAT4	},
3836e5c31af7Sopenharmony_ci	};
3837e5c31af7Sopenharmony_ci
3838e5c31af7Sopenharmony_ci	tcu::TestCaseGroup* group;
3839e5c31af7Sopenharmony_ci
3840e5c31af7Sopenharmony_ci	if (createTestGroup)
3841e5c31af7Sopenharmony_ci	{
3842e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "matrix", "Basic matrix type");
3843e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
3844e5c31af7Sopenharmony_ci		group = blockGroup;
3845e5c31af7Sopenharmony_ci	}
3846e5c31af7Sopenharmony_ci	else
3847e5c31af7Sopenharmony_ci		group = targetGroup;
3848e5c31af7Sopenharmony_ci
3849e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
3850e5c31af7Sopenharmony_ci	{
3851e5c31af7Sopenharmony_ci		if (variableTypes[ndx].priority < expandLevel)
3852e5c31af7Sopenharmony_ci		{
3853e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
3854e5c31af7Sopenharmony_ci			group->addChild(new ResourceTestCase(context, variable, queryTarget));
3855e5c31af7Sopenharmony_ci		}
3856e5c31af7Sopenharmony_ci	}
3857e5c31af7Sopenharmony_ci}
3858e5c31af7Sopenharmony_ci
3859e5c31af7Sopenharmony_cistatic void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel);
3860e5c31af7Sopenharmony_ci
3861e5c31af7Sopenharmony_cistatic void generateMatrixArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3862e5c31af7Sopenharmony_ci{
3863e5c31af7Sopenharmony_ci	if (expandLevel > 0)
3864e5c31af7Sopenharmony_ci	{
3865e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
3866e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");
3867e5c31af7Sopenharmony_ci
3868e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
3869e5c31af7Sopenharmony_ci
3870e5c31af7Sopenharmony_ci		// Arrays of basic variables
3871e5c31af7Sopenharmony_ci		generateMatrixVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3872e5c31af7Sopenharmony_ci
3873e5c31af7Sopenharmony_ci		// Arrays of arrays
3874e5c31af7Sopenharmony_ci		generateMatrixArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3875e5c31af7Sopenharmony_ci
3876e5c31af7Sopenharmony_ci		// Arrays of structs
3877e5c31af7Sopenharmony_ci		generateMatrixStructCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
3878e5c31af7Sopenharmony_ci	}
3879e5c31af7Sopenharmony_ci}
3880e5c31af7Sopenharmony_ci
3881e5c31af7Sopenharmony_cistatic void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
3882e5c31af7Sopenharmony_ci{
3883e5c31af7Sopenharmony_ci	if (expandLevel > 0)
3884e5c31af7Sopenharmony_ci	{
3885e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
3886e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");
3887e5c31af7Sopenharmony_ci
3888e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
3889e5c31af7Sopenharmony_ci
3890e5c31af7Sopenharmony_ci		// Struct containing basic variable
3891e5c31af7Sopenharmony_ci		generateMatrixVariableCases(context, structMember, blockGroup, queryTarget, expandLevel != 1, expandLevel);
3892e5c31af7Sopenharmony_ci
3893e5c31af7Sopenharmony_ci		// Struct containing arrays
3894e5c31af7Sopenharmony_ci		generateMatrixArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3895e5c31af7Sopenharmony_ci
3896e5c31af7Sopenharmony_ci		// Struct containing struct
3897e5c31af7Sopenharmony_ci		generateMatrixStructCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
3898e5c31af7Sopenharmony_ci	}
3899e5c31af7Sopenharmony_ci}
3900e5c31af7Sopenharmony_ci
3901e5c31af7Sopenharmony_cistatic void generateUniformMatrixOrderCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3902e5c31af7Sopenharmony_ci{
3903e5c31af7Sopenharmony_ci	static const struct
3904e5c31af7Sopenharmony_ci	{
3905e5c31af7Sopenharmony_ci		const char*			name;
3906e5c31af7Sopenharmony_ci		glu::MatrixOrder	order;
3907e5c31af7Sopenharmony_ci	} qualifiers[] =
3908e5c31af7Sopenharmony_ci	{
3909e5c31af7Sopenharmony_ci		{ "no_qualifier",	glu::MATRIXORDER_LAST			},
3910e5c31af7Sopenharmony_ci		{ "row_major",		glu::MATRIXORDER_ROW_MAJOR		},
3911e5c31af7Sopenharmony_ci		{ "column_major",	glu::MATRIXORDER_COLUMN_MAJOR	},
3912e5c31af7Sopenharmony_ci	};
3913e5c31af7Sopenharmony_ci
3914e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR);
3915e5c31af7Sopenharmony_ci
3916e5c31af7Sopenharmony_ci	for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3917e5c31af7Sopenharmony_ci	{
3918e5c31af7Sopenharmony_ci		// Add layout qualifiers only for block members
3919e5c31af7Sopenharmony_ci		if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3920e5c31af7Sopenharmony_ci		{
3921e5c31af7Sopenharmony_ci			ResourceDefinition::Node::SharedPtr	subStructure	= parentStructure;
3922e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const			qualifierGroup	= new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3923e5c31af7Sopenharmony_ci
3924e5c31af7Sopenharmony_ci			targetGroup->addChild(qualifierGroup);
3925e5c31af7Sopenharmony_ci
3926e5c31af7Sopenharmony_ci			if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3927e5c31af7Sopenharmony_ci			{
3928e5c31af7Sopenharmony_ci				glu::Layout layout;
3929e5c31af7Sopenharmony_ci				layout.matrixOrder = qualifiers[qualifierNdx].order;
3930e5c31af7Sopenharmony_ci				subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3931e5c31af7Sopenharmony_ci			}
3932e5c31af7Sopenharmony_ci
3933e5c31af7Sopenharmony_ci			if (extendedBasicTypeCases && qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3934e5c31af7Sopenharmony_ci			{
3935e5c31af7Sopenharmony_ci				// .types
3936e5c31af7Sopenharmony_ci				{
3937e5c31af7Sopenharmony_ci					tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
3938e5c31af7Sopenharmony_ci					qualifierGroup->addChild(blockGroup);
3939e5c31af7Sopenharmony_ci
3940e5c31af7Sopenharmony_ci					generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
3941e5c31af7Sopenharmony_ci					generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
3942e5c31af7Sopenharmony_ci					if (opaqueCases)
3943e5c31af7Sopenharmony_ci						generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
3944e5c31af7Sopenharmony_ci				}
3945e5c31af7Sopenharmony_ci
3946e5c31af7Sopenharmony_ci				// .aggregates
3947e5c31af7Sopenharmony_ci				{
3948e5c31af7Sopenharmony_ci					tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
3949e5c31af7Sopenharmony_ci					qualifierGroup->addChild(blockGroup);
3950e5c31af7Sopenharmony_ci
3951e5c31af7Sopenharmony_ci					generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3952e5c31af7Sopenharmony_ci				}
3953e5c31af7Sopenharmony_ci			}
3954e5c31af7Sopenharmony_ci			else
3955e5c31af7Sopenharmony_ci			{
3956e5c31af7Sopenharmony_ci				generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
3957e5c31af7Sopenharmony_ci			}
3958e5c31af7Sopenharmony_ci		}
3959e5c31af7Sopenharmony_ci	}
3960e5c31af7Sopenharmony_ci}
3961e5c31af7Sopenharmony_ci
3962e5c31af7Sopenharmony_cistatic void generateUniformMatrixStrideCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
3963e5c31af7Sopenharmony_ci{
3964e5c31af7Sopenharmony_ci	static const struct
3965e5c31af7Sopenharmony_ci	{
3966e5c31af7Sopenharmony_ci		const char*			name;
3967e5c31af7Sopenharmony_ci		glu::MatrixOrder	order;
3968e5c31af7Sopenharmony_ci	} qualifiers[] =
3969e5c31af7Sopenharmony_ci	{
3970e5c31af7Sopenharmony_ci		{ "no_qualifier",	glu::MATRIXORDER_LAST			},
3971e5c31af7Sopenharmony_ci		{ "row_major",		glu::MATRIXORDER_ROW_MAJOR		},
3972e5c31af7Sopenharmony_ci		{ "column_major",	glu::MATRIXORDER_COLUMN_MAJOR	},
3973e5c31af7Sopenharmony_ci	};
3974e5c31af7Sopenharmony_ci
3975e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_STRIDE);
3976e5c31af7Sopenharmony_ci
3977e5c31af7Sopenharmony_ci	for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
3978e5c31af7Sopenharmony_ci	{
3979e5c31af7Sopenharmony_ci		// Add layout qualifiers only for block members
3980e5c31af7Sopenharmony_ci		if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
3981e5c31af7Sopenharmony_ci		{
3982e5c31af7Sopenharmony_ci			ResourceDefinition::Node::SharedPtr	subStructure	= parentStructure;
3983e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const			qualifierGroup	= new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");
3984e5c31af7Sopenharmony_ci
3985e5c31af7Sopenharmony_ci			targetGroup->addChild(qualifierGroup);
3986e5c31af7Sopenharmony_ci
3987e5c31af7Sopenharmony_ci			if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
3988e5c31af7Sopenharmony_ci			{
3989e5c31af7Sopenharmony_ci				glu::Layout layout;
3990e5c31af7Sopenharmony_ci				layout.matrixOrder = qualifiers[qualifierNdx].order;
3991e5c31af7Sopenharmony_ci				subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
3992e5c31af7Sopenharmony_ci			}
3993e5c31af7Sopenharmony_ci
3994e5c31af7Sopenharmony_ci			if (extendedBasicTypeCases)
3995e5c31af7Sopenharmony_ci			{
3996e5c31af7Sopenharmony_ci				// .types
3997e5c31af7Sopenharmony_ci				// .matrix
3998e5c31af7Sopenharmony_ci				if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
3999e5c31af7Sopenharmony_ci				{
4000e5c31af7Sopenharmony_ci					tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
4001e5c31af7Sopenharmony_ci					qualifierGroup->addChild(blockGroup);
4002e5c31af7Sopenharmony_ci
4003e5c31af7Sopenharmony_ci					generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
4004e5c31af7Sopenharmony_ci					generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
4005e5c31af7Sopenharmony_ci					if (opaqueCases)
4006e5c31af7Sopenharmony_ci						generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
4007e5c31af7Sopenharmony_ci				}
4008e5c31af7Sopenharmony_ci				else
4009e5c31af7Sopenharmony_ci					generateMatrixVariableCases(context, subStructure, qualifierGroup, queryTarget);
4010e5c31af7Sopenharmony_ci
4011e5c31af7Sopenharmony_ci				// .aggregates
4012e5c31af7Sopenharmony_ci				{
4013e5c31af7Sopenharmony_ci					tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
4014e5c31af7Sopenharmony_ci					qualifierGroup->addChild(blockGroup);
4015e5c31af7Sopenharmony_ci
4016e5c31af7Sopenharmony_ci					generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
4017e5c31af7Sopenharmony_ci				}
4018e5c31af7Sopenharmony_ci			}
4019e5c31af7Sopenharmony_ci			else
4020e5c31af7Sopenharmony_ci				generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
4021e5c31af7Sopenharmony_ci		}
4022e5c31af7Sopenharmony_ci	}
4023e5c31af7Sopenharmony_ci}
4024e5c31af7Sopenharmony_ci
4025e5c31af7Sopenharmony_cistatic void generateUniformMatrixCaseBlocks (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const, bool, bool))
4026e5c31af7Sopenharmony_ci{
4027e5c31af7Sopenharmony_ci	static const struct
4028e5c31af7Sopenharmony_ci	{
4029e5c31af7Sopenharmony_ci		const char*			name;
4030e5c31af7Sopenharmony_ci		const char*			description;
4031e5c31af7Sopenharmony_ci		bool				block;
4032e5c31af7Sopenharmony_ci		bool				namedBlock;
4033e5c31af7Sopenharmony_ci		bool				extendedBasicTypeCases;
4034e5c31af7Sopenharmony_ci		glu::MatrixOrder	order;
4035e5c31af7Sopenharmony_ci	} children[] =
4036e5c31af7Sopenharmony_ci	{
4037e5c31af7Sopenharmony_ci		{ "default_block",				"Default block",			false,	true,	true,	glu::MATRIXORDER_LAST			},
4038e5c31af7Sopenharmony_ci		{ "named_block",				"Named uniform block",		true,	true,	true,	glu::MATRIXORDER_LAST			},
4039e5c31af7Sopenharmony_ci		{ "named_block_row_major",		"Named uniform block",		true,	true,	false,	glu::MATRIXORDER_ROW_MAJOR		},
4040e5c31af7Sopenharmony_ci		{ "named_block_col_major",		"Named uniform block",		true,	true,	false,	glu::MATRIXORDER_COLUMN_MAJOR	},
4041e5c31af7Sopenharmony_ci		{ "unnamed_block",				"Unnamed uniform block",	true,	false,	false,	glu::MATRIXORDER_LAST			},
4042e5c31af7Sopenharmony_ci		{ "unnamed_block_row_major",	"Unnamed uniform block",	true,	false,	false,	glu::MATRIXORDER_ROW_MAJOR		},
4043e5c31af7Sopenharmony_ci		{ "unnamed_block_col_major",	"Unnamed uniform block",	true,	false,	false,	glu::MATRIXORDER_COLUMN_MAJOR	},
4044e5c31af7Sopenharmony_ci	};
4045e5c31af7Sopenharmony_ci
4046e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
4047e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr uniform		(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4048e5c31af7Sopenharmony_ci
4049e5c31af7Sopenharmony_ci	for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
4050e5c31af7Sopenharmony_ci	{
4051e5c31af7Sopenharmony_ci		ResourceDefinition::Node::SharedPtr	subStructure	= uniform;
4052e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const			blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), children[childNdx].name, children[childNdx].description);
4053e5c31af7Sopenharmony_ci		const bool							addOpaqueCases	= children[childNdx].extendedBasicTypeCases && !children[childNdx].block;
4054e5c31af7Sopenharmony_ci
4055e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
4056e5c31af7Sopenharmony_ci
4057e5c31af7Sopenharmony_ci		if (children[childNdx].order != glu::MATRIXORDER_LAST)
4058e5c31af7Sopenharmony_ci		{
4059e5c31af7Sopenharmony_ci			glu::Layout layout;
4060e5c31af7Sopenharmony_ci			layout.matrixOrder = children[childNdx].order;
4061e5c31af7Sopenharmony_ci			subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
4062e5c31af7Sopenharmony_ci		}
4063e5c31af7Sopenharmony_ci
4064e5c31af7Sopenharmony_ci		if (children[childNdx].block)
4065e5c31af7Sopenharmony_ci			subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(subStructure, children[childNdx].namedBlock));
4066e5c31af7Sopenharmony_ci
4067e5c31af7Sopenharmony_ci		blockContentGenerator(context, subStructure, blockGroup, children[childNdx].extendedBasicTypeCases, addOpaqueCases);
4068e5c31af7Sopenharmony_ci	}
4069e5c31af7Sopenharmony_ci}
4070e5c31af7Sopenharmony_ci
4071e5c31af7Sopenharmony_cistatic void generateBufferReferencedByShaderInterfaceBlockCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool extendedCases)
4072e5c31af7Sopenharmony_ci{
4073e5c31af7Sopenharmony_ci	const bool isDefaultBlock = (parentStructure->getType() != ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
4074e5c31af7Sopenharmony_ci
4075e5c31af7Sopenharmony_ci	// .float
4076e5c31af7Sopenharmony_ci	// .float_array
4077e5c31af7Sopenharmony_ci	// .float_struct
4078e5c31af7Sopenharmony_ci	{
4079e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT));
4080e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
4081e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
4082e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4083e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variableStruct	(new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4084e5c31af7Sopenharmony_ci
4085e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "float"));
4086e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_array"));
4087e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "float_struct"));
4088e5c31af7Sopenharmony_ci	}
4089e5c31af7Sopenharmony_ci
4090e5c31af7Sopenharmony_ci	// .sampler
4091e5c31af7Sopenharmony_ci	// .sampler_array
4092e5c31af7Sopenharmony_ci	// .sampler_struct
4093e5c31af7Sopenharmony_ci	if (isDefaultBlock)
4094e5c31af7Sopenharmony_ci	{
4095e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	layout			(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4096e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(layout, glu::TYPE_SAMPLER_2D));
4097e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(layout));
4098e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
4099e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_SAMPLER_2D));
4100e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variableStruct	(new ResourceDefinition::Variable(structMember, glu::TYPE_SAMPLER_2D));
4101e5c31af7Sopenharmony_ci
4102e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "sampler"));
4103e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "sampler_array"));
4104e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "sampler_struct"));
4105e5c31af7Sopenharmony_ci	}
4106e5c31af7Sopenharmony_ci
4107e5c31af7Sopenharmony_ci	// .atomic_uint
4108e5c31af7Sopenharmony_ci	// .atomic_uint_array
4109e5c31af7Sopenharmony_ci	if (isDefaultBlock)
4110e5c31af7Sopenharmony_ci	{
4111e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	layout			(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
4112e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(layout, glu::TYPE_UINT_ATOMIC_COUNTER));
4113e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(layout));
4114e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
4115e5c31af7Sopenharmony_ci
4116e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "atomic_uint"));
4117e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "atomic_uint_array"));
4118e5c31af7Sopenharmony_ci	}
4119e5c31af7Sopenharmony_ci
4120e5c31af7Sopenharmony_ci	if (extendedCases)
4121e5c31af7Sopenharmony_ci	{
4122e5c31af7Sopenharmony_ci		// .float_array_struct
4123e5c31af7Sopenharmony_ci		{
4124e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	structMember		(new ResourceDefinition::StructMember(parentStructure));
4125e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElement		(new ResourceDefinition::ArrayElement(structMember));
4126e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	variableArrayStruct	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4127e5c31af7Sopenharmony_ci
4128e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_struct"));
4129e5c31af7Sopenharmony_ci		}
4130e5c31af7Sopenharmony_ci
4131e5c31af7Sopenharmony_ci		// .float_struct_array
4132e5c31af7Sopenharmony_ci		{
4133e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElement		(new ResourceDefinition::ArrayElement(parentStructure));
4134e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayStructMember	(new ResourceDefinition::StructMember(arrayElement));
4135e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	variableArrayStruct	(new ResourceDefinition::Variable(arrayStructMember, glu::TYPE_FLOAT));
4136e5c31af7Sopenharmony_ci
4137e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_array"));
4138e5c31af7Sopenharmony_ci		}
4139e5c31af7Sopenharmony_ci
4140e5c31af7Sopenharmony_ci		// .float_array_array
4141e5c31af7Sopenharmony_ci		{
4142e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElement		(new ResourceDefinition::ArrayElement(parentStructure));
4143e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	subArrayElement		(new ResourceDefinition::ArrayElement(arrayElement));
4144e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	variableArrayStruct	(new ResourceDefinition::Variable(subArrayElement, glu::TYPE_FLOAT));
4145e5c31af7Sopenharmony_ci
4146e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_array"));
4147e5c31af7Sopenharmony_ci		}
4148e5c31af7Sopenharmony_ci
4149e5c31af7Sopenharmony_ci		// .float_struct_struct
4150e5c31af7Sopenharmony_ci		{
4151e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	structMember		(new ResourceDefinition::StructMember(parentStructure));
4152e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	subStructMember		(new ResourceDefinition::StructMember(structMember));
4153e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	variableArrayStruct	(new ResourceDefinition::Variable(subStructMember, glu::TYPE_FLOAT));
4154e5c31af7Sopenharmony_ci
4155e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_struct"));
4156e5c31af7Sopenharmony_ci		}
4157e5c31af7Sopenharmony_ci
4158e5c31af7Sopenharmony_ci		if (queryTarget.interface == PROGRAMINTERFACE_BUFFER_VARIABLE)
4159e5c31af7Sopenharmony_ci		{
4160e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4161e5c31af7Sopenharmony_ci
4162e5c31af7Sopenharmony_ci			// .float_unsized_array
4163e5c31af7Sopenharmony_ci			{
4164e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
4165e5c31af7Sopenharmony_ci
4166e5c31af7Sopenharmony_ci				targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_array"));
4167e5c31af7Sopenharmony_ci			}
4168e5c31af7Sopenharmony_ci
4169e5c31af7Sopenharmony_ci			// .float_unsized_struct_array
4170e5c31af7Sopenharmony_ci			{
4171e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(arrayElement));
4172e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
4173e5c31af7Sopenharmony_ci
4174e5c31af7Sopenharmony_ci				targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_struct_array"));
4175e5c31af7Sopenharmony_ci			}
4176e5c31af7Sopenharmony_ci		}
4177e5c31af7Sopenharmony_ci	}
4178e5c31af7Sopenharmony_ci}
4179e5c31af7Sopenharmony_ci
4180e5c31af7Sopenharmony_cistatic void generateUniformReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, int expandLevel)
4181e5c31af7Sopenharmony_ci{
4182e5c31af7Sopenharmony_ci	DE_UNREF(expandLevel);
4183e5c31af7Sopenharmony_ci
4184e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(parentStructure));
4185e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	uniform				(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4186e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget		queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
4187e5c31af7Sopenharmony_ci	const bool									singleShaderCase	= parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
4188e5c31af7Sopenharmony_ci
4189e5c31af7Sopenharmony_ci	// .default_block
4190e5c31af7Sopenharmony_ci	{
4191e5c31af7Sopenharmony_ci		TestCaseGroup* const blockGroup = new TestCaseGroup(context, "default_block", "");
4192e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
4193e5c31af7Sopenharmony_ci
4194e5c31af7Sopenharmony_ci		generateBufferReferencedByShaderInterfaceBlockCases(context, uniform, blockGroup, queryTarget, singleShaderCase);
4195e5c31af7Sopenharmony_ci	}
4196e5c31af7Sopenharmony_ci
4197e5c31af7Sopenharmony_ci	// .named_block
4198e5c31af7Sopenharmony_ci	{
4199e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(uniform, true));
4200e5c31af7Sopenharmony_ci		TestCaseGroup* const						blockGroup	= new TestCaseGroup(context, "uniform_block", "");
4201e5c31af7Sopenharmony_ci
4202e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
4203e5c31af7Sopenharmony_ci
4204e5c31af7Sopenharmony_ci		generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, singleShaderCase);
4205e5c31af7Sopenharmony_ci	}
4206e5c31af7Sopenharmony_ci
4207e5c31af7Sopenharmony_ci	// .unnamed_block
4208e5c31af7Sopenharmony_ci	{
4209e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(uniform, false));
4210e5c31af7Sopenharmony_ci		TestCaseGroup* const						blockGroup	= new TestCaseGroup(context, "unnamed_block", "");
4211e5c31af7Sopenharmony_ci
4212e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
4213e5c31af7Sopenharmony_ci
4214e5c31af7Sopenharmony_ci		generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4215e5c31af7Sopenharmony_ci	}
4216e5c31af7Sopenharmony_ci
4217e5c31af7Sopenharmony_ci	// .block_array
4218e5c31af7Sopenharmony_ci	{
4219e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(uniform));
4220e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
4221e5c31af7Sopenharmony_ci		TestCaseGroup* const						blockGroup		= new TestCaseGroup(context, "block_array", "");
4222e5c31af7Sopenharmony_ci
4223e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
4224e5c31af7Sopenharmony_ci
4225e5c31af7Sopenharmony_ci		generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
4226e5c31af7Sopenharmony_ci	}
4227e5c31af7Sopenharmony_ci}
4228e5c31af7Sopenharmony_ci
4229e5c31af7Sopenharmony_cistatic void generateReferencedByShaderCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, void (*generateBlockContent)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, int expandLevel))
4230e5c31af7Sopenharmony_ci{
4231e5c31af7Sopenharmony_ci	static const struct
4232e5c31af7Sopenharmony_ci	{
4233e5c31af7Sopenharmony_ci		const char*		name;
4234e5c31af7Sopenharmony_ci		glu::ShaderType	stage;
4235e5c31af7Sopenharmony_ci		int				expandLevel;
4236e5c31af7Sopenharmony_ci	} singleStageCases[] =
4237e5c31af7Sopenharmony_ci	{
4238e5c31af7Sopenharmony_ci		{ "compute",				glu::SHADERTYPE_COMPUTE,					3	},
4239e5c31af7Sopenharmony_ci		{ "separable_vertex",		glu::SHADERTYPE_VERTEX,						2	},
4240e5c31af7Sopenharmony_ci		{ "separable_fragment",		glu::SHADERTYPE_FRAGMENT,					2	},
4241e5c31af7Sopenharmony_ci		{ "separable_tess_ctrl",	glu::SHADERTYPE_TESSELLATION_CONTROL,		2	},
4242e5c31af7Sopenharmony_ci		{ "separable_tess_eval",	glu::SHADERTYPE_TESSELLATION_EVALUATION,	2	},
4243e5c31af7Sopenharmony_ci		{ "separable_geometry",		glu::SHADERTYPE_GEOMETRY,					2	},
4244e5c31af7Sopenharmony_ci	};
4245e5c31af7Sopenharmony_ci	static const struct
4246e5c31af7Sopenharmony_ci	{
4247e5c31af7Sopenharmony_ci		const char*	name;
4248e5c31af7Sopenharmony_ci		deUint32	flags;
4249e5c31af7Sopenharmony_ci		int			expandLevel;
4250e5c31af7Sopenharmony_ci		int			subExpandLevel;
4251e5c31af7Sopenharmony_ci	} pipelines[] =
4252e5c31af7Sopenharmony_ci	{
4253e5c31af7Sopenharmony_ci		{
4254e5c31af7Sopenharmony_ci			"vertex_fragment",
4255e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
4256e5c31af7Sopenharmony_ci			3,
4257e5c31af7Sopenharmony_ci			2,
4258e5c31af7Sopenharmony_ci		},
4259e5c31af7Sopenharmony_ci		{
4260e5c31af7Sopenharmony_ci			"vertex_tess_fragment",
4261e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
4262e5c31af7Sopenharmony_ci			2,
4263e5c31af7Sopenharmony_ci			2,
4264e5c31af7Sopenharmony_ci		},
4265e5c31af7Sopenharmony_ci		{
4266e5c31af7Sopenharmony_ci			"vertex_geo_fragment",
4267e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
4268e5c31af7Sopenharmony_ci			2,
4269e5c31af7Sopenharmony_ci			2,
4270e5c31af7Sopenharmony_ci		},
4271e5c31af7Sopenharmony_ci		{
4272e5c31af7Sopenharmony_ci			"vertex_tess_geo_fragment",
4273e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
4274e5c31af7Sopenharmony_ci			2,
4275e5c31af7Sopenharmony_ci			1,
4276e5c31af7Sopenharmony_ci		},
4277e5c31af7Sopenharmony_ci	};
4278e5c31af7Sopenharmony_ci
4279e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
4280e5c31af7Sopenharmony_ci	{
4281e5c31af7Sopenharmony_ci		TestCaseGroup* const						blockGroup			= new TestCaseGroup(context, singleStageCases[ndx].name, "");
4282e5c31af7Sopenharmony_ci		const bool									programSeparable	= (singleStageCases[ndx].stage != glu::SHADERTYPE_COMPUTE);
4283e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program(programSeparable));
4284e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	stage				(new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
4285e5c31af7Sopenharmony_ci
4286e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
4287e5c31af7Sopenharmony_ci
4288e5c31af7Sopenharmony_ci		generateBlockContent(context, stage, blockGroup, singleStageCases[ndx].expandLevel);
4289e5c31af7Sopenharmony_ci	}
4290e5c31af7Sopenharmony_ci
4291e5c31af7Sopenharmony_ci	for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
4292e5c31af7Sopenharmony_ci	{
4293e5c31af7Sopenharmony_ci		// whole pipeline
4294e5c31af7Sopenharmony_ci		{
4295e5c31af7Sopenharmony_ci			TestCaseGroup* const						blockGroup			= new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
4296e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program());
4297e5c31af7Sopenharmony_ci			ResourceDefinition::ShaderSet*				shaderSet			= new ResourceDefinition::ShaderSet(program,
4298e5c31af7Sopenharmony_ci																												glslVersion,
4299e5c31af7Sopenharmony_ci																												pipelines[pipelineNdx].flags,
4300e5c31af7Sopenharmony_ci																												pipelines[pipelineNdx].flags);
4301e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
4302e5c31af7Sopenharmony_ci
4303e5c31af7Sopenharmony_ci			{
4304e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr shaders(shaderSet);
4305e5c31af7Sopenharmony_ci				generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].expandLevel);
4306e5c31af7Sopenharmony_ci			}
4307e5c31af7Sopenharmony_ci		}
4308e5c31af7Sopenharmony_ci
4309e5c31af7Sopenharmony_ci		// only one stage
4310e5c31af7Sopenharmony_ci		for (int selectedStageBit = 0; selectedStageBit < glu::SHADERTYPE_LAST; ++selectedStageBit)
4311e5c31af7Sopenharmony_ci		{
4312e5c31af7Sopenharmony_ci			if (pipelines[pipelineNdx].flags & (1 << selectedStageBit))
4313e5c31af7Sopenharmony_ci			{
4314e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program());
4315e5c31af7Sopenharmony_ci				ResourceDefinition::ShaderSet*				shaderSet	= new ResourceDefinition::ShaderSet(program,
4316e5c31af7Sopenharmony_ci																											glslVersion,
4317e5c31af7Sopenharmony_ci																											pipelines[pipelineNdx].flags,
4318e5c31af7Sopenharmony_ci																											(1u << selectedStageBit));
4319e5c31af7Sopenharmony_ci				const char*									stageName	= (selectedStageBit == glu::SHADERTYPE_VERTEX)					? ("vertex")
4320e5c31af7Sopenharmony_ci																		: (selectedStageBit == glu::SHADERTYPE_FRAGMENT)				? ("fragment")
4321e5c31af7Sopenharmony_ci																		: (selectedStageBit == glu::SHADERTYPE_GEOMETRY)				? ("geo")
4322e5c31af7Sopenharmony_ci																		: (selectedStageBit == glu::SHADERTYPE_TESSELLATION_CONTROL)	? ("tess_ctrl")
4323e5c31af7Sopenharmony_ci																		: (selectedStageBit == glu::SHADERTYPE_TESSELLATION_EVALUATION)	? ("tess_eval")
4324e5c31af7Sopenharmony_ci																		: (DE_NULL);
4325e5c31af7Sopenharmony_ci				const std::string							setName		= std::string() + pipelines[pipelineNdx].name + "_only_" + stageName;
4326e5c31af7Sopenharmony_ci				TestCaseGroup* const						blockGroup	= new TestCaseGroup(context, setName.c_str(), "");
4327e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	shaders		(shaderSet);
4328e5c31af7Sopenharmony_ci
4329e5c31af7Sopenharmony_ci				generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].subExpandLevel);
4330e5c31af7Sopenharmony_ci				targetGroup->addChild(blockGroup);
4331e5c31af7Sopenharmony_ci			}
4332e5c31af7Sopenharmony_ci		}
4333e5c31af7Sopenharmony_ci	}
4334e5c31af7Sopenharmony_ci}
4335e5c31af7Sopenharmony_ci
4336e5c31af7Sopenharmony_cistatic glu::DataType generateRandomDataType (de::Random& rnd, bool excludeOpaqueTypes)
4337e5c31af7Sopenharmony_ci{
4338e5c31af7Sopenharmony_ci	static const glu::DataType s_types[] =
4339e5c31af7Sopenharmony_ci	{
4340e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT,
4341e5c31af7Sopenharmony_ci		glu::TYPE_INT,
4342e5c31af7Sopenharmony_ci		glu::TYPE_UINT,
4343e5c31af7Sopenharmony_ci		glu::TYPE_BOOL,
4344e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_VEC2,
4345e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_VEC3,
4346e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_VEC4,
4347e5c31af7Sopenharmony_ci		glu::TYPE_INT_VEC2,
4348e5c31af7Sopenharmony_ci		glu::TYPE_INT_VEC3,
4349e5c31af7Sopenharmony_ci		glu::TYPE_INT_VEC4,
4350e5c31af7Sopenharmony_ci		glu::TYPE_UINT_VEC2,
4351e5c31af7Sopenharmony_ci		glu::TYPE_UINT_VEC3,
4352e5c31af7Sopenharmony_ci		glu::TYPE_UINT_VEC4,
4353e5c31af7Sopenharmony_ci		glu::TYPE_BOOL_VEC2,
4354e5c31af7Sopenharmony_ci		glu::TYPE_BOOL_VEC3,
4355e5c31af7Sopenharmony_ci		glu::TYPE_BOOL_VEC4,
4356e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT2,
4357e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT2X3,
4358e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT2X4,
4359e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT3X2,
4360e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT3,
4361e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT3X4,
4362e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT4X2,
4363e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT4X3,
4364e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT4,
4365e5c31af7Sopenharmony_ci
4366e5c31af7Sopenharmony_ci		glu::TYPE_SAMPLER_2D,
4367e5c31af7Sopenharmony_ci		glu::TYPE_SAMPLER_CUBE,
4368e5c31af7Sopenharmony_ci		glu::TYPE_SAMPLER_2D_ARRAY,
4369e5c31af7Sopenharmony_ci		glu::TYPE_SAMPLER_3D,
4370e5c31af7Sopenharmony_ci		glu::TYPE_SAMPLER_2D_SHADOW,
4371e5c31af7Sopenharmony_ci		glu::TYPE_SAMPLER_CUBE_SHADOW,
4372e5c31af7Sopenharmony_ci		glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
4373e5c31af7Sopenharmony_ci		glu::TYPE_INT_SAMPLER_2D,
4374e5c31af7Sopenharmony_ci		glu::TYPE_INT_SAMPLER_CUBE,
4375e5c31af7Sopenharmony_ci		glu::TYPE_INT_SAMPLER_2D_ARRAY,
4376e5c31af7Sopenharmony_ci		glu::TYPE_INT_SAMPLER_3D,
4377e5c31af7Sopenharmony_ci		glu::TYPE_UINT_SAMPLER_2D,
4378e5c31af7Sopenharmony_ci		glu::TYPE_UINT_SAMPLER_CUBE,
4379e5c31af7Sopenharmony_ci		glu::TYPE_UINT_SAMPLER_2D_ARRAY,
4380e5c31af7Sopenharmony_ci		glu::TYPE_UINT_SAMPLER_3D,
4381e5c31af7Sopenharmony_ci		glu::TYPE_SAMPLER_2D_MULTISAMPLE,
4382e5c31af7Sopenharmony_ci		glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE,
4383e5c31af7Sopenharmony_ci		glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE,
4384e5c31af7Sopenharmony_ci		glu::TYPE_IMAGE_2D,
4385e5c31af7Sopenharmony_ci		glu::TYPE_IMAGE_CUBE,
4386e5c31af7Sopenharmony_ci		glu::TYPE_IMAGE_2D_ARRAY,
4387e5c31af7Sopenharmony_ci		glu::TYPE_IMAGE_3D,
4388e5c31af7Sopenharmony_ci		glu::TYPE_INT_IMAGE_2D,
4389e5c31af7Sopenharmony_ci		glu::TYPE_INT_IMAGE_CUBE,
4390e5c31af7Sopenharmony_ci		glu::TYPE_INT_IMAGE_2D_ARRAY,
4391e5c31af7Sopenharmony_ci		glu::TYPE_INT_IMAGE_3D,
4392e5c31af7Sopenharmony_ci		glu::TYPE_UINT_IMAGE_2D,
4393e5c31af7Sopenharmony_ci		glu::TYPE_UINT_IMAGE_CUBE,
4394e5c31af7Sopenharmony_ci		glu::TYPE_UINT_IMAGE_2D_ARRAY,
4395e5c31af7Sopenharmony_ci		glu::TYPE_UINT_IMAGE_3D,
4396e5c31af7Sopenharmony_ci		glu::TYPE_UINT_ATOMIC_COUNTER
4397e5c31af7Sopenharmony_ci	};
4398e5c31af7Sopenharmony_ci
4399e5c31af7Sopenharmony_ci	for (;;)
4400e5c31af7Sopenharmony_ci	{
4401e5c31af7Sopenharmony_ci		const glu::DataType type = s_types[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_types)-1)];
4402e5c31af7Sopenharmony_ci
4403e5c31af7Sopenharmony_ci		if (!excludeOpaqueTypes					||
4404e5c31af7Sopenharmony_ci			glu::isDataTypeScalarOrVector(type)	||
4405e5c31af7Sopenharmony_ci			glu::isDataTypeMatrix(type))
4406e5c31af7Sopenharmony_ci			return type;
4407e5c31af7Sopenharmony_ci	}
4408e5c31af7Sopenharmony_ci}
4409e5c31af7Sopenharmony_ci
4410e5c31af7Sopenharmony_cistatic ResourceDefinition::Node::SharedPtr generateRandomVariableDefinition (de::Random&								rnd,
4411e5c31af7Sopenharmony_ci																			 const ResourceDefinition::Node::SharedPtr&	parentStructure,
4412e5c31af7Sopenharmony_ci																			 glu::DataType								baseType,
4413e5c31af7Sopenharmony_ci																			 const glu::Layout&							layout,
4414e5c31af7Sopenharmony_ci																			 bool										allowUnsized)
4415e5c31af7Sopenharmony_ci{
4416e5c31af7Sopenharmony_ci	const int							maxNesting			= 4;
4417e5c31af7Sopenharmony_ci	ResourceDefinition::Node::SharedPtr	currentStructure	= parentStructure;
4418e5c31af7Sopenharmony_ci	const bool							canBeInsideAStruct	= layout.binding == -1 && !isDataTypeLayoutQualified(baseType);
4419e5c31af7Sopenharmony_ci
4420e5c31af7Sopenharmony_ci	for (int nestNdx = 0; nestNdx < maxNesting; ++nestNdx)
4421e5c31af7Sopenharmony_ci	{
4422e5c31af7Sopenharmony_ci		if (allowUnsized && nestNdx == 0 && rnd.getFloat() < 0.2)
4423e5c31af7Sopenharmony_ci			currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
4424e5c31af7Sopenharmony_ci		else if (rnd.getFloat() < 0.3 && canBeInsideAStruct)
4425e5c31af7Sopenharmony_ci			currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StructMember(currentStructure));
4426e5c31af7Sopenharmony_ci		else if (rnd.getFloat() < 0.3)
4427e5c31af7Sopenharmony_ci			currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4428e5c31af7Sopenharmony_ci		else
4429e5c31af7Sopenharmony_ci			break;
4430e5c31af7Sopenharmony_ci	}
4431e5c31af7Sopenharmony_ci
4432e5c31af7Sopenharmony_ci	return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Variable(currentStructure, baseType));
4433e5c31af7Sopenharmony_ci}
4434e5c31af7Sopenharmony_ci
4435e5c31af7Sopenharmony_cistatic ResourceDefinition::Node::SharedPtr generateRandomCoreShaderSet (de::Random& rnd, glu::GLSLVersion glslVersion)
4436e5c31af7Sopenharmony_ci{
4437e5c31af7Sopenharmony_ci	if (rnd.getFloat() < 0.5f)
4438e5c31af7Sopenharmony_ci	{
4439e5c31af7Sopenharmony_ci		// compute only
4440e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
4441e5c31af7Sopenharmony_ci		return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4442e5c31af7Sopenharmony_ci	}
4443e5c31af7Sopenharmony_ci	else if (rnd.getFloat() < 0.5f)
4444e5c31af7Sopenharmony_ci	{
4445e5c31af7Sopenharmony_ci		// vertex and fragment
4446e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program());
4447e5c31af7Sopenharmony_ci		ResourceDefinition::ShaderSet*				shaderSet	= new ResourceDefinition::ShaderSet(program, glslVersion);
4448e5c31af7Sopenharmony_ci
4449e5c31af7Sopenharmony_ci		if (rnd.getBool())
4450e5c31af7Sopenharmony_ci		{
4451e5c31af7Sopenharmony_ci			shaderSet->setStage(glu::SHADERTYPE_VERTEX, true);
4452e5c31af7Sopenharmony_ci			shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4453e5c31af7Sopenharmony_ci		}
4454e5c31af7Sopenharmony_ci		else
4455e5c31af7Sopenharmony_ci		{
4456e5c31af7Sopenharmony_ci			shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4457e5c31af7Sopenharmony_ci			shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, true);
4458e5c31af7Sopenharmony_ci		}
4459e5c31af7Sopenharmony_ci
4460e5c31af7Sopenharmony_ci		return ResourceDefinition::Node::SharedPtr(shaderSet);
4461e5c31af7Sopenharmony_ci	}
4462e5c31af7Sopenharmony_ci	else
4463e5c31af7Sopenharmony_ci	{
4464e5c31af7Sopenharmony_ci		// separate vertex or fragment
4465e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program(true));
4466e5c31af7Sopenharmony_ci		const glu::ShaderType						shaderType	= (rnd.getBool()) ? (glu::SHADERTYPE_VERTEX) : (glu::SHADERTYPE_FRAGMENT);
4467e5c31af7Sopenharmony_ci
4468e5c31af7Sopenharmony_ci		return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glslVersion));
4469e5c31af7Sopenharmony_ci	}
4470e5c31af7Sopenharmony_ci}
4471e5c31af7Sopenharmony_ci
4472e5c31af7Sopenharmony_cistatic ResourceDefinition::Node::SharedPtr generateRandomExtShaderSet (de::Random& rnd, glu::GLSLVersion glslVersion)
4473e5c31af7Sopenharmony_ci{
4474e5c31af7Sopenharmony_ci	if (rnd.getFloat() < 0.5f)
4475e5c31af7Sopenharmony_ci	{
4476e5c31af7Sopenharmony_ci		// whole pipeline
4477e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program());
4478e5c31af7Sopenharmony_ci		ResourceDefinition::ShaderSet*				shaderSet	= new ResourceDefinition::ShaderSet(program, glslVersion);
4479e5c31af7Sopenharmony_ci
4480e5c31af7Sopenharmony_ci		shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
4481e5c31af7Sopenharmony_ci		shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
4482e5c31af7Sopenharmony_ci
4483e5c31af7Sopenharmony_ci		// tess shader are either both or neither present. Make cases interesting
4484e5c31af7Sopenharmony_ci		// by forcing one extended shader to always have reference
4485e5c31af7Sopenharmony_ci		if (rnd.getBool())
4486e5c31af7Sopenharmony_ci		{
4487e5c31af7Sopenharmony_ci			shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, true);
4488e5c31af7Sopenharmony_ci
4489e5c31af7Sopenharmony_ci			if (rnd.getBool())
4490e5c31af7Sopenharmony_ci			{
4491e5c31af7Sopenharmony_ci				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4492e5c31af7Sopenharmony_ci				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4493e5c31af7Sopenharmony_ci			}
4494e5c31af7Sopenharmony_ci		}
4495e5c31af7Sopenharmony_ci		else
4496e5c31af7Sopenharmony_ci		{
4497e5c31af7Sopenharmony_ci			shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, rnd.getBool());
4498e5c31af7Sopenharmony_ci
4499e5c31af7Sopenharmony_ci			if (rnd.getBool())
4500e5c31af7Sopenharmony_ci			{
4501e5c31af7Sopenharmony_ci				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, true);
4502e5c31af7Sopenharmony_ci				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
4503e5c31af7Sopenharmony_ci			}
4504e5c31af7Sopenharmony_ci			else
4505e5c31af7Sopenharmony_ci			{
4506e5c31af7Sopenharmony_ci				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
4507e5c31af7Sopenharmony_ci				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, true);
4508e5c31af7Sopenharmony_ci			}
4509e5c31af7Sopenharmony_ci		}
4510e5c31af7Sopenharmony_ci
4511e5c31af7Sopenharmony_ci		return ResourceDefinition::Node::SharedPtr(shaderSet);
4512e5c31af7Sopenharmony_ci	}
4513e5c31af7Sopenharmony_ci	else
4514e5c31af7Sopenharmony_ci	{
4515e5c31af7Sopenharmony_ci		// separate
4516e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program(true));
4517e5c31af7Sopenharmony_ci		const int									selector	= rnd.getInt(0, 2);
4518e5c31af7Sopenharmony_ci		const glu::ShaderType						shaderType	= (selector == 0) ? (glu::SHADERTYPE_GEOMETRY)
4519e5c31af7Sopenharmony_ci																: (selector == 1) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
4520e5c31af7Sopenharmony_ci																: (selector == 2) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
4521e5c31af7Sopenharmony_ci																:					(glu::SHADERTYPE_LAST);
4522e5c31af7Sopenharmony_ci
4523e5c31af7Sopenharmony_ci		return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glslVersion));
4524e5c31af7Sopenharmony_ci	}
4525e5c31af7Sopenharmony_ci}
4526e5c31af7Sopenharmony_ci
4527e5c31af7Sopenharmony_cistatic ResourceDefinition::Node::SharedPtr generateRandomShaderSet (de::Random& rnd, glu::GLSLVersion glslVersion, bool onlyExtensionStages)
4528e5c31af7Sopenharmony_ci{
4529e5c31af7Sopenharmony_ci	if (!onlyExtensionStages)
4530e5c31af7Sopenharmony_ci		return generateRandomCoreShaderSet(rnd, glslVersion);
4531e5c31af7Sopenharmony_ci	else
4532e5c31af7Sopenharmony_ci		return generateRandomExtShaderSet(rnd, glslVersion);
4533e5c31af7Sopenharmony_ci}
4534e5c31af7Sopenharmony_ci
4535e5c31af7Sopenharmony_cistatic glu::Layout generateRandomUniformBlockLayout (de::Random& rnd)
4536e5c31af7Sopenharmony_ci{
4537e5c31af7Sopenharmony_ci	glu::Layout layout;
4538e5c31af7Sopenharmony_ci
4539e5c31af7Sopenharmony_ci	if (rnd.getBool())
4540e5c31af7Sopenharmony_ci		layout.binding = rnd.getInt(0, 5);
4541e5c31af7Sopenharmony_ci
4542e5c31af7Sopenharmony_ci	if (rnd.getBool())
4543e5c31af7Sopenharmony_ci		layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4544e5c31af7Sopenharmony_ci
4545e5c31af7Sopenharmony_ci	return layout;
4546e5c31af7Sopenharmony_ci}
4547e5c31af7Sopenharmony_ci
4548e5c31af7Sopenharmony_cistatic glu::Layout generateRandomBufferBlockLayout (de::Random& rnd)
4549e5c31af7Sopenharmony_ci{
4550e5c31af7Sopenharmony_ci	return generateRandomUniformBlockLayout(rnd);
4551e5c31af7Sopenharmony_ci}
4552e5c31af7Sopenharmony_ci
4553e5c31af7Sopenharmony_cistatic glu::Layout generateRandomVariableLayout (de::Random& rnd, glu::DataType type, bool interfaceBlockMember)
4554e5c31af7Sopenharmony_ci{
4555e5c31af7Sopenharmony_ci	glu::Layout layout;
4556e5c31af7Sopenharmony_ci
4557e5c31af7Sopenharmony_ci	if ((glu::isDataTypeAtomicCounter(type) || glu::isDataTypeImage(type) || glu::isDataTypeSampler(type)) && rnd.getBool())
4558e5c31af7Sopenharmony_ci		layout.binding = rnd.getInt(0, 5);
4559e5c31af7Sopenharmony_ci
4560e5c31af7Sopenharmony_ci	if (glu::isDataTypeAtomicCounter(type) && rnd.getBool())
4561e5c31af7Sopenharmony_ci		layout.offset = rnd.getInt(0, 3) * 4;
4562e5c31af7Sopenharmony_ci
4563e5c31af7Sopenharmony_ci	if (glu::isDataTypeMatrix(type) && interfaceBlockMember && rnd.getBool())
4564e5c31af7Sopenharmony_ci		layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);
4565e5c31af7Sopenharmony_ci
4566e5c31af7Sopenharmony_ci	return layout;
4567e5c31af7Sopenharmony_ci}
4568e5c31af7Sopenharmony_ci
4569e5c31af7Sopenharmony_cistatic void generateUniformRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
4570e5c31af7Sopenharmony_ci{
4571e5c31af7Sopenharmony_ci	de::Random									rnd					(index * 0x12345);
4572e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	shader				= generateRandomShaderSet(rnd, glslVersion, onlyExtensionStages);
4573e5c31af7Sopenharmony_ci	const bool									interfaceBlock		= rnd.getBool();
4574e5c31af7Sopenharmony_ci	const glu::DataType							type				= generateRandomDataType(rnd, interfaceBlock);
4575e5c31af7Sopenharmony_ci	const glu::Layout							layout				= generateRandomVariableLayout(rnd, type, interfaceBlock);
4576e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));
4577e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	uniform				(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
4578e5c31af7Sopenharmony_ci	ResourceDefinition::Node::SharedPtr			currentStructure	= uniform;
4579e5c31af7Sopenharmony_ci
4580e5c31af7Sopenharmony_ci	if (interfaceBlock)
4581e5c31af7Sopenharmony_ci	{
4582e5c31af7Sopenharmony_ci		const bool namedBlock = rnd.getBool();
4583e5c31af7Sopenharmony_ci
4584e5c31af7Sopenharmony_ci		currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, generateRandomUniformBlockLayout(rnd)));
4585e5c31af7Sopenharmony_ci
4586e5c31af7Sopenharmony_ci		if (namedBlock && rnd.getBool())
4587e5c31af7Sopenharmony_ci			currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
4588e5c31af7Sopenharmony_ci
4589e5c31af7Sopenharmony_ci		currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
4590e5c31af7Sopenharmony_ci	}
4591e5c31af7Sopenharmony_ci
4592e5c31af7Sopenharmony_ci	currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
4593e5c31af7Sopenharmony_ci	currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, false);
4594e5c31af7Sopenharmony_ci
4595e5c31af7Sopenharmony_ci	targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK), de::toString(index).c_str()));
4596e5c31af7Sopenharmony_ci}
4597e5c31af7Sopenharmony_ci
4598e5c31af7Sopenharmony_cistatic void generateUniformCaseRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion)
4599e5c31af7Sopenharmony_ci{
4600e5c31af7Sopenharmony_ci	const int numBasicCases		= 40;
4601e5c31af7Sopenharmony_ci	const int numTessGeoCases	= 40;
4602e5c31af7Sopenharmony_ci
4603e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < numBasicCases; ++ndx)
4604e5c31af7Sopenharmony_ci		generateUniformRandomCase(context, targetGroup, glslVersion, ndx, false);
4605e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
4606e5c31af7Sopenharmony_ci		generateUniformRandomCase(context, targetGroup, glslVersion, numBasicCases + ndx, true);
4607e5c31af7Sopenharmony_ci}
4608e5c31af7Sopenharmony_ci
4609e5c31af7Sopenharmony_ciclass UniformInterfaceTestGroup : public TestCaseGroup
4610e5c31af7Sopenharmony_ci{
4611e5c31af7Sopenharmony_cipublic:
4612e5c31af7Sopenharmony_ci			UniformInterfaceTestGroup	(Context& context);
4613e5c31af7Sopenharmony_ci	void	init						(void);
4614e5c31af7Sopenharmony_ci};
4615e5c31af7Sopenharmony_ci
4616e5c31af7Sopenharmony_ciUniformInterfaceTestGroup::UniformInterfaceTestGroup (Context& context)
4617e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "uniform", "Uniform interace")
4618e5c31af7Sopenharmony_ci{
4619e5c31af7Sopenharmony_ci}
4620e5c31af7Sopenharmony_ci
4621e5c31af7Sopenharmony_civoid UniformInterfaceTestGroup::init (void)
4622e5c31af7Sopenharmony_ci{
4623e5c31af7Sopenharmony_ci	glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
4624e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
4625e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	computeShader	(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4626e5c31af7Sopenharmony_ci
4627e5c31af7Sopenharmony_ci	// .resource_list
4628e5c31af7Sopenharmony_ci	{
4629e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4630e5c31af7Sopenharmony_ci		addChild(blockGroup);
4631e5c31af7Sopenharmony_ci		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformResourceListBlockContents);
4632e5c31af7Sopenharmony_ci	}
4633e5c31af7Sopenharmony_ci
4634e5c31af7Sopenharmony_ci	// .array_size
4635e5c31af7Sopenharmony_ci	{
4636e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Query array size");
4637e5c31af7Sopenharmony_ci		addChild(blockGroup);
4638e5c31af7Sopenharmony_ci		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArraySizeContents);
4639e5c31af7Sopenharmony_ci	}
4640e5c31af7Sopenharmony_ci
4641e5c31af7Sopenharmony_ci	// .array_stride
4642e5c31af7Sopenharmony_ci	{
4643e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_stride", "Query array stride");
4644e5c31af7Sopenharmony_ci		addChild(blockGroup);
4645e5c31af7Sopenharmony_ci		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArrayStrideContents);
4646e5c31af7Sopenharmony_ci	}
4647e5c31af7Sopenharmony_ci
4648e5c31af7Sopenharmony_ci	// .atomic_counter_buffer_index
4649e5c31af7Sopenharmony_ci	{
4650e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "atomic_counter_buffer_index", "Query atomic counter buffer index");
4651e5c31af7Sopenharmony_ci		addChild(blockGroup);
4652e5c31af7Sopenharmony_ci		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED, generateUniformBlockAtomicCounterBufferIndexContents);
4653e5c31af7Sopenharmony_ci	}
4654e5c31af7Sopenharmony_ci
4655e5c31af7Sopenharmony_ci	// .block_index
4656e5c31af7Sopenharmony_ci	{
4657e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "block_index", "Query block index");
4658e5c31af7Sopenharmony_ci		addChild(blockGroup);
4659e5c31af7Sopenharmony_ci		generateUniformBlockBlockIndexContents(m_context, blockGroup, glslVersion);
4660e5c31af7Sopenharmony_ci	}
4661e5c31af7Sopenharmony_ci
4662e5c31af7Sopenharmony_ci	// .location
4663e5c31af7Sopenharmony_ci	{
4664e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Query location");
4665e5c31af7Sopenharmony_ci		addChild(blockGroup);
4666e5c31af7Sopenharmony_ci		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED | BLOCKFLAG_UNNAMED, generateUniformBlockLocationContents);
4667e5c31af7Sopenharmony_ci	}
4668e5c31af7Sopenharmony_ci
4669e5c31af7Sopenharmony_ci	// .matrix_row_major
4670e5c31af7Sopenharmony_ci	{
4671e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_row_major", "Query matrix row_major");
4672e5c31af7Sopenharmony_ci		addChild(blockGroup);
4673e5c31af7Sopenharmony_ci		generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixOrderCaseBlockContentCases);
4674e5c31af7Sopenharmony_ci	}
4675e5c31af7Sopenharmony_ci
4676e5c31af7Sopenharmony_ci	// .matrix_stride
4677e5c31af7Sopenharmony_ci	{
4678e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_stride", "Query matrix stride");
4679e5c31af7Sopenharmony_ci		addChild(blockGroup);
4680e5c31af7Sopenharmony_ci		generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixStrideCaseBlockContentCases);
4681e5c31af7Sopenharmony_ci	}
4682e5c31af7Sopenharmony_ci
4683e5c31af7Sopenharmony_ci	// .name_length
4684e5c31af7Sopenharmony_ci	{
4685e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Query name length");
4686e5c31af7Sopenharmony_ci		addChild(blockGroup);
4687e5c31af7Sopenharmony_ci		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockNameLengthContents);
4688e5c31af7Sopenharmony_ci	}
4689e5c31af7Sopenharmony_ci
4690e5c31af7Sopenharmony_ci	// .offset
4691e5c31af7Sopenharmony_ci	{
4692e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "offset", "Query offset");
4693e5c31af7Sopenharmony_ci		addChild(blockGroup);
4694e5c31af7Sopenharmony_ci		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockOffsetContents);
4695e5c31af7Sopenharmony_ci	}
4696e5c31af7Sopenharmony_ci
4697e5c31af7Sopenharmony_ci	// .referenced_by_shader
4698e5c31af7Sopenharmony_ci	{
4699e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by_shader", "Query referenced by shader");
4700e5c31af7Sopenharmony_ci		addChild(blockGroup);
4701e5c31af7Sopenharmony_ci		generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateUniformReferencedByShaderSingleBlockContentCases);
4702e5c31af7Sopenharmony_ci	}
4703e5c31af7Sopenharmony_ci
4704e5c31af7Sopenharmony_ci	// .type
4705e5c31af7Sopenharmony_ci	{
4706e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Query type");
4707e5c31af7Sopenharmony_ci		addChild(blockGroup);
4708e5c31af7Sopenharmony_ci		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockTypeContents);
4709e5c31af7Sopenharmony_ci	}
4710e5c31af7Sopenharmony_ci
4711e5c31af7Sopenharmony_ci	// .random
4712e5c31af7Sopenharmony_ci	{
4713e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random");
4714e5c31af7Sopenharmony_ci		addChild(blockGroup);
4715e5c31af7Sopenharmony_ci		generateUniformCaseRandomCases(m_context, blockGroup, glslVersion);
4716e5c31af7Sopenharmony_ci	}
4717e5c31af7Sopenharmony_ci}
4718e5c31af7Sopenharmony_ci
4719e5c31af7Sopenharmony_cistatic void generateBufferBackedInterfaceResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4720e5c31af7Sopenharmony_ci{
4721e5c31af7Sopenharmony_ci	targetGroup->addChild(new ResourceListTestCase(context, targetResource, interface, blockName));
4722e5c31af7Sopenharmony_ci}
4723e5c31af7Sopenharmony_ci
4724e5c31af7Sopenharmony_cistatic void generateBufferBackedInterfaceNameLengthCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
4725e5c31af7Sopenharmony_ci{
4726e5c31af7Sopenharmony_ci	targetGroup->addChild(new ResourceTestCase(context, targetResource, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_NAME_LENGTH), blockName));
4727e5c31af7Sopenharmony_ci}
4728e5c31af7Sopenharmony_ci
4729e5c31af7Sopenharmony_cistatic void generateBufferBackedInterfaceResourceBasicBlockTypes (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, glu::Storage storage, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const, ProgramInterface interface, const char* blockName))
4730e5c31af7Sopenharmony_ci{
4731e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program());
4732e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	shader				(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4733e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));
4734e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	storageQualifier	(new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4735e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	binding				(new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, 1)));
4736e5c31af7Sopenharmony_ci	const ProgramInterface						programInterface	= (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4737e5c31af7Sopenharmony_ci
4738e5c31af7Sopenharmony_ci	// .named_block
4739e5c31af7Sopenharmony_ci	{
4740e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(binding, true));
4741e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4742e5c31af7Sopenharmony_ci
4743e5c31af7Sopenharmony_ci		blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "named_block");
4744e5c31af7Sopenharmony_ci	}
4745e5c31af7Sopenharmony_ci
4746e5c31af7Sopenharmony_ci	// .unnamed_block
4747e5c31af7Sopenharmony_ci	{
4748e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(binding, false));
4749e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4750e5c31af7Sopenharmony_ci
4751e5c31af7Sopenharmony_ci		blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "unnamed_block");
4752e5c31af7Sopenharmony_ci	}
4753e5c31af7Sopenharmony_ci
4754e5c31af7Sopenharmony_ci	// .block_array
4755e5c31af7Sopenharmony_ci	{
4756e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(binding, 3));
4757e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
4758e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4759e5c31af7Sopenharmony_ci
4760e5c31af7Sopenharmony_ci		blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "block_array");
4761e5c31af7Sopenharmony_ci	}
4762e5c31af7Sopenharmony_ci
4763e5c31af7Sopenharmony_ci	// .block_array_single_element
4764e5c31af7Sopenharmony_ci	{
4765e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(binding, 1));
4766e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
4767e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4768e5c31af7Sopenharmony_ci
4769e5c31af7Sopenharmony_ci		blockContentGenerator(context, unusedVariable, targetGroup, programInterface, "block_array_single_element");
4770e5c31af7Sopenharmony_ci	}
4771e5c31af7Sopenharmony_ci}
4772e5c31af7Sopenharmony_ci
4773e5c31af7Sopenharmony_cistatic void generateBufferBackedInterfaceResourceBufferBindingCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, glu::Storage storage)
4774e5c31af7Sopenharmony_ci{
4775e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program());
4776e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	shader				(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
4777e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));
4778e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	storageQualifier	(new ResourceDefinition::StorageQualifier(defaultBlock, storage));
4779e5c31af7Sopenharmony_ci
4780e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < 2; ++ndx)
4781e5c31af7Sopenharmony_ci	{
4782e5c31af7Sopenharmony_ci		const bool									explicitBinding		= (ndx == 1);
4783e5c31af7Sopenharmony_ci		const int									bindingNdx			= (explicitBinding) ? (1) : (-1);
4784e5c31af7Sopenharmony_ci		const std::string							nameSuffix			= (explicitBinding) ? ("_explicit_binding") : ("");
4785e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	binding				(new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, bindingNdx)));
4786e5c31af7Sopenharmony_ci		const ProgramInterface						programInterface	= (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);
4787e5c31af7Sopenharmony_ci
4788e5c31af7Sopenharmony_ci		// .named_block*
4789e5c31af7Sopenharmony_ci		{
4790e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(binding, true));
4791e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4792e5c31af7Sopenharmony_ci
4793e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("named_block" + nameSuffix).c_str()));
4794e5c31af7Sopenharmony_ci		}
4795e5c31af7Sopenharmony_ci
4796e5c31af7Sopenharmony_ci		// .unnamed_block*
4797e5c31af7Sopenharmony_ci		{
4798e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(binding, false));
4799e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4800e5c31af7Sopenharmony_ci
4801e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("unnamed_block" + nameSuffix).c_str()));
4802e5c31af7Sopenharmony_ci		}
4803e5c31af7Sopenharmony_ci
4804e5c31af7Sopenharmony_ci		// .block_array*
4805e5c31af7Sopenharmony_ci		{
4806e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(binding, 3));
4807e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
4808e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4809e5c31af7Sopenharmony_ci
4810e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("block_array" + nameSuffix).c_str()));
4811e5c31af7Sopenharmony_ci		}
4812e5c31af7Sopenharmony_ci	}
4813e5c31af7Sopenharmony_ci}
4814e5c31af7Sopenharmony_ci
4815e5c31af7Sopenharmony_citemplate <glu::Storage Storage>
4816e5c31af7Sopenharmony_cistatic void generateBufferBlockReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
4817e5c31af7Sopenharmony_ci{
4818e5c31af7Sopenharmony_ci	const ProgramInterface						programInterface	= (Storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
4819e5c31af7Sopenharmony_ci																      (Storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
4820e5c31af7Sopenharmony_ci																      (PROGRAMINTERFACE_LAST);
4821e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(parentStructure));
4822e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	storage				(new ResourceDefinition::StorageQualifier(defaultBlock, Storage));
4823e5c31af7Sopenharmony_ci
4824e5c31af7Sopenharmony_ci	DE_UNREF(expandLevel);
4825e5c31af7Sopenharmony_ci
4826e5c31af7Sopenharmony_ci	DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);
4827e5c31af7Sopenharmony_ci
4828e5c31af7Sopenharmony_ci	// .named_block
4829e5c31af7Sopenharmony_ci	{
4830e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(storage, true));
4831e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4832e5c31af7Sopenharmony_ci
4833e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "named_block"));
4834e5c31af7Sopenharmony_ci	}
4835e5c31af7Sopenharmony_ci
4836e5c31af7Sopenharmony_ci	// .unnamed_block
4837e5c31af7Sopenharmony_ci	{
4838e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(storage, false));
4839e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4840e5c31af7Sopenharmony_ci
4841e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "unnamed_block"));
4842e5c31af7Sopenharmony_ci	}
4843e5c31af7Sopenharmony_ci
4844e5c31af7Sopenharmony_ci	// .block_array
4845e5c31af7Sopenharmony_ci	{
4846e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(storage, 3));
4847e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
4848e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));
4849e5c31af7Sopenharmony_ci
4850e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, unusedVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "block_array"));
4851e5c31af7Sopenharmony_ci	}
4852e5c31af7Sopenharmony_ci}
4853e5c31af7Sopenharmony_ci
4854e5c31af7Sopenharmony_cistatic void generateBufferBackedInterfaceResourceActiveVariablesCase (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4855e5c31af7Sopenharmony_ci{
4856e5c31af7Sopenharmony_ci	targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "named_block",		"Named block",		storage,	InterfaceBlockActiveVariablesTestCase::CASE_NAMED_BLOCK));
4857e5c31af7Sopenharmony_ci	targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "unnamed_block",	"Unnamed block",	storage,	InterfaceBlockActiveVariablesTestCase::CASE_UNNAMED_BLOCK));
4858e5c31af7Sopenharmony_ci	targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "block_array",		"Block array",		storage,	InterfaceBlockActiveVariablesTestCase::CASE_BLOCK_ARRAY));
4859e5c31af7Sopenharmony_ci}
4860e5c31af7Sopenharmony_ci
4861e5c31af7Sopenharmony_cistatic void generateBufferBackedInterfaceResourceBufferDataSizeCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
4862e5c31af7Sopenharmony_ci{
4863e5c31af7Sopenharmony_ci	targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "named_block",	"Named block",		storage,	InterfaceBlockDataSizeTestCase::CASE_NAMED_BLOCK));
4864e5c31af7Sopenharmony_ci	targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "unnamed_block",	"Unnamed block",	storage,	InterfaceBlockDataSizeTestCase::CASE_UNNAMED_BLOCK));
4865e5c31af7Sopenharmony_ci	targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "block_array",	"Block array",		storage,	InterfaceBlockDataSizeTestCase::CASE_BLOCK_ARRAY));
4866e5c31af7Sopenharmony_ci}
4867e5c31af7Sopenharmony_ci
4868e5c31af7Sopenharmony_ciclass BufferBackedBlockInterfaceTestGroup : public TestCaseGroup
4869e5c31af7Sopenharmony_ci{
4870e5c31af7Sopenharmony_cipublic:
4871e5c31af7Sopenharmony_ci						BufferBackedBlockInterfaceTestGroup	(Context& context, glu::Storage interfaceBlockStorage);
4872e5c31af7Sopenharmony_ci	void				init								(void);
4873e5c31af7Sopenharmony_ci
4874e5c31af7Sopenharmony_ciprivate:
4875e5c31af7Sopenharmony_ci	static const char*	getGroupName						(glu::Storage storage);
4876e5c31af7Sopenharmony_ci	static const char*	getGroupDescription					(glu::Storage storage);
4877e5c31af7Sopenharmony_ci
4878e5c31af7Sopenharmony_ci	const glu::Storage	m_storage;
4879e5c31af7Sopenharmony_ci};
4880e5c31af7Sopenharmony_ci
4881e5c31af7Sopenharmony_ciBufferBackedBlockInterfaceTestGroup::BufferBackedBlockInterfaceTestGroup(Context& context, glu::Storage storage)
4882e5c31af7Sopenharmony_ci	: TestCaseGroup	(context, getGroupName(storage), getGroupDescription(storage))
4883e5c31af7Sopenharmony_ci	, m_storage		(storage)
4884e5c31af7Sopenharmony_ci{
4885e5c31af7Sopenharmony_ci	DE_ASSERT(storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM);
4886e5c31af7Sopenharmony_ci}
4887e5c31af7Sopenharmony_ci
4888e5c31af7Sopenharmony_civoid BufferBackedBlockInterfaceTestGroup::init (void)
4889e5c31af7Sopenharmony_ci{
4890e5c31af7Sopenharmony_ci	const glu::GLSLVersion	glslVersion	= glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
4891e5c31af7Sopenharmony_ci
4892e5c31af7Sopenharmony_ci	// .resource_list
4893e5c31af7Sopenharmony_ci	{
4894e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
4895e5c31af7Sopenharmony_ci		addChild(blockGroup);
4896e5c31af7Sopenharmony_ci		generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, glslVersion, m_storage, generateBufferBackedInterfaceResourceListCase);
4897e5c31af7Sopenharmony_ci	}
4898e5c31af7Sopenharmony_ci
4899e5c31af7Sopenharmony_ci	// .active_variables
4900e5c31af7Sopenharmony_ci	{
4901e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "active_variables", "Active variables");
4902e5c31af7Sopenharmony_ci		addChild(blockGroup);
4903e5c31af7Sopenharmony_ci		generateBufferBackedInterfaceResourceActiveVariablesCase(m_context, blockGroup, m_storage);
4904e5c31af7Sopenharmony_ci	}
4905e5c31af7Sopenharmony_ci
4906e5c31af7Sopenharmony_ci	// .buffer_binding
4907e5c31af7Sopenharmony_ci	{
4908e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_binding", "Buffer binding");
4909e5c31af7Sopenharmony_ci		addChild(blockGroup);
4910e5c31af7Sopenharmony_ci		generateBufferBackedInterfaceResourceBufferBindingCases(m_context, blockGroup, glslVersion, m_storage);
4911e5c31af7Sopenharmony_ci	}
4912e5c31af7Sopenharmony_ci
4913e5c31af7Sopenharmony_ci	// .buffer_data_size
4914e5c31af7Sopenharmony_ci	{
4915e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_data_size", "Buffer data size");
4916e5c31af7Sopenharmony_ci		addChild(blockGroup);
4917e5c31af7Sopenharmony_ci		generateBufferBackedInterfaceResourceBufferDataSizeCases(m_context, blockGroup, m_storage);
4918e5c31af7Sopenharmony_ci	}
4919e5c31af7Sopenharmony_ci
4920e5c31af7Sopenharmony_ci	// .name_length
4921e5c31af7Sopenharmony_ci	{
4922e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
4923e5c31af7Sopenharmony_ci		addChild(blockGroup);
4924e5c31af7Sopenharmony_ci		generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, glslVersion, m_storage, generateBufferBackedInterfaceNameLengthCase);
4925e5c31af7Sopenharmony_ci	}
4926e5c31af7Sopenharmony_ci
4927e5c31af7Sopenharmony_ci	// .referenced_by
4928e5c31af7Sopenharmony_ci	{
4929e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Referenced by shader");
4930e5c31af7Sopenharmony_ci		addChild(blockGroup);
4931e5c31af7Sopenharmony_ci
4932e5c31af7Sopenharmony_ci		if (m_storage == glu::STORAGE_UNIFORM)
4933e5c31af7Sopenharmony_ci			generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_UNIFORM>);
4934e5c31af7Sopenharmony_ci		else if (m_storage == glu::STORAGE_BUFFER)
4935e5c31af7Sopenharmony_ci			generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_BUFFER>);
4936e5c31af7Sopenharmony_ci		else
4937e5c31af7Sopenharmony_ci			DE_ASSERT(false);
4938e5c31af7Sopenharmony_ci	}
4939e5c31af7Sopenharmony_ci}
4940e5c31af7Sopenharmony_ci
4941e5c31af7Sopenharmony_ciconst char* BufferBackedBlockInterfaceTestGroup::getGroupName (glu::Storage storage)
4942e5c31af7Sopenharmony_ci{
4943e5c31af7Sopenharmony_ci	switch (storage)
4944e5c31af7Sopenharmony_ci	{
4945e5c31af7Sopenharmony_ci		case glu::STORAGE_UNIFORM:	return "uniform_block";
4946e5c31af7Sopenharmony_ci		case glu::STORAGE_BUFFER:	return "shader_storage_block";
4947e5c31af7Sopenharmony_ci		default:
4948e5c31af7Sopenharmony_ci			DE_FATAL("invalid storage enum value");
4949e5c31af7Sopenharmony_ci			return DE_NULL;
4950e5c31af7Sopenharmony_ci	}
4951e5c31af7Sopenharmony_ci}
4952e5c31af7Sopenharmony_ci
4953e5c31af7Sopenharmony_ciconst char* BufferBackedBlockInterfaceTestGroup::getGroupDescription (glu::Storage storage)
4954e5c31af7Sopenharmony_ci{
4955e5c31af7Sopenharmony_ci	switch (storage)
4956e5c31af7Sopenharmony_ci	{
4957e5c31af7Sopenharmony_ci		case glu::STORAGE_UNIFORM:	return "Uniform block interface";
4958e5c31af7Sopenharmony_ci		case glu::STORAGE_BUFFER:	return "Shader storage block interface";
4959e5c31af7Sopenharmony_ci		default:
4960e5c31af7Sopenharmony_ci			DE_FATAL("invalid storage enum value");
4961e5c31af7Sopenharmony_ci			return DE_NULL;
4962e5c31af7Sopenharmony_ci	}
4963e5c31af7Sopenharmony_ci}
4964e5c31af7Sopenharmony_ci
4965e5c31af7Sopenharmony_ciclass AtomicCounterTestGroup : public TestCaseGroup
4966e5c31af7Sopenharmony_ci{
4967e5c31af7Sopenharmony_cipublic:
4968e5c31af7Sopenharmony_ci			AtomicCounterTestGroup	(Context& context);
4969e5c31af7Sopenharmony_ci	void	init					(void);
4970e5c31af7Sopenharmony_ci};
4971e5c31af7Sopenharmony_ci
4972e5c31af7Sopenharmony_ciAtomicCounterTestGroup::AtomicCounterTestGroup (Context& context)
4973e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "atomic_counter_buffer", "Atomic counter buffer")
4974e5c31af7Sopenharmony_ci{
4975e5c31af7Sopenharmony_ci}
4976e5c31af7Sopenharmony_ci
4977e5c31af7Sopenharmony_civoid AtomicCounterTestGroup::init (void)
4978e5c31af7Sopenharmony_ci{
4979e5c31af7Sopenharmony_ci	static const struct
4980e5c31af7Sopenharmony_ci	{
4981e5c31af7Sopenharmony_ci		const char*	name;
4982e5c31af7Sopenharmony_ci		deUint32	flags;
4983e5c31af7Sopenharmony_ci	} pipelines[] =
4984e5c31af7Sopenharmony_ci	{
4985e5c31af7Sopenharmony_ci		{
4986e5c31af7Sopenharmony_ci			"vertex_fragment",
4987e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT)
4988e5c31af7Sopenharmony_ci		},
4989e5c31af7Sopenharmony_ci		{
4990e5c31af7Sopenharmony_ci			"vertex_tess_fragment",
4991e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)
4992e5c31af7Sopenharmony_ci		},
4993e5c31af7Sopenharmony_ci		{
4994e5c31af7Sopenharmony_ci			"vertex_geo_fragment",
4995e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY)
4996e5c31af7Sopenharmony_ci		},
4997e5c31af7Sopenharmony_ci		{
4998e5c31af7Sopenharmony_ci			"vertex_tess_geo_fragment",
4999e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
5000e5c31af7Sopenharmony_ci		},
5001e5c31af7Sopenharmony_ci	};
5002e5c31af7Sopenharmony_ci
5003e5c31af7Sopenharmony_ci	// .resource_list
5004e5c31af7Sopenharmony_ci	addChild(new AtomicCounterResourceListCase(m_context, "resource_list", "Resource list"));
5005e5c31af7Sopenharmony_ci
5006e5c31af7Sopenharmony_ci	// .active_variables
5007e5c31af7Sopenharmony_ci	addChild(new AtomicCounterActiveVariablesCase(m_context, "active_variables", "Active variables"));
5008e5c31af7Sopenharmony_ci
5009e5c31af7Sopenharmony_ci	// .buffer_binding
5010e5c31af7Sopenharmony_ci	addChild(new AtomicCounterBufferBindingCase(m_context, "buffer_binding", "Buffer binding"));
5011e5c31af7Sopenharmony_ci
5012e5c31af7Sopenharmony_ci	// .buffer_data_size
5013e5c31af7Sopenharmony_ci	addChild(new AtomicCounterBufferDataSizeCase(m_context, "buffer_data_size", "Buffer binding"));
5014e5c31af7Sopenharmony_ci
5015e5c31af7Sopenharmony_ci	// .referenced_by
5016e5c31af7Sopenharmony_ci	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_compute",				"",	false,	(1 << glu::SHADERTYPE_COMPUTE),										(1 << glu::SHADERTYPE_COMPUTE)));
5017e5c31af7Sopenharmony_ci	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_vertex",		"",	true,	(1 << glu::SHADERTYPE_VERTEX),										(1 << glu::SHADERTYPE_VERTEX)));
5018e5c31af7Sopenharmony_ci	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_fragment",	"",	true,	(1 << glu::SHADERTYPE_FRAGMENT),									(1 << glu::SHADERTYPE_FRAGMENT)));
5019e5c31af7Sopenharmony_ci	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_geometry",	"",	true,	(1 << glu::SHADERTYPE_GEOMETRY),									(1 << glu::SHADERTYPE_GEOMETRY)));
5020e5c31af7Sopenharmony_ci	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_ctrl",	"",	true,	(1 << glu::SHADERTYPE_TESSELLATION_CONTROL),						(1 << glu::SHADERTYPE_TESSELLATION_CONTROL)));
5021e5c31af7Sopenharmony_ci	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_eval",	"",	true,	(1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),						(1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)));
5022e5c31af7Sopenharmony_ci
5023e5c31af7Sopenharmony_ci	for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
5024e5c31af7Sopenharmony_ci	{
5025e5c31af7Sopenharmony_ci		addChild(new AtomicCounterReferencedByCase(m_context, (std::string() + "referenced_by_" + pipelines[pipelineNdx].name).c_str(), "", false, pipelines[pipelineNdx].flags, pipelines[pipelineNdx].flags));
5026e5c31af7Sopenharmony_ci
5027e5c31af7Sopenharmony_ci		for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
5028e5c31af7Sopenharmony_ci		{
5029e5c31af7Sopenharmony_ci			const deUint32 currentBit = (1u << stageNdx);
5030e5c31af7Sopenharmony_ci			if (currentBit > pipelines[pipelineNdx].flags)
5031e5c31af7Sopenharmony_ci				break;
5032e5c31af7Sopenharmony_ci			if (currentBit & pipelines[pipelineNdx].flags)
5033e5c31af7Sopenharmony_ci			{
5034e5c31af7Sopenharmony_ci				const char*			stageName	= (stageNdx == glu::SHADERTYPE_VERTEX)					? ("vertex")
5035e5c31af7Sopenharmony_ci												: (stageNdx == glu::SHADERTYPE_FRAGMENT)				? ("fragment")
5036e5c31af7Sopenharmony_ci												: (stageNdx == glu::SHADERTYPE_GEOMETRY)				? ("geo")
5037e5c31af7Sopenharmony_ci												: (stageNdx == glu::SHADERTYPE_TESSELLATION_CONTROL)	? ("tess_ctrl")
5038e5c31af7Sopenharmony_ci												: (stageNdx == glu::SHADERTYPE_TESSELLATION_EVALUATION)	? ("tess_eval")
5039e5c31af7Sopenharmony_ci												: (DE_NULL);
5040e5c31af7Sopenharmony_ci				const std::string	name		= std::string() + "referenced_by_" + pipelines[pipelineNdx].name + "_only_" + stageName;
5041e5c31af7Sopenharmony_ci
5042e5c31af7Sopenharmony_ci				addChild(new AtomicCounterReferencedByCase(m_context, name.c_str(), "", false, pipelines[pipelineNdx].flags, currentBit));
5043e5c31af7Sopenharmony_ci			}
5044e5c31af7Sopenharmony_ci		}
5045e5c31af7Sopenharmony_ci	}
5046e5c31af7Sopenharmony_ci}
5047e5c31af7Sopenharmony_ci
5048e5c31af7Sopenharmony_cistatic void generateProgramInputOutputShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, bool withCompute, bool inputCase, bool isGL45, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, deUint32, bool))
5049e5c31af7Sopenharmony_ci{
5050e5c31af7Sopenharmony_ci	static const struct
5051e5c31af7Sopenharmony_ci	{
5052e5c31af7Sopenharmony_ci		const char*		name;
5053e5c31af7Sopenharmony_ci		glu::ShaderType	stage;
5054e5c31af7Sopenharmony_ci	} singleStageCases[] =
5055e5c31af7Sopenharmony_ci	{
5056e5c31af7Sopenharmony_ci		{ "separable_vertex",		glu::SHADERTYPE_VERTEX					},
5057e5c31af7Sopenharmony_ci		{ "separable_fragment",		glu::SHADERTYPE_FRAGMENT				},
5058e5c31af7Sopenharmony_ci		{ "separable_tess_ctrl",	glu::SHADERTYPE_TESSELLATION_CONTROL	},
5059e5c31af7Sopenharmony_ci		{ "separable_tess_eval",	glu::SHADERTYPE_TESSELLATION_EVALUATION	},
5060e5c31af7Sopenharmony_ci		{ "separable_geometry",		glu::SHADERTYPE_GEOMETRY				},
5061e5c31af7Sopenharmony_ci	};
5062e5c31af7Sopenharmony_ci
5063e5c31af7Sopenharmony_ci	// .vertex_fragment
5064e5c31af7Sopenharmony_ci	{
5065e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "vertex_fragment", "Vertex and fragment");
5066e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program(false));
5067e5c31af7Sopenharmony_ci		ResourceDefinition::ShaderSet*				shaderSetPtr	= new ResourceDefinition::ShaderSet(program, glslVersion);
5068e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	shaderSet		(shaderSetPtr);
5069e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shaderSet));
5070e5c31af7Sopenharmony_ci
5071e5c31af7Sopenharmony_ci		shaderSetPtr->setStage(glu::SHADERTYPE_VERTEX, inputCase);
5072e5c31af7Sopenharmony_ci		shaderSetPtr->setStage(glu::SHADERTYPE_FRAGMENT, !inputCase);
5073e5c31af7Sopenharmony_ci
5074e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
5075e5c31af7Sopenharmony_ci
5076e5c31af7Sopenharmony_ci		blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT), isGL45);
5077e5c31af7Sopenharmony_ci	}
5078e5c31af7Sopenharmony_ci
5079e5c31af7Sopenharmony_ci	// .separable_*
5080e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
5081e5c31af7Sopenharmony_ci	{
5082e5c31af7Sopenharmony_ci		TestCaseGroup* const						blockGroup			= new TestCaseGroup(context, singleStageCases[ndx].name, "");
5083e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program(true));
5084e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	shader				(new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
5085e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));
5086e5c31af7Sopenharmony_ci
5087e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
5088e5c31af7Sopenharmony_ci		blockContentGenerator(context, defaultBlock, blockGroup, (1 << singleStageCases[ndx].stage), isGL45);
5089e5c31af7Sopenharmony_ci	}
5090e5c31af7Sopenharmony_ci
5091e5c31af7Sopenharmony_ci	// .compute
5092e5c31af7Sopenharmony_ci	if (withCompute)
5093e5c31af7Sopenharmony_ci	{
5094e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "compute", "Compute");
5095e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program(true));
5096e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
5097e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
5098e5c31af7Sopenharmony_ci
5099e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
5100e5c31af7Sopenharmony_ci
5101e5c31af7Sopenharmony_ci		blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_COMPUTE), isGL45);
5102e5c31af7Sopenharmony_ci	}
5103e5c31af7Sopenharmony_ci
5104e5c31af7Sopenharmony_ci	// .interface_blocks
5105e5c31af7Sopenharmony_ci	{
5106e5c31af7Sopenharmony_ci		static const struct
5107e5c31af7Sopenharmony_ci		{
5108e5c31af7Sopenharmony_ci			const char*			inputName;
5109e5c31af7Sopenharmony_ci			glu::ShaderType		inputStage;
5110e5c31af7Sopenharmony_ci			glu::Storage		inputStorage;
5111e5c31af7Sopenharmony_ci			const char*			outputName;
5112e5c31af7Sopenharmony_ci			glu::ShaderType		outputStage;
5113e5c31af7Sopenharmony_ci			glu::Storage		outputStorage;
5114e5c31af7Sopenharmony_ci		} ioBlockTypes[] =
5115e5c31af7Sopenharmony_ci		{
5116e5c31af7Sopenharmony_ci			{
5117e5c31af7Sopenharmony_ci				"in",
5118e5c31af7Sopenharmony_ci				glu::SHADERTYPE_FRAGMENT,
5119e5c31af7Sopenharmony_ci				glu::STORAGE_IN,
5120e5c31af7Sopenharmony_ci				"out",
5121e5c31af7Sopenharmony_ci				glu::SHADERTYPE_VERTEX,
5122e5c31af7Sopenharmony_ci				glu::STORAGE_OUT,
5123e5c31af7Sopenharmony_ci			},
5124e5c31af7Sopenharmony_ci			{
5125e5c31af7Sopenharmony_ci				"patch_in",
5126e5c31af7Sopenharmony_ci				glu::SHADERTYPE_TESSELLATION_EVALUATION,
5127e5c31af7Sopenharmony_ci				glu::STORAGE_PATCH_IN,
5128e5c31af7Sopenharmony_ci				"patch_out",
5129e5c31af7Sopenharmony_ci				glu::SHADERTYPE_TESSELLATION_CONTROL,
5130e5c31af7Sopenharmony_ci				glu::STORAGE_PATCH_OUT,
5131e5c31af7Sopenharmony_ci			},
5132e5c31af7Sopenharmony_ci		};
5133e5c31af7Sopenharmony_ci
5134e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const ioBlocksGroup = new TestCaseGroup(context, "interface_blocks", "Interface blocks");
5135e5c31af7Sopenharmony_ci		targetGroup->addChild(ioBlocksGroup);
5136e5c31af7Sopenharmony_ci
5137e5c31af7Sopenharmony_ci		// .in/out
5138e5c31af7Sopenharmony_ci		// .sample in/out
5139e5c31af7Sopenharmony_ci		// .patch in/out
5140e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioBlockTypes); ++ndx)
5141e5c31af7Sopenharmony_ci		{
5142e5c31af7Sopenharmony_ci			const char* const							name			= (inputCase) ? (ioBlockTypes[ndx].inputName) : (ioBlockTypes[ndx].outputName);
5143e5c31af7Sopenharmony_ci			const glu::ShaderType						shaderType		= (inputCase) ? (ioBlockTypes[ndx].inputStage) : (ioBlockTypes[ndx].outputStage);
5144e5c31af7Sopenharmony_ci			const glu::Storage							storageType		= (inputCase) ? (ioBlockTypes[ndx].inputStorage) : (ioBlockTypes[ndx].outputStorage);
5145e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					ioBlockGroup	= new TestCaseGroup(context, name, "");
5146e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program(true));
5147e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, shaderType, glslVersion));
5148e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
5149e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	storage			(new ResourceDefinition::StorageQualifier(defaultBlock, storageType));
5150e5c31af7Sopenharmony_ci
5151e5c31af7Sopenharmony_ci			ioBlocksGroup->addChild(ioBlockGroup);
5152e5c31af7Sopenharmony_ci
5153e5c31af7Sopenharmony_ci			// .named_block
5154e5c31af7Sopenharmony_ci			{
5155e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(storage, true));
5156e5c31af7Sopenharmony_ci				tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "named_block", "Named block");
5157e5c31af7Sopenharmony_ci
5158e5c31af7Sopenharmony_ci				ioBlockGroup->addChild(blockGroup);
5159e5c31af7Sopenharmony_ci
5160e5c31af7Sopenharmony_ci				blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5161e5c31af7Sopenharmony_ci			}
5162e5c31af7Sopenharmony_ci
5163e5c31af7Sopenharmony_ci			// .named_block_explicit_location
5164e5c31af7Sopenharmony_ci			{
5165e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	layout		(new ResourceDefinition::LayoutQualifier(storage, glu::Layout(3)));
5166e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(layout, true));
5167e5c31af7Sopenharmony_ci				tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "named_block_explicit_location", "Named block with explicit location");
5168e5c31af7Sopenharmony_ci
5169e5c31af7Sopenharmony_ci				ioBlockGroup->addChild(blockGroup);
5170e5c31af7Sopenharmony_ci
5171e5c31af7Sopenharmony_ci				blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5172e5c31af7Sopenharmony_ci			}
5173e5c31af7Sopenharmony_ci
5174e5c31af7Sopenharmony_ci			// .unnamed_block
5175e5c31af7Sopenharmony_ci			if (!isGL45)
5176e5c31af7Sopenharmony_ci			{
5177e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(storage, false));
5178e5c31af7Sopenharmony_ci				tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unnamed_block", "Unnamed block");
5179e5c31af7Sopenharmony_ci
5180e5c31af7Sopenharmony_ci				ioBlockGroup->addChild(blockGroup);
5181e5c31af7Sopenharmony_ci
5182e5c31af7Sopenharmony_ci				blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5183e5c31af7Sopenharmony_ci			}
5184e5c31af7Sopenharmony_ci
5185e5c31af7Sopenharmony_ci			// .block_array
5186e5c31af7Sopenharmony_ci			{
5187e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(storage));
5188e5c31af7Sopenharmony_ci				const ResourceDefinition::Node::SharedPtr	block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
5189e5c31af7Sopenharmony_ci				tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "block_array", "Block array");
5190e5c31af7Sopenharmony_ci
5191e5c31af7Sopenharmony_ci				ioBlockGroup->addChild(blockGroup);
5192e5c31af7Sopenharmony_ci
5193e5c31af7Sopenharmony_ci				blockContentGenerator(context, block, blockGroup, (1 << shaderType), isGL45);
5194e5c31af7Sopenharmony_ci			}
5195e5c31af7Sopenharmony_ci		}
5196e5c31af7Sopenharmony_ci	}
5197e5c31af7Sopenharmony_ci}
5198e5c31af7Sopenharmony_ci
5199e5c31af7Sopenharmony_cistatic void generateProgramInputBlockContents (Context&										context,
5200e5c31af7Sopenharmony_ci											   const ResourceDefinition::Node::SharedPtr&	parentStructure,
5201e5c31af7Sopenharmony_ci											   tcu::TestCaseGroup*							targetGroup,
5202e5c31af7Sopenharmony_ci											   deUint32										presentShadersMask,
5203e5c31af7Sopenharmony_ci											   bool											includeEmpty,
5204e5c31af7Sopenharmony_ci											   void											(*genCase)(Context&										context,
5205e5c31af7Sopenharmony_ci																									   const ResourceDefinition::Node::SharedPtr&	parentStructure,
5206e5c31af7Sopenharmony_ci																									   tcu::TestCaseGroup*							targetGroup,
5207e5c31af7Sopenharmony_ci																									   ProgramInterface								interface,
5208e5c31af7Sopenharmony_ci																									   const char*									name))
5209e5c31af7Sopenharmony_ci{
5210e5c31af7Sopenharmony_ci	const bool									inDefaultBlock	= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5211e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	input			= (inDefaultBlock)
5212e5c31af7Sopenharmony_ci																	? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5213e5c31af7Sopenharmony_ci																	: (parentStructure);
5214e5c31af7Sopenharmony_ci	const glu::ShaderType						firstStage		= getShaderMaskFirstStage(presentShadersMask);
5215e5c31af7Sopenharmony_ci
5216e5c31af7Sopenharmony_ci	// .empty
5217e5c31af7Sopenharmony_ci	if (includeEmpty && inDefaultBlock)
5218e5c31af7Sopenharmony_ci		genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "empty");
5219e5c31af7Sopenharmony_ci
5220e5c31af7Sopenharmony_ci	if (firstStage == glu::SHADERTYPE_VERTEX)
5221e5c31af7Sopenharmony_ci	{
5222e5c31af7Sopenharmony_ci		// .var
5223e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5224e5c31af7Sopenharmony_ci		genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5225e5c31af7Sopenharmony_ci	}
5226e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5227e5c31af7Sopenharmony_ci	{
5228e5c31af7Sopenharmony_ci		// .var
5229e5c31af7Sopenharmony_ci		{
5230e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5231e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5232e5c31af7Sopenharmony_ci		}
5233e5c31af7Sopenharmony_ci		// .var_struct
5234e5c31af7Sopenharmony_ci		{
5235e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(input));
5236e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5237e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_struct");
5238e5c31af7Sopenharmony_ci		}
5239e5c31af7Sopenharmony_ci		// .var_array
5240e5c31af7Sopenharmony_ci		{
5241e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input));
5242e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5243e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_array");
5244e5c31af7Sopenharmony_ci		}
5245e5c31af7Sopenharmony_ci	}
5246e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5247e5c31af7Sopenharmony_ci			 firstStage == glu::SHADERTYPE_GEOMETRY)
5248e5c31af7Sopenharmony_ci	{
5249e5c31af7Sopenharmony_ci		// arrayed interface
5250e5c31af7Sopenharmony_ci
5251e5c31af7Sopenharmony_ci		// .var
5252e5c31af7Sopenharmony_ci		{
5253e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5254e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5255e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5256e5c31af7Sopenharmony_ci		}
5257e5c31af7Sopenharmony_ci		// extension forbids use arrays of structs
5258e5c31af7Sopenharmony_ci		// extension forbids use arrays of arrays
5259e5c31af7Sopenharmony_ci	}
5260e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5261e5c31af7Sopenharmony_ci	{
5262e5c31af7Sopenharmony_ci		// arrayed interface
5263e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5264e5c31af7Sopenharmony_ci
5265e5c31af7Sopenharmony_ci		// .var
5266e5c31af7Sopenharmony_ci		{
5267e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5268e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5269e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
5270e5c31af7Sopenharmony_ci		}
5271e5c31af7Sopenharmony_ci		// extension forbids use arrays of structs
5272e5c31af7Sopenharmony_ci		// extension forbids use arrays of arrays
5273e5c31af7Sopenharmony_ci
5274e5c31af7Sopenharmony_ci		// .patch_var
5275e5c31af7Sopenharmony_ci		{
5276e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5277e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var");
5278e5c31af7Sopenharmony_ci		}
5279e5c31af7Sopenharmony_ci		// .patch_var_struct
5280e5c31af7Sopenharmony_ci		{
5281e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(patchInput));
5282e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5283e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_struct");
5284e5c31af7Sopenharmony_ci		}
5285e5c31af7Sopenharmony_ci		// .patch_var_array
5286e5c31af7Sopenharmony_ci		{
5287e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(patchInput));
5288e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5289e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_array");
5290e5c31af7Sopenharmony_ci		}
5291e5c31af7Sopenharmony_ci	}
5292e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_COMPUTE)
5293e5c31af7Sopenharmony_ci	{
5294e5c31af7Sopenharmony_ci		// nada
5295e5c31af7Sopenharmony_ci	}
5296e5c31af7Sopenharmony_ci	else
5297e5c31af7Sopenharmony_ci		DE_ASSERT(false);
5298e5c31af7Sopenharmony_ci}
5299e5c31af7Sopenharmony_ci
5300e5c31af7Sopenharmony_cistatic void generateProgramOutputBlockContents (Context&										context,
5301e5c31af7Sopenharmony_ci												const ResourceDefinition::Node::SharedPtr&		parentStructure,
5302e5c31af7Sopenharmony_ci												tcu::TestCaseGroup*								targetGroup,
5303e5c31af7Sopenharmony_ci												deUint32										presentShadersMask,
5304e5c31af7Sopenharmony_ci												bool											includeEmpty,
5305e5c31af7Sopenharmony_ci												void											(*genCase)(Context&										context,
5306e5c31af7Sopenharmony_ci																										   const ResourceDefinition::Node::SharedPtr&	parentStructure,
5307e5c31af7Sopenharmony_ci																										   tcu::TestCaseGroup*							targetGroup,
5308e5c31af7Sopenharmony_ci																										   ProgramInterface								interface,
5309e5c31af7Sopenharmony_ci																										   const char*									name))
5310e5c31af7Sopenharmony_ci{
5311e5c31af7Sopenharmony_ci	const bool									inDefaultBlock	= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5312e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	output			= (inDefaultBlock)
5313e5c31af7Sopenharmony_ci																	? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5314e5c31af7Sopenharmony_ci																	: (parentStructure);
5315e5c31af7Sopenharmony_ci	const glu::ShaderType						lastStage		= getShaderMaskLastStage(presentShadersMask);
5316e5c31af7Sopenharmony_ci
5317e5c31af7Sopenharmony_ci	// .empty
5318e5c31af7Sopenharmony_ci	if (includeEmpty && inDefaultBlock)
5319e5c31af7Sopenharmony_ci		genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "empty");
5320e5c31af7Sopenharmony_ci
5321e5c31af7Sopenharmony_ci	if (lastStage == glu::SHADERTYPE_VERTEX						||
5322e5c31af7Sopenharmony_ci		lastStage == glu::SHADERTYPE_GEOMETRY					||
5323e5c31af7Sopenharmony_ci		lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION	||
5324e5c31af7Sopenharmony_ci		!inDefaultBlock)
5325e5c31af7Sopenharmony_ci	{
5326e5c31af7Sopenharmony_ci		// .var
5327e5c31af7Sopenharmony_ci		{
5328e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5329e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5330e5c31af7Sopenharmony_ci		}
5331e5c31af7Sopenharmony_ci		// .var_struct
5332e5c31af7Sopenharmony_ci		{
5333e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(output));
5334e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5335e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_struct");
5336e5c31af7Sopenharmony_ci		}
5337e5c31af7Sopenharmony_ci		// .var_array
5338e5c31af7Sopenharmony_ci		{
5339e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
5340e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5341e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5342e5c31af7Sopenharmony_ci		}
5343e5c31af7Sopenharmony_ci	}
5344e5c31af7Sopenharmony_ci	else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5345e5c31af7Sopenharmony_ci	{
5346e5c31af7Sopenharmony_ci		// .var
5347e5c31af7Sopenharmony_ci		{
5348e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5349e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5350e5c31af7Sopenharmony_ci		}
5351e5c31af7Sopenharmony_ci		// .var_array
5352e5c31af7Sopenharmony_ci		{
5353e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
5354e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5355e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
5356e5c31af7Sopenharmony_ci		}
5357e5c31af7Sopenharmony_ci	}
5358e5c31af7Sopenharmony_ci	else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5359e5c31af7Sopenharmony_ci	{
5360e5c31af7Sopenharmony_ci		// arrayed interface
5361e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5362e5c31af7Sopenharmony_ci
5363e5c31af7Sopenharmony_ci		// .var
5364e5c31af7Sopenharmony_ci		{
5365e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5366e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5367e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
5368e5c31af7Sopenharmony_ci		}
5369e5c31af7Sopenharmony_ci		// extension forbids use arrays of structs
5370e5c31af7Sopenharmony_ci		// extension forbids use array of arrays
5371e5c31af7Sopenharmony_ci
5372e5c31af7Sopenharmony_ci		// .patch_var
5373e5c31af7Sopenharmony_ci		{
5374e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5375e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var");
5376e5c31af7Sopenharmony_ci		}
5377e5c31af7Sopenharmony_ci		// .patch_var_struct
5378e5c31af7Sopenharmony_ci		{
5379e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(patchOutput));
5380e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5381e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_struct");
5382e5c31af7Sopenharmony_ci		}
5383e5c31af7Sopenharmony_ci		// .patch_var_array
5384e5c31af7Sopenharmony_ci		{
5385e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(patchOutput));
5386e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5387e5c31af7Sopenharmony_ci			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_array");
5388e5c31af7Sopenharmony_ci		}
5389e5c31af7Sopenharmony_ci	}
5390e5c31af7Sopenharmony_ci	else if (lastStage == glu::SHADERTYPE_COMPUTE)
5391e5c31af7Sopenharmony_ci	{
5392e5c31af7Sopenharmony_ci		// nada
5393e5c31af7Sopenharmony_ci	}
5394e5c31af7Sopenharmony_ci	else
5395e5c31af7Sopenharmony_ci		DE_ASSERT(false);
5396e5c31af7Sopenharmony_ci}
5397e5c31af7Sopenharmony_ci
5398e5c31af7Sopenharmony_cistatic void addProgramInputOutputResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5399e5c31af7Sopenharmony_ci{
5400e5c31af7Sopenharmony_ci	ResourceListTestCase* const resourceListCase = new ResourceListTestCase(context, parentStructure, programInterface);
5401e5c31af7Sopenharmony_ci
5402e5c31af7Sopenharmony_ci	DE_ASSERT(deStringEqual(name, resourceListCase->getName()));
5403e5c31af7Sopenharmony_ci	DE_UNREF(name);
5404e5c31af7Sopenharmony_ci	targetGroup->addChild(resourceListCase);
5405e5c31af7Sopenharmony_ci}
5406e5c31af7Sopenharmony_ci
5407e5c31af7Sopenharmony_cistatic void generateProgramInputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5408e5c31af7Sopenharmony_ci{
5409e5c31af7Sopenharmony_ci	DE_UNREF(isGL45);
5410e5c31af7Sopenharmony_ci	generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5411e5c31af7Sopenharmony_ci}
5412e5c31af7Sopenharmony_ci
5413e5c31af7Sopenharmony_cistatic void generateProgramOutputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5414e5c31af7Sopenharmony_ci{
5415e5c31af7Sopenharmony_ci	DE_UNREF(isGL45);
5416e5c31af7Sopenharmony_ci	generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
5417e5c31af7Sopenharmony_ci}
5418e5c31af7Sopenharmony_ci
5419e5c31af7Sopenharmony_citemplate <ProgramResourcePropFlags TargetProp>
5420e5c31af7Sopenharmony_cistatic void addProgramInputOutputResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
5421e5c31af7Sopenharmony_ci{
5422e5c31af7Sopenharmony_ci	ResourceTestCase* const resourceTestCase = new ResourceTestCase(context, parentStructure, ProgramResourceQueryTestTarget(programInterface, TargetProp), name);
5423e5c31af7Sopenharmony_ci	targetGroup->addChild(resourceTestCase);
5424e5c31af7Sopenharmony_ci}
5425e5c31af7Sopenharmony_ci
5426e5c31af7Sopenharmony_citemplate <ProgramResourcePropFlags TargetProp>
5427e5c31af7Sopenharmony_cistatic void generateProgramInputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5428e5c31af7Sopenharmony_ci{
5429e5c31af7Sopenharmony_ci	DE_UNREF(isGL45);
5430e5c31af7Sopenharmony_ci	generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5431e5c31af7Sopenharmony_ci}
5432e5c31af7Sopenharmony_ci
5433e5c31af7Sopenharmony_citemplate <ProgramResourcePropFlags TargetProp>
5434e5c31af7Sopenharmony_cistatic void generateProgramOutputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5435e5c31af7Sopenharmony_ci{
5436e5c31af7Sopenharmony_ci	DE_UNREF(isGL45);
5437e5c31af7Sopenharmony_ci	generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
5438e5c31af7Sopenharmony_ci}
5439e5c31af7Sopenharmony_ci
5440e5c31af7Sopenharmony_cistatic void generateProgramInputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5441e5c31af7Sopenharmony_ci{
5442e5c31af7Sopenharmony_ci	DE_UNREF(isGL45);
5443e5c31af7Sopenharmony_ci	const bool									inDefaultBlock	= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5444e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	input			= (inDefaultBlock)
5445e5c31af7Sopenharmony_ci																	? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5446e5c31af7Sopenharmony_ci																	: (parentStructure);
5447e5c31af7Sopenharmony_ci	const glu::ShaderType						firstStage		= getShaderMaskFirstStage(presentShadersMask);
5448e5c31af7Sopenharmony_ci
5449e5c31af7Sopenharmony_ci	const bool									inBlockArray	= DE_TRUE == deStringEqual("block_array", targetGroup->getName());
5450e5c31af7Sopenharmony_ci
5451e5c31af7Sopenharmony_ci	if (firstStage == glu::SHADERTYPE_VERTEX)
5452e5c31af7Sopenharmony_ci	{
5453e5c31af7Sopenharmony_ci		// .var
5454e5c31af7Sopenharmony_ci		{
5455e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5456e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5457e5c31af7Sopenharmony_ci		}
5458e5c31af7Sopenharmony_ci		// .var_explicit_location
5459e5c31af7Sopenharmony_ci		{
5460e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5461e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5462e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5463e5c31af7Sopenharmony_ci		}
5464e5c31af7Sopenharmony_ci	}
5465e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5466e5c31af7Sopenharmony_ci	{
5467e5c31af7Sopenharmony_ci		// .var
5468e5c31af7Sopenharmony_ci		{
5469e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
5470e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5471e5c31af7Sopenharmony_ci		}
5472e5c31af7Sopenharmony_ci		// .var_explicit_location
5473e5c31af7Sopenharmony_ci		if (!inBlockArray)
5474e5c31af7Sopenharmony_ci		{
5475e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5476e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5477e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5478e5c31af7Sopenharmony_ci		}
5479e5c31af7Sopenharmony_ci		// .var_struct
5480e5c31af7Sopenharmony_ci		{
5481e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(input));
5482e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5483e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5484e5c31af7Sopenharmony_ci		}
5485e5c31af7Sopenharmony_ci		// .var_struct_explicit_location
5486e5c31af7Sopenharmony_ci		if (!inBlockArray)
5487e5c31af7Sopenharmony_ci		{
5488e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5489e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(layout));
5490e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5491e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5492e5c31af7Sopenharmony_ci		}
5493e5c31af7Sopenharmony_ci		// .var_array
5494e5c31af7Sopenharmony_ci		{
5495e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input));
5496e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5497e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5498e5c31af7Sopenharmony_ci		}
5499e5c31af7Sopenharmony_ci		// .var_array_explicit_location
5500e5c31af7Sopenharmony_ci		if (!inBlockArray)
5501e5c31af7Sopenharmony_ci		{
5502e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5503e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
5504e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5505e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5506e5c31af7Sopenharmony_ci		}
5507e5c31af7Sopenharmony_ci	}
5508e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5509e5c31af7Sopenharmony_ci			 firstStage == glu::SHADERTYPE_GEOMETRY)
5510e5c31af7Sopenharmony_ci	{
5511e5c31af7Sopenharmony_ci		// arrayed interface
5512e5c31af7Sopenharmony_ci
5513e5c31af7Sopenharmony_ci		// .var
5514e5c31af7Sopenharmony_ci		{
5515e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5516e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5517e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5518e5c31af7Sopenharmony_ci		}
5519e5c31af7Sopenharmony_ci		// .var_explicit_location
5520e5c31af7Sopenharmony_ci		{
5521e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5522e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5523e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5524e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5525e5c31af7Sopenharmony_ci		}
5526e5c31af7Sopenharmony_ci		// extension forbids use arrays of structs
5527e5c31af7Sopenharmony_ci		// extension forbids use arrays of arrays
5528e5c31af7Sopenharmony_ci	}
5529e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5530e5c31af7Sopenharmony_ci	{
5531e5c31af7Sopenharmony_ci		// arrayed interface
5532e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5533e5c31af7Sopenharmony_ci
5534e5c31af7Sopenharmony_ci		// .var
5535e5c31af7Sopenharmony_ci		{
5536e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5537e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5538e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5539e5c31af7Sopenharmony_ci		}
5540e5c31af7Sopenharmony_ci		// .var_explicit_location
5541e5c31af7Sopenharmony_ci		{
5542e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
5543e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5544e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5545e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5546e5c31af7Sopenharmony_ci		}
5547e5c31af7Sopenharmony_ci		// extension forbids use arrays of structs
5548e5c31af7Sopenharmony_ci		// extension forbids use arrays of arrays
5549e5c31af7Sopenharmony_ci
5550e5c31af7Sopenharmony_ci		// .patch_var
5551e5c31af7Sopenharmony_ci		{
5552e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
5553e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5554e5c31af7Sopenharmony_ci		}
5555e5c31af7Sopenharmony_ci		// .patch_var_explicit_location
5556e5c31af7Sopenharmony_ci		{
5557e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5558e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5559e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5560e5c31af7Sopenharmony_ci		}
5561e5c31af7Sopenharmony_ci		// .patch_var_struct
5562e5c31af7Sopenharmony_ci		{
5563e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(patchInput));
5564e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5565e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5566e5c31af7Sopenharmony_ci		}
5567e5c31af7Sopenharmony_ci		// .patch_var_struct_explicit_location
5568e5c31af7Sopenharmony_ci		{
5569e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5570e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(layout));
5571e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5572e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5573e5c31af7Sopenharmony_ci		}
5574e5c31af7Sopenharmony_ci		// .patch_var_array
5575e5c31af7Sopenharmony_ci		{
5576e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(patchInput));
5577e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5578e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5579e5c31af7Sopenharmony_ci		}
5580e5c31af7Sopenharmony_ci		// .patch_var_array_explicit_location
5581e5c31af7Sopenharmony_ci		{
5582e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
5583e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
5584e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5585e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5586e5c31af7Sopenharmony_ci		}
5587e5c31af7Sopenharmony_ci	}
5588e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_COMPUTE)
5589e5c31af7Sopenharmony_ci	{
5590e5c31af7Sopenharmony_ci		// nada
5591e5c31af7Sopenharmony_ci	}
5592e5c31af7Sopenharmony_ci	else
5593e5c31af7Sopenharmony_ci		DE_ASSERT(false);
5594e5c31af7Sopenharmony_ci}
5595e5c31af7Sopenharmony_ci
5596e5c31af7Sopenharmony_cistatic void generateProgramOutputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5597e5c31af7Sopenharmony_ci{
5598e5c31af7Sopenharmony_ci	DE_UNREF(isGL45);
5599e5c31af7Sopenharmony_ci	const bool									inDefaultBlock	= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5600e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	output			= (inDefaultBlock)
5601e5c31af7Sopenharmony_ci																	? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5602e5c31af7Sopenharmony_ci																	: (parentStructure);
5603e5c31af7Sopenharmony_ci	const glu::ShaderType						lastStage		= getShaderMaskLastStage(presentShadersMask);
5604e5c31af7Sopenharmony_ci
5605e5c31af7Sopenharmony_ci	const bool									inBlockArray	= DE_TRUE == deStringEqual("block_array", targetGroup->getName());
5606e5c31af7Sopenharmony_ci
5607e5c31af7Sopenharmony_ci	if (lastStage == glu::SHADERTYPE_VERTEX						||
5608e5c31af7Sopenharmony_ci		lastStage == glu::SHADERTYPE_GEOMETRY					||
5609e5c31af7Sopenharmony_ci		lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION	||
5610e5c31af7Sopenharmony_ci		!inDefaultBlock)
5611e5c31af7Sopenharmony_ci	{
5612e5c31af7Sopenharmony_ci		// .var
5613e5c31af7Sopenharmony_ci		{
5614e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5615e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5616e5c31af7Sopenharmony_ci		}
5617e5c31af7Sopenharmony_ci		// .var_explicit_location
5618e5c31af7Sopenharmony_ci		if (!inBlockArray)
5619e5c31af7Sopenharmony_ci		{
5620e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5621e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5622e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5623e5c31af7Sopenharmony_ci		}
5624e5c31af7Sopenharmony_ci		// .var_struct
5625e5c31af7Sopenharmony_ci		{
5626e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(output));
5627e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5628e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
5629e5c31af7Sopenharmony_ci		}
5630e5c31af7Sopenharmony_ci		// .var_struct_explicit_location
5631e5c31af7Sopenharmony_ci		if (!inBlockArray)
5632e5c31af7Sopenharmony_ci		{
5633e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5634e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(layout));
5635e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5636e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
5637e5c31af7Sopenharmony_ci		}
5638e5c31af7Sopenharmony_ci		// .var_array
5639e5c31af7Sopenharmony_ci		{
5640e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
5641e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5642e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5643e5c31af7Sopenharmony_ci		}
5644e5c31af7Sopenharmony_ci		// .var_array_explicit_location
5645e5c31af7Sopenharmony_ci		if (!inBlockArray)
5646e5c31af7Sopenharmony_ci		{
5647e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5648e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
5649e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5650e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5651e5c31af7Sopenharmony_ci		}
5652e5c31af7Sopenharmony_ci	}
5653e5c31af7Sopenharmony_ci	else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5654e5c31af7Sopenharmony_ci	{
5655e5c31af7Sopenharmony_ci		// .var
5656e5c31af7Sopenharmony_ci		{
5657e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
5658e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5659e5c31af7Sopenharmony_ci		}
5660e5c31af7Sopenharmony_ci		// .var_explicit_location
5661e5c31af7Sopenharmony_ci		if (!inBlockArray)
5662e5c31af7Sopenharmony_ci		{
5663e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5664e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5665e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5666e5c31af7Sopenharmony_ci		}
5667e5c31af7Sopenharmony_ci		// .var_array
5668e5c31af7Sopenharmony_ci		{
5669e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
5670e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5671e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
5672e5c31af7Sopenharmony_ci		}
5673e5c31af7Sopenharmony_ci		// .var_array_explicit_location
5674e5c31af7Sopenharmony_ci		if (!inBlockArray)
5675e5c31af7Sopenharmony_ci		{
5676e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(1)));
5677e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
5678e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5679e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
5680e5c31af7Sopenharmony_ci		}
5681e5c31af7Sopenharmony_ci	}
5682e5c31af7Sopenharmony_ci	else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5683e5c31af7Sopenharmony_ci	{
5684e5c31af7Sopenharmony_ci		// arrayed interface
5685e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5686e5c31af7Sopenharmony_ci
5687e5c31af7Sopenharmony_ci		// .var
5688e5c31af7Sopenharmony_ci		{
5689e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5690e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5691e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
5692e5c31af7Sopenharmony_ci		}
5693e5c31af7Sopenharmony_ci		// .var_explicit_location
5694e5c31af7Sopenharmony_ci		{
5695e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
5696e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5697e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5698e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
5699e5c31af7Sopenharmony_ci		}
5700e5c31af7Sopenharmony_ci		// extension forbids use arrays of structs
5701e5c31af7Sopenharmony_ci		// extension forbids use array of arrays
5702e5c31af7Sopenharmony_ci
5703e5c31af7Sopenharmony_ci		// .patch_var
5704e5c31af7Sopenharmony_ci		{
5705e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
5706e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
5707e5c31af7Sopenharmony_ci		}
5708e5c31af7Sopenharmony_ci		// .patch_var_explicit_location
5709e5c31af7Sopenharmony_ci		{
5710e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5711e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
5712e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
5713e5c31af7Sopenharmony_ci		}
5714e5c31af7Sopenharmony_ci		// .patch_var_struct
5715e5c31af7Sopenharmony_ci		{
5716e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(patchOutput));
5717e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5718e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
5719e5c31af7Sopenharmony_ci		}
5720e5c31af7Sopenharmony_ci		// .patch_var_struct_explicit_location
5721e5c31af7Sopenharmony_ci		{
5722e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5723e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(layout));
5724e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
5725e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
5726e5c31af7Sopenharmony_ci		}
5727e5c31af7Sopenharmony_ci		// .patch_var_array
5728e5c31af7Sopenharmony_ci		{
5729e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(patchOutput));
5730e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5731e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
5732e5c31af7Sopenharmony_ci		}
5733e5c31af7Sopenharmony_ci		// .patch_var_array_explicit_location
5734e5c31af7Sopenharmony_ci		{
5735e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
5736e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
5737e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
5738e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
5739e5c31af7Sopenharmony_ci		}
5740e5c31af7Sopenharmony_ci	}
5741e5c31af7Sopenharmony_ci	else if (lastStage == glu::SHADERTYPE_COMPUTE)
5742e5c31af7Sopenharmony_ci	{
5743e5c31af7Sopenharmony_ci		// nada
5744e5c31af7Sopenharmony_ci	}
5745e5c31af7Sopenharmony_ci	else
5746e5c31af7Sopenharmony_ci		DE_ASSERT(false);
5747e5c31af7Sopenharmony_ci}
5748e5c31af7Sopenharmony_ci
5749e5c31af7Sopenharmony_cistatic void generateProgramInputOutputReferencedByCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
5750e5c31af7Sopenharmony_ci{
5751e5c31af7Sopenharmony_ci	// all whole pipelines
5752e5c31af7Sopenharmony_ci	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_fragment",			"",	storage,	ProgramInputOutputReferencedByCase::CASE_VERTEX_FRAGMENT));
5753e5c31af7Sopenharmony_ci	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_fragment",		"",	storage,	ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_FRAGMENT));
5754e5c31af7Sopenharmony_ci	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_geo_fragment",		"",	storage,	ProgramInputOutputReferencedByCase::CASE_VERTEX_GEO_FRAGMENT));
5755e5c31af7Sopenharmony_ci	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_geo_fragment",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_GEO_FRAGMENT));
5756e5c31af7Sopenharmony_ci
5757e5c31af7Sopenharmony_ci	// all partial pipelines
5758e5c31af7Sopenharmony_ci	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_vertex",		"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_VERTEX));
5759e5c31af7Sopenharmony_ci	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_fragment",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_FRAGMENT));
5760e5c31af7Sopenharmony_ci	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_geometry",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_GEOMETRY));
5761e5c31af7Sopenharmony_ci	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5762e5c31af7Sopenharmony_ci	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5763e5c31af7Sopenharmony_ci
5764e5c31af7Sopenharmony_ci	// patch
5765e5c31af7Sopenharmony_ci	if (storage == glu::STORAGE_IN)
5766e5c31af7Sopenharmony_ci		targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval_patch_in", "", glu::STORAGE_PATCH_IN, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
5767e5c31af7Sopenharmony_ci	else if (storage == glu::STORAGE_OUT)
5768e5c31af7Sopenharmony_ci		targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl_patch_out", "", glu::STORAGE_PATCH_OUT, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
5769e5c31af7Sopenharmony_ci	else
5770e5c31af7Sopenharmony_ci		DE_ASSERT(false);
5771e5c31af7Sopenharmony_ci}
5772e5c31af7Sopenharmony_ci
5773e5c31af7Sopenharmony_citemplate <ProgramInterface interface>
5774e5c31af7Sopenharmony_cistatic void generateProgramInputOutputTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool allowMatrixCases, int expandLevel)
5775e5c31af7Sopenharmony_ci{
5776e5c31af7Sopenharmony_ci	static const struct
5777e5c31af7Sopenharmony_ci	{
5778e5c31af7Sopenharmony_ci		glu::DataType	type;
5779e5c31af7Sopenharmony_ci		bool			isMatrix;
5780e5c31af7Sopenharmony_ci		int				level;
5781e5c31af7Sopenharmony_ci	} variableTypes[] =
5782e5c31af7Sopenharmony_ci	{
5783e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT,			false,		0	},
5784e5c31af7Sopenharmony_ci		{ glu::TYPE_INT,			false,		1	},
5785e5c31af7Sopenharmony_ci		{ glu::TYPE_UINT,			false,		1	},
5786e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_VEC2,		false,		2	},
5787e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_VEC3,		false,		1	},
5788e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_VEC4,		false,		2	},
5789e5c31af7Sopenharmony_ci		{ glu::TYPE_INT_VEC2,		false,		0	},
5790e5c31af7Sopenharmony_ci		{ glu::TYPE_INT_VEC3,		false,		2	},
5791e5c31af7Sopenharmony_ci		{ glu::TYPE_INT_VEC4,		false,		2	},
5792e5c31af7Sopenharmony_ci		{ glu::TYPE_UINT_VEC2,		false,		2	},
5793e5c31af7Sopenharmony_ci		{ glu::TYPE_UINT_VEC3,		false,		2	},
5794e5c31af7Sopenharmony_ci		{ glu::TYPE_UINT_VEC4,		false,		0	},
5795e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT2,		true,		2	},
5796e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT2X3,	true,		2	},
5797e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT2X4,	true,		2	},
5798e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT3X2,	true,		0	},
5799e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT3,		true,		2	},
5800e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT3X4,	true,		2	},
5801e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT4X2,	true,		2	},
5802e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT4X3,	true,		2	},
5803e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT4,		true,		2	},
5804e5c31af7Sopenharmony_ci	};
5805e5c31af7Sopenharmony_ci
5806e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
5807e5c31af7Sopenharmony_ci	{
5808e5c31af7Sopenharmony_ci		if (!allowMatrixCases && variableTypes[ndx].isMatrix)
5809e5c31af7Sopenharmony_ci			continue;
5810e5c31af7Sopenharmony_ci
5811e5c31af7Sopenharmony_ci		if (variableTypes[ndx].level <= expandLevel)
5812e5c31af7Sopenharmony_ci		{
5813e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
5814e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_TYPE)));
5815e5c31af7Sopenharmony_ci		}
5816e5c31af7Sopenharmony_ci	}
5817e5c31af7Sopenharmony_ci}
5818e5c31af7Sopenharmony_ci
5819e5c31af7Sopenharmony_cistatic void generateProgramInputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5820e5c31af7Sopenharmony_ci{
5821e5c31af7Sopenharmony_ci	DE_UNREF(isGL45);
5822e5c31af7Sopenharmony_ci	const bool									inDefaultBlock						= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5823e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	input								= (inDefaultBlock)
5824e5c31af7Sopenharmony_ci																						? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
5825e5c31af7Sopenharmony_ci																						: (parentStructure);
5826e5c31af7Sopenharmony_ci	const glu::ShaderType						firstStage							= getShaderMaskFirstStage(presentShadersMask);
5827e5c31af7Sopenharmony_ci	const int									interfaceBlockExpansionReducement	= (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5828e5c31af7Sopenharmony_ci
5829e5c31af7Sopenharmony_ci	if (firstStage == glu::SHADERTYPE_VERTEX)
5830e5c31af7Sopenharmony_ci	{
5831e5c31af7Sopenharmony_ci		// Only basic types (and no booleans)
5832e5c31af7Sopenharmony_ci		generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, input, targetGroup, true, 2 - interfaceBlockExpansionReducement);
5833e5c31af7Sopenharmony_ci	}
5834e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
5835e5c31af7Sopenharmony_ci	{
5836e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(input, glu::INTERPOLATION_FLAT));
5837e5c31af7Sopenharmony_ci
5838e5c31af7Sopenharmony_ci		// Only basic types, arrays of basic types, struct of basic types (and no booleans)
5839e5c31af7Sopenharmony_ci		{
5840e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5841e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5842e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5843e5c31af7Sopenharmony_ci		}
5844e5c31af7Sopenharmony_ci		{
5845e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(flatShading));
5846e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "array", "Array types");
5847e5c31af7Sopenharmony_ci
5848e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5849e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5850e5c31af7Sopenharmony_ci		}
5851e5c31af7Sopenharmony_ci		{
5852e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(flatShading));
5853e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "struct", "Struct types");
5854e5c31af7Sopenharmony_ci
5855e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5856e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMember, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5857e5c31af7Sopenharmony_ci		}
5858e5c31af7Sopenharmony_ci	}
5859e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
5860e5c31af7Sopenharmony_ci			 firstStage == glu::SHADERTYPE_GEOMETRY)
5861e5c31af7Sopenharmony_ci	{
5862e5c31af7Sopenharmony_ci		// arrayed interface
5863e5c31af7Sopenharmony_ci
5864e5c31af7Sopenharmony_ci		// Only basic types (and no booleans)
5865e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5866e5c31af7Sopenharmony_ci		generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, targetGroup, true, 2);
5867e5c31af7Sopenharmony_ci	}
5868e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
5869e5c31af7Sopenharmony_ci	{
5870e5c31af7Sopenharmony_ci		// arrayed interface
5871e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));
5872e5c31af7Sopenharmony_ci
5873e5c31af7Sopenharmony_ci		// .var
5874e5c31af7Sopenharmony_ci		{
5875e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElem		(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5876e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "basic_type", "Basic types");
5877e5c31af7Sopenharmony_ci
5878e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5879e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 2);
5880e5c31af7Sopenharmony_ci		}
5881e5c31af7Sopenharmony_ci		// extension forbids use arrays of structs
5882e5c31af7Sopenharmony_ci		// extension forbids use arrays of arrays
5883e5c31af7Sopenharmony_ci
5884e5c31af7Sopenharmony_ci		// .patch_var
5885e5c31af7Sopenharmony_ci		{
5886e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5887e5c31af7Sopenharmony_ci
5888e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5889e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, patchInput, blockGroup, true, 1);
5890e5c31af7Sopenharmony_ci		}
5891e5c31af7Sopenharmony_ci		// .patch_var_struct
5892e5c31af7Sopenharmony_ci		{
5893e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	structMbr		(new ResourceDefinition::StructMember(patchInput));
5894e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
5895e5c31af7Sopenharmony_ci
5896e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5897e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMbr, blockGroup, true, 1);
5898e5c31af7Sopenharmony_ci		}
5899e5c31af7Sopenharmony_ci		// .patch_var_array
5900e5c31af7Sopenharmony_ci		{
5901e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElem		(new ResourceDefinition::ArrayElement(patchInput));
5902e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
5903e5c31af7Sopenharmony_ci
5904e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5905e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 1);
5906e5c31af7Sopenharmony_ci		}
5907e5c31af7Sopenharmony_ci	}
5908e5c31af7Sopenharmony_ci	else if (firstStage == glu::SHADERTYPE_COMPUTE)
5909e5c31af7Sopenharmony_ci	{
5910e5c31af7Sopenharmony_ci		// nada
5911e5c31af7Sopenharmony_ci	}
5912e5c31af7Sopenharmony_ci	else
5913e5c31af7Sopenharmony_ci		DE_ASSERT(false);
5914e5c31af7Sopenharmony_ci}
5915e5c31af7Sopenharmony_ci
5916e5c31af7Sopenharmony_cistatic void generateProgramOutputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
5917e5c31af7Sopenharmony_ci{
5918e5c31af7Sopenharmony_ci	DE_UNREF(isGL45);
5919e5c31af7Sopenharmony_ci	const bool									inDefaultBlock						= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
5920e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	output								= (inDefaultBlock)
5921e5c31af7Sopenharmony_ci																						? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
5922e5c31af7Sopenharmony_ci																						: (parentStructure);
5923e5c31af7Sopenharmony_ci	const glu::ShaderType						lastStage							= getShaderMaskLastStage(presentShadersMask);
5924e5c31af7Sopenharmony_ci	const int									interfaceBlockExpansionReducement	= (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable
5925e5c31af7Sopenharmony_ci
5926e5c31af7Sopenharmony_ci	if (lastStage == glu::SHADERTYPE_VERTEX						||
5927e5c31af7Sopenharmony_ci		lastStage == glu::SHADERTYPE_GEOMETRY					||
5928e5c31af7Sopenharmony_ci		lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION	||
5929e5c31af7Sopenharmony_ci		!inDefaultBlock)
5930e5c31af7Sopenharmony_ci	{
5931e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
5932e5c31af7Sopenharmony_ci
5933e5c31af7Sopenharmony_ci		// Only basic types, arrays of basic types, struct of basic types (and no booleans)
5934e5c31af7Sopenharmony_ci		{
5935e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5936e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5937e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
5938e5c31af7Sopenharmony_ci		}
5939e5c31af7Sopenharmony_ci		{
5940e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElement			(new ResourceDefinition::ArrayElement(flatShading));
5941e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup				= new TestCaseGroup(context, "array", "Array types");
5942e5c31af7Sopenharmony_ci			const int									typeExpansionReducement	= (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5943e5c31af7Sopenharmony_ci			const int									expansionLevel			= 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5944e5c31af7Sopenharmony_ci
5945e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5946e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, true, expansionLevel);
5947e5c31af7Sopenharmony_ci		}
5948e5c31af7Sopenharmony_ci		{
5949e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	structMember			(new ResourceDefinition::StructMember(flatShading));
5950e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup				= new TestCaseGroup(context, "struct", "Struct types");
5951e5c31af7Sopenharmony_ci			const int									typeExpansionReducement	= (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
5952e5c31af7Sopenharmony_ci			const int									expansionLevel			= 2 - interfaceBlockExpansionReducement - typeExpansionReducement;
5953e5c31af7Sopenharmony_ci
5954e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5955e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMember, blockGroup, true, expansionLevel);
5956e5c31af7Sopenharmony_ci		}
5957e5c31af7Sopenharmony_ci	}
5958e5c31af7Sopenharmony_ci	else if (lastStage == glu::SHADERTYPE_FRAGMENT)
5959e5c31af7Sopenharmony_ci	{
5960e5c31af7Sopenharmony_ci		// only basic type and basic type array (and no booleans or matrices)
5961e5c31af7Sopenharmony_ci		{
5962e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
5963e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5964e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, output, blockGroup, false, 2);
5965e5c31af7Sopenharmony_ci		}
5966e5c31af7Sopenharmony_ci		{
5967e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(output));
5968e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "array", "Array types");
5969e5c31af7Sopenharmony_ci
5970e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5971e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, false, 2);
5972e5c31af7Sopenharmony_ci		}
5973e5c31af7Sopenharmony_ci	}
5974e5c31af7Sopenharmony_ci	else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
5975e5c31af7Sopenharmony_ci	{
5976e5c31af7Sopenharmony_ci		// arrayed interface
5977e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));
5978e5c31af7Sopenharmony_ci
5979e5c31af7Sopenharmony_ci		// .var
5980e5c31af7Sopenharmony_ci		{
5981e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElem		(new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
5982e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "basic_type", "Basic types");
5983e5c31af7Sopenharmony_ci
5984e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5985e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 2);
5986e5c31af7Sopenharmony_ci		}
5987e5c31af7Sopenharmony_ci		// extension forbids use arrays of structs
5988e5c31af7Sopenharmony_ci		// extension forbids use arrays of arrays
5989e5c31af7Sopenharmony_ci
5990e5c31af7Sopenharmony_ci		// .patch_var
5991e5c31af7Sopenharmony_ci		{
5992e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var", "Basic types, per-patch");
5993e5c31af7Sopenharmony_ci
5994e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
5995e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, patchOutput, blockGroup, true, 1);
5996e5c31af7Sopenharmony_ci		}
5997e5c31af7Sopenharmony_ci		// .patch_var_struct
5998e5c31af7Sopenharmony_ci		{
5999e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	structMbr		(new ResourceDefinition::StructMember(patchOutput));
6000e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");
6001e5c31af7Sopenharmony_ci
6002e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
6003e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMbr, blockGroup, true, 1);
6004e5c31af7Sopenharmony_ci		}
6005e5c31af7Sopenharmony_ci		// .patch_var_array
6006e5c31af7Sopenharmony_ci		{
6007e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr	arrayElem		(new ResourceDefinition::ArrayElement(patchOutput));
6008e5c31af7Sopenharmony_ci			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");
6009e5c31af7Sopenharmony_ci
6010e5c31af7Sopenharmony_ci			targetGroup->addChild(blockGroup);
6011e5c31af7Sopenharmony_ci			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 1);
6012e5c31af7Sopenharmony_ci		}
6013e5c31af7Sopenharmony_ci	}
6014e5c31af7Sopenharmony_ci	else if (lastStage == glu::SHADERTYPE_COMPUTE)
6015e5c31af7Sopenharmony_ci	{
6016e5c31af7Sopenharmony_ci		// nada
6017e5c31af7Sopenharmony_ci	}
6018e5c31af7Sopenharmony_ci	else
6019e5c31af7Sopenharmony_ci		DE_ASSERT(false);
6020e5c31af7Sopenharmony_ci}
6021e5c31af7Sopenharmony_ci
6022e5c31af7Sopenharmony_ciclass ProgramInputTestGroup : public TestCaseGroup
6023e5c31af7Sopenharmony_ci{
6024e5c31af7Sopenharmony_cipublic:
6025e5c31af7Sopenharmony_ci			ProgramInputTestGroup	(Context& context, bool is_GL45);
6026e5c31af7Sopenharmony_ci	void	init					(void);
6027e5c31af7Sopenharmony_ci
6028e5c31af7Sopenharmony_ciprivate:
6029e5c31af7Sopenharmony_ci	bool m_isGL45;
6030e5c31af7Sopenharmony_ci};
6031e5c31af7Sopenharmony_ci
6032e5c31af7Sopenharmony_ciProgramInputTestGroup::ProgramInputTestGroup (Context& context, bool is_GL45)
6033e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "program_input", "Program input")
6034e5c31af7Sopenharmony_ci	, m_isGL45(is_GL45)
6035e5c31af7Sopenharmony_ci{
6036e5c31af7Sopenharmony_ci}
6037e5c31af7Sopenharmony_ci
6038e5c31af7Sopenharmony_civoid ProgramInputTestGroup::init (void)
6039e5c31af7Sopenharmony_ci{
6040e5c31af7Sopenharmony_ci	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6041e5c31af7Sopenharmony_ci
6042e5c31af7Sopenharmony_ci	// .resource_list
6043e5c31af7Sopenharmony_ci	{
6044e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6045e5c31af7Sopenharmony_ci		addChild(blockGroup);
6046e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, true, m_isGL45, generateProgramInputResourceListBlockContents);
6047e5c31af7Sopenharmony_ci	}
6048e5c31af7Sopenharmony_ci
6049e5c31af7Sopenharmony_ci	// .array_size
6050e5c31af7Sopenharmony_ci	{
6051e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6052e5c31af7Sopenharmony_ci		addChild(blockGroup);
6053e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6054e5c31af7Sopenharmony_ci	}
6055e5c31af7Sopenharmony_ci
6056e5c31af7Sopenharmony_ci	// .location
6057e5c31af7Sopenharmony_ci	{
6058e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6059e5c31af7Sopenharmony_ci		addChild(blockGroup);
6060e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputLocationBlockContents);
6061e5c31af7Sopenharmony_ci	}
6062e5c31af7Sopenharmony_ci
6063e5c31af7Sopenharmony_ci	// .name_length
6064e5c31af7Sopenharmony_ci	{
6065e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6066e5c31af7Sopenharmony_ci		addChild(blockGroup);
6067e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6068e5c31af7Sopenharmony_ci	}
6069e5c31af7Sopenharmony_ci
6070e5c31af7Sopenharmony_ci	// .referenced_by
6071e5c31af7Sopenharmony_ci	{
6072e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6073e5c31af7Sopenharmony_ci		addChild(blockGroup);
6074e5c31af7Sopenharmony_ci		generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_IN);
6075e5c31af7Sopenharmony_ci	}
6076e5c31af7Sopenharmony_ci
6077e5c31af7Sopenharmony_ci	// .type
6078e5c31af7Sopenharmony_ci	{
6079e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6080e5c31af7Sopenharmony_ci		addChild(blockGroup);
6081e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputTypeBlockContents);
6082e5c31af7Sopenharmony_ci	}
6083e5c31af7Sopenharmony_ci
6084e5c31af7Sopenharmony_ci	// .is_per_patch
6085e5c31af7Sopenharmony_ci	{
6086e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6087e5c31af7Sopenharmony_ci		addChild(blockGroup);
6088e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6089e5c31af7Sopenharmony_ci	}
6090e5c31af7Sopenharmony_ci}
6091e5c31af7Sopenharmony_ci
6092e5c31af7Sopenharmony_ciclass ProgramOutputTestGroup : public TestCaseGroup
6093e5c31af7Sopenharmony_ci{
6094e5c31af7Sopenharmony_cipublic:
6095e5c31af7Sopenharmony_ci			ProgramOutputTestGroup	(Context& context, bool is_GL45);
6096e5c31af7Sopenharmony_ci	void	init					(void);
6097e5c31af7Sopenharmony_ci
6098e5c31af7Sopenharmony_ciprivate:
6099e5c31af7Sopenharmony_ci	bool m_isGL45;
6100e5c31af7Sopenharmony_ci};
6101e5c31af7Sopenharmony_ci
6102e5c31af7Sopenharmony_ciProgramOutputTestGroup::ProgramOutputTestGroup (Context& context, bool is_GL45)
6103e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "program_output", "Program output")
6104e5c31af7Sopenharmony_ci	, m_isGL45(is_GL45)
6105e5c31af7Sopenharmony_ci{
6106e5c31af7Sopenharmony_ci}
6107e5c31af7Sopenharmony_ci
6108e5c31af7Sopenharmony_civoid ProgramOutputTestGroup::init (void)
6109e5c31af7Sopenharmony_ci{
6110e5c31af7Sopenharmony_ci	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6111e5c31af7Sopenharmony_ci
6112e5c31af7Sopenharmony_ci	// .resource_list
6113e5c31af7Sopenharmony_ci	{
6114e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
6115e5c31af7Sopenharmony_ci		addChild(blockGroup);
6116e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, false, m_isGL45, generateProgramOutputResourceListBlockContents);
6117e5c31af7Sopenharmony_ci	}
6118e5c31af7Sopenharmony_ci
6119e5c31af7Sopenharmony_ci	// .array_size
6120e5c31af7Sopenharmony_ci	{
6121e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
6122e5c31af7Sopenharmony_ci		addChild(blockGroup);
6123e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6124e5c31af7Sopenharmony_ci	}
6125e5c31af7Sopenharmony_ci
6126e5c31af7Sopenharmony_ci	// .location
6127e5c31af7Sopenharmony_ci	{
6128e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
6129e5c31af7Sopenharmony_ci		addChild(blockGroup);
6130e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputLocationBlockContents);
6131e5c31af7Sopenharmony_ci	}
6132e5c31af7Sopenharmony_ci
6133e5c31af7Sopenharmony_ci	// .name_length
6134e5c31af7Sopenharmony_ci	{
6135e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
6136e5c31af7Sopenharmony_ci		addChild(blockGroup);
6137e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6138e5c31af7Sopenharmony_ci	}
6139e5c31af7Sopenharmony_ci
6140e5c31af7Sopenharmony_ci	// .referenced_by
6141e5c31af7Sopenharmony_ci	{
6142e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
6143e5c31af7Sopenharmony_ci		addChild(blockGroup);
6144e5c31af7Sopenharmony_ci		generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_OUT);
6145e5c31af7Sopenharmony_ci	}
6146e5c31af7Sopenharmony_ci
6147e5c31af7Sopenharmony_ci	// .type
6148e5c31af7Sopenharmony_ci	{
6149e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
6150e5c31af7Sopenharmony_ci		addChild(blockGroup);
6151e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputTypeBlockContents);
6152e5c31af7Sopenharmony_ci	}
6153e5c31af7Sopenharmony_ci
6154e5c31af7Sopenharmony_ci	// .is_per_patch
6155e5c31af7Sopenharmony_ci	{
6156e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
6157e5c31af7Sopenharmony_ci		addChild(blockGroup);
6158e5c31af7Sopenharmony_ci		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
6159e5c31af7Sopenharmony_ci	}
6160e5c31af7Sopenharmony_ci}
6161e5c31af7Sopenharmony_ci
6162e5c31af7Sopenharmony_cistatic void generateTransformFeedbackShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6163e5c31af7Sopenharmony_ci{
6164e5c31af7Sopenharmony_ci	static const struct
6165e5c31af7Sopenharmony_ci	{
6166e5c31af7Sopenharmony_ci		const char*	name;
6167e5c31af7Sopenharmony_ci		deUint32	stageBits;
6168e5c31af7Sopenharmony_ci		deUint32	lastStageBit;
6169e5c31af7Sopenharmony_ci		bool		reducedSet;
6170e5c31af7Sopenharmony_ci	} pipelines[] =
6171e5c31af7Sopenharmony_ci	{
6172e5c31af7Sopenharmony_ci		{
6173e5c31af7Sopenharmony_ci			"vertex_fragment",
6174e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
6175e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX),
6176e5c31af7Sopenharmony_ci			false
6177e5c31af7Sopenharmony_ci		},
6178e5c31af7Sopenharmony_ci		{
6179e5c31af7Sopenharmony_ci			"vertex_tess_fragment",
6180e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6181e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
6182e5c31af7Sopenharmony_ci			true
6183e5c31af7Sopenharmony_ci		},
6184e5c31af7Sopenharmony_ci		{
6185e5c31af7Sopenharmony_ci			"vertex_geo_fragment",
6186e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
6187e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_GEOMETRY),
6188e5c31af7Sopenharmony_ci			true
6189e5c31af7Sopenharmony_ci		},
6190e5c31af7Sopenharmony_ci		{
6191e5c31af7Sopenharmony_ci			"vertex_tess_geo_fragment",
6192e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
6193e5c31af7Sopenharmony_ci			(1 << glu::SHADERTYPE_GEOMETRY),
6194e5c31af7Sopenharmony_ci			true
6195e5c31af7Sopenharmony_ci		},
6196e5c31af7Sopenharmony_ci	};
6197e5c31af7Sopenharmony_ci	static const struct
6198e5c31af7Sopenharmony_ci	{
6199e5c31af7Sopenharmony_ci		const char*		name;
6200e5c31af7Sopenharmony_ci		glu::ShaderType	stage;
6201e5c31af7Sopenharmony_ci		bool			reducedSet;
6202e5c31af7Sopenharmony_ci	} singleStageCases[] =
6203e5c31af7Sopenharmony_ci	{
6204e5c31af7Sopenharmony_ci		{ "separable_vertex",		glu::SHADERTYPE_VERTEX,						false	},
6205e5c31af7Sopenharmony_ci		{ "separable_tess_eval",	glu::SHADERTYPE_TESSELLATION_EVALUATION,	true	},
6206e5c31af7Sopenharmony_ci		{ "separable_geometry",		glu::SHADERTYPE_GEOMETRY,					true	},
6207e5c31af7Sopenharmony_ci	};
6208e5c31af7Sopenharmony_ci
6209e5c31af7Sopenharmony_ci	// monolithic pipeline
6210e5c31af7Sopenharmony_ci	for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
6211e5c31af7Sopenharmony_ci	{
6212e5c31af7Sopenharmony_ci		TestCaseGroup* const						blockGroup		= new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
6213e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
6214e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	shaderSet		(new ResourceDefinition::ShaderSet(program,
6215e5c31af7Sopenharmony_ci																									   glslVersion,
6216e5c31af7Sopenharmony_ci																									   pipelines[pipelineNdx].stageBits,
6217e5c31af7Sopenharmony_ci																									   pipelines[pipelineNdx].lastStageBit));
6218e5c31af7Sopenharmony_ci
6219e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6220e5c31af7Sopenharmony_ci		blockContentGenerator(context, shaderSet, blockGroup, pipelines[pipelineNdx].reducedSet);
6221e5c31af7Sopenharmony_ci	}
6222e5c31af7Sopenharmony_ci
6223e5c31af7Sopenharmony_ci	// separable pipeline
6224e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
6225e5c31af7Sopenharmony_ci	{
6226e5c31af7Sopenharmony_ci		TestCaseGroup* const						blockGroup			= new TestCaseGroup(context, singleStageCases[ndx].name, "");
6227e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program(true));
6228e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	shader				(new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glslVersion));
6229e5c31af7Sopenharmony_ci
6230e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6231e5c31af7Sopenharmony_ci		blockContentGenerator(context, shader, blockGroup, singleStageCases[ndx].reducedSet);
6232e5c31af7Sopenharmony_ci	}
6233e5c31af7Sopenharmony_ci}
6234e5c31af7Sopenharmony_ci
6235e5c31af7Sopenharmony_cistatic void generateTransformFeedbackResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6236e5c31af7Sopenharmony_ci{
6237e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
6238e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	output			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6239e5c31af7Sopenharmony_ci
6240e5c31af7Sopenharmony_ci	DE_UNREF(reducedSet);
6241e5c31af7Sopenharmony_ci
6242e5c31af7Sopenharmony_ci	// .builtin_gl_position
6243e5c31af7Sopenharmony_ci	{
6244e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6245e5c31af7Sopenharmony_ci		targetGroup->addChild(new FeedbackResourceListTestCase(context, xfbTarget, "builtin_gl_position"));
6246e5c31af7Sopenharmony_ci	}
6247e5c31af7Sopenharmony_ci	// .default_block_basic_type
6248e5c31af7Sopenharmony_ci	{
6249e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(output));
6250e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6251e5c31af7Sopenharmony_ci		targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_basic_type"));
6252e5c31af7Sopenharmony_ci	}
6253e5c31af7Sopenharmony_ci	// .default_block_struct_member
6254e5c31af7Sopenharmony_ci	{
6255e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(output));
6256e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(structMbr));
6257e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6258e5c31af7Sopenharmony_ci		targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_struct_member"));
6259e5c31af7Sopenharmony_ci	}
6260e5c31af7Sopenharmony_ci	// .default_block_array
6261e5c31af7Sopenharmony_ci	{
6262e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(output));
6263e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(xfbTarget));
6264e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6265e5c31af7Sopenharmony_ci		targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array"));
6266e5c31af7Sopenharmony_ci	}
6267e5c31af7Sopenharmony_ci	// .default_block_array_element
6268e5c31af7Sopenharmony_ci	{
6269e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
6270e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6271e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6272e5c31af7Sopenharmony_ci		targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array_element"));
6273e5c31af7Sopenharmony_ci	}
6274e5c31af7Sopenharmony_ci}
6275e5c31af7Sopenharmony_ci
6276e5c31af7Sopenharmony_citemplate <ProgramResourcePropFlags TargetProp>
6277e5c31af7Sopenharmony_cistatic void generateTransformFeedbackVariableBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6278e5c31af7Sopenharmony_ci{
6279e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
6280e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	output			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6281e5c31af7Sopenharmony_ci
6282e5c31af7Sopenharmony_ci	DE_UNREF(reducedSet);
6283e5c31af7Sopenharmony_ci
6284e5c31af7Sopenharmony_ci	// .builtin_gl_position
6285e5c31af7Sopenharmony_ci	{
6286e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6287e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "builtin_gl_position"));
6288e5c31af7Sopenharmony_ci	}
6289e5c31af7Sopenharmony_ci	// .default_block_basic_type
6290e5c31af7Sopenharmony_ci	{
6291e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(output));
6292e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6293e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_basic_type"));
6294e5c31af7Sopenharmony_ci	}
6295e5c31af7Sopenharmony_ci	// .default_block_struct_member
6296e5c31af7Sopenharmony_ci	{
6297e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(output));
6298e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(structMbr));
6299e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6300e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_struct_member"));
6301e5c31af7Sopenharmony_ci	}
6302e5c31af7Sopenharmony_ci	// .default_block_array
6303e5c31af7Sopenharmony_ci	{
6304e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(output));
6305e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(xfbTarget));
6306e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
6307e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array"));
6308e5c31af7Sopenharmony_ci	}
6309e5c31af7Sopenharmony_ci	// .default_block_array_element
6310e5c31af7Sopenharmony_ci	{
6311e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
6312e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(arrayElem));
6313e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
6314e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array_element"));
6315e5c31af7Sopenharmony_ci	}
6316e5c31af7Sopenharmony_ci}
6317e5c31af7Sopenharmony_ci
6318e5c31af7Sopenharmony_cistatic void generateTransformFeedbackVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6319e5c31af7Sopenharmony_ci{
6320e5c31af7Sopenharmony_ci	static const struct
6321e5c31af7Sopenharmony_ci	{
6322e5c31af7Sopenharmony_ci		glu::DataType	type;
6323e5c31af7Sopenharmony_ci		bool			important;
6324e5c31af7Sopenharmony_ci	} variableTypes[] =
6325e5c31af7Sopenharmony_ci	{
6326e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT,			true	},
6327e5c31af7Sopenharmony_ci		{ glu::TYPE_INT,			true	},
6328e5c31af7Sopenharmony_ci		{ glu::TYPE_UINT,			true	},
6329e5c31af7Sopenharmony_ci
6330e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_VEC2,		false	},
6331e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_VEC3,		true	},
6332e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_VEC4,		false	},
6333e5c31af7Sopenharmony_ci
6334e5c31af7Sopenharmony_ci		{ glu::TYPE_INT_VEC2,		false	},
6335e5c31af7Sopenharmony_ci		{ glu::TYPE_INT_VEC3,		true	},
6336e5c31af7Sopenharmony_ci		{ glu::TYPE_INT_VEC4,		false	},
6337e5c31af7Sopenharmony_ci
6338e5c31af7Sopenharmony_ci		{ glu::TYPE_UINT_VEC2,		true	},
6339e5c31af7Sopenharmony_ci		{ glu::TYPE_UINT_VEC3,		false	},
6340e5c31af7Sopenharmony_ci		{ glu::TYPE_UINT_VEC4,		false	},
6341e5c31af7Sopenharmony_ci
6342e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT2,		false	},
6343e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT2X3,	false	},
6344e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT2X4,	false	},
6345e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT3X2,	false	},
6346e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT3,		false	},
6347e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT3X4,	true	},
6348e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT4X2,	false	},
6349e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT4X3,	false	},
6350e5c31af7Sopenharmony_ci		{ glu::TYPE_FLOAT_MAT4,		false	},
6351e5c31af7Sopenharmony_ci	};
6352e5c31af7Sopenharmony_ci
6353e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6354e5c31af7Sopenharmony_ci	{
6355e5c31af7Sopenharmony_ci		if (variableTypes[ndx].important || !reducedSet)
6356e5c31af7Sopenharmony_ci		{
6357e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
6358e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE)));
6359e5c31af7Sopenharmony_ci		}
6360e5c31af7Sopenharmony_ci	}
6361e5c31af7Sopenharmony_ci}
6362e5c31af7Sopenharmony_ci
6363e5c31af7Sopenharmony_cistatic void generateTransformFeedbackVariableTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
6364e5c31af7Sopenharmony_ci{
6365e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
6366e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	output			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
6367e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	flatShading		(new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));
6368e5c31af7Sopenharmony_ci
6369e5c31af7Sopenharmony_ci	// Only builtins, basic types, arrays of basic types, struct of basic types (and no booleans)
6370e5c31af7Sopenharmony_ci	{
6371e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
6372e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "builtin", "Built-in outputs");
6373e5c31af7Sopenharmony_ci
6374e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6375e5c31af7Sopenharmony_ci		blockGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE), "gl_position"));
6376e5c31af7Sopenharmony_ci	}
6377e5c31af7Sopenharmony_ci	{
6378e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(flatShading));
6379e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "basic_type", "Basic types");
6380e5c31af7Sopenharmony_ci
6381e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6382e5c31af7Sopenharmony_ci		generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6383e5c31af7Sopenharmony_ci	}
6384e5c31af7Sopenharmony_ci	{
6385e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(flatShading));
6386e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(arrayElement));
6387e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "array", "Array types");
6388e5c31af7Sopenharmony_ci
6389e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6390e5c31af7Sopenharmony_ci		generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6391e5c31af7Sopenharmony_ci	}
6392e5c31af7Sopenharmony_ci	{
6393e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(flatShading));
6394e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(xfbTarget));
6395e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "whole_array", "Whole array");
6396e5c31af7Sopenharmony_ci
6397e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6398e5c31af7Sopenharmony_ci		generateTransformFeedbackVariableBasicTypeCases(context, arrayElement, blockGroup, reducedSet);
6399e5c31af7Sopenharmony_ci	}
6400e5c31af7Sopenharmony_ci	{
6401e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(flatShading));
6402e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(structMember));
6403e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "struct", "Struct types");
6404e5c31af7Sopenharmony_ci
6405e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6406e5c31af7Sopenharmony_ci		generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
6407e5c31af7Sopenharmony_ci	}
6408e5c31af7Sopenharmony_ci}
6409e5c31af7Sopenharmony_ci
6410e5c31af7Sopenharmony_ciclass TransformFeedbackVaryingTestGroup : public TestCaseGroup
6411e5c31af7Sopenharmony_ci{
6412e5c31af7Sopenharmony_cipublic:
6413e5c31af7Sopenharmony_ci			TransformFeedbackVaryingTestGroup	(Context& context);
6414e5c31af7Sopenharmony_ci	void	init								(void);
6415e5c31af7Sopenharmony_ci};
6416e5c31af7Sopenharmony_ci
6417e5c31af7Sopenharmony_ciTransformFeedbackVaryingTestGroup::TransformFeedbackVaryingTestGroup (Context& context)
6418e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "transform_feedback_varying", "Transform feedback varyings")
6419e5c31af7Sopenharmony_ci{
6420e5c31af7Sopenharmony_ci}
6421e5c31af7Sopenharmony_ci
6422e5c31af7Sopenharmony_civoid TransformFeedbackVaryingTestGroup::init (void)
6423e5c31af7Sopenharmony_ci{
6424e5c31af7Sopenharmony_ci	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6425e5c31af7Sopenharmony_ci
6426e5c31af7Sopenharmony_ci	// .resource_list
6427e5c31af7Sopenharmony_ci	{
6428e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6429e5c31af7Sopenharmony_ci		addChild(blockGroup);
6430e5c31af7Sopenharmony_ci		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackResourceListBlockContents);
6431e5c31af7Sopenharmony_ci	}
6432e5c31af7Sopenharmony_ci
6433e5c31af7Sopenharmony_ci	// .array_size
6434e5c31af7Sopenharmony_ci	{
6435e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6436e5c31af7Sopenharmony_ci		addChild(blockGroup);
6437e5c31af7Sopenharmony_ci		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6438e5c31af7Sopenharmony_ci	}
6439e5c31af7Sopenharmony_ci
6440e5c31af7Sopenharmony_ci	// .name_length
6441e5c31af7Sopenharmony_ci	{
6442e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
6443e5c31af7Sopenharmony_ci		addChild(blockGroup);
6444e5c31af7Sopenharmony_ci		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
6445e5c31af7Sopenharmony_ci	}
6446e5c31af7Sopenharmony_ci
6447e5c31af7Sopenharmony_ci	// .type
6448e5c31af7Sopenharmony_ci	{
6449e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
6450e5c31af7Sopenharmony_ci		addChild(blockGroup);
6451e5c31af7Sopenharmony_ci		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableTypeBlockContents);
6452e5c31af7Sopenharmony_ci	}
6453e5c31af7Sopenharmony_ci}
6454e5c31af7Sopenharmony_ci
6455e5c31af7Sopenharmony_cistatic void generateBufferVariableBufferCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*))
6456e5c31af7Sopenharmony_ci{
6457e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
6458e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6459e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
6460e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	bufferStorage	(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6461e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	binding			(new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6462e5c31af7Sopenharmony_ci
6463e5c31af7Sopenharmony_ci	// .named_block
6464e5c31af7Sopenharmony_ci	{
6465e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, true));
6466e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "named_block", "Named block");
6467e5c31af7Sopenharmony_ci
6468e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6469e5c31af7Sopenharmony_ci
6470e5c31af7Sopenharmony_ci		blockContentGenerator(context, buffer, blockGroup);
6471e5c31af7Sopenharmony_ci	}
6472e5c31af7Sopenharmony_ci
6473e5c31af7Sopenharmony_ci	// .unnamed_block
6474e5c31af7Sopenharmony_ci	{
6475e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, false));
6476e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6477e5c31af7Sopenharmony_ci
6478e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6479e5c31af7Sopenharmony_ci
6480e5c31af7Sopenharmony_ci		blockContentGenerator(context, buffer, blockGroup);
6481e5c31af7Sopenharmony_ci	}
6482e5c31af7Sopenharmony_ci
6483e5c31af7Sopenharmony_ci	// .block_array
6484e5c31af7Sopenharmony_ci	{
6485e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(binding));
6486e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
6487e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "block_array", "Block array");
6488e5c31af7Sopenharmony_ci
6489e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6490e5c31af7Sopenharmony_ci
6491e5c31af7Sopenharmony_ci		blockContentGenerator(context, buffer, blockGroup);
6492e5c31af7Sopenharmony_ci	}
6493e5c31af7Sopenharmony_ci}
6494e5c31af7Sopenharmony_ci
6495e5c31af7Sopenharmony_cistatic void generateBufferVariableResourceListBlockContentsProxy (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6496e5c31af7Sopenharmony_ci{
6497e5c31af7Sopenharmony_ci	generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, 4);
6498e5c31af7Sopenharmony_ci}
6499e5c31af7Sopenharmony_ci
6500e5c31af7Sopenharmony_cistatic void generateBufferVariableArraySizeSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramResourcePropFlags targetProp, bool sizedArray, bool extendedCases)
6501e5c31af7Sopenharmony_ci{
6502e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget	queryTarget		(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp);
6503e5c31af7Sopenharmony_ci	tcu::TestCaseGroup*						aggregateGroup;
6504e5c31af7Sopenharmony_ci
6505e5c31af7Sopenharmony_ci	// .types
6506e5c31af7Sopenharmony_ci	if (extendedCases)
6507e5c31af7Sopenharmony_ci	{
6508e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
6509e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6510e5c31af7Sopenharmony_ci
6511e5c31af7Sopenharmony_ci		generateVariableCases(context, parentStructure, blockGroup, queryTarget, (sizedArray) ? (2) : (1), false);
6512e5c31af7Sopenharmony_ci	}
6513e5c31af7Sopenharmony_ci
6514e5c31af7Sopenharmony_ci	// .aggregates
6515e5c31af7Sopenharmony_ci	if (extendedCases)
6516e5c31af7Sopenharmony_ci	{
6517e5c31af7Sopenharmony_ci		aggregateGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
6518e5c31af7Sopenharmony_ci		targetGroup->addChild(aggregateGroup);
6519e5c31af7Sopenharmony_ci	}
6520e5c31af7Sopenharmony_ci	else
6521e5c31af7Sopenharmony_ci		aggregateGroup = targetGroup;
6522e5c31af7Sopenharmony_ci
6523e5c31af7Sopenharmony_ci	// .float_*
6524e5c31af7Sopenharmony_ci	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6525e5c31af7Sopenharmony_ci
6526e5c31af7Sopenharmony_ci	// .bool_*
6527e5c31af7Sopenharmony_ci	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL, (extendedCases && sizedArray) ? (1) : (0), !extendedCases);
6528e5c31af7Sopenharmony_ci
6529e5c31af7Sopenharmony_ci	// .bvec3_*
6530e5c31af7Sopenharmony_ci	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6531e5c31af7Sopenharmony_ci
6532e5c31af7Sopenharmony_ci	// .vec4_*
6533e5c31af7Sopenharmony_ci	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC4, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6534e5c31af7Sopenharmony_ci
6535e5c31af7Sopenharmony_ci	// .ivec2_*
6536e5c31af7Sopenharmony_ci	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_INT_VEC2, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
6537e5c31af7Sopenharmony_ci}
6538e5c31af7Sopenharmony_ci
6539e5c31af7Sopenharmony_citemplate <ProgramResourcePropFlags TargetProp>
6540e5c31af7Sopenharmony_cistatic void generateBufferVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
6541e5c31af7Sopenharmony_ci{
6542e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp);
6543e5c31af7Sopenharmony_ci	const bool								namedNonArrayBlock	= static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named && parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;
6544e5c31af7Sopenharmony_ci
6545e5c31af7Sopenharmony_ci	// .non_array
6546e5c31af7Sopenharmony_ci	if (namedNonArrayBlock)
6547e5c31af7Sopenharmony_ci	{
6548e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "non_array", "Non-array target");
6549e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6550e5c31af7Sopenharmony_ci
6551e5c31af7Sopenharmony_ci		generateVariableCases(context, parentStructure, blockGroup, queryTarget, 1, false);
6552e5c31af7Sopenharmony_ci	}
6553e5c31af7Sopenharmony_ci
6554e5c31af7Sopenharmony_ci	// .sized
6555e5c31af7Sopenharmony_ci	{
6556e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	sized		(new ResourceDefinition::ArrayElement(parentStructure));
6557e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "sized", "Sized target");
6558e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6559e5c31af7Sopenharmony_ci
6560e5c31af7Sopenharmony_ci		generateBufferVariableArraySizeSubCases(context, sized, blockGroup, TargetProp, true, namedNonArrayBlock);
6561e5c31af7Sopenharmony_ci	}
6562e5c31af7Sopenharmony_ci
6563e5c31af7Sopenharmony_ci	// .unsized
6564e5c31af7Sopenharmony_ci	{
6565e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	unsized		(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6566e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unsized", "Unsized target");
6567e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6568e5c31af7Sopenharmony_ci
6569e5c31af7Sopenharmony_ci		generateBufferVariableArraySizeSubCases(context, unsized, blockGroup, TargetProp, false, namedNonArrayBlock);
6570e5c31af7Sopenharmony_ci	}
6571e5c31af7Sopenharmony_ci}
6572e5c31af7Sopenharmony_ci
6573e5c31af7Sopenharmony_cistatic void generateBufferVariableBlockIndexCases (Context& context, glu::GLSLVersion glslVersion, tcu::TestCaseGroup* const targetGroup)
6574e5c31af7Sopenharmony_ci{
6575e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
6576e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6577e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
6578e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	bufferStorage	(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6579e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	binding			(new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));
6580e5c31af7Sopenharmony_ci
6581e5c31af7Sopenharmony_ci	// .named_block
6582e5c31af7Sopenharmony_ci	{
6583e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, true));
6584e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6585e5c31af7Sopenharmony_ci
6586e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
6587e5c31af7Sopenharmony_ci	}
6588e5c31af7Sopenharmony_ci
6589e5c31af7Sopenharmony_ci	// .unnamed_block
6590e5c31af7Sopenharmony_ci	{
6591e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, false));
6592e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6593e5c31af7Sopenharmony_ci
6594e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
6595e5c31af7Sopenharmony_ci	}
6596e5c31af7Sopenharmony_ci
6597e5c31af7Sopenharmony_ci	// .block_array
6598e5c31af7Sopenharmony_ci	{
6599e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(binding));
6600e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
6601e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));
6602e5c31af7Sopenharmony_ci
6603e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
6604e5c31af7Sopenharmony_ci	}
6605e5c31af7Sopenharmony_ci}
6606e5c31af7Sopenharmony_ci
6607e5c31af7Sopenharmony_cistatic void generateBufferVariableMatrixCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
6608e5c31af7Sopenharmony_ci{
6609e5c31af7Sopenharmony_ci	static const struct
6610e5c31af7Sopenharmony_ci	{
6611e5c31af7Sopenharmony_ci		const char*			name;
6612e5c31af7Sopenharmony_ci		const char*			description;
6613e5c31af7Sopenharmony_ci		bool				namedBlock;
6614e5c31af7Sopenharmony_ci		bool				extendedBasicTypeCases;
6615e5c31af7Sopenharmony_ci		glu::MatrixOrder	order;
6616e5c31af7Sopenharmony_ci	} children[] =
6617e5c31af7Sopenharmony_ci	{
6618e5c31af7Sopenharmony_ci		{ "named_block",				"Named uniform block",		true,	true,	glu::MATRIXORDER_LAST			},
6619e5c31af7Sopenharmony_ci		{ "named_block_row_major",		"Named uniform block",		true,	false,	glu::MATRIXORDER_ROW_MAJOR		},
6620e5c31af7Sopenharmony_ci		{ "named_block_col_major",		"Named uniform block",		true,	false,	glu::MATRIXORDER_COLUMN_MAJOR	},
6621e5c31af7Sopenharmony_ci		{ "unnamed_block",				"Unnamed uniform block",	false,	false,	glu::MATRIXORDER_LAST			},
6622e5c31af7Sopenharmony_ci		{ "unnamed_block_row_major",	"Unnamed uniform block",	false,	false,	glu::MATRIXORDER_ROW_MAJOR		},
6623e5c31af7Sopenharmony_ci		{ "unnamed_block_col_major",	"Unnamed uniform block",	false,	false,	glu::MATRIXORDER_COLUMN_MAJOR	},
6624e5c31af7Sopenharmony_ci	};
6625e5c31af7Sopenharmony_ci
6626e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
6627e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6628e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
6629e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6630e5c31af7Sopenharmony_ci
6631e5c31af7Sopenharmony_ci	for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
6632e5c31af7Sopenharmony_ci	{
6633e5c31af7Sopenharmony_ci		ResourceDefinition::Node::SharedPtr	parentStructure	= buffer;
6634e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const			blockGroup		= new TestCaseGroup(context, children[childNdx].name, children[childNdx].description);
6635e5c31af7Sopenharmony_ci
6636e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6637e5c31af7Sopenharmony_ci
6638e5c31af7Sopenharmony_ci		if (children[childNdx].order != glu::MATRIXORDER_LAST)
6639e5c31af7Sopenharmony_ci		{
6640e5c31af7Sopenharmony_ci			glu::Layout layout;
6641e5c31af7Sopenharmony_ci			layout.matrixOrder = children[childNdx].order;
6642e5c31af7Sopenharmony_ci			parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(parentStructure, layout));
6643e5c31af7Sopenharmony_ci		}
6644e5c31af7Sopenharmony_ci
6645e5c31af7Sopenharmony_ci		parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(parentStructure, children[childNdx].namedBlock));
6646e5c31af7Sopenharmony_ci
6647e5c31af7Sopenharmony_ci		blockContentGenerator(context, parentStructure, blockGroup, children[childNdx].extendedBasicTypeCases);
6648e5c31af7Sopenharmony_ci	}
6649e5c31af7Sopenharmony_ci}
6650e5c31af7Sopenharmony_ci
6651e5c31af7Sopenharmony_cistatic void generateBufferVariableMatrixVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6652e5c31af7Sopenharmony_ci{
6653e5c31af7Sopenharmony_ci	// all matrix types and some non-matrix
6654e5c31af7Sopenharmony_ci
6655e5c31af7Sopenharmony_ci	static const glu::DataType variableTypes[] =
6656e5c31af7Sopenharmony_ci	{
6657e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT,
6658e5c31af7Sopenharmony_ci		glu::TYPE_INT_VEC3,
6659e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT2,
6660e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT2X3,
6661e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT2X4,
6662e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT3X2,
6663e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT3,
6664e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT3X4,
6665e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT4X2,
6666e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT4X3,
6667e5c31af7Sopenharmony_ci		glu::TYPE_FLOAT_MAT4,
6668e5c31af7Sopenharmony_ci	};
6669e5c31af7Sopenharmony_ci
6670e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6671e5c31af7Sopenharmony_ci	{
6672e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx]));
6673e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp)));
6674e5c31af7Sopenharmony_ci	}
6675e5c31af7Sopenharmony_ci}
6676e5c31af7Sopenharmony_ci
6677e5c31af7Sopenharmony_cistatic void generateBufferVariableMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
6678e5c31af7Sopenharmony_ci{
6679e5c31af7Sopenharmony_ci	// Basic aggregates
6680e5c31af7Sopenharmony_ci	generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp, glu::TYPE_FLOAT_MAT3X2, "", 2);
6681e5c31af7Sopenharmony_ci
6682e5c31af7Sopenharmony_ci	// Unsized array
6683e5c31af7Sopenharmony_ci	{
6684e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	unsized		(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6685e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(unsized, glu::TYPE_FLOAT_MAT3X2));
6686e5c31af7Sopenharmony_ci
6687e5c31af7Sopenharmony_ci		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp), "var_unsized_array"));
6688e5c31af7Sopenharmony_ci	}
6689e5c31af7Sopenharmony_ci}
6690e5c31af7Sopenharmony_ci
6691e5c31af7Sopenharmony_citemplate <ProgramResourcePropFlags TargetProp>
6692e5c31af7Sopenharmony_cistatic void generateBufferVariableMatrixCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool extendedTypeCases)
6693e5c31af7Sopenharmony_ci{
6694e5c31af7Sopenharmony_ci	// .types
6695e5c31af7Sopenharmony_ci	if (extendedTypeCases)
6696e5c31af7Sopenharmony_ci	{
6697e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "types", "Types");
6698e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6699e5c31af7Sopenharmony_ci		generateBufferVariableMatrixVariableBasicTypeCases(context, parentStructure, blockGroup, TargetProp);
6700e5c31af7Sopenharmony_ci	}
6701e5c31af7Sopenharmony_ci
6702e5c31af7Sopenharmony_ci	// .no_qualifier
6703e5c31af7Sopenharmony_ci	{
6704e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "no_qualifier", "No qualifier");
6705e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6706e5c31af7Sopenharmony_ci		generateBufferVariableMatrixVariableCases(context, parentStructure, blockGroup, TargetProp);
6707e5c31af7Sopenharmony_ci	}
6708e5c31af7Sopenharmony_ci
6709e5c31af7Sopenharmony_ci	// .column_major
6710e5c31af7Sopenharmony_ci	{
6711e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_COLUMN_MAJOR)));
6712e5c31af7Sopenharmony_ci
6713e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "column_major", "Column major qualifier");
6714e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6715e5c31af7Sopenharmony_ci		generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6716e5c31af7Sopenharmony_ci	}
6717e5c31af7Sopenharmony_ci
6718e5c31af7Sopenharmony_ci	// .row_major
6719e5c31af7Sopenharmony_ci	{
6720e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_ROW_MAJOR)));
6721e5c31af7Sopenharmony_ci
6722e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "row_major", "Row major qualifier");
6723e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6724e5c31af7Sopenharmony_ci		generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
6725e5c31af7Sopenharmony_ci	}
6726e5c31af7Sopenharmony_ci}
6727e5c31af7Sopenharmony_ci
6728e5c31af7Sopenharmony_cistatic void generateBufferVariableNameLengthCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6729e5c31af7Sopenharmony_ci{
6730e5c31af7Sopenharmony_ci	// .sized
6731e5c31af7Sopenharmony_ci	{
6732e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6733e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6734e5c31af7Sopenharmony_ci
6735e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 3);
6736e5c31af7Sopenharmony_ci	}
6737e5c31af7Sopenharmony_ci
6738e5c31af7Sopenharmony_ci	// .unsized
6739e5c31af7Sopenharmony_ci	{
6740e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	unsized		(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6741e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unsized", "Unsized target");
6742e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6743e5c31af7Sopenharmony_ci
6744e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
6745e5c31af7Sopenharmony_ci	}
6746e5c31af7Sopenharmony_ci}
6747e5c31af7Sopenharmony_ci
6748e5c31af7Sopenharmony_cistatic void generateBufferVariableOffsetCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6749e5c31af7Sopenharmony_ci{
6750e5c31af7Sopenharmony_ci	// .sized
6751e5c31af7Sopenharmony_ci	{
6752e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
6753e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6754e5c31af7Sopenharmony_ci
6755e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 3);
6756e5c31af7Sopenharmony_ci	}
6757e5c31af7Sopenharmony_ci
6758e5c31af7Sopenharmony_ci	// .unsized
6759e5c31af7Sopenharmony_ci	{
6760e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	unsized		(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6761e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unsized", "Unsized target");
6762e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6763e5c31af7Sopenharmony_ci
6764e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 2);
6765e5c31af7Sopenharmony_ci	}
6766e5c31af7Sopenharmony_ci}
6767e5c31af7Sopenharmony_ci
6768e5c31af7Sopenharmony_cistatic void generateBufferVariableReferencedByBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6769e5c31af7Sopenharmony_ci{
6770e5c31af7Sopenharmony_ci	DE_UNREF(expandLevel);
6771e5c31af7Sopenharmony_ci
6772e5c31af7Sopenharmony_ci	const ProgramResourceQueryTestTarget		queryTarget		(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
6773e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
6774e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	storage			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6775e5c31af7Sopenharmony_ci	const bool									singleShaderCase	= parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;
6776e5c31af7Sopenharmony_ci
6777e5c31af7Sopenharmony_ci	// .named_block
6778e5c31af7Sopenharmony_ci	{
6779e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(storage, true));
6780e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "named_block", "Named block");
6781e5c31af7Sopenharmony_ci
6782e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6783e5c31af7Sopenharmony_ci
6784e5c31af7Sopenharmony_ci		generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, singleShaderCase);
6785e5c31af7Sopenharmony_ci	}
6786e5c31af7Sopenharmony_ci
6787e5c31af7Sopenharmony_ci	// .unnamed_block
6788e5c31af7Sopenharmony_ci	{
6789e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(storage, false));
6790e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unnamed_block", "Unnamed block");
6791e5c31af7Sopenharmony_ci
6792e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6793e5c31af7Sopenharmony_ci
6794e5c31af7Sopenharmony_ci		generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6795e5c31af7Sopenharmony_ci	}
6796e5c31af7Sopenharmony_ci
6797e5c31af7Sopenharmony_ci	// .block_array
6798e5c31af7Sopenharmony_ci	{
6799e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(storage));
6800e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
6801e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "block_array", "Block array");
6802e5c31af7Sopenharmony_ci
6803e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6804e5c31af7Sopenharmony_ci
6805e5c31af7Sopenharmony_ci		generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
6806e5c31af7Sopenharmony_ci	}
6807e5c31af7Sopenharmony_ci}
6808e5c31af7Sopenharmony_ci
6809e5c31af7Sopenharmony_citemplate <ProgramResourcePropFlags TargetProp>
6810e5c31af7Sopenharmony_cistatic void generateBufferVariableTopLevelCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
6811e5c31af7Sopenharmony_ci{
6812e5c31af7Sopenharmony_ci	// basic and aggregate types
6813e5c31af7Sopenharmony_ci	generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "", 3);
6814e5c31af7Sopenharmony_ci
6815e5c31af7Sopenharmony_ci	// basic and aggregate types in an unsized array
6816e5c31af7Sopenharmony_ci	{
6817e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr unsized(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
6818e5c31af7Sopenharmony_ci
6819e5c31af7Sopenharmony_ci		generateBufferBackedVariableAggregateTypeCases(context, unsized, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "_unsized_array", 2);
6820e5c31af7Sopenharmony_ci	}
6821e5c31af7Sopenharmony_ci}
6822e5c31af7Sopenharmony_ci
6823e5c31af7Sopenharmony_cistatic void generateBufferVariableTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
6824e5c31af7Sopenharmony_ci{
6825e5c31af7Sopenharmony_ci	static const struct
6826e5c31af7Sopenharmony_ci	{
6827e5c31af7Sopenharmony_ci		int				level;
6828e5c31af7Sopenharmony_ci		glu::DataType	dataType;
6829e5c31af7Sopenharmony_ci	} variableTypes[] =
6830e5c31af7Sopenharmony_ci	{
6831e5c31af7Sopenharmony_ci		{ 0,	glu::TYPE_FLOAT			},
6832e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_INT			},
6833e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_UINT			},
6834e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_BOOL			},
6835e5c31af7Sopenharmony_ci
6836e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_VEC2	},
6837e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_FLOAT_VEC3	},
6838e5c31af7Sopenharmony_ci		{ 1,	glu::TYPE_FLOAT_VEC4	},
6839e5c31af7Sopenharmony_ci
6840e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_VEC2		},
6841e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_INT_VEC3		},
6842e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_INT_VEC4		},
6843e5c31af7Sopenharmony_ci
6844e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_VEC2		},
6845e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_UINT_VEC3		},
6846e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_UINT_VEC4		},
6847e5c31af7Sopenharmony_ci
6848e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_BOOL_VEC2		},
6849e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_BOOL_VEC3		},
6850e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_BOOL_VEC4		},
6851e5c31af7Sopenharmony_ci
6852e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT2	},
6853e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_MAT2X3	},
6854e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_MAT2X4	},
6855e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT3X2	},
6856e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT3	},
6857e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_MAT3X4	},
6858e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT4X2	},
6859e5c31af7Sopenharmony_ci		{ 3,	glu::TYPE_FLOAT_MAT4X3	},
6860e5c31af7Sopenharmony_ci		{ 2,	glu::TYPE_FLOAT_MAT4	},
6861e5c31af7Sopenharmony_ci	};
6862e5c31af7Sopenharmony_ci
6863e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
6864e5c31af7Sopenharmony_ci	{
6865e5c31af7Sopenharmony_ci		if (variableTypes[ndx].level <= expandLevel)
6866e5c31af7Sopenharmony_ci		{
6867e5c31af7Sopenharmony_ci			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
6868e5c31af7Sopenharmony_ci			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_TYPE)));
6869e5c31af7Sopenharmony_ci		}
6870e5c31af7Sopenharmony_ci	}
6871e5c31af7Sopenharmony_ci}
6872e5c31af7Sopenharmony_ci
6873e5c31af7Sopenharmony_cistatic void generateBufferVariableTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int depth = 3)
6874e5c31af7Sopenharmony_ci{
6875e5c31af7Sopenharmony_ci	// .basic_type
6876e5c31af7Sopenharmony_ci	if (depth > 0)
6877e5c31af7Sopenharmony_ci	{
6878e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic type");
6879e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6880e5c31af7Sopenharmony_ci		generateBufferVariableTypeBasicTypeCases(context, parentStructure, blockGroup, depth);
6881e5c31af7Sopenharmony_ci	}
6882e5c31af7Sopenharmony_ci	else
6883e5c31af7Sopenharmony_ci	{
6884e5c31af7Sopenharmony_ci		// flatten bottom-level
6885e5c31af7Sopenharmony_ci		generateBufferVariableTypeBasicTypeCases(context, parentStructure, targetGroup, depth);
6886e5c31af7Sopenharmony_ci	}
6887e5c31af7Sopenharmony_ci
6888e5c31af7Sopenharmony_ci	// .array
6889e5c31af7Sopenharmony_ci	if (depth > 0)
6890e5c31af7Sopenharmony_ci	{
6891e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
6892e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "array", "Arrays");
6893e5c31af7Sopenharmony_ci
6894e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6895e5c31af7Sopenharmony_ci		generateBufferVariableTypeCases(context, arrayElement, blockGroup, depth-1);
6896e5c31af7Sopenharmony_ci	}
6897e5c31af7Sopenharmony_ci
6898e5c31af7Sopenharmony_ci	// .struct
6899e5c31af7Sopenharmony_ci	if (depth > 0)
6900e5c31af7Sopenharmony_ci	{
6901e5c31af7Sopenharmony_ci		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
6902e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "struct", "Structs");
6903e5c31af7Sopenharmony_ci
6904e5c31af7Sopenharmony_ci		targetGroup->addChild(blockGroup);
6905e5c31af7Sopenharmony_ci		generateBufferVariableTypeCases(context, structMember, blockGroup, depth-1);
6906e5c31af7Sopenharmony_ci	}
6907e5c31af7Sopenharmony_ci}
6908e5c31af7Sopenharmony_ci
6909e5c31af7Sopenharmony_cistatic void generateBufferVariableTypeBlock (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion)
6910e5c31af7Sopenharmony_ci{
6911e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
6912e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
6913e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
6914e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6915e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	block			(new ResourceDefinition::InterfaceBlock(buffer, true));
6916e5c31af7Sopenharmony_ci
6917e5c31af7Sopenharmony_ci	generateBufferVariableTypeCases(context, block, targetGroup);
6918e5c31af7Sopenharmony_ci}
6919e5c31af7Sopenharmony_ci
6920e5c31af7Sopenharmony_cistatic void generateBufferVariableRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
6921e5c31af7Sopenharmony_ci{
6922e5c31af7Sopenharmony_ci	de::Random									rnd					(index * 0x12345);
6923e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	shader				= generateRandomShaderSet(rnd, glslVersion, onlyExtensionStages);
6924e5c31af7Sopenharmony_ci	const glu::DataType							type				= generateRandomDataType(rnd, true);
6925e5c31af7Sopenharmony_ci	const glu::Layout							layout				= generateRandomVariableLayout(rnd, type, true);
6926e5c31af7Sopenharmony_ci	const bool									namedBlock			= rnd.getBool();
6927e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));
6928e5c31af7Sopenharmony_ci	const ResourceDefinition::Node::SharedPtr	buffer				(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
6929e5c31af7Sopenharmony_ci	ResourceDefinition::Node::SharedPtr			currentStructure	(new ResourceDefinition::LayoutQualifier(buffer, generateRandomBufferBlockLayout(rnd)));
6930e5c31af7Sopenharmony_ci
6931e5c31af7Sopenharmony_ci	if (namedBlock && rnd.getBool())
6932e5c31af7Sopenharmony_ci		currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
6933e5c31af7Sopenharmony_ci	currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
6934e5c31af7Sopenharmony_ci
6935e5c31af7Sopenharmony_ci	currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
6936e5c31af7Sopenharmony_ci	currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, true);
6937e5c31af7Sopenharmony_ci
6938e5c31af7Sopenharmony_ci	targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK), de::toString(index).c_str()));
6939e5c31af7Sopenharmony_ci}
6940e5c31af7Sopenharmony_ci
6941e5c31af7Sopenharmony_cistatic void generateBufferVariableRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup, glu::GLSLVersion glslVersion)
6942e5c31af7Sopenharmony_ci{
6943e5c31af7Sopenharmony_ci	const int numBasicCases		= 40;
6944e5c31af7Sopenharmony_ci	const int numTessGeoCases	= 40;
6945e5c31af7Sopenharmony_ci
6946e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < numBasicCases; ++ndx)
6947e5c31af7Sopenharmony_ci		generateBufferVariableRandomCase(context, targetGroup, glslVersion, ndx, false);
6948e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
6949e5c31af7Sopenharmony_ci		generateBufferVariableRandomCase(context, targetGroup, glslVersion, numBasicCases + ndx, true);
6950e5c31af7Sopenharmony_ci}
6951e5c31af7Sopenharmony_ci
6952e5c31af7Sopenharmony_ciclass BufferVariableTestGroup : public TestCaseGroup
6953e5c31af7Sopenharmony_ci{
6954e5c31af7Sopenharmony_cipublic:
6955e5c31af7Sopenharmony_ci			BufferVariableTestGroup	(Context& context);
6956e5c31af7Sopenharmony_ci	void	init								(void);
6957e5c31af7Sopenharmony_ci};
6958e5c31af7Sopenharmony_ci
6959e5c31af7Sopenharmony_ciBufferVariableTestGroup::BufferVariableTestGroup (Context& context)
6960e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "buffer_variable", "Buffer variable")
6961e5c31af7Sopenharmony_ci{
6962e5c31af7Sopenharmony_ci}
6963e5c31af7Sopenharmony_ci
6964e5c31af7Sopenharmony_civoid BufferVariableTestGroup::init (void)
6965e5c31af7Sopenharmony_ci{
6966e5c31af7Sopenharmony_ci	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
6967e5c31af7Sopenharmony_ci
6968e5c31af7Sopenharmony_ci	// .resource_list
6969e5c31af7Sopenharmony_ci	{
6970e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
6971e5c31af7Sopenharmony_ci		addChild(blockGroup);
6972e5c31af7Sopenharmony_ci		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableResourceListBlockContentsProxy);
6973e5c31af7Sopenharmony_ci	}
6974e5c31af7Sopenharmony_ci
6975e5c31af7Sopenharmony_ci	// .array_size
6976e5c31af7Sopenharmony_ci	{
6977e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
6978e5c31af7Sopenharmony_ci		addChild(blockGroup);
6979e5c31af7Sopenharmony_ci		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
6980e5c31af7Sopenharmony_ci	}
6981e5c31af7Sopenharmony_ci
6982e5c31af7Sopenharmony_ci	// .array_stride
6983e5c31af7Sopenharmony_ci	{
6984e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_stride", "Array stride");
6985e5c31af7Sopenharmony_ci		addChild(blockGroup);
6986e5c31af7Sopenharmony_ci		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_STRIDE>);
6987e5c31af7Sopenharmony_ci	}
6988e5c31af7Sopenharmony_ci
6989e5c31af7Sopenharmony_ci	// .block_index
6990e5c31af7Sopenharmony_ci	{
6991e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "block_index", "Block index");
6992e5c31af7Sopenharmony_ci		addChild(blockGroup);
6993e5c31af7Sopenharmony_ci		generateBufferVariableBlockIndexCases(m_context, glslVersion, blockGroup);
6994e5c31af7Sopenharmony_ci	}
6995e5c31af7Sopenharmony_ci
6996e5c31af7Sopenharmony_ci	// .is_row_major
6997e5c31af7Sopenharmony_ci	{
6998e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "is_row_major", "Is row major");
6999e5c31af7Sopenharmony_ci		addChild(blockGroup);
7000e5c31af7Sopenharmony_ci		generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR>);
7001e5c31af7Sopenharmony_ci	}
7002e5c31af7Sopenharmony_ci
7003e5c31af7Sopenharmony_ci	// .matrix_stride
7004e5c31af7Sopenharmony_ci	{
7005e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "matrix_stride", "Matrix stride");
7006e5c31af7Sopenharmony_ci		addChild(blockGroup);
7007e5c31af7Sopenharmony_ci		generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_STRIDE>);
7008e5c31af7Sopenharmony_ci	}
7009e5c31af7Sopenharmony_ci
7010e5c31af7Sopenharmony_ci	// .name_length
7011e5c31af7Sopenharmony_ci	{
7012e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
7013e5c31af7Sopenharmony_ci		addChild(blockGroup);
7014e5c31af7Sopenharmony_ci		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableNameLengthCases);
7015e5c31af7Sopenharmony_ci	}
7016e5c31af7Sopenharmony_ci
7017e5c31af7Sopenharmony_ci	// .offset
7018e5c31af7Sopenharmony_ci	{
7019e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "offset", "Offset");
7020e5c31af7Sopenharmony_ci		addChild(blockGroup);
7021e5c31af7Sopenharmony_ci		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableOffsetCases);
7022e5c31af7Sopenharmony_ci	}
7023e5c31af7Sopenharmony_ci
7024e5c31af7Sopenharmony_ci	// .referenced_by
7025e5c31af7Sopenharmony_ci	{
7026e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "referenced_by", "Referenced by");
7027e5c31af7Sopenharmony_ci		addChild(blockGroup);
7028e5c31af7Sopenharmony_ci		generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableReferencedByBlockContents);
7029e5c31af7Sopenharmony_ci	}
7030e5c31af7Sopenharmony_ci
7031e5c31af7Sopenharmony_ci	// .top_level_array_size
7032e5c31af7Sopenharmony_ci	{
7033e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_size", "Top-level array size");
7034e5c31af7Sopenharmony_ci		addChild(blockGroup);
7035e5c31af7Sopenharmony_ci		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE>);
7036e5c31af7Sopenharmony_ci	}
7037e5c31af7Sopenharmony_ci
7038e5c31af7Sopenharmony_ci	// .top_level_array_stride
7039e5c31af7Sopenharmony_ci	{
7040e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_stride", "Top-level array stride");
7041e5c31af7Sopenharmony_ci		addChild(blockGroup);
7042e5c31af7Sopenharmony_ci		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE>);
7043e5c31af7Sopenharmony_ci	}
7044e5c31af7Sopenharmony_ci
7045e5c31af7Sopenharmony_ci	// .type
7046e5c31af7Sopenharmony_ci	{
7047e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
7048e5c31af7Sopenharmony_ci		addChild(blockGroup);
7049e5c31af7Sopenharmony_ci		generateBufferVariableTypeBlock(m_context, blockGroup, glslVersion);
7050e5c31af7Sopenharmony_ci	}
7051e5c31af7Sopenharmony_ci
7052e5c31af7Sopenharmony_ci	// .random
7053e5c31af7Sopenharmony_ci	{
7054e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "random", "Random");
7055e5c31af7Sopenharmony_ci		addChild(blockGroup);
7056e5c31af7Sopenharmony_ci		generateBufferVariableRandomCases(m_context, blockGroup, glslVersion);
7057e5c31af7Sopenharmony_ci	}
7058e5c31af7Sopenharmony_ci}
7059e5c31af7Sopenharmony_ci
7060e5c31af7Sopenharmony_ci} // anonymous
7061e5c31af7Sopenharmony_ci
7062e5c31af7Sopenharmony_ciProgramInterfaceQueryTests::ProgramInterfaceQueryTests (Context& context, bool is_GL45)
7063e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "program_interface_query", "Program interface query tests")
7064e5c31af7Sopenharmony_ci	, m_isGL45 (is_GL45)
7065e5c31af7Sopenharmony_ci{
7066e5c31af7Sopenharmony_ci}
7067e5c31af7Sopenharmony_ci
7068e5c31af7Sopenharmony_ciProgramInterfaceQueryTests::~ProgramInterfaceQueryTests (void)
7069e5c31af7Sopenharmony_ci{
7070e5c31af7Sopenharmony_ci}
7071e5c31af7Sopenharmony_ci
7072e5c31af7Sopenharmony_civoid ProgramInterfaceQueryTests::init (void)
7073e5c31af7Sopenharmony_ci{
7074e5c31af7Sopenharmony_ci	// Misc queries
7075e5c31af7Sopenharmony_ci
7076e5c31af7Sopenharmony_ci	// .buffer_limited_query
7077e5c31af7Sopenharmony_ci	{
7078e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "buffer_limited_query", "Queries limited by the buffer size");
7079e5c31af7Sopenharmony_ci
7080e5c31af7Sopenharmony_ci		addChild(group);
7081e5c31af7Sopenharmony_ci
7082e5c31af7Sopenharmony_ci		group->addChild(new ResourceNameBufferLimitCase(m_context, "resource_name_query", "Test GetProgramResourceName with too small a buffer"));
7083e5c31af7Sopenharmony_ci		group->addChild(new ResourceQueryBufferLimitCase(m_context, "resource_query", "Test GetProgramResourceiv with too small a buffer"));
7084e5c31af7Sopenharmony_ci	}
7085e5c31af7Sopenharmony_ci
7086e5c31af7Sopenharmony_ci	// Interfaces
7087e5c31af7Sopenharmony_ci
7088e5c31af7Sopenharmony_ci	// .uniform
7089e5c31af7Sopenharmony_ci	addChild(new UniformInterfaceTestGroup(m_context));
7090e5c31af7Sopenharmony_ci
7091e5c31af7Sopenharmony_ci	// .uniform_block
7092e5c31af7Sopenharmony_ci	addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_UNIFORM));
7093e5c31af7Sopenharmony_ci
7094e5c31af7Sopenharmony_ci	// .atomic_counter_buffer
7095e5c31af7Sopenharmony_ci	addChild(new AtomicCounterTestGroup(m_context));
7096e5c31af7Sopenharmony_ci
7097e5c31af7Sopenharmony_ci	// .program_input
7098e5c31af7Sopenharmony_ci	addChild(new ProgramInputTestGroup(m_context, m_isGL45));
7099e5c31af7Sopenharmony_ci
7100e5c31af7Sopenharmony_ci	// .program_output
7101e5c31af7Sopenharmony_ci	addChild(new ProgramOutputTestGroup(m_context, m_isGL45));
7102e5c31af7Sopenharmony_ci
7103e5c31af7Sopenharmony_ci	// .transform_feedback_varying
7104e5c31af7Sopenharmony_ci	addChild(new TransformFeedbackVaryingTestGroup(m_context));
7105e5c31af7Sopenharmony_ci
7106e5c31af7Sopenharmony_ci	// .buffer_variable
7107e5c31af7Sopenharmony_ci	addChild(new BufferVariableTestGroup(m_context));
7108e5c31af7Sopenharmony_ci
7109e5c31af7Sopenharmony_ci	// .shader_storage_block
7110e5c31af7Sopenharmony_ci	addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_BUFFER));
7111e5c31af7Sopenharmony_ci}
7112e5c31af7Sopenharmony_ci
7113e5c31af7Sopenharmony_ci} // Functional
7114e5c31af7Sopenharmony_ci} // gles31
7115e5c31af7Sopenharmony_ci} // deqp
7116