1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci * -----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2014-2016 The Khronos Group Inc.
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
22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es31cProgramInterfaceQueryTests.hpp"
25e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
26e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
27e5c31af7Sopenharmony_ci#include <cstdarg>
28e5c31af7Sopenharmony_ci#include <map>
29e5c31af7Sopenharmony_ci#include <set>
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_cinamespace glcts
32e5c31af7Sopenharmony_ci{
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_ciusing namespace glw;
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_cinamespace
37e5c31af7Sopenharmony_ci{
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_ciclass PIQBase : public glcts::SubcaseBase
40e5c31af7Sopenharmony_ci{
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_cipublic:
43e5c31af7Sopenharmony_ci	virtual ~PIQBase()
44e5c31af7Sopenharmony_ci	{
45e5c31af7Sopenharmony_ci	}
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
48e5c31af7Sopenharmony_ci	{
49e5c31af7Sopenharmony_ci		return "All called functions return expected values.";
50e5c31af7Sopenharmony_ci	}
51e5c31af7Sopenharmony_ci
52e5c31af7Sopenharmony_ci	virtual std::string Purpose()
53e5c31af7Sopenharmony_ci	{
54e5c31af7Sopenharmony_ci		return "Verify that the set of tested functions glGetProgram* return\n"
55e5c31af7Sopenharmony_ci			   "expected results when used to get data from program\n"
56e5c31af7Sopenharmony_ci			   "made of " +
57e5c31af7Sopenharmony_ci			   ShadersDesc() + "." + PurposeExt();
58e5c31af7Sopenharmony_ci	}
59e5c31af7Sopenharmony_ci
60e5c31af7Sopenharmony_ci	virtual std::string Method()
61e5c31af7Sopenharmony_ci	{
62e5c31af7Sopenharmony_ci		return "Create a program using " + ShadersDesc() +
63e5c31af7Sopenharmony_ci			   "\n"
64e5c31af7Sopenharmony_ci			   "then use set of tested functions to get an information about it and\n"
65e5c31af7Sopenharmony_ci			   "verify that information with the expected data" +
66e5c31af7Sopenharmony_ci			   Expectations();
67e5c31af7Sopenharmony_ci	}
68e5c31af7Sopenharmony_ci
69e5c31af7Sopenharmony_ci	virtual long Cleanup()
70e5c31af7Sopenharmony_ci	{
71e5c31af7Sopenharmony_ci		glUseProgram(0);
72e5c31af7Sopenharmony_ci		return NO_ERROR;
73e5c31af7Sopenharmony_ci	}
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ci	virtual long Setup()
76e5c31af7Sopenharmony_ci	{
77e5c31af7Sopenharmony_ci		return NO_ERROR;
78e5c31af7Sopenharmony_ci	}
79e5c31af7Sopenharmony_ci
80e5c31af7Sopenharmony_ciprotected:
81e5c31af7Sopenharmony_ci	void LinkProgram(GLuint program)
82e5c31af7Sopenharmony_ci	{
83e5c31af7Sopenharmony_ci		glLinkProgram(program);
84e5c31af7Sopenharmony_ci		GLsizei length;
85e5c31af7Sopenharmony_ci		GLchar  log[1024];
86e5c31af7Sopenharmony_ci		glGetProgramInfoLog(program, sizeof(log), &length, log);
87e5c31af7Sopenharmony_ci		if (length > 1)
88e5c31af7Sopenharmony_ci		{
89e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
90e5c31af7Sopenharmony_ci												<< log << tcu::TestLog::EndMessage;
91e5c31af7Sopenharmony_ci		}
92e5c31af7Sopenharmony_ci	}
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ci	GLuint CreateProgram(const char* src_vs, const char* src_fs, bool link)
95e5c31af7Sopenharmony_ci	{
96e5c31af7Sopenharmony_ci		const GLuint p = glCreateProgram();
97e5c31af7Sopenharmony_ci
98e5c31af7Sopenharmony_ci		if (src_vs)
99e5c31af7Sopenharmony_ci		{
100e5c31af7Sopenharmony_ci			GLuint sh = glCreateShader(GL_VERTEX_SHADER);
101e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
102e5c31af7Sopenharmony_ci			glDeleteShader(sh);
103e5c31af7Sopenharmony_ci			glShaderSource(sh, 1, &src_vs, NULL);
104e5c31af7Sopenharmony_ci			glCompileShader(sh);
105e5c31af7Sopenharmony_ci		}
106e5c31af7Sopenharmony_ci		if (src_fs)
107e5c31af7Sopenharmony_ci		{
108e5c31af7Sopenharmony_ci			GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
109e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
110e5c31af7Sopenharmony_ci			glDeleteShader(sh);
111e5c31af7Sopenharmony_ci			glShaderSource(sh, 1, &src_fs, NULL);
112e5c31af7Sopenharmony_ci			glCompileShader(sh);
113e5c31af7Sopenharmony_ci		}
114e5c31af7Sopenharmony_ci		if (link)
115e5c31af7Sopenharmony_ci		{
116e5c31af7Sopenharmony_ci			LinkProgram(p);
117e5c31af7Sopenharmony_ci		}
118e5c31af7Sopenharmony_ci		return p;
119e5c31af7Sopenharmony_ci	}
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
122e5c31af7Sopenharmony_ci	{
123e5c31af7Sopenharmony_ci		return "";
124e5c31af7Sopenharmony_ci	}
125e5c31af7Sopenharmony_ci
126e5c31af7Sopenharmony_ci	virtual std::string Expectations()
127e5c31af7Sopenharmony_ci	{
128e5c31af7Sopenharmony_ci		return ".";
129e5c31af7Sopenharmony_ci	}
130e5c31af7Sopenharmony_ci
131e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
132e5c31af7Sopenharmony_ci	{
133e5c31af7Sopenharmony_ci		return "";
134e5c31af7Sopenharmony_ci	}
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ci	virtual inline void ExpectError(GLenum expected, long& error)
137e5c31af7Sopenharmony_ci	{
138e5c31af7Sopenharmony_ci		if (error != NO_ERROR)
139e5c31af7Sopenharmony_ci			return;
140e5c31af7Sopenharmony_ci		GLenum tmp = glGetError();
141e5c31af7Sopenharmony_ci		if (tmp == expected)
142e5c31af7Sopenharmony_ci		{
143e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
144e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Found expected error" << tcu::TestLog::EndMessage;
145e5c31af7Sopenharmony_ci			error = NO_ERROR; // Error is expected
146e5c31af7Sopenharmony_ci		}
147e5c31af7Sopenharmony_ci		else
148e5c31af7Sopenharmony_ci		{
149e5c31af7Sopenharmony_ci			error = ERROR;
150e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << expected
151e5c31af7Sopenharmony_ci												<< " error was expected, found: " << tmp << tcu::TestLog::EndMessage;
152e5c31af7Sopenharmony_ci		}
153e5c31af7Sopenharmony_ci	}
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, int expected,
156e5c31af7Sopenharmony_ci													long& error)
157e5c31af7Sopenharmony_ci	{
158e5c31af7Sopenharmony_ci		GLint res;
159e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, programInterface, pname, &res);
160e5c31af7Sopenharmony_ci		if (res != expected)
161e5c31af7Sopenharmony_ci		{
162e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
163e5c31af7Sopenharmony_ci												<< expected << tcu::TestLog::EndMessage;
164e5c31af7Sopenharmony_ci			error = ERROR;
165e5c31af7Sopenharmony_ci		}
166e5c31af7Sopenharmony_ci	}
167e5c31af7Sopenharmony_ci
168e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface, const std::string& name,
169e5c31af7Sopenharmony_ci													  GLuint expected, long& error)
170e5c31af7Sopenharmony_ci	{
171e5c31af7Sopenharmony_ci		GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
172e5c31af7Sopenharmony_ci		if (res != expected)
173e5c31af7Sopenharmony_ci		{
174e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
175e5c31af7Sopenharmony_ci												<< expected << tcu::TestLog::EndMessage;
176e5c31af7Sopenharmony_ci			error = ERROR;
177e5c31af7Sopenharmony_ci		}
178e5c31af7Sopenharmony_ci	}
179e5c31af7Sopenharmony_ci
180e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum		 programInterface,
181e5c31af7Sopenharmony_ci													  std::map<std::string, GLuint>& indices, const std::string& name,
182e5c31af7Sopenharmony_ci													  long& error)
183e5c31af7Sopenharmony_ci	{
184e5c31af7Sopenharmony_ci		GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
185e5c31af7Sopenharmony_ci		if (res == GL_INVALID_INDEX)
186e5c31af7Sopenharmony_ci		{
187e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
188e5c31af7Sopenharmony_ci												<< ", expected number other than -1" << tcu::TestLog::EndMessage;
189e5c31af7Sopenharmony_ci			error = ERROR;
190e5c31af7Sopenharmony_ci			return;
191e5c31af7Sopenharmony_ci		}
192e5c31af7Sopenharmony_ci		std::map<std::string, GLuint>::iterator it = indices.begin();
193e5c31af7Sopenharmony_ci		while (it != indices.end())
194e5c31af7Sopenharmony_ci		{
195e5c31af7Sopenharmony_ci			if (it->second == res)
196e5c31af7Sopenharmony_ci			{
197e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
198e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
199e5c31af7Sopenharmony_ci				error = ERROR;
200e5c31af7Sopenharmony_ci				return;
201e5c31af7Sopenharmony_ci			}
202e5c31af7Sopenharmony_ci			++it;
203e5c31af7Sopenharmony_ci		}
204e5c31af7Sopenharmony_ci		indices[name] = res;
205e5c31af7Sopenharmony_ci	}
206e5c31af7Sopenharmony_ci
207e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index,
208e5c31af7Sopenharmony_ci													 const std::string& expected, long& error)
209e5c31af7Sopenharmony_ci	{
210e5c31af7Sopenharmony_ci		GLchar  name[1024] = { '\0' };
211e5c31af7Sopenharmony_ci		GLsizei len;
212e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, programInterface, index, 1024, &len, name);
213e5c31af7Sopenharmony_ci		if (len <= 0 || len > 1023 || name[len - 1] == '\0')
214e5c31af7Sopenharmony_ci		{
215e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
216e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
217e5c31af7Sopenharmony_ci				<< "ERROR: Length in glGetProgramResourceName should not count null terminator!"
218e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
219e5c31af7Sopenharmony_ci			error = ERROR;
220e5c31af7Sopenharmony_ci		}
221e5c31af7Sopenharmony_ci		else if (name != expected || name[len] != '\0')
222e5c31af7Sopenharmony_ci		{
223e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << name << ", expected "
224e5c31af7Sopenharmony_ci												<< expected << tcu::TestLog::EndMessage;
225e5c31af7Sopenharmony_ci			error = ERROR;
226e5c31af7Sopenharmony_ci		}
227e5c31af7Sopenharmony_ci	}
228e5c31af7Sopenharmony_ci
229e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface,
230e5c31af7Sopenharmony_ci														 const std::string& name, GLint expected, long& error)
231e5c31af7Sopenharmony_ci	{
232e5c31af7Sopenharmony_ci		GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
233e5c31af7Sopenharmony_ci		if (res != expected)
234e5c31af7Sopenharmony_ci		{
235e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
236e5c31af7Sopenharmony_ci												<< expected << tcu::TestLog::EndMessage;
237e5c31af7Sopenharmony_ci			error = ERROR;
238e5c31af7Sopenharmony_ci		}
239e5c31af7Sopenharmony_ci	}
240e5c31af7Sopenharmony_ci
241e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum		   programInterface,
242e5c31af7Sopenharmony_ci														 std::map<std::string, GLint>& locations,
243e5c31af7Sopenharmony_ci														 const std::string& name, long& error)
244e5c31af7Sopenharmony_ci	{
245e5c31af7Sopenharmony_ci		GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
246e5c31af7Sopenharmony_ci		if (res < 0)
247e5c31af7Sopenharmony_ci		{
248e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
249e5c31af7Sopenharmony_ci												<< ", expected not less than 0" << tcu::TestLog::EndMessage;
250e5c31af7Sopenharmony_ci			error = ERROR;
251e5c31af7Sopenharmony_ci			return;
252e5c31af7Sopenharmony_ci		}
253e5c31af7Sopenharmony_ci		std::map<std::string, GLint>::iterator it = locations.begin();
254e5c31af7Sopenharmony_ci		while (it != locations.end())
255e5c31af7Sopenharmony_ci		{
256e5c31af7Sopenharmony_ci			if (it->second == res)
257e5c31af7Sopenharmony_ci			{
258e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
259e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
260e5c31af7Sopenharmony_ci				error = ERROR;
261e5c31af7Sopenharmony_ci				return;
262e5c31af7Sopenharmony_ci			}
263e5c31af7Sopenharmony_ci			++it;
264e5c31af7Sopenharmony_ci		}
265e5c31af7Sopenharmony_ci		locations[name] = res;
266e5c31af7Sopenharmony_ci	}
267e5c31af7Sopenharmony_ci
268e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index,
269e5c31af7Sopenharmony_ci												   GLsizei propCount, const GLenum props[], GLsizei expectedLength,
270e5c31af7Sopenharmony_ci												   const GLint expected[], long& error)
271e5c31af7Sopenharmony_ci	{
272e5c31af7Sopenharmony_ci		const GLsizei bufSize = 1000;
273e5c31af7Sopenharmony_ci		GLsizei		  length;
274e5c31af7Sopenharmony_ci		GLint		  params[bufSize];
275e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, &length, params);
276e5c31af7Sopenharmony_ci		if (length != expectedLength || length <= 0)
277e5c31af7Sopenharmony_ci		{
278e5c31af7Sopenharmony_ci			error = ERROR;
279e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
280e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: Got length " << length << ", expected " << expectedLength
281e5c31af7Sopenharmony_ci				<< "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
282e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
283e5c31af7Sopenharmony_ci			return;
284e5c31af7Sopenharmony_ci		}
285e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
286e5c31af7Sopenharmony_ci		{
287e5c31af7Sopenharmony_ci			if (params[i] != expected[i])
288e5c31af7Sopenharmony_ci			{
289e5c31af7Sopenharmony_ci				error = ERROR;
290e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
291e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "ERROR: Got " << params[i] << ", expected " << expected[i]
292e5c31af7Sopenharmony_ci					<< " at: " << i << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
293e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
294e5c31af7Sopenharmony_ci			}
295e5c31af7Sopenharmony_ci		}
296e5c31af7Sopenharmony_ci	}
297e5c31af7Sopenharmony_ci
298e5c31af7Sopenharmony_ci	virtual inline GLint GetProgramivRetValue(GLuint program, GLenum pname)
299e5c31af7Sopenharmony_ci	{
300e5c31af7Sopenharmony_ci		GLint ret;
301e5c31af7Sopenharmony_ci		glGetProgramiv(program, pname, &ret);
302e5c31af7Sopenharmony_ci		return ret;
303e5c31af7Sopenharmony_ci	}
304e5c31af7Sopenharmony_ci
305e5c31af7Sopenharmony_ci	static const GLenum interfaces[];
306e5c31af7Sopenharmony_ci};
307e5c31af7Sopenharmony_ci
308e5c31af7Sopenharmony_ciconst GLenum PIQBase::interfaces[] = { GL_PROGRAM_INPUT,
309e5c31af7Sopenharmony_ci									   GL_PROGRAM_OUTPUT,
310e5c31af7Sopenharmony_ci									   GL_UNIFORM,
311e5c31af7Sopenharmony_ci									   GL_UNIFORM_BLOCK,
312e5c31af7Sopenharmony_ci									   GL_BUFFER_VARIABLE,
313e5c31af7Sopenharmony_ci									   GL_SHADER_STORAGE_BLOCK,
314e5c31af7Sopenharmony_ci									   GL_ATOMIC_COUNTER_BUFFER,
315e5c31af7Sopenharmony_ci									   GL_TRANSFORM_FEEDBACK_VARYING };
316e5c31af7Sopenharmony_ci
317e5c31af7Sopenharmony_ciclass NoShaders : public PIQBase
318e5c31af7Sopenharmony_ci{
319e5c31af7Sopenharmony_ci
320e5c31af7Sopenharmony_ci	virtual std::string Title()
321e5c31af7Sopenharmony_ci	{
322e5c31af7Sopenharmony_ci		return "No Shaders Test";
323e5c31af7Sopenharmony_ci	}
324e5c31af7Sopenharmony_ci
325e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
326e5c31af7Sopenharmony_ci	{
327e5c31af7Sopenharmony_ci		return "no shaders";
328e5c31af7Sopenharmony_ci	}
329e5c31af7Sopenharmony_ci
330e5c31af7Sopenharmony_ci	virtual long Run()
331e5c31af7Sopenharmony_ci	{
332e5c31af7Sopenharmony_ci		const GLuint program = glCreateProgram();
333e5c31af7Sopenharmony_ci
334e5c31af7Sopenharmony_ci		long error = NO_ERROR;
335e5c31af7Sopenharmony_ci		int  size  = sizeof(PIQBase::interfaces) / sizeof(PIQBase::interfaces[0]);
336e5c31af7Sopenharmony_ci
337e5c31af7Sopenharmony_ci		for (int i = 0; i < size; ++i)
338e5c31af7Sopenharmony_ci		{
339e5c31af7Sopenharmony_ci			VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_ACTIVE_RESOURCES, 0, error);
340e5c31af7Sopenharmony_ci			if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
341e5c31af7Sopenharmony_ci				continue;
342e5c31af7Sopenharmony_ci			VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_MAX_NAME_LENGTH, 0, error);
343e5c31af7Sopenharmony_ci		}
344e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
345e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
346e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
347e5c31af7Sopenharmony_ci
348e5c31af7Sopenharmony_ci		for (int i = 0; i < size; ++i)
349e5c31af7Sopenharmony_ci		{
350e5c31af7Sopenharmony_ci			if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
351e5c31af7Sopenharmony_ci				continue;
352e5c31af7Sopenharmony_ci			VerifyGetProgramResourceIndex(program, PIQBase::interfaces[i], "", GL_INVALID_INDEX, error);
353e5c31af7Sopenharmony_ci		}
354e5c31af7Sopenharmony_ci
355e5c31af7Sopenharmony_ci		// can't test GetProgramResourceLocation* here since program has to be linked
356e5c31af7Sopenharmony_ci		// can't test GetProgramResourceiv, need valid index
357e5c31af7Sopenharmony_ci
358e5c31af7Sopenharmony_ci		glDeleteProgram(program);
359e5c31af7Sopenharmony_ci		return error;
360e5c31af7Sopenharmony_ci	}
361e5c31af7Sopenharmony_ci};
362e5c31af7Sopenharmony_ci
363e5c31af7Sopenharmony_ciclass SimpleShaders : public PIQBase
364e5c31af7Sopenharmony_ci{
365e5c31af7Sopenharmony_ci
366e5c31af7Sopenharmony_cipublic:
367e5c31af7Sopenharmony_ci	virtual std::string Title()
368e5c31af7Sopenharmony_ci	{
369e5c31af7Sopenharmony_ci		return "Simple Shaders Test";
370e5c31af7Sopenharmony_ci	}
371e5c31af7Sopenharmony_ci
372e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
373e5c31af7Sopenharmony_ci	{
374e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders";
375e5c31af7Sopenharmony_ci	}
376e5c31af7Sopenharmony_ci
377e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
378e5c31af7Sopenharmony_ci	{
379e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
380e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
381e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
382e5c31af7Sopenharmony_ci			   "{                                    \n"
383e5c31af7Sopenharmony_ci			   "    gl_Position = position;          \n"
384e5c31af7Sopenharmony_ci			   "}";
385e5c31af7Sopenharmony_ci	}
386e5c31af7Sopenharmony_ci
387e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
388e5c31af7Sopenharmony_ci	{
389e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
390e5c31af7Sopenharmony_ci			   "out mediump vec4 color;        \n"
391e5c31af7Sopenharmony_ci			   "void main() {                  \n"
392e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1);  \n"
393e5c31af7Sopenharmony_ci			   "}";
394e5c31af7Sopenharmony_ci	}
395e5c31af7Sopenharmony_ci
396e5c31af7Sopenharmony_ci	virtual long Run()
397e5c31af7Sopenharmony_ci	{
398e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
399e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
400e5c31af7Sopenharmony_ci		glLinkProgram(program);
401e5c31af7Sopenharmony_ci
402e5c31af7Sopenharmony_ci		long error = NO_ERROR;
403e5c31af7Sopenharmony_ci
404e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
405e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
406e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
407e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
408e5c31af7Sopenharmony_ci
409e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
410e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
411e5c31af7Sopenharmony_ci
412e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
413e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
414e5c31af7Sopenharmony_ci
415e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
416e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
417e5c31af7Sopenharmony_ci
418e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
419e5c31af7Sopenharmony_ci						   GL_TYPE,
420e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
421e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
422e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
423e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
424e5c31af7Sopenharmony_ci						   GL_LOCATION };
425e5c31af7Sopenharmony_ci		GLint expected[] = { 9, 35666, 1, 0, 0, 1, 0 };
426e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 7, props, 7, expected, error);
427e5c31af7Sopenharmony_ci
428e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
429e5c31af7Sopenharmony_ci							GL_TYPE,
430e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
431e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
432e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
433e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
434e5c31af7Sopenharmony_ci							GL_LOCATION };
435e5c31af7Sopenharmony_ci		GLint expected2[] = { 6, 35666, 1, 0, 1, 0, 0 };
436e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error);
437e5c31af7Sopenharmony_ci
438e5c31af7Sopenharmony_ci		glDeleteProgram(program);
439e5c31af7Sopenharmony_ci		return error;
440e5c31af7Sopenharmony_ci	}
441e5c31af7Sopenharmony_ci};
442e5c31af7Sopenharmony_ci
443e5c31af7Sopenharmony_ciclass ComputeShaderTest : public PIQBase
444e5c31af7Sopenharmony_ci{
445e5c31af7Sopenharmony_cipublic:
446e5c31af7Sopenharmony_ci	virtual std::string Title()
447e5c31af7Sopenharmony_ci	{
448e5c31af7Sopenharmony_ci		return "Compute Shader Test";
449e5c31af7Sopenharmony_ci	}
450e5c31af7Sopenharmony_ci
451e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
452e5c31af7Sopenharmony_ci	{
453e5c31af7Sopenharmony_ci		return "compute shader";
454e5c31af7Sopenharmony_ci	}
455e5c31af7Sopenharmony_ci
456e5c31af7Sopenharmony_ci	virtual std::string ComputeShader()
457e5c31af7Sopenharmony_ci	{
458e5c31af7Sopenharmony_ci		return "layout(local_size_x = 1, local_size_y = 1) in; \n"
459e5c31af7Sopenharmony_ci			   "layout(std430) buffer Output {                 \n"
460e5c31af7Sopenharmony_ci			   "  mediump vec4 data[];                         \n"
461e5c31af7Sopenharmony_ci			   "} g_out;                                       \n"
462e5c31af7Sopenharmony_ci			   ""
463e5c31af7Sopenharmony_ci			   "void main() {                                   \n"
464e5c31af7Sopenharmony_ci			   "   g_out.data[0] = vec4(1.0, 2.0, 3.0, 4.0);    \n"
465e5c31af7Sopenharmony_ci			   "   g_out.data[100] = vec4(1.0, 2.0, 3.0, 4.0);  \n"
466e5c31af7Sopenharmony_ci			   "}";
467e5c31af7Sopenharmony_ci	}
468e5c31af7Sopenharmony_ci
469e5c31af7Sopenharmony_ci	GLuint CreateComputeProgram(const std::string& cs)
470e5c31af7Sopenharmony_ci	{
471e5c31af7Sopenharmony_ci		const GLuint p = glCreateProgram();
472e5c31af7Sopenharmony_ci
473e5c31af7Sopenharmony_ci		const char* const kGLSLVer = "#version 310 es\n";
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_ci		if (!cs.empty())
476e5c31af7Sopenharmony_ci		{
477e5c31af7Sopenharmony_ci			const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
478e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
479e5c31af7Sopenharmony_ci			glDeleteShader(sh);
480e5c31af7Sopenharmony_ci			const char* const src[2] = { kGLSLVer, cs.c_str() };
481e5c31af7Sopenharmony_ci			glShaderSource(sh, 2, src, NULL);
482e5c31af7Sopenharmony_ci			glCompileShader(sh);
483e5c31af7Sopenharmony_ci		}
484e5c31af7Sopenharmony_ci
485e5c31af7Sopenharmony_ci		return p;
486e5c31af7Sopenharmony_ci	}
487e5c31af7Sopenharmony_ci
488e5c31af7Sopenharmony_ci	bool CheckProgram(GLuint program, bool* compile_error = NULL)
489e5c31af7Sopenharmony_ci	{
490e5c31af7Sopenharmony_ci		GLint compile_status = GL_TRUE;
491e5c31af7Sopenharmony_ci		GLint status;
492e5c31af7Sopenharmony_ci		glGetProgramiv(program, GL_LINK_STATUS, &status);
493e5c31af7Sopenharmony_ci
494e5c31af7Sopenharmony_ci		if (status == GL_FALSE)
495e5c31af7Sopenharmony_ci		{
496e5c31af7Sopenharmony_ci			GLint attached_shaders;
497e5c31af7Sopenharmony_ci			glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
498e5c31af7Sopenharmony_ci
499e5c31af7Sopenharmony_ci			if (attached_shaders > 0)
500e5c31af7Sopenharmony_ci			{
501e5c31af7Sopenharmony_ci				std::vector<GLuint> shaders(attached_shaders);
502e5c31af7Sopenharmony_ci				glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
503e5c31af7Sopenharmony_ci
504e5c31af7Sopenharmony_ci				for (GLint i = 0; i < attached_shaders; ++i)
505e5c31af7Sopenharmony_ci				{
506e5c31af7Sopenharmony_ci					GLenum type;
507e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
508e5c31af7Sopenharmony_ci					switch (type)
509e5c31af7Sopenharmony_ci					{
510e5c31af7Sopenharmony_ci					case GL_VERTEX_SHADER:
511e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
512e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
513e5c31af7Sopenharmony_ci						break;
514e5c31af7Sopenharmony_ci					case GL_TESS_CONTROL_SHADER:
515e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
516e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Tessellation Control Shader ***"
517e5c31af7Sopenharmony_ci							<< tcu::TestLog::EndMessage;
518e5c31af7Sopenharmony_ci						break;
519e5c31af7Sopenharmony_ci					case GL_TESS_EVALUATION_SHADER:
520e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
521e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
522e5c31af7Sopenharmony_ci							<< tcu::TestLog::EndMessage;
523e5c31af7Sopenharmony_ci						break;
524e5c31af7Sopenharmony_ci					case GL_GEOMETRY_SHADER:
525e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
526e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
527e5c31af7Sopenharmony_ci						break;
528e5c31af7Sopenharmony_ci					case GL_FRAGMENT_SHADER:
529e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
530e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
531e5c31af7Sopenharmony_ci						break;
532e5c31af7Sopenharmony_ci					case GL_COMPUTE_SHADER:
533e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
534e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
535e5c31af7Sopenharmony_ci						break;
536e5c31af7Sopenharmony_ci					default:
537e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
538e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
539e5c31af7Sopenharmony_ci					}
540e5c31af7Sopenharmony_ci
541e5c31af7Sopenharmony_ci					GLint res;
542e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
543e5c31af7Sopenharmony_ci					if (res != GL_TRUE)
544e5c31af7Sopenharmony_ci						compile_status = res;
545e5c31af7Sopenharmony_ci
546e5c31af7Sopenharmony_ci					// shader source
547e5c31af7Sopenharmony_ci					GLint length;
548e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
549e5c31af7Sopenharmony_ci					if (length > 0)
550e5c31af7Sopenharmony_ci					{
551e5c31af7Sopenharmony_ci						std::vector<GLchar> source(length);
552e5c31af7Sopenharmony_ci						glGetShaderSource(shaders[i], length, NULL, &source[0]);
553e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
554e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
555e5c31af7Sopenharmony_ci					}
556e5c31af7Sopenharmony_ci
557e5c31af7Sopenharmony_ci					// shader info log
558e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
559e5c31af7Sopenharmony_ci					if (length > 0)
560e5c31af7Sopenharmony_ci					{
561e5c31af7Sopenharmony_ci						std::vector<GLchar> log(length);
562e5c31af7Sopenharmony_ci						glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
563e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
564e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
565e5c31af7Sopenharmony_ci					}
566e5c31af7Sopenharmony_ci				}
567e5c31af7Sopenharmony_ci			}
568e5c31af7Sopenharmony_ci
569e5c31af7Sopenharmony_ci			// program info log
570e5c31af7Sopenharmony_ci			GLint length;
571e5c31af7Sopenharmony_ci			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
572e5c31af7Sopenharmony_ci			if (length > 0)
573e5c31af7Sopenharmony_ci			{
574e5c31af7Sopenharmony_ci				std::vector<GLchar> log(length);
575e5c31af7Sopenharmony_ci				glGetProgramInfoLog(program, length, NULL, &log[0]);
576e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
577e5c31af7Sopenharmony_ci			}
578e5c31af7Sopenharmony_ci		}
579e5c31af7Sopenharmony_ci
580e5c31af7Sopenharmony_ci		if (compile_error)
581e5c31af7Sopenharmony_ci			*compile_error = (compile_status == GL_TRUE ? false : true);
582e5c31af7Sopenharmony_ci		if (compile_status != GL_TRUE)
583e5c31af7Sopenharmony_ci			return false;
584e5c31af7Sopenharmony_ci		return status == GL_TRUE ? true : false;
585e5c31af7Sopenharmony_ci	}
586e5c31af7Sopenharmony_ci
587e5c31af7Sopenharmony_ci	virtual void inline VerifyCompute(GLuint program, long& error)
588e5c31af7Sopenharmony_ci	{
589e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 15, error);
590e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
591e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
592e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 7, error);
593e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
594e5c31af7Sopenharmony_ci
595e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesSSB;
596e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesBV;
597e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Output", error);
598e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "Output.data", error);
599e5c31af7Sopenharmony_ci
600e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], "Output", error);
601e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], "Output.data[0]", error);
602e5c31af7Sopenharmony_ci
603e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
604e5c31af7Sopenharmony_ci							GL_BUFFER_BINDING,
605e5c31af7Sopenharmony_ci							GL_NUM_ACTIVE_VARIABLES,
606e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
607e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
608e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
609e5c31af7Sopenharmony_ci							GL_ACTIVE_VARIABLES };
610e5c31af7Sopenharmony_ci		GLint expected3[] = { 7, 0, 1, 1, 0, 0, static_cast<GLint>(indicesBV["Outputa.data"]) };
611e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], 7, props3, 7, expected3,
612e5c31af7Sopenharmony_ci								   error);
613e5c31af7Sopenharmony_ci
614e5c31af7Sopenharmony_ci		GLenum props4[] = { GL_NAME_LENGTH,
615e5c31af7Sopenharmony_ci							GL_TYPE,
616e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
617e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
618e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
619e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
620e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
621e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
622e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_SIZE };
623e5c31af7Sopenharmony_ci		GLint expected4[] = { 15, 35666, 0, static_cast<GLint>(indicesSSB["Output"]), 0, 1, 0, 0, 1 };
624e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], 9, props4, 9, expected4,
625e5c31af7Sopenharmony_ci								   error);
626e5c31af7Sopenharmony_ci	}
627e5c31af7Sopenharmony_ci
628e5c31af7Sopenharmony_ci	virtual long Run()
629e5c31af7Sopenharmony_ci	{
630e5c31af7Sopenharmony_ci		GLuint program = CreateComputeProgram(ComputeShader());
631e5c31af7Sopenharmony_ci		glLinkProgram(program);
632e5c31af7Sopenharmony_ci		if (!CheckProgram(program))
633e5c31af7Sopenharmony_ci		{
634e5c31af7Sopenharmony_ci			glDeleteProgram(program);
635e5c31af7Sopenharmony_ci			return ERROR;
636e5c31af7Sopenharmony_ci		}
637e5c31af7Sopenharmony_ci		glUseProgram(program);
638e5c31af7Sopenharmony_ci
639e5c31af7Sopenharmony_ci		long error = NO_ERROR;
640e5c31af7Sopenharmony_ci
641e5c31af7Sopenharmony_ci		VerifyCompute(program, error);
642e5c31af7Sopenharmony_ci
643e5c31af7Sopenharmony_ci		glDeleteProgram(program);
644e5c31af7Sopenharmony_ci		return error;
645e5c31af7Sopenharmony_ci	}
646e5c31af7Sopenharmony_ci};
647e5c31af7Sopenharmony_ci
648e5c31af7Sopenharmony_ciclass InputTypes : public SimpleShaders
649e5c31af7Sopenharmony_ci{
650e5c31af7Sopenharmony_ci	virtual std::string Title()
651e5c31af7Sopenharmony_ci	{
652e5c31af7Sopenharmony_ci		return "Input Types Test";
653e5c31af7Sopenharmony_ci	}
654e5c31af7Sopenharmony_ci
655e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
656e5c31af7Sopenharmony_ci	{
657e5c31af7Sopenharmony_ci		return "vertex shader with different `in` types and a fallthrough fragment shader";
658e5c31af7Sopenharmony_ci	}
659e5c31af7Sopenharmony_ci
660e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
661e5c31af7Sopenharmony_ci	{
662e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
663e5c31af7Sopenharmony_ci			   "in mat4 a;                           \n"
664e5c31af7Sopenharmony_ci			   "in vec4 b;                           \n"
665e5c31af7Sopenharmony_ci			   "in float c;                          \n"
666e5c31af7Sopenharmony_ci			   "in mat2x3 d;                         \n"
667e5c31af7Sopenharmony_ci			   "in vec2 e;                           \n"
668e5c31af7Sopenharmony_ci			   "in uint f;                           \n"
669e5c31af7Sopenharmony_ci			   "in vec3 g;                           \n"
670e5c31af7Sopenharmony_ci			   "in int h;                            \n"
671e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
672e5c31af7Sopenharmony_ci			   "{                                    \n"
673e5c31af7Sopenharmony_ci			   "   vec4 pos;                                                 \n"
674e5c31af7Sopenharmony_ci			   "   pos.w = float(h) + g.x + g.y + d[1].y;                    \n"
675e5c31af7Sopenharmony_ci			   "   pos.y = float(b.x) * c + c + d[0][0];                     \n"
676e5c31af7Sopenharmony_ci			   "   pos.x = a[0].x + a[1].y + a[2].z + a[3].w;                \n"
677e5c31af7Sopenharmony_ci			   "   pos.z = d[0][1] + float(e.x) * float(f) + d[1][0];        \n"
678e5c31af7Sopenharmony_ci			   "   gl_Position = pos;                                        \n"
679e5c31af7Sopenharmony_ci			   "}";
680e5c31af7Sopenharmony_ci	}
681e5c31af7Sopenharmony_ci
682e5c31af7Sopenharmony_ci	virtual long Run()
683e5c31af7Sopenharmony_ci	{
684e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
685e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "a");
686e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 4, "b");
687e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 5, "c");
688e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 7, "d");
689e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 11, "e");
690e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 12, "f");
691e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 13, "g");
692e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 15, "h");
693e5c31af7Sopenharmony_ci		LinkProgram(program);
694e5c31af7Sopenharmony_ci
695e5c31af7Sopenharmony_ci		long error = NO_ERROR;
696e5c31af7Sopenharmony_ci
697e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
698e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
699e5c31af7Sopenharmony_ci
700e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
701e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
702e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
703e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c", error);
704e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
705e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
706e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
707e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
708e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
709e5c31af7Sopenharmony_ci
710e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
711e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
712e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c"], "c", error);
713e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d", error);
714e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
715e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
716e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g", error);
717e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
718e5c31af7Sopenharmony_ci
719e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
720e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
721e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
722e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
723e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
724e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
725e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
726e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
727e5c31af7Sopenharmony_ci
728e5c31af7Sopenharmony_ci		GLenum props[] = {
729e5c31af7Sopenharmony_ci			GL_NAME_LENGTH,
730e5c31af7Sopenharmony_ci			GL_TYPE,
731e5c31af7Sopenharmony_ci			GL_ARRAY_SIZE,
732e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_COMPUTE_SHADER,
733e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_FRAGMENT_SHADER,
734e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_VERTEX_SHADER,
735e5c31af7Sopenharmony_ci			GL_LOCATION,
736e5c31af7Sopenharmony_ci		};
737e5c31af7Sopenharmony_ci		GLint expected[] = { 2, 35676, 1, 0, 0, 1, 0 };
738e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 7, props, 7, expected, error);
739e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, 35666, 1, 0, 0, 1, 4 };
740e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 7, props, 7, expected2, error);
741e5c31af7Sopenharmony_ci		GLint expected3[] = { 2, 5126, 1, 0, 0, 1, 5 };
742e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c"], 7, props, 7, expected3, error);
743e5c31af7Sopenharmony_ci		GLint expected4[] = { 2, 35685, 1, 0, 0, 1, 7 };
744e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 7, props, 7, expected4, error);
745e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, 35664, 1, 0, 0, 1, 11 };
746e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 7, props, 7, expected5, error);
747e5c31af7Sopenharmony_ci		GLint expected6[] = { 2, 5125, 1, 0, 0, 1, 12 };
748e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 7, props, 7, expected6, error);
749e5c31af7Sopenharmony_ci		GLint expected7[] = { 2, 35665, 1, 0, 0, 1, 13 };
750e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 7, props, 7, expected7, error);
751e5c31af7Sopenharmony_ci		GLint expected8[] = { 2, 5124, 1, 0, 0, 1, 15 };
752e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 7, props, 7, expected8, error);
753e5c31af7Sopenharmony_ci
754e5c31af7Sopenharmony_ci		glDeleteProgram(program);
755e5c31af7Sopenharmony_ci		return error;
756e5c31af7Sopenharmony_ci	}
757e5c31af7Sopenharmony_ci};
758e5c31af7Sopenharmony_ci
759e5c31af7Sopenharmony_ciclass InputBuiltIn : public SimpleShaders
760e5c31af7Sopenharmony_ci{
761e5c31af7Sopenharmony_ci
762e5c31af7Sopenharmony_ci	virtual std::string Title()
763e5c31af7Sopenharmony_ci	{
764e5c31af7Sopenharmony_ci		return "Input Built-ins Test";
765e5c31af7Sopenharmony_ci	}
766e5c31af7Sopenharmony_ci
767e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
768e5c31af7Sopenharmony_ci	{
769e5c31af7Sopenharmony_ci		return "vertex shader using built-in variables and a fallthrough fragment shader";
770e5c31af7Sopenharmony_ci	}
771e5c31af7Sopenharmony_ci
772e5c31af7Sopenharmony_ci	virtual std::string Expectations()
773e5c31af7Sopenharmony_ci	{
774e5c31af7Sopenharmony_ci		return ".\n\n In this case we ask for information about built-in variables for the input interface.";
775e5c31af7Sopenharmony_ci	}
776e5c31af7Sopenharmony_ci
777e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
778e5c31af7Sopenharmony_ci	{
779e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
780e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
781e5c31af7Sopenharmony_ci			   "{                                    \n"
782e5c31af7Sopenharmony_ci			   "    gl_Position = (float(gl_VertexID) + float(gl_InstanceID)) * vec4(0.1);          \n"
783e5c31af7Sopenharmony_ci			   "}";
784e5c31af7Sopenharmony_ci	}
785e5c31af7Sopenharmony_ci
786e5c31af7Sopenharmony_ci	virtual long Run()
787e5c31af7Sopenharmony_ci	{
788e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
789e5c31af7Sopenharmony_ci		LinkProgram(program);
790e5c31af7Sopenharmony_ci
791e5c31af7Sopenharmony_ci		long error = NO_ERROR;
792e5c31af7Sopenharmony_ci
793e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 2, error);
794e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 14, error);
795e5c31af7Sopenharmony_ci
796e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
797e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_VertexID", error);
798e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_InstanceID", error);
799e5c31af7Sopenharmony_ci
800e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], "gl_VertexID", error);
801e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], "gl_InstanceID", error);
802e5c31af7Sopenharmony_ci
803e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_VertexID", -1, error);
804e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_InstanceID", -1, error);
805e5c31af7Sopenharmony_ci
806e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
807e5c31af7Sopenharmony_ci						   GL_TYPE,
808e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
809e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
810e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
811e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
812e5c31af7Sopenharmony_ci						   GL_LOCATION };
813e5c31af7Sopenharmony_ci		GLint expected[] = { 12, 5124, 1, 0, 0, 1, -1 };
814e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], 7, props, 7, expected, error);
815e5c31af7Sopenharmony_ci		GLint expected2[] = { 14, 5124, 1, 0, 0, 1, -1 };
816e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], 7, props, 7, expected2, error);
817e5c31af7Sopenharmony_ci
818e5c31af7Sopenharmony_ci		glDeleteProgram(program);
819e5c31af7Sopenharmony_ci		return error;
820e5c31af7Sopenharmony_ci	}
821e5c31af7Sopenharmony_ci};
822e5c31af7Sopenharmony_ci
823e5c31af7Sopenharmony_ciclass InputLayout : public SimpleShaders
824e5c31af7Sopenharmony_ci{
825e5c31af7Sopenharmony_ci	virtual std::string Title()
826e5c31af7Sopenharmony_ci	{
827e5c31af7Sopenharmony_ci		return "Input Layout Test";
828e5c31af7Sopenharmony_ci	}
829e5c31af7Sopenharmony_ci
830e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
831e5c31af7Sopenharmony_ci	{
832e5c31af7Sopenharmony_ci		return "vertex shader with different `in` variables locations set through layout and a fallthrough fragment "
833e5c31af7Sopenharmony_ci			   "shader";
834e5c31af7Sopenharmony_ci	}
835e5c31af7Sopenharmony_ci
836e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
837e5c31af7Sopenharmony_ci	{
838e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
839e5c31af7Sopenharmony_ci			   "layout(location = 4) in vec4 b;      \n"
840e5c31af7Sopenharmony_ci			   "layout(location = 7) in mat2x3 d;    \n"
841e5c31af7Sopenharmony_ci			   "layout(location = 5) in float c;     \n"
842e5c31af7Sopenharmony_ci			   "layout(location = 12) in uint f;     \n"
843e5c31af7Sopenharmony_ci			   "layout(location = 13) in vec3 g;     \n"
844e5c31af7Sopenharmony_ci			   "layout(location = 0) in mat4 a;      \n"
845e5c31af7Sopenharmony_ci			   "layout(location = 15) in int h;      \n"
846e5c31af7Sopenharmony_ci			   "layout(location = 11) in vec2 e;     \n"
847e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
848e5c31af7Sopenharmony_ci			   "{                                    \n"
849e5c31af7Sopenharmony_ci			   "   vec4 pos;                                              \n"
850e5c31af7Sopenharmony_ci			   "   pos.w = float(h) + g.x + g.y + d[1][1];                \n"
851e5c31af7Sopenharmony_ci			   "   pos.y = float(b.x) * c + c + d[0][0];                  \n"
852e5c31af7Sopenharmony_ci			   "   pos.x = a[0].x + a[1].y + a[2].z + a[3].w;             \n"
853e5c31af7Sopenharmony_ci			   "   pos.z = d[0][1] + float(e.x) * float(f) + d[1][0];     \n"
854e5c31af7Sopenharmony_ci			   "   gl_Position = pos;                                     \n"
855e5c31af7Sopenharmony_ci			   "}";
856e5c31af7Sopenharmony_ci	}
857e5c31af7Sopenharmony_ci
858e5c31af7Sopenharmony_ci	virtual long Run()
859e5c31af7Sopenharmony_ci	{
860e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
861e5c31af7Sopenharmony_ci		LinkProgram(program);
862e5c31af7Sopenharmony_ci
863e5c31af7Sopenharmony_ci		long error = NO_ERROR;
864e5c31af7Sopenharmony_ci
865e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
866e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
867e5c31af7Sopenharmony_ci
868e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
869e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
870e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
871e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c", error);
872e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
873e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
874e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
875e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
876e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
877e5c31af7Sopenharmony_ci
878e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
879e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
880e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c"], "c", error);
881e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d", error);
882e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
883e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
884e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g", error);
885e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
886e5c31af7Sopenharmony_ci
887e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
888e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
889e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
890e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
891e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
892e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
893e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
894e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
895e5c31af7Sopenharmony_ci
896e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
897e5c31af7Sopenharmony_ci						   GL_TYPE,
898e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
899e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
900e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
901e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
902e5c31af7Sopenharmony_ci						   GL_LOCATION };
903e5c31af7Sopenharmony_ci		GLint expected[] = { 2, 35676, 1, 0, 0, 1, 0 };
904e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 7, props, 7, expected, error);
905e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, 35666, 1, 0, 0, 1, 4 };
906e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 7, props, 7, expected2, error);
907e5c31af7Sopenharmony_ci		GLint expected3[] = { 2, 5126, 1, 0, 0, 1, 5 };
908e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c"], 7, props, 7, expected3, error);
909e5c31af7Sopenharmony_ci		GLint expected4[] = { 2, 35685, 1, 0, 0, 1, 7 };
910e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 7, props, 7, expected4, error);
911e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, 35664, 1, 0, 0, 1, 11 };
912e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 7, props, 7, expected5, error);
913e5c31af7Sopenharmony_ci		GLint expected6[] = { 2, 5125, 1, 0, 0, 1, 12 };
914e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 7, props, 7, expected6, error);
915e5c31af7Sopenharmony_ci		GLint expected7[] = { 2, 35665, 1, 0, 0, 1, 13 };
916e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 7, props, 7, expected7, error);
917e5c31af7Sopenharmony_ci		GLint expected8[] = { 2, 5124, 1, 0, 0, 1, 15 };
918e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 7, props, 7, expected8, error);
919e5c31af7Sopenharmony_ci
920e5c31af7Sopenharmony_ci		glDeleteProgram(program);
921e5c31af7Sopenharmony_ci		return error;
922e5c31af7Sopenharmony_ci	}
923e5c31af7Sopenharmony_ci};
924e5c31af7Sopenharmony_ci
925e5c31af7Sopenharmony_ciclass OutputLayout : public SimpleShaders
926e5c31af7Sopenharmony_ci{
927e5c31af7Sopenharmony_ci	virtual std::string Title()
928e5c31af7Sopenharmony_ci	{
929e5c31af7Sopenharmony_ci		return "Output Layout Test";
930e5c31af7Sopenharmony_ci	}
931e5c31af7Sopenharmony_ci
932e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
933e5c31af7Sopenharmony_ci	{
934e5c31af7Sopenharmony_ci		return "fragment shader with different `out` variables locations set through layout and a fallthrough vertex "
935e5c31af7Sopenharmony_ci			   "shader";
936e5c31af7Sopenharmony_ci	}
937e5c31af7Sopenharmony_ci
938e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
939e5c31af7Sopenharmony_ci	{
940e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
941e5c31af7Sopenharmony_ci			   "layout(location = 2) out uint b;                    \n"
942e5c31af7Sopenharmony_ci			   "layout(location = 3) out mediump vec2 e;            \n"
943e5c31af7Sopenharmony_ci			   "layout(location = 0) out mediump vec3 a[2];         \n"
944e5c31af7Sopenharmony_ci			   "void main() {                  \n"
945e5c31af7Sopenharmony_ci			   "    b = 12u;                   \n"
946e5c31af7Sopenharmony_ci			   "    e = vec2(0, 1);            \n"
947e5c31af7Sopenharmony_ci			   "    a[1] = vec3(0, 1, 0);      \n"
948e5c31af7Sopenharmony_ci			   "    a[0] = vec3(0, 1, 0);      \n"
949e5c31af7Sopenharmony_ci			   "}";
950e5c31af7Sopenharmony_ci	}
951e5c31af7Sopenharmony_ci
952e5c31af7Sopenharmony_ci	virtual long Run()
953e5c31af7Sopenharmony_ci	{
954e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
955e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
956e5c31af7Sopenharmony_ci		LinkProgram(program);
957e5c31af7Sopenharmony_ci
958e5c31af7Sopenharmony_ci		long error = NO_ERROR;
959e5c31af7Sopenharmony_ci
960e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 3, error);
961e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
962e5c31af7Sopenharmony_ci
963e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
964e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error);
965e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error);
966e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error);
967e5c31af7Sopenharmony_ci
968e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error);
969e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error);
970e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error);
971e5c31af7Sopenharmony_ci
972e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
973e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error);
974e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error);
975e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error);
976e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 3, error);
977e5c31af7Sopenharmony_ci
978e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
979e5c31af7Sopenharmony_ci						   GL_TYPE,
980e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
981e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
982e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
983e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
984e5c31af7Sopenharmony_ci						   GL_LOCATION };
985e5c31af7Sopenharmony_ci		GLint expected_a[] = { 5, 35665, 2, 0, 1, 0, 0 };
986e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 7, props, 7, expected_a, error);
987e5c31af7Sopenharmony_ci		GLint expected_b[] = { 2, 5125, 1, 0, 1, 0, 2 };
988e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 7, props, 7, expected_b, error);
989e5c31af7Sopenharmony_ci		GLint expected_e[] = { 2, 35664, 1, 0, 1, 0, 3 };
990e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 7, props, 7, expected_e, error);
991e5c31af7Sopenharmony_ci
992e5c31af7Sopenharmony_ci		glDeleteProgram(program);
993e5c31af7Sopenharmony_ci		return error;
994e5c31af7Sopenharmony_ci	}
995e5c31af7Sopenharmony_ci};
996e5c31af7Sopenharmony_ci
997e5c31af7Sopenharmony_ciclass UniformSimple : public PIQBase
998e5c31af7Sopenharmony_ci{
999e5c31af7Sopenharmony_ci	virtual std::string Title()
1000e5c31af7Sopenharmony_ci	{
1001e5c31af7Sopenharmony_ci		return "Uniform Simple Test";
1002e5c31af7Sopenharmony_ci	}
1003e5c31af7Sopenharmony_ci
1004e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1005e5c31af7Sopenharmony_ci	{
1006e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with uniforms used";
1007e5c31af7Sopenharmony_ci	}
1008e5c31af7Sopenharmony_ci
1009e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1010e5c31af7Sopenharmony_ci	{
1011e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.";
1012e5c31af7Sopenharmony_ci	}
1013e5c31af7Sopenharmony_ci
1014e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1015e5c31af7Sopenharmony_ci	{
1016e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
1017e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
1018e5c31af7Sopenharmony_ci			   "uniform mediump vec4 repos;          \n"
1019e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
1020e5c31af7Sopenharmony_ci			   "{                                    \n"
1021e5c31af7Sopenharmony_ci			   "    gl_Position = position + repos;  \n"
1022e5c31af7Sopenharmony_ci			   "}";
1023e5c31af7Sopenharmony_ci	}
1024e5c31af7Sopenharmony_ci
1025e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1026e5c31af7Sopenharmony_ci	{
1027e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
1028e5c31af7Sopenharmony_ci			   "uniform mediump vec4 recolor;  \n"
1029e5c31af7Sopenharmony_ci			   "out mediump vec4 color;        \n"
1030e5c31af7Sopenharmony_ci			   "void main() {                  \n"
1031e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1) + recolor;  \n"
1032e5c31af7Sopenharmony_ci			   "}";
1033e5c31af7Sopenharmony_ci	}
1034e5c31af7Sopenharmony_ci
1035e5c31af7Sopenharmony_ci	virtual long Run()
1036e5c31af7Sopenharmony_ci	{
1037e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1038e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1039e5c31af7Sopenharmony_ci		LinkProgram(program);
1040e5c31af7Sopenharmony_ci
1041e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1042e5c31af7Sopenharmony_ci
1043e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1044e5c31af7Sopenharmony_ci									GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1045e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 8, error);
1046e5c31af7Sopenharmony_ci
1047e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
1048e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "repos", error);
1049e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "recolor", error);
1050e5c31af7Sopenharmony_ci
1051e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["repos"], "repos", error);
1052e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["recolor"], "recolor", error);
1053e5c31af7Sopenharmony_ci
1054e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "repos", glGetUniformLocation(program, "repos"), error);
1055e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "recolor", glGetUniformLocation(program, "recolor"),
1056e5c31af7Sopenharmony_ci										 error);
1057e5c31af7Sopenharmony_ci
1058e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
1059e5c31af7Sopenharmony_ci						   GL_TYPE,
1060e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
1061e5c31af7Sopenharmony_ci						   GL_OFFSET,
1062e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
1063e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
1064e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
1065e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
1066e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
1067e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
1068e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
1069e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
1070e5c31af7Sopenharmony_ci						   GL_LOCATION };
1071e5c31af7Sopenharmony_ci		GLint expected[] = { 6, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "repos") };
1072e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["repos"], 13, props, 13, expected, error);
1073e5c31af7Sopenharmony_ci
1074e5c31af7Sopenharmony_ci		GLint expected2[] = { 8, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "recolor") };
1075e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["recolor"], 13, props, 13, expected2, error);
1076e5c31af7Sopenharmony_ci
1077e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1078e5c31af7Sopenharmony_ci		return error;
1079e5c31af7Sopenharmony_ci	}
1080e5c31af7Sopenharmony_ci};
1081e5c31af7Sopenharmony_ci
1082e5c31af7Sopenharmony_ciclass UniformTypes : public PIQBase
1083e5c31af7Sopenharmony_ci{
1084e5c31af7Sopenharmony_ci	virtual std::string Title()
1085e5c31af7Sopenharmony_ci	{
1086e5c31af7Sopenharmony_ci		return "Uniform Types Test";
1087e5c31af7Sopenharmony_ci	}
1088e5c31af7Sopenharmony_ci
1089e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1090e5c31af7Sopenharmony_ci	{
1091e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different uniform types used";
1092e5c31af7Sopenharmony_ci	}
1093e5c31af7Sopenharmony_ci
1094e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1095e5c31af7Sopenharmony_ci	{
1096e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.\n";
1097e5c31af7Sopenharmony_ci	}
1098e5c31af7Sopenharmony_ci
1099e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1100e5c31af7Sopenharmony_ci	{
1101e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
1102e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
1103e5c31af7Sopenharmony_ci			   "uniform mediump vec4 a;              \n"
1104e5c31af7Sopenharmony_ci			   "uniform ivec3 b;                     \n"
1105e5c31af7Sopenharmony_ci			   "uniform uvec2 c[3];                  \n"
1106e5c31af7Sopenharmony_ci			   "uniform mediump mat2 g[8];           \n"
1107e5c31af7Sopenharmony_ci			   "uniform mediump mat3x2 i;            \n"
1108e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
1109e5c31af7Sopenharmony_ci			   "{                                    \n"
1110e5c31af7Sopenharmony_ci			   "    float tmp;                       \n"
1111e5c31af7Sopenharmony_ci			   "    tmp = g[0][1][1] * g[1][0][0] + g[2][1][0] - g[3][0][1]; \n"
1112e5c31af7Sopenharmony_ci			   "    tmp = tmp + g[4][0][0] * g[5][1][0] - g[6][1][1] + g[7][0][1]; \n"
1113e5c31af7Sopenharmony_ci			   "    tmp = tmp + a.z + +float(b.y) + float(c[0].x) - float(c[1].x) * float(c[2].y);   \n"
1114e5c31af7Sopenharmony_ci			   "    tmp = tmp + i[1][1];             \n"
1115e5c31af7Sopenharmony_ci			   "    gl_Position = position * tmp;    \n"
1116e5c31af7Sopenharmony_ci			   "}";
1117e5c31af7Sopenharmony_ci	}
1118e5c31af7Sopenharmony_ci
1119e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1120e5c31af7Sopenharmony_ci	{
1121e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
1122e5c31af7Sopenharmony_ci			   "struct U {                     \n"
1123e5c31af7Sopenharmony_ci			   "   bool a[3];                  \n"
1124e5c31af7Sopenharmony_ci			   "   mediump vec4 b;                     \n"
1125e5c31af7Sopenharmony_ci			   "   mediump mat3 c;                     \n"
1126e5c31af7Sopenharmony_ci			   "   mediump float d[2];                 \n"
1127e5c31af7Sopenharmony_ci			   "};                             \n"
1128e5c31af7Sopenharmony_ci			   "struct UU {                    \n"
1129e5c31af7Sopenharmony_ci			   "   U a;                        \n"
1130e5c31af7Sopenharmony_ci			   "   U b[2];                     \n"
1131e5c31af7Sopenharmony_ci			   "   uvec2 c;                    \n"
1132e5c31af7Sopenharmony_ci			   "};                             \n"
1133e5c31af7Sopenharmony_ci			   "uniform mediump mat4 d;                \n"
1134e5c31af7Sopenharmony_ci			   "uniform mediump mat3 e;                \n"
1135e5c31af7Sopenharmony_ci			   "uniform mediump float h;               \n"
1136e5c31af7Sopenharmony_ci			   "uniform int f;                 \n"
1137e5c31af7Sopenharmony_ci			   "uniform U j;                   \n"
1138e5c31af7Sopenharmony_ci			   "uniform UU k;                  \n"
1139e5c31af7Sopenharmony_ci			   "uniform UU l[3];               \n"
1140e5c31af7Sopenharmony_ci			   "out mediump vec4 color;                \n"
1141e5c31af7Sopenharmony_ci			   "void main() {                  \n"
1142e5c31af7Sopenharmony_ci			   "    mediump float tmp;                 \n"
1143e5c31af7Sopenharmony_ci			   "    tmp = h + float(f) + e[2][2];           \n"
1144e5c31af7Sopenharmony_ci			   "    tmp = tmp + d[0][0] + j.b.x;     \n"
1145e5c31af7Sopenharmony_ci			   "    tmp = tmp + k.b[0].c[0][0];      \n"
1146e5c31af7Sopenharmony_ci			   "    tmp = tmp + l[2].a.c[0][1];      \n"
1147e5c31af7Sopenharmony_ci			   "    int i = int(tmp);                \n"
1148e5c31af7Sopenharmony_ci			   "    if (i < 2)                       \n"
1149e5c31af7Sopenharmony_ci			   "        tmp = tmp + l[2].b[1].d[i];  \n"
1150e5c31af7Sopenharmony_ci			   "    else                             \n"
1151e5c31af7Sopenharmony_ci			   "        tmp = tmp + l[2].b[1].d[0];  \n"
1152e5c31af7Sopenharmony_ci			   "    tmp = tmp + float(l[0].c.x);     \n"
1153e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1) * tmp;  \n"
1154e5c31af7Sopenharmony_ci			   "}";
1155e5c31af7Sopenharmony_ci	}
1156e5c31af7Sopenharmony_ci
1157e5c31af7Sopenharmony_ci	virtual long Run()
1158e5c31af7Sopenharmony_ci	{
1159e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1160e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1161e5c31af7Sopenharmony_ci		LinkProgram(program);
1162e5c31af7Sopenharmony_ci
1163e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1164e5c31af7Sopenharmony_ci
1165e5c31af7Sopenharmony_ci		// only active structure members
1166e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1167e5c31af7Sopenharmony_ci									GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1168e5c31af7Sopenharmony_ci		// l[2].b[1].d[0] and \0
1169e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error);
1170e5c31af7Sopenharmony_ci
1171e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
1172e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error);
1173e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error);
1174e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error);
1175e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error);
1176e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error);
1177e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error);
1178e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error);
1179e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error);
1180e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error);
1181e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error);
1182e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error);
1183e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error);
1184e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error);
1185e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error);
1186e5c31af7Sopenharmony_ci
1187e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error);
1188e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error);
1189e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error);
1190e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error);
1191e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error);
1192e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error);
1193e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error);
1194e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error);
1195e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error);
1196e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error);
1197e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error);
1198e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error);
1199e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error);
1200e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error);
1201e5c31af7Sopenharmony_ci
1202e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
1203e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error);
1204e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error);
1205e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error);
1206e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error);
1207e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error);
1208e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error);
1209e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error);
1210e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error);
1211e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error);
1212e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"),
1213e5c31af7Sopenharmony_ci										 error);
1214e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error);
1215e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]",
1216e5c31af7Sopenharmony_ci										 glGetUniformLocation(program, "l[2].b[1].d[0]"), error);
1217e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"),
1218e5c31af7Sopenharmony_ci										 error);
1219e5c31af7Sopenharmony_ci
1220e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
1221e5c31af7Sopenharmony_ci						   GL_TYPE,
1222e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
1223e5c31af7Sopenharmony_ci						   GL_OFFSET,
1224e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
1225e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
1226e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
1227e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
1228e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
1229e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
1230e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
1231e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
1232e5c31af7Sopenharmony_ci						   GL_LOCATION };
1233e5c31af7Sopenharmony_ci		GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a") };
1234e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 13, props, 13, expected, error);
1235e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, 35668, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "b") };
1236e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 13, props, 13, expected2, error);
1237e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, 36294, 3, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "c") };
1238e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 13, props, 13, expected3, error);
1239e5c31af7Sopenharmony_ci		GLint expected4[] = { 2, 35676, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "d") };
1240e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 13, props, 13, expected4, error);
1241e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "e") };
1242e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 13, props, 13, expected5, error);
1243e5c31af7Sopenharmony_ci		GLint expected6[] = { 2, 5124, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "f") };
1244e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 13, props, 13, expected6, error);
1245e5c31af7Sopenharmony_ci		GLint expected7[] = { 5, 35674, 8, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "g") };
1246e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 13, props, 13, expected7, error);
1247e5c31af7Sopenharmony_ci		GLint expected8[] = { 2, 5126, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "h") };
1248e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 13, props, 13, expected8, error);
1249e5c31af7Sopenharmony_ci		GLint expected9[] = { 2, 35687, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "i") };
1250e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 13, props, 13, expected9, error);
1251e5c31af7Sopenharmony_ci		GLint expected10[] = { 4, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "j.b") };
1252e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 13, props, 13, expected10, error);
1253e5c31af7Sopenharmony_ci		GLint expected11[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "k.b[0].c") };
1254e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 13, props, 13, expected11, error);
1255e5c31af7Sopenharmony_ci		GLint expected12[] = { 7, 36294, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[0].c") };
1256e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 13, props, 13, expected12, error);
1257e5c31af7Sopenharmony_ci		GLint expected13[] = {
1258e5c31af7Sopenharmony_ci			15, 5126, 2, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].b[1].d[0]")
1259e5c31af7Sopenharmony_ci		};
1260e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 13, props, 13, expected13, error);
1261e5c31af7Sopenharmony_ci		GLint expected14[] = { 9, 35675, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, glGetUniformLocation(program, "l[2].a.c") };
1262e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 13, props, 13, expected14, error);
1263e5c31af7Sopenharmony_ci
1264e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1265e5c31af7Sopenharmony_ci		return error;
1266e5c31af7Sopenharmony_ci	}
1267e5c31af7Sopenharmony_ci};
1268e5c31af7Sopenharmony_ci
1269e5c31af7Sopenharmony_ciclass UniformBlockTypes : public PIQBase
1270e5c31af7Sopenharmony_ci{
1271e5c31af7Sopenharmony_ci	virtual std::string Title()
1272e5c31af7Sopenharmony_ci	{
1273e5c31af7Sopenharmony_ci		return "Uniform Block Types Test";
1274e5c31af7Sopenharmony_ci	}
1275e5c31af7Sopenharmony_ci
1276e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1277e5c31af7Sopenharmony_ci	{
1278e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
1279e5c31af7Sopenharmony_ci	}
1280e5c31af7Sopenharmony_ci
1281e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1282e5c31af7Sopenharmony_ci	{
1283e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n";
1284e5c31af7Sopenharmony_ci	}
1285e5c31af7Sopenharmony_ci
1286e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1287e5c31af7Sopenharmony_ci	{
1288e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
1289e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
1290e5c31af7Sopenharmony_ci			   ""
1291e5c31af7Sopenharmony_ci			   "uniform SimpleBlock {                \n"
1292e5c31af7Sopenharmony_ci			   "   mediump mat3x2 a;                         \n"
1293e5c31af7Sopenharmony_ci			   "   mediump mat4 b;                           \n"
1294e5c31af7Sopenharmony_ci			   "   vec4 c;                           \n"
1295e5c31af7Sopenharmony_ci			   "};                                   \n"
1296e5c31af7Sopenharmony_ci			   ""
1297e5c31af7Sopenharmony_ci			   "uniform NotSoSimpleBlockk {          \n"
1298e5c31af7Sopenharmony_ci			   "   ivec2 a[4];                       \n"
1299e5c31af7Sopenharmony_ci			   "   mediump mat3 b[2];                        \n"
1300e5c31af7Sopenharmony_ci			   "   mediump mat2 c;                           \n"
1301e5c31af7Sopenharmony_ci			   "} d;                                         \n"
1302e5c31af7Sopenharmony_ci			   ""
1303e5c31af7Sopenharmony_ci			   "void main(void)                                               \n"
1304e5c31af7Sopenharmony_ci			   "{                                                             \n"
1305e5c31af7Sopenharmony_ci			   "    mediump float tmp;                                        \n"
1306e5c31af7Sopenharmony_ci			   "    tmp =  a[0][1] * b[1][2] * c.x;                           \n"
1307e5c31af7Sopenharmony_ci			   "    tmp = tmp + float(d.a[2].y) + d.b[0][1][1] + d.c[1][1];   \n"
1308e5c31af7Sopenharmony_ci			   "    gl_Position = position * tmp;                             \n"
1309e5c31af7Sopenharmony_ci			   "}";
1310e5c31af7Sopenharmony_ci	}
1311e5c31af7Sopenharmony_ci
1312e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1313e5c31af7Sopenharmony_ci	{
1314e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
1315e5c31af7Sopenharmony_ci			   "struct U {                     \n"
1316e5c31af7Sopenharmony_ci			   "   bool a[3];                  \n"
1317e5c31af7Sopenharmony_ci			   "   mediump vec4 b;                     \n"
1318e5c31af7Sopenharmony_ci			   "   mediump mat3 c;                     \n"
1319e5c31af7Sopenharmony_ci			   "   mediump float d[2];                 \n"
1320e5c31af7Sopenharmony_ci			   "};                             \n"
1321e5c31af7Sopenharmony_ci			   "struct UU {                    \n"
1322e5c31af7Sopenharmony_ci			   "   U a;                        \n"
1323e5c31af7Sopenharmony_ci			   "   U b[2];                     \n"
1324e5c31af7Sopenharmony_ci			   "   uvec2 c;                    \n"
1325e5c31af7Sopenharmony_ci			   "};                             \n"
1326e5c31af7Sopenharmony_ci			   ""
1327e5c31af7Sopenharmony_ci			   "uniform TrickyBlock {                            \n"
1328e5c31af7Sopenharmony_ci			   "   UU a[3];                                      \n"
1329e5c31af7Sopenharmony_ci			   "   mediump mat4 b;                               \n"
1330e5c31af7Sopenharmony_ci			   "   uint c;                                       \n"
1331e5c31af7Sopenharmony_ci			   "} e[2];                                          \n"
1332e5c31af7Sopenharmony_ci			   ""
1333e5c31af7Sopenharmony_ci			   "out mediump vec4 color;                        \n"
1334e5c31af7Sopenharmony_ci			   "void main() {                                  \n"
1335e5c31af7Sopenharmony_ci			   "    mediump float tmp;                         \n"
1336e5c31af7Sopenharmony_ci			   "    tmp = e[0].a[2].b[0].d[1] * float(e[1].c); \n"
1337e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1) * tmp;            \n"
1338e5c31af7Sopenharmony_ci			   "}";
1339e5c31af7Sopenharmony_ci	}
1340e5c31af7Sopenharmony_ci
1341e5c31af7Sopenharmony_ci	virtual long Run()
1342e5c31af7Sopenharmony_ci	{
1343e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1344e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1345e5c31af7Sopenharmony_ci		LinkProgram(program);
1346e5c31af7Sopenharmony_ci
1347e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1348e5c31af7Sopenharmony_ci
1349e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1350e5c31af7Sopenharmony_ci									GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1351e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
1352e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
1353e5c31af7Sopenharmony_ci
1354e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesUB;
1355e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
1356e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error);
1357e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error);
1358e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error);
1359e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error);
1360e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1361e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1362e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1363e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error);
1364e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error);
1365e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error);
1366e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error);
1367e5c31af7Sopenharmony_ci
1368e5c31af7Sopenharmony_ci		glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0);
1369e5c31af7Sopenharmony_ci		glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2);
1370e5c31af7Sopenharmony_ci		glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3);
1371e5c31af7Sopenharmony_ci		glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4);
1372e5c31af7Sopenharmony_ci
1373e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error);
1374e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk",
1375e5c31af7Sopenharmony_ci									 error);
1376e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error);
1377e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error);
1378e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1379e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1380e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1381e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]",
1382e5c31af7Sopenharmony_ci									 error);
1383e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c",
1384e5c31af7Sopenharmony_ci									 error);
1385e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]",
1386e5c31af7Sopenharmony_ci									 error);
1387e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"],
1388e5c31af7Sopenharmony_ci									 "TrickyBlock.a[2].b[0].d[0]", error);
1389e5c31af7Sopenharmony_ci
1390e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1391e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1392e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1393e5c31af7Sopenharmony_ci
1394e5c31af7Sopenharmony_ci		GLenum props[] = {
1395e5c31af7Sopenharmony_ci			GL_NAME_LENGTH,
1396e5c31af7Sopenharmony_ci			GL_BUFFER_BINDING,
1397e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_COMPUTE_SHADER,
1398e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_FRAGMENT_SHADER,
1399e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_VERTEX_SHADER,
1400e5c31af7Sopenharmony_ci			GL_BUFFER_DATA_SIZE,
1401e5c31af7Sopenharmony_ci		};
1402e5c31af7Sopenharmony_ci		GLint size;
1403e5c31af7Sopenharmony_ci		glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1404e5c31af7Sopenharmony_ci		GLint expected[] = { 12, 0, 0, 0, 1, size };
1405e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 6, props, 6, expected, error);
1406e5c31af7Sopenharmony_ci		glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1407e5c31af7Sopenharmony_ci		GLint expected2[] = { 18, 2, 0, 0, 1, size };
1408e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 6, props, 6, expected2,
1409e5c31af7Sopenharmony_ci								   error);
1410e5c31af7Sopenharmony_ci		glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1411e5c31af7Sopenharmony_ci		GLint expected3[] = { 15, 3, 0, 1, 0, size };
1412e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 6, props, 6, expected3, error);
1413e5c31af7Sopenharmony_ci		GLint expected4[] = { 15, 4, 0, 1, 0, size };
1414e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 6, props, 6, expected4,
1415e5c31af7Sopenharmony_ci								   error);
1416e5c31af7Sopenharmony_ci
1417e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
1418e5c31af7Sopenharmony_ci							GL_TYPE,
1419e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
1420e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
1421e5c31af7Sopenharmony_ci							GL_ARRAY_STRIDE,
1422e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
1423e5c31af7Sopenharmony_ci							GL_ATOMIC_COUNTER_BUFFER_INDEX,
1424e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
1425e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
1426e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
1427e5c31af7Sopenharmony_ci							GL_LOCATION };
1428e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 1, -1 };
1429e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 11, props2, 11, expected5, error);
1430e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
1431e5c31af7Sopenharmony_ci							GL_TYPE,
1432e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
1433e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
1434e5c31af7Sopenharmony_ci							GL_MATRIX_STRIDE,
1435e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
1436e5c31af7Sopenharmony_ci							GL_ATOMIC_COUNTER_BUFFER_INDEX,
1437e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
1438e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
1439e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
1440e5c31af7Sopenharmony_ci							GL_LOCATION };
1441e5c31af7Sopenharmony_ci		GLint expected6[] = { 27, 5126, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, -1 };
1442e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 11, props3, 11, expected6,
1443e5c31af7Sopenharmony_ci								   error);
1444e5c31af7Sopenharmony_ci
1445e5c31af7Sopenharmony_ci		GLenum			 prop	= GL_ACTIVE_VARIABLES;
1446e5c31af7Sopenharmony_ci		const GLsizei	bufSize = 1000;
1447e5c31af7Sopenharmony_ci		GLsizei			 length;
1448e5c31af7Sopenharmony_ci		GLint			 param[bufSize];
1449e5c31af7Sopenharmony_ci		std::set<GLuint> exp;
1450e5c31af7Sopenharmony_ci		exp.insert(indicesU["a"]);
1451e5c31af7Sopenharmony_ci		exp.insert(indicesU["b"]);
1452e5c31af7Sopenharmony_ci		exp.insert(indicesU["c"]);
1453e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param);
1454e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
1455e5c31af7Sopenharmony_ci		{
1456e5c31af7Sopenharmony_ci			if (exp.find(param[i]) == exp.end())
1457e5c31af7Sopenharmony_ci			{
1458e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1459e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1460e5c31af7Sopenharmony_ci					<< "Unexpected index found in active variables of SimpleBlock: " << param[i]
1461e5c31af7Sopenharmony_ci					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1462e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
1463e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1464e5c31af7Sopenharmony_ci				return ERROR;
1465e5c31af7Sopenharmony_ci			}
1466e5c31af7Sopenharmony_ci			else if (length != 3)
1467e5c31af7Sopenharmony_ci			{
1468e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1469e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1470e5c31af7Sopenharmony_ci					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1471e5c31af7Sopenharmony_ci					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1472e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1473e5c31af7Sopenharmony_ci				return ERROR;
1474e5c31af7Sopenharmony_ci			}
1475e5c31af7Sopenharmony_ci		}
1476e5c31af7Sopenharmony_ci		std::set<GLuint> exp2;
1477e5c31af7Sopenharmony_ci		exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]);
1478e5c31af7Sopenharmony_ci		exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]);
1479e5c31af7Sopenharmony_ci		exp2.insert(indicesU["NotSoSimpleBlockk.c"]);
1480e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length,
1481e5c31af7Sopenharmony_ci							   param);
1482e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
1483e5c31af7Sopenharmony_ci		{
1484e5c31af7Sopenharmony_ci			if (exp2.find(param[i]) == exp2.end())
1485e5c31af7Sopenharmony_ci			{
1486e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1487e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1488e5c31af7Sopenharmony_ci					<< "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i]
1489e5c31af7Sopenharmony_ci					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1490e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
1491e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1492e5c31af7Sopenharmony_ci				return ERROR;
1493e5c31af7Sopenharmony_ci			}
1494e5c31af7Sopenharmony_ci			else if (length != 3)
1495e5c31af7Sopenharmony_ci			{
1496e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1497e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1498e5c31af7Sopenharmony_ci					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1499e5c31af7Sopenharmony_ci					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1500e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1501e5c31af7Sopenharmony_ci				return ERROR;
1502e5c31af7Sopenharmony_ci			}
1503e5c31af7Sopenharmony_ci		}
1504e5c31af7Sopenharmony_ci
1505e5c31af7Sopenharmony_ci		GLint res;
1506e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
1507e5c31af7Sopenharmony_ci		if (res < 3)
1508e5c31af7Sopenharmony_ci		{
1509e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
1510e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!"
1511e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
1512e5c31af7Sopenharmony_ci			glDeleteProgram(program);
1513e5c31af7Sopenharmony_ci			return ERROR;
1514e5c31af7Sopenharmony_ci		}
1515e5c31af7Sopenharmony_ci
1516e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1517e5c31af7Sopenharmony_ci		return error;
1518e5c31af7Sopenharmony_ci	}
1519e5c31af7Sopenharmony_ci};
1520e5c31af7Sopenharmony_ci
1521e5c31af7Sopenharmony_ciclass UniformBlockArray : public PIQBase
1522e5c31af7Sopenharmony_ci{
1523e5c31af7Sopenharmony_ci	virtual std::string Title()
1524e5c31af7Sopenharmony_ci	{
1525e5c31af7Sopenharmony_ci		return "Uniform Block Array Test";
1526e5c31af7Sopenharmony_ci	}
1527e5c31af7Sopenharmony_ci
1528e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1529e5c31af7Sopenharmony_ci	{
1530e5c31af7Sopenharmony_ci		return "verify BLOCK_INDEX property when an interface block is declared as an array of block instances";
1531e5c31af7Sopenharmony_ci	}
1532e5c31af7Sopenharmony_ci
1533e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1534e5c31af7Sopenharmony_ci	{
1535e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_BLOCK_INDEX as an interface param.\n";
1536e5c31af7Sopenharmony_ci	}
1537e5c31af7Sopenharmony_ci
1538e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1539e5c31af7Sopenharmony_ci	{
1540e5c31af7Sopenharmony_ci		return "#version 310 es                 \n"
1541e5c31af7Sopenharmony_ci			   "void main(void)                 \n"
1542e5c31af7Sopenharmony_ci			   "{                               \n"
1543e5c31af7Sopenharmony_ci			   "    gl_Position = vec4(1.0);    \n"
1544e5c31af7Sopenharmony_ci			   "}";
1545e5c31af7Sopenharmony_ci	}
1546e5c31af7Sopenharmony_ci
1547e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1548e5c31af7Sopenharmony_ci	{
1549e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
1550e5c31af7Sopenharmony_ci			   "uniform TestBlock {            \n"
1551e5c31af7Sopenharmony_ci			   "   mediump vec4 color;         \n"
1552e5c31af7Sopenharmony_ci			   "} blockInstance[4];            \n"
1553e5c31af7Sopenharmony_ci			   ""
1554e5c31af7Sopenharmony_ci			   "out mediump vec4 color;                                      \n"
1555e5c31af7Sopenharmony_ci			   "void main() {                                                \n"
1556e5c31af7Sopenharmony_ci			   "    color = blockInstance[2].color + blockInstance[3].color; \n"
1557e5c31af7Sopenharmony_ci			   "}";
1558e5c31af7Sopenharmony_ci	}
1559e5c31af7Sopenharmony_ci
1560e5c31af7Sopenharmony_ci	virtual long Run()
1561e5c31af7Sopenharmony_ci	{
1562e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1563e5c31af7Sopenharmony_ci		LinkProgram(program);
1564e5c31af7Sopenharmony_ci
1565e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1566e5c31af7Sopenharmony_ci
1567e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesUB;
1568e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TestBlock", error);
1569e5c31af7Sopenharmony_ci
1570e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
1571e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TestBlock.color", error);
1572e5c31af7Sopenharmony_ci
1573e5c31af7Sopenharmony_ci		GLenum props[]	= { GL_BLOCK_INDEX };
1574e5c31af7Sopenharmony_ci		GLint  expected[] = { static_cast<GLint>(indicesUB["TestBlock"]) };
1575e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TestBlock.color"], 1, props, 1, expected, error);
1576e5c31af7Sopenharmony_ci
1577e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1578e5c31af7Sopenharmony_ci		return error;
1579e5c31af7Sopenharmony_ci	}
1580e5c31af7Sopenharmony_ci};
1581e5c31af7Sopenharmony_ci
1582e5c31af7Sopenharmony_ciclass TransformFeedbackTypes : public SimpleShaders
1583e5c31af7Sopenharmony_ci{
1584e5c31af7Sopenharmony_ci	virtual std::string Title()
1585e5c31af7Sopenharmony_ci	{
1586e5c31af7Sopenharmony_ci		return "Transform Feedback Varying Types";
1587e5c31af7Sopenharmony_ci	}
1588e5c31af7Sopenharmony_ci
1589e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1590e5c31af7Sopenharmony_ci	{
1591e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different types of out variables used";
1592e5c31af7Sopenharmony_ci	}
1593e5c31af7Sopenharmony_ci
1594e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1595e5c31af7Sopenharmony_ci	{
1596e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1597e5c31af7Sopenharmony_ci	}
1598e5c31af7Sopenharmony_ci
1599e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1600e5c31af7Sopenharmony_ci	{
1601e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
1602e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
1603e5c31af7Sopenharmony_ci			   ""
1604e5c31af7Sopenharmony_ci			   "flat out highp vec4 a;               \n"
1605e5c31af7Sopenharmony_ci			   "out mediump float b[2];              \n"
1606e5c31af7Sopenharmony_ci			   "flat out highp uvec2 c;              \n"
1607e5c31af7Sopenharmony_ci			   "flat out highp uint d;               \n"
1608e5c31af7Sopenharmony_ci			   "out mediump vec3 e[2];               \n"
1609e5c31af7Sopenharmony_ci			   "flat out int f;                      \n"
1610e5c31af7Sopenharmony_ci			   ""
1611e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
1612e5c31af7Sopenharmony_ci			   "{                                    \n"
1613e5c31af7Sopenharmony_ci			   "   vec4 pos;                         \n"
1614e5c31af7Sopenharmony_ci			   "   a = vec4(1);                      \n"
1615e5c31af7Sopenharmony_ci			   "   b[0] = 1.1;                       \n"
1616e5c31af7Sopenharmony_ci			   "   b[1] = 1.1;                       \n"
1617e5c31af7Sopenharmony_ci			   "   c = uvec2(1u);                    \n"
1618e5c31af7Sopenharmony_ci			   "   d = 1u;                           \n"
1619e5c31af7Sopenharmony_ci			   "   e[0] = vec3(1.1);                 \n"
1620e5c31af7Sopenharmony_ci			   "   e[1] = vec3(1.1);                 \n"
1621e5c31af7Sopenharmony_ci			   "   f = 1;                            \n"
1622e5c31af7Sopenharmony_ci			   "   gl_Position = position;           \n"
1623e5c31af7Sopenharmony_ci			   "}";
1624e5c31af7Sopenharmony_ci	}
1625e5c31af7Sopenharmony_ci
1626e5c31af7Sopenharmony_ci	virtual long Run()
1627e5c31af7Sopenharmony_ci	{
1628e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1629e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1630e5c31af7Sopenharmony_ci		const char* varyings[6] = { "a", "b[0]", "b[1]", "c", "d", "e" };
1631e5c31af7Sopenharmony_ci		glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS);
1632e5c31af7Sopenharmony_ci		LinkProgram(program);
1633e5c31af7Sopenharmony_ci
1634e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1635e5c31af7Sopenharmony_ci
1636e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error);
1637e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error);
1638e5c31af7Sopenharmony_ci
1639e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
1640e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1641e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error);
1642e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error);
1643e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1644e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1645e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1646e5c31af7Sopenharmony_ci
1647e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1648e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error);
1649e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error);
1650e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1651e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1652e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1653e5c31af7Sopenharmony_ci
1654e5c31af7Sopenharmony_ci		GLenum props[]	= { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
1655e5c31af7Sopenharmony_ci		GLint  expected[] = { 2, 35666, 1 };
1656e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1657e5c31af7Sopenharmony_ci		GLint expected2[] = { 5, 5126, 1 };
1658e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2,
1659e5c31af7Sopenharmony_ci								   error);
1660e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, 5126, 1 };
1661e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3,
1662e5c31af7Sopenharmony_ci								   error);
1663e5c31af7Sopenharmony_ci		GLint expected4[] = { 2, 36294, 1 };
1664e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error);
1665e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, 5125, 1 };
1666e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error);
1667e5c31af7Sopenharmony_ci		GLint expected6[] = { 2, 35665, 2 };
1668e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error);
1669e5c31af7Sopenharmony_ci
1670e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1671e5c31af7Sopenharmony_ci		return error;
1672e5c31af7Sopenharmony_ci	}
1673e5c31af7Sopenharmony_ci};
1674e5c31af7Sopenharmony_ci
1675e5c31af7Sopenharmony_ciclass TransformFeedbackTypesFullArrayCapture : public SimpleShaders
1676e5c31af7Sopenharmony_ci{
1677e5c31af7Sopenharmony_ci	virtual std::string Title()
1678e5c31af7Sopenharmony_ci	{
1679e5c31af7Sopenharmony_ci		return "Transform Feedback Varying Types Without Element Capture";
1680e5c31af7Sopenharmony_ci	}
1681e5c31af7Sopenharmony_ci
1682e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1683e5c31af7Sopenharmony_ci	{
1684e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different types of out variables used";
1685e5c31af7Sopenharmony_ci	}
1686e5c31af7Sopenharmony_ci
1687e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1688e5c31af7Sopenharmony_ci	{
1689e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1690e5c31af7Sopenharmony_ci	}
1691e5c31af7Sopenharmony_ci
1692e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1693e5c31af7Sopenharmony_ci	{
1694e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
1695e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
1696e5c31af7Sopenharmony_ci			   ""
1697e5c31af7Sopenharmony_ci			   "flat out highp vec4 a;               \n"
1698e5c31af7Sopenharmony_ci			   "out mediump float b[2];              \n"
1699e5c31af7Sopenharmony_ci			   "flat out highp uvec2 c;              \n"
1700e5c31af7Sopenharmony_ci			   "flat out highp uint d;               \n"
1701e5c31af7Sopenharmony_ci			   "out mediump vec3 e[2];               \n"
1702e5c31af7Sopenharmony_ci			   "flat out int f;                      \n"
1703e5c31af7Sopenharmony_ci			   ""
1704e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
1705e5c31af7Sopenharmony_ci			   "{                                    \n"
1706e5c31af7Sopenharmony_ci			   "   vec4 pos;                         \n"
1707e5c31af7Sopenharmony_ci			   "   a = vec4(1);                      \n"
1708e5c31af7Sopenharmony_ci			   "   b[0] = 1.1;                       \n"
1709e5c31af7Sopenharmony_ci			   "   b[1] = 1.1;                       \n"
1710e5c31af7Sopenharmony_ci			   "   c = uvec2(1u);                    \n"
1711e5c31af7Sopenharmony_ci			   "   d = 1u;                           \n"
1712e5c31af7Sopenharmony_ci			   "   e[0] = vec3(1.1);                 \n"
1713e5c31af7Sopenharmony_ci			   "   e[1] = vec3(1.1);                 \n"
1714e5c31af7Sopenharmony_ci			   "   f = 1;                            \n"
1715e5c31af7Sopenharmony_ci			   "   gl_Position = position;           \n"
1716e5c31af7Sopenharmony_ci			   "}";
1717e5c31af7Sopenharmony_ci	}
1718e5c31af7Sopenharmony_ci
1719e5c31af7Sopenharmony_ci	virtual long Run()
1720e5c31af7Sopenharmony_ci	{
1721e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1722e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1723e5c31af7Sopenharmony_ci		const char* varyings[5] = { "a", "b", "c", "d", "e" };
1724e5c31af7Sopenharmony_ci		glTransformFeedbackVaryings(program, 5, varyings, GL_INTERLEAVED_ATTRIBS);
1725e5c31af7Sopenharmony_ci		LinkProgram(program);
1726e5c31af7Sopenharmony_ci
1727e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1728e5c31af7Sopenharmony_ci
1729e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 5, error);
1730e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 2, error);
1731e5c31af7Sopenharmony_ci
1732e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
1733e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1734e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b", error);
1735e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1736e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1737e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1738e5c31af7Sopenharmony_ci
1739e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1740e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b"], "b", error);
1741e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1742e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1743e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1744e5c31af7Sopenharmony_ci
1745e5c31af7Sopenharmony_ci		GLenum props[]	= { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
1746e5c31af7Sopenharmony_ci		GLint  expected[] = { 2, GL_FLOAT_VEC4, 1 };
1747e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1748e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, GL_FLOAT, 2 };
1749e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b"], 3, props, 3, expected2, error);
1750e5c31af7Sopenharmony_ci		GLint expected3[] = { 2, GL_UNSIGNED_INT_VEC2, 1 };
1751e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected3, error);
1752e5c31af7Sopenharmony_ci		GLint expected4[] = { 2, GL_UNSIGNED_INT, 1 };
1753e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected4, error);
1754e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, GL_FLOAT_VEC3, 2 };
1755e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected5, error);
1756e5c31af7Sopenharmony_ci
1757e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1758e5c31af7Sopenharmony_ci		return error;
1759e5c31af7Sopenharmony_ci	}
1760e5c31af7Sopenharmony_ci};
1761e5c31af7Sopenharmony_ci
1762e5c31af7Sopenharmony_ciclass AtomicCounterSimple : public ComputeShaderTest
1763e5c31af7Sopenharmony_ci{
1764e5c31af7Sopenharmony_cipublic:
1765e5c31af7Sopenharmony_ci	virtual std::string Title()
1766e5c31af7Sopenharmony_ci	{
1767e5c31af7Sopenharmony_ci		return "Atomic Counter Buffer Simple Test";
1768e5c31af7Sopenharmony_ci	}
1769e5c31af7Sopenharmony_ci
1770e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1771e5c31af7Sopenharmony_ci	{
1772e5c31af7Sopenharmony_ci		return "compute shader with atomic counters used";
1773e5c31af7Sopenharmony_ci	}
1774e5c31af7Sopenharmony_ci
1775e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1776e5c31af7Sopenharmony_ci	{
1777e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1778e5c31af7Sopenharmony_ci	}
1779e5c31af7Sopenharmony_ci
1780e5c31af7Sopenharmony_ci	virtual long Run()
1781e5c31af7Sopenharmony_ci	{
1782e5c31af7Sopenharmony_ci
1783e5c31af7Sopenharmony_ci		GLint max_buffer_bindings = 0;
1784e5c31af7Sopenharmony_ci		glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1785e5c31af7Sopenharmony_ci		if (max_buffer_bindings < 6)
1786e5c31af7Sopenharmony_ci		{
1787e5c31af7Sopenharmony_ci			OutputNotSupported("Test requires at least 6 atomic counter buffer binding points.");
1788e5c31af7Sopenharmony_ci			return NOT_SUPPORTED;
1789e5c31af7Sopenharmony_ci		}
1790e5c31af7Sopenharmony_ci
1791e5c31af7Sopenharmony_ci		const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in;  \n"
1792e5c31af7Sopenharmony_ci									"layout(std430) buffer Output {                  \n"
1793e5c31af7Sopenharmony_ci									"   mediump vec4 data;                           \n"
1794e5c31af7Sopenharmony_ci									"} g_out;                                        \n"
1795e5c31af7Sopenharmony_ci									""
1796e5c31af7Sopenharmony_ci									"layout (binding = 1, offset = 0) uniform highp atomic_uint a;    \n"
1797e5c31af7Sopenharmony_ci									"layout (binding = 2, offset = 0) uniform highp atomic_uint b;    \n"
1798e5c31af7Sopenharmony_ci									"layout (binding = 2, offset = 4) uniform highp atomic_uint c;    \n"
1799e5c31af7Sopenharmony_ci									"layout (binding = 5, offset = 0) uniform highp atomic_uint d[3]; \n"
1800e5c31af7Sopenharmony_ci									"layout (binding = 5, offset = 12) uniform highp atomic_uint e;   \n"
1801e5c31af7Sopenharmony_ci									""
1802e5c31af7Sopenharmony_ci									"void main() {                                                         \n"
1803e5c31af7Sopenharmony_ci									"   uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
1804e5c31af7Sopenharmony_ci									"   uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
1805e5c31af7Sopenharmony_ci									"   uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
1806e5c31af7Sopenharmony_ci									"   uint w = atomicCounterIncrement(e);                                \n"
1807e5c31af7Sopenharmony_ci									"   g_out.data = vec4(float(x), float(y), float(z), float(w));         \n"
1808e5c31af7Sopenharmony_ci									"}";
1809e5c31af7Sopenharmony_ci
1810e5c31af7Sopenharmony_ci		GLuint program = CreateComputeProgram(glsl_cs);
1811e5c31af7Sopenharmony_ci		glLinkProgram(program);
1812e5c31af7Sopenharmony_ci		if (!CheckProgram(program))
1813e5c31af7Sopenharmony_ci		{
1814e5c31af7Sopenharmony_ci			glDeleteProgram(program);
1815e5c31af7Sopenharmony_ci			return ERROR;
1816e5c31af7Sopenharmony_ci		}
1817e5c31af7Sopenharmony_ci		glUseProgram(program);
1818e5c31af7Sopenharmony_ci
1819e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1820e5c31af7Sopenharmony_ci
1821e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
1822e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
1823e5c31af7Sopenharmony_ci
1824e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
1825e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1826e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1827e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1828e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
1829e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
1830e5c31af7Sopenharmony_ci
1831e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1832e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1833e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1834e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
1835e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
1836e5c31af7Sopenharmony_ci
1837e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1838e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1839e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1840e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
1841e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
1842e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
1843e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
1844e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
1845e5c31af7Sopenharmony_ci
1846e5c31af7Sopenharmony_ci		GLenum		  prop	= GL_ATOMIC_COUNTER_BUFFER_INDEX;
1847e5c31af7Sopenharmony_ci		const GLsizei bufSize = 1000;
1848e5c31af7Sopenharmony_ci		GLsizei		  length;
1849e5c31af7Sopenharmony_ci		GLint		  res;
1850e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1851e5c31af7Sopenharmony_ci
1852e5c31af7Sopenharmony_ci		GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES };
1853e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1854e5c31af7Sopenharmony_ci		GLint expected[] = { 1, 4, 1, static_cast<GLint>(indicesU["a"]) };
1855e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
1856e5c31af7Sopenharmony_ci
1857e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
1858e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1859e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, 8, 2 };
1860e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1861e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
1862e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1863e5c31af7Sopenharmony_ci
1864e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1865e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, 16, 2 };
1866e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1867e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
1868e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1869e5c31af7Sopenharmony_ci
1870e5c31af7Sopenharmony_ci		GLenum			 prop2 = GL_ACTIVE_VARIABLES;
1871e5c31af7Sopenharmony_ci		GLint			 param[bufSize];
1872e5c31af7Sopenharmony_ci		std::set<GLuint> exp;
1873e5c31af7Sopenharmony_ci		exp.insert(indicesU["b"]);
1874e5c31af7Sopenharmony_ci		exp.insert(indicesU["c"]);
1875e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1876e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
1877e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
1878e5c31af7Sopenharmony_ci		{
1879e5c31af7Sopenharmony_ci			if (exp.find(param[i]) == exp.end() || length != 2)
1880e5c31af7Sopenharmony_ci			{
1881e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1882e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "Length: " << length
1883e5c31af7Sopenharmony_ci					<< "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
1884e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
1885e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1886e5c31af7Sopenharmony_ci				return ERROR;
1887e5c31af7Sopenharmony_ci			}
1888e5c31af7Sopenharmony_ci		}
1889e5c31af7Sopenharmony_ci		std::set<GLuint> exp2;
1890e5c31af7Sopenharmony_ci		GLint			 param2[bufSize];
1891e5c31af7Sopenharmony_ci		exp2.insert(indicesU["d"]);
1892e5c31af7Sopenharmony_ci		exp2.insert(indicesU["e"]);
1893e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1894e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
1895e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
1896e5c31af7Sopenharmony_ci		{
1897e5c31af7Sopenharmony_ci			if (exp2.find(param2[i]) == exp2.end() || length != 2)
1898e5c31af7Sopenharmony_ci			{
1899e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1900e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "Length: " << length
1901e5c31af7Sopenharmony_ci					<< "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
1902e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
1903e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1904e5c31af7Sopenharmony_ci				return ERROR;
1905e5c31af7Sopenharmony_ci			}
1906e5c31af7Sopenharmony_ci		}
1907e5c31af7Sopenharmony_ci
1908e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1909e5c31af7Sopenharmony_ci		return error;
1910e5c31af7Sopenharmony_ci	}
1911e5c31af7Sopenharmony_ci};
1912e5c31af7Sopenharmony_ci
1913e5c31af7Sopenharmony_ciclass AtomicCounterSimpleOneBuffer : public ComputeShaderTest
1914e5c31af7Sopenharmony_ci{
1915e5c31af7Sopenharmony_cipublic:
1916e5c31af7Sopenharmony_ci	virtual std::string Title()
1917e5c31af7Sopenharmony_ci	{
1918e5c31af7Sopenharmony_ci		return "Atomic Counter Buffer Simple One Buffer Test";
1919e5c31af7Sopenharmony_ci	}
1920e5c31af7Sopenharmony_ci
1921e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1922e5c31af7Sopenharmony_ci	{
1923e5c31af7Sopenharmony_ci		return "compute shader with atomic counters used";
1924e5c31af7Sopenharmony_ci	}
1925e5c31af7Sopenharmony_ci
1926e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1927e5c31af7Sopenharmony_ci	{
1928e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1929e5c31af7Sopenharmony_ci	}
1930e5c31af7Sopenharmony_ci
1931e5c31af7Sopenharmony_ci	virtual long Run()
1932e5c31af7Sopenharmony_ci	{
1933e5c31af7Sopenharmony_ci
1934e5c31af7Sopenharmony_ci		GLint max_buffer_bindings = 0;
1935e5c31af7Sopenharmony_ci		glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, &max_buffer_bindings);
1936e5c31af7Sopenharmony_ci		if (max_buffer_bindings < 3)
1937e5c31af7Sopenharmony_ci		{
1938e5c31af7Sopenharmony_ci			OutputNotSupported("Test requires at least 3 atomic counter buffer binding points.");
1939e5c31af7Sopenharmony_ci			return NOT_SUPPORTED;
1940e5c31af7Sopenharmony_ci		}
1941e5c31af7Sopenharmony_ci
1942e5c31af7Sopenharmony_ci		const char* const glsl_cs = "layout(local_size_x = 1, local_size_y = 1) in;  \n"
1943e5c31af7Sopenharmony_ci									"layout(std430) buffer Output {                  \n"
1944e5c31af7Sopenharmony_ci									"   mediump vec4 data;                           \n"
1945e5c31af7Sopenharmony_ci									"} g_out;                                        \n"
1946e5c31af7Sopenharmony_ci									""
1947e5c31af7Sopenharmony_ci									"layout (binding = 0, offset = 0) uniform highp atomic_uint a;    \n"
1948e5c31af7Sopenharmony_ci									"layout (binding = 0, offset = 4) uniform highp atomic_uint b[3]; \n"
1949e5c31af7Sopenharmony_ci									"layout (binding = 0, offset = 16) uniform highp atomic_uint c;   \n"
1950e5c31af7Sopenharmony_ci									""
1951e5c31af7Sopenharmony_ci									"void main() {                                                         \n"
1952e5c31af7Sopenharmony_ci									"   uint x = atomicCounterIncrement(b[0]) + atomicCounterIncrement(a); \n"
1953e5c31af7Sopenharmony_ci									"   uint y = atomicCounterIncrement(b[1]) + atomicCounterIncrement(a); \n"
1954e5c31af7Sopenharmony_ci									"   uint z = atomicCounterIncrement(b[2]) + atomicCounterIncrement(a); \n"
1955e5c31af7Sopenharmony_ci									"   uint w = atomicCounterIncrement(c);                                \n"
1956e5c31af7Sopenharmony_ci									"   g_out.data = vec4(float(x), float(y), float(z), float(w));         \n"
1957e5c31af7Sopenharmony_ci									"}";
1958e5c31af7Sopenharmony_ci
1959e5c31af7Sopenharmony_ci		GLuint program = CreateComputeProgram(glsl_cs);
1960e5c31af7Sopenharmony_ci		glLinkProgram(program);
1961e5c31af7Sopenharmony_ci		if (!CheckProgram(program))
1962e5c31af7Sopenharmony_ci		{
1963e5c31af7Sopenharmony_ci			glDeleteProgram(program);
1964e5c31af7Sopenharmony_ci			return ERROR;
1965e5c31af7Sopenharmony_ci		}
1966e5c31af7Sopenharmony_ci		glUseProgram(program);
1967e5c31af7Sopenharmony_ci
1968e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1969e5c31af7Sopenharmony_ci
1970e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 1, error);
1971e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 3, error);
1972e5c31af7Sopenharmony_ci
1973e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
1974e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1975e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1976e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1977e5c31af7Sopenharmony_ci
1978e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1979e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b[0]", error);
1980e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1981e5c31af7Sopenharmony_ci
1982e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1983e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1984e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1985e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[0]", -1, error);
1986e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[1]", -1, error);
1987e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b[2]", -1, error);
1988e5c31af7Sopenharmony_ci
1989e5c31af7Sopenharmony_ci		GLenum		  prop	= GL_ATOMIC_COUNTER_BUFFER_INDEX;
1990e5c31af7Sopenharmony_ci		const GLsizei bufSize = 1000;
1991e5c31af7Sopenharmony_ci		GLsizei		  length;
1992e5c31af7Sopenharmony_ci		GLint		  res;
1993e5c31af7Sopenharmony_ci
1994e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1995e5c31af7Sopenharmony_ci		if (res != 0)
1996e5c31af7Sopenharmony_ci		{
1997e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
1998e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
1999e5c31af7Sopenharmony_ci			glDeleteProgram(program);
2000e5c31af7Sopenharmony_ci			return ERROR;
2001e5c31af7Sopenharmony_ci		}
2002e5c31af7Sopenharmony_ci
2003e5c31af7Sopenharmony_ci		GLenum props[]	= { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
2004e5c31af7Sopenharmony_ci		GLint  expected[] = { 0, 20, 3 };
2005e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props, 3, expected, error);
2006e5c31af7Sopenharmony_ci
2007e5c31af7Sopenharmony_ci		GLenum			 prop2 = GL_ACTIVE_VARIABLES;
2008e5c31af7Sopenharmony_ci		GLint			 param[bufSize];
2009e5c31af7Sopenharmony_ci		std::set<GLuint> exp;
2010e5c31af7Sopenharmony_ci		exp.insert(indicesU["a"]);
2011e5c31af7Sopenharmony_ci		exp.insert(indicesU["b"]);
2012e5c31af7Sopenharmony_ci		exp.insert(indicesU["c"]);
2013e5c31af7Sopenharmony_ci
2014e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
2015e5c31af7Sopenharmony_ci		if (res != 0)
2016e5c31af7Sopenharmony_ci		{
2017e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
2018e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Got buffer index " << res << ", expected 0." << tcu::TestLog::EndMessage;
2019e5c31af7Sopenharmony_ci			glDeleteProgram(program);
2020e5c31af7Sopenharmony_ci			return ERROR;
2021e5c31af7Sopenharmony_ci		}
2022e5c31af7Sopenharmony_ci
2023e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
2024e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
2025e5c31af7Sopenharmony_ci		{
2026e5c31af7Sopenharmony_ci			if (exp.find(param[i]) == exp.end() || length != 3)
2027e5c31af7Sopenharmony_ci			{
2028e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
2029e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "Length: " << length
2030e5c31af7Sopenharmony_ci					<< "Unexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
2031e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
2032e5c31af7Sopenharmony_ci				glDeleteProgram(program);
2033e5c31af7Sopenharmony_ci				return ERROR;
2034e5c31af7Sopenharmony_ci			}
2035e5c31af7Sopenharmony_ci		}
2036e5c31af7Sopenharmony_ci
2037e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2038e5c31af7Sopenharmony_ci		return error;
2039e5c31af7Sopenharmony_ci	}
2040e5c31af7Sopenharmony_ci};
2041e5c31af7Sopenharmony_ci
2042e5c31af7Sopenharmony_ciclass InvalidValueTest : public SimpleShaders
2043e5c31af7Sopenharmony_ci{
2044e5c31af7Sopenharmony_ci	virtual std::string Title()
2045e5c31af7Sopenharmony_ci	{
2046e5c31af7Sopenharmony_ci		return "Invalid Value Test";
2047e5c31af7Sopenharmony_ci	}
2048e5c31af7Sopenharmony_ci
2049e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
2050e5c31af7Sopenharmony_ci	{
2051e5c31af7Sopenharmony_ci		return "GL_INVALID_VALUE error is generated after every function call.";
2052e5c31af7Sopenharmony_ci	}
2053e5c31af7Sopenharmony_ci
2054e5c31af7Sopenharmony_ci	virtual std::string Purpose()
2055e5c31af7Sopenharmony_ci	{
2056e5c31af7Sopenharmony_ci		return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
2057e5c31af7Sopenharmony_ci	}
2058e5c31af7Sopenharmony_ci
2059e5c31af7Sopenharmony_ci	virtual std::string Method()
2060e5c31af7Sopenharmony_ci	{
2061e5c31af7Sopenharmony_ci		return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
2062e5c31af7Sopenharmony_ci	}
2063e5c31af7Sopenharmony_ci
2064e5c31af7Sopenharmony_ci	virtual long Run()
2065e5c31af7Sopenharmony_ci	{
2066e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2067e5c31af7Sopenharmony_ci
2068e5c31af7Sopenharmony_ci		GLint   res;
2069e5c31af7Sopenharmony_ci		GLsizei len		  = 0;
2070e5c31af7Sopenharmony_ci		GLchar  name[100] = { '\0' };
2071e5c31af7Sopenharmony_ci		GLenum  props[1]  = { GL_NAME_LENGTH };
2072e5c31af7Sopenharmony_ci
2073e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2074e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
2075e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2076e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2077e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2078e5c31af7Sopenharmony_ci		glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
2079e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2080e5c31af7Sopenharmony_ci		glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2081e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2082e5c31af7Sopenharmony_ci		glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2083e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2084e5c31af7Sopenharmony_ci		glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
2085e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2086e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
2087e5c31af7Sopenharmony_ci
2088e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2089e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2090e5c31af7Sopenharmony_ci		LinkProgram(program);
2091e5c31af7Sopenharmony_ci
2092e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2093e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message
2094e5c31af7Sopenharmony_ci			<< "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
2095e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2096e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1: finished" << tcu::TestLog::EndMessage;
2097e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
2098e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2099e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2: finished" << tcu::TestLog::EndMessage;
2100e5c31af7Sopenharmony_ci
2101e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2102e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
2103e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2104e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
2105e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2106e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3: finished" << tcu::TestLog::EndMessage;
2107e5c31af7Sopenharmony_ci
2108e5c31af7Sopenharmony_ci		std::string str = "position";
2109e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char*>(str.c_str()));
2110e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2111e5c31af7Sopenharmony_ci		GLenum prop = GL_NAME_LENGTH;
2112e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
2113e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2114e5c31af7Sopenharmony_ci
2115e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2116e5c31af7Sopenharmony_ci		return error;
2117e5c31af7Sopenharmony_ci	}
2118e5c31af7Sopenharmony_ci};
2119e5c31af7Sopenharmony_ci
2120e5c31af7Sopenharmony_ciclass InvalidEnumTest : public SimpleShaders
2121e5c31af7Sopenharmony_ci{
2122e5c31af7Sopenharmony_ci	virtual std::string Title()
2123e5c31af7Sopenharmony_ci	{
2124e5c31af7Sopenharmony_ci		return "Invalid Enum Test";
2125e5c31af7Sopenharmony_ci	}
2126e5c31af7Sopenharmony_ci
2127e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
2128e5c31af7Sopenharmony_ci	{
2129e5c31af7Sopenharmony_ci		return "GL_INVALID_ENUM error is generated after every function call.";
2130e5c31af7Sopenharmony_ci	}
2131e5c31af7Sopenharmony_ci
2132e5c31af7Sopenharmony_ci	virtual std::string Purpose()
2133e5c31af7Sopenharmony_ci	{
2134e5c31af7Sopenharmony_ci		return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
2135e5c31af7Sopenharmony_ci	}
2136e5c31af7Sopenharmony_ci
2137e5c31af7Sopenharmony_ci	virtual std::string Method()
2138e5c31af7Sopenharmony_ci	{
2139e5c31af7Sopenharmony_ci		return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
2140e5c31af7Sopenharmony_ci	}
2141e5c31af7Sopenharmony_ci
2142e5c31af7Sopenharmony_ci	// make sure at least one atomic counter resource is active
2143e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
2144e5c31af7Sopenharmony_ci	{
2145e5c31af7Sopenharmony_ci		return "#version 310 es                                        \n"
2146e5c31af7Sopenharmony_ci			   "layout (binding = 0, offset = 0) uniform highp atomic_uint a;\n"
2147e5c31af7Sopenharmony_ci			   "out mediump vec4 outColor;                             \n"
2148e5c31af7Sopenharmony_ci			   "void main(void) {                                      \n"
2149e5c31af7Sopenharmony_ci			   "   uint b = atomicCounterIncrement(a);                 \n"
2150e5c31af7Sopenharmony_ci			   "   outColor = vec4(float(b));                          \n"
2151e5c31af7Sopenharmony_ci			   "}                                                      \n";
2152e5c31af7Sopenharmony_ci	}
2153e5c31af7Sopenharmony_ci
2154e5c31af7Sopenharmony_ci	virtual long Run()
2155e5c31af7Sopenharmony_ci	{
2156e5c31af7Sopenharmony_ci		GLint max_buffers = 0, max_counters = 0;
2157e5c31af7Sopenharmony_ci		glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_buffers);
2158e5c31af7Sopenharmony_ci		glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &max_counters);
2159e5c31af7Sopenharmony_ci		if (max_buffers < 1 || max_counters < 1)
2160e5c31af7Sopenharmony_ci		{
2161e5c31af7Sopenharmony_ci			OutputNotSupported("Test requires at least 1 atomic counter.");
2162e5c31af7Sopenharmony_ci			return NOT_SUPPORTED;
2163e5c31af7Sopenharmony_ci		}
2164e5c31af7Sopenharmony_ci
2165e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2166e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2167e5c31af7Sopenharmony_ci		LinkProgram(program);
2168e5c31af7Sopenharmony_ci
2169e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2170e5c31af7Sopenharmony_ci
2171e5c31af7Sopenharmony_ci		GLint   res;
2172e5c31af7Sopenharmony_ci		GLsizei len		  = 0;
2173e5c31af7Sopenharmony_ci		GLchar  name[100] = { '\0' };
2174e5c31af7Sopenharmony_ci		GLenum  props[1]  = { GL_TEXTURE_1D };
2175e5c31af7Sopenharmony_ci
2176e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2177e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER in "
2178e5c31af7Sopenharmony_ci										"GetProgramResourceIndex or GetProgramResourceName"
2179e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2180e5c31af7Sopenharmony_ci		glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
2181e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_ENUM, error);
2182e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
2183e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_ENUM, error);
2184e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2185e5c31af7Sopenharmony_ci
2186e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2187e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message
2188e5c31af7Sopenharmony_ci			<< "Case 2: <props> is not a property name supported by the command GetProgramResourceiv"
2189e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2190e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2191e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_ENUM, error);
2192e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2193e5c31af7Sopenharmony_ci
2194e5c31af7Sopenharmony_ci		glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
2195e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_ENUM, error);
2196e5c31af7Sopenharmony_ci
2197e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2198e5c31af7Sopenharmony_ci		return error;
2199e5c31af7Sopenharmony_ci	}
2200e5c31af7Sopenharmony_ci};
2201e5c31af7Sopenharmony_ci
2202e5c31af7Sopenharmony_ciclass InvalidOperationTest : public SimpleShaders
2203e5c31af7Sopenharmony_ci{
2204e5c31af7Sopenharmony_ci	virtual std::string Title()
2205e5c31af7Sopenharmony_ci	{
2206e5c31af7Sopenharmony_ci		return "Invalid Operation Test";
2207e5c31af7Sopenharmony_ci	}
2208e5c31af7Sopenharmony_ci
2209e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
2210e5c31af7Sopenharmony_ci	{
2211e5c31af7Sopenharmony_ci		return "GL_INVALID_OPERATION error is generated after every function call.";
2212e5c31af7Sopenharmony_ci	}
2213e5c31af7Sopenharmony_ci
2214e5c31af7Sopenharmony_ci	virtual std::string Purpose()
2215e5c31af7Sopenharmony_ci	{
2216e5c31af7Sopenharmony_ci		return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
2217e5c31af7Sopenharmony_ci	}
2218e5c31af7Sopenharmony_ci
2219e5c31af7Sopenharmony_ci	virtual std::string Method()
2220e5c31af7Sopenharmony_ci	{
2221e5c31af7Sopenharmony_ci		return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
2222e5c31af7Sopenharmony_ci	}
2223e5c31af7Sopenharmony_ci
2224e5c31af7Sopenharmony_ci	virtual long Run()
2225e5c31af7Sopenharmony_ci	{
2226e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2227e5c31af7Sopenharmony_ci
2228e5c31af7Sopenharmony_ci		GLuint program  = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2229e5c31af7Sopenharmony_ci		GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2230e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2231e5c31af7Sopenharmony_ci		LinkProgram(program);
2232e5c31af7Sopenharmony_ci
2233e5c31af7Sopenharmony_ci		const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
2234e5c31af7Sopenharmony_ci		GLint		 res;
2235e5c31af7Sopenharmony_ci		GLsizei		 len	   = 0;
2236e5c31af7Sopenharmony_ci		GLchar		 name[100] = { '\0' };
2237e5c31af7Sopenharmony_ci		GLenum		 props[1]  = { GL_OFFSET };
2238e5c31af7Sopenharmony_ci
2239e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2240e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
2241e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2242e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2243e5c31af7Sopenharmony_ci		glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
2244e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2245e5c31af7Sopenharmony_ci		glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2246e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2247e5c31af7Sopenharmony_ci		glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2248e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2249e5c31af7Sopenharmony_ci		glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
2250e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2251e5c31af7Sopenharmony_ci		glDeleteShader(sh);
2252e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2253e5c31af7Sopenharmony_ci
2254e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2255e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 2: <pname> is not supported in GetProgramInterfaceiv"
2256e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2257e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2258e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2259e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2260e5c31af7Sopenharmony_ci
2261e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2262e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 3: <props> is not supported in GetProgramResourceiv"
2263e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2264e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2265e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2266e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
2267e5c31af7Sopenharmony_ci
2268e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2269e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 4: <program> has not been linked in GetProgramResourceLocation"
2270e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2271e5c31af7Sopenharmony_ci		glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
2272e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2273e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished" << tcu::TestLog::EndMessage;
2274e5c31af7Sopenharmony_ci
2275e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2276e5c31af7Sopenharmony_ci		glDeleteProgram(program2);
2277e5c31af7Sopenharmony_ci		return error;
2278e5c31af7Sopenharmony_ci	}
2279e5c31af7Sopenharmony_ci};
2280e5c31af7Sopenharmony_ci
2281e5c31af7Sopenharmony_ciclass ShaderStorageBlock : public ComputeShaderTest
2282e5c31af7Sopenharmony_ci{
2283e5c31af7Sopenharmony_ci	virtual std::string Title()
2284e5c31af7Sopenharmony_ci	{
2285e5c31af7Sopenharmony_ci		return "Shader Storage Block Test";
2286e5c31af7Sopenharmony_ci	}
2287e5c31af7Sopenharmony_ci
2288e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
2289e5c31af7Sopenharmony_ci	{
2290e5c31af7Sopenharmony_ci		return "compute shader different types of storage blocks used";
2291e5c31af7Sopenharmony_ci	}
2292e5c31af7Sopenharmony_ci
2293e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2294e5c31af7Sopenharmony_ci	{
2295e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
2296e5c31af7Sopenharmony_ci			   "params.\n";
2297e5c31af7Sopenharmony_ci	}
2298e5c31af7Sopenharmony_ci
2299e5c31af7Sopenharmony_ci	virtual std::string ComputeShader()
2300e5c31af7Sopenharmony_ci	{
2301e5c31af7Sopenharmony_ci		return "layout(local_size_x = 1, local_size_y = 1) in;  \n"
2302e5c31af7Sopenharmony_ci			   "layout(std430) buffer Output {                  \n"
2303e5c31af7Sopenharmony_ci			   "   mediump vec4 data;                           \n"
2304e5c31af7Sopenharmony_ci			   "} g_out;                                        \n"
2305e5c31af7Sopenharmony_ci			   ""
2306e5c31af7Sopenharmony_ci			   "struct U {                     \n"
2307e5c31af7Sopenharmony_ci			   "   bool a[3];                  \n"
2308e5c31af7Sopenharmony_ci			   "   mediump vec4 b;                     \n"
2309e5c31af7Sopenharmony_ci			   "   mediump mat3 c;                     \n"
2310e5c31af7Sopenharmony_ci			   "   mediump float d[2];                 \n"
2311e5c31af7Sopenharmony_ci			   "};                             \n"
2312e5c31af7Sopenharmony_ci			   "struct UU {                    \n"
2313e5c31af7Sopenharmony_ci			   "   U a;                        \n"
2314e5c31af7Sopenharmony_ci			   "   U b[2];                     \n"
2315e5c31af7Sopenharmony_ci			   "   uvec2 c;                    \n"
2316e5c31af7Sopenharmony_ci			   "};                             \n"
2317e5c31af7Sopenharmony_ci			   ""
2318e5c31af7Sopenharmony_ci			   "layout(binding=4) buffer TrickyBuffer {          \n"
2319e5c31af7Sopenharmony_ci			   "   UU a[3];                                      \n"
2320e5c31af7Sopenharmony_ci			   "   mediump mat4 b;                               \n"
2321e5c31af7Sopenharmony_ci			   "   uint c;                                       \n"
2322e5c31af7Sopenharmony_ci			   "} e[2];                                          \n"
2323e5c31af7Sopenharmony_ci			   ""
2324e5c31af7Sopenharmony_ci			   "layout(binding = 0) buffer SimpleBuffer {                \n"
2325e5c31af7Sopenharmony_ci			   "   mediump mat3x2 a;                                     \n"
2326e5c31af7Sopenharmony_ci			   "   mediump mat4 b;                                       \n"
2327e5c31af7Sopenharmony_ci			   "   mediump vec4 c;                                       \n"
2328e5c31af7Sopenharmony_ci			   "};                                                       \n"
2329e5c31af7Sopenharmony_ci			   ""
2330e5c31af7Sopenharmony_ci			   "layout(binding = 1) buffer NotSoSimpleBuffer {           \n"
2331e5c31af7Sopenharmony_ci			   "   ivec2 a[4];                                           \n"
2332e5c31af7Sopenharmony_ci			   "   mediump mat3 b[2];                                    \n"
2333e5c31af7Sopenharmony_ci			   "   mediump mat2 c;                                       \n"
2334e5c31af7Sopenharmony_ci			   "} d;                                                     \n"
2335e5c31af7Sopenharmony_ci			   ""
2336e5c31af7Sopenharmony_ci			   "void main() {                                    \n"
2337e5c31af7Sopenharmony_ci			   "    mediump float tmp;                           \n"
2338e5c31af7Sopenharmony_ci			   "    mediump float tmp2;                          \n"
2339e5c31af7Sopenharmony_ci			   "    tmp = e[0].a[0].b[0].d[0] * float(e[1].c);   \n"
2340e5c31af7Sopenharmony_ci			   "    tmp2 = a[0][0] * b[0][0] * c.x;                                \n"
2341e5c31af7Sopenharmony_ci			   "    tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0];      \n"
2342e5c31af7Sopenharmony_ci			   "    g_out.data = vec4(0, 1, 0, 1) * tmp * tmp2;                    \n"
2343e5c31af7Sopenharmony_ci			   "}";
2344e5c31af7Sopenharmony_ci	}
2345e5c31af7Sopenharmony_ci
2346e5c31af7Sopenharmony_ci	virtual long Run()
2347e5c31af7Sopenharmony_ci	{
2348e5c31af7Sopenharmony_ci		GLuint program = CreateComputeProgram(ComputeShader());
2349e5c31af7Sopenharmony_ci		glLinkProgram(program);
2350e5c31af7Sopenharmony_ci		if (!CheckProgram(program))
2351e5c31af7Sopenharmony_ci		{
2352e5c31af7Sopenharmony_ci			glDeleteProgram(program);
2353e5c31af7Sopenharmony_ci			return ERROR;
2354e5c31af7Sopenharmony_ci		}
2355e5c31af7Sopenharmony_ci		glUseProgram(program);
2356e5c31af7Sopenharmony_ci
2357e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2358e5c31af7Sopenharmony_ci
2359e5c31af7Sopenharmony_ci		GLint res;
2360e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
2361e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
2362e5c31af7Sopenharmony_ci		if (res < 7)
2363e5c31af7Sopenharmony_ci		{
2364e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
2365e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
2366e5c31af7Sopenharmony_ci				<< "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
2367e5c31af7Sopenharmony_ci				<< "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
2368e5c31af7Sopenharmony_ci			glDeleteProgram(program);
2369e5c31af7Sopenharmony_ci			return ERROR;
2370e5c31af7Sopenharmony_ci		}
2371e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 5, error);
2372e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
2373e5c31af7Sopenharmony_ci
2374e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesSSB;
2375e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesBV;
2376e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
2377e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
2378e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
2379e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
2380e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
2381e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
2382e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
2383e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
2384e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
2385e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
2386e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
2387e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
2388e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
2389e5c31af7Sopenharmony_ci
2390e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
2391e5c31af7Sopenharmony_ci									 error);
2392e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
2393e5c31af7Sopenharmony_ci									 "NotSoSimpleBuffer", error);
2394e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
2395e5c31af7Sopenharmony_ci									 error);
2396e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
2397e5c31af7Sopenharmony_ci									 error);
2398e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
2399e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
2400e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
2401e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
2402e5c31af7Sopenharmony_ci									 "NotSoSimpleBuffer.a[0]", error);
2403e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
2404e5c31af7Sopenharmony_ci									 "NotSoSimpleBuffer.c", error);
2405e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
2406e5c31af7Sopenharmony_ci									 "NotSoSimpleBuffer.b[0]", error);
2407e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
2408e5c31af7Sopenharmony_ci									 "TrickyBuffer.a[0].b[0].d[0]", error);
2409e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
2410e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
2411e5c31af7Sopenharmony_ci
2412e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
2413e5c31af7Sopenharmony_ci						   GL_BUFFER_BINDING,
2414e5c31af7Sopenharmony_ci						   GL_NUM_ACTIVE_VARIABLES,
2415e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
2416e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
2417e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER };
2418e5c31af7Sopenharmony_ci		GLint expected[] = { 13, 0, 3, 1, 0, 0 };
2419e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 6, props, 6, expected,
2420e5c31af7Sopenharmony_ci								   error);
2421e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH, GL_BUFFER_BINDING, GL_REFERENCED_BY_COMPUTE_SHADER,
2422e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_VERTEX_SHADER };
2423e5c31af7Sopenharmony_ci		GLint expected2[] = { 18, 1, 1, 0, 0 };
2424e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 5, props2, 5,
2425e5c31af7Sopenharmony_ci								   expected2, error);
2426e5c31af7Sopenharmony_ci		GLint expected3[] = { 16, 4, 1, 0, 0 };
2427e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 5, props2, 5,
2428e5c31af7Sopenharmony_ci								   expected3, error);
2429e5c31af7Sopenharmony_ci		GLint expected4[] = { 16, 5, 1, 0, 0 };
2430e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 5, props2, 5,
2431e5c31af7Sopenharmony_ci								   expected4, error);
2432e5c31af7Sopenharmony_ci
2433e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
2434e5c31af7Sopenharmony_ci							GL_TYPE,
2435e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
2436e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
2437e5c31af7Sopenharmony_ci							GL_ARRAY_STRIDE,
2438e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
2439e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
2440e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
2441e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
2442e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_SIZE,
2443e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_STRIDE };
2444e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, 35687, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 1, 0, 0, 1, 0 };
2445e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props3, 11, expected5, error);
2446e5c31af7Sopenharmony_ci		GLenum props4[] = { GL_NAME_LENGTH,
2447e5c31af7Sopenharmony_ci							GL_TYPE,
2448e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
2449e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
2450e5c31af7Sopenharmony_ci							GL_MATRIX_STRIDE,
2451e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
2452e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
2453e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
2454e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
2455e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_SIZE };
2456e5c31af7Sopenharmony_ci		GLint expected6[] = { 28, 5126, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 1, 0, 0, 3 };
2457e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 10, props4, 10,
2458e5c31af7Sopenharmony_ci								   expected6, error);
2459e5c31af7Sopenharmony_ci
2460e5c31af7Sopenharmony_ci		GLenum			 prop	= GL_ACTIVE_VARIABLES;
2461e5c31af7Sopenharmony_ci		const GLsizei	bufSize = 1000;
2462e5c31af7Sopenharmony_ci		GLsizei			 length;
2463e5c31af7Sopenharmony_ci		GLint			 param[bufSize];
2464e5c31af7Sopenharmony_ci		std::set<GLuint> exp;
2465e5c31af7Sopenharmony_ci		exp.insert(indicesBV["a"]);
2466e5c31af7Sopenharmony_ci		exp.insert(indicesBV["b"]);
2467e5c31af7Sopenharmony_ci		exp.insert(indicesBV["c"]);
2468e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
2469e5c31af7Sopenharmony_ci							   param);
2470e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
2471e5c31af7Sopenharmony_ci		{
2472e5c31af7Sopenharmony_ci			if (exp.find(param[i]) == exp.end())
2473e5c31af7Sopenharmony_ci			{
2474e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
2475e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
2476e5c31af7Sopenharmony_ci					<< "Unexpected index found in active variables of SimpleBuffer: " << param[i]
2477e5c31af7Sopenharmony_ci					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2478e5c31af7Sopenharmony_ci					   "GL_SHADER_STORAGE_BLOCK"
2479e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
2480e5c31af7Sopenharmony_ci				glDeleteProgram(program);
2481e5c31af7Sopenharmony_ci				return ERROR;
2482e5c31af7Sopenharmony_ci			}
2483e5c31af7Sopenharmony_ci			else if (length != 3)
2484e5c31af7Sopenharmony_ci			{
2485e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
2486e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
2487e5c31af7Sopenharmony_ci					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2488e5c31af7Sopenharmony_ci					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2489e5c31af7Sopenharmony_ci				glDeleteProgram(program);
2490e5c31af7Sopenharmony_ci				return ERROR;
2491e5c31af7Sopenharmony_ci			}
2492e5c31af7Sopenharmony_ci		}
2493e5c31af7Sopenharmony_ci		std::set<GLuint> exp2;
2494e5c31af7Sopenharmony_ci		exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
2495e5c31af7Sopenharmony_ci		exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
2496e5c31af7Sopenharmony_ci		exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
2497e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
2498e5c31af7Sopenharmony_ci							   &length, param);
2499e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
2500e5c31af7Sopenharmony_ci		{
2501e5c31af7Sopenharmony_ci			if (exp2.find(param[i]) == exp2.end())
2502e5c31af7Sopenharmony_ci			{
2503e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
2504e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
2505e5c31af7Sopenharmony_ci					<< "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
2506e5c31af7Sopenharmony_ci					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
2507e5c31af7Sopenharmony_ci					   "GL_SHADER_STORAGE_BLOCK"
2508e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
2509e5c31af7Sopenharmony_ci				glDeleteProgram(program);
2510e5c31af7Sopenharmony_ci				return ERROR;
2511e5c31af7Sopenharmony_ci			}
2512e5c31af7Sopenharmony_ci			else if (length != 3)
2513e5c31af7Sopenharmony_ci			{
2514e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
2515e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
2516e5c31af7Sopenharmony_ci					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_SHADER_STORAGE_BLOCK"
2517e5c31af7Sopenharmony_ci					<< param[i] << "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
2518e5c31af7Sopenharmony_ci				glDeleteProgram(program);
2519e5c31af7Sopenharmony_ci				return ERROR;
2520e5c31af7Sopenharmony_ci			}
2521e5c31af7Sopenharmony_ci		}
2522e5c31af7Sopenharmony_ci
2523e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2524e5c31af7Sopenharmony_ci		if (res < 3)
2525e5c31af7Sopenharmony_ci		{
2526e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
2527e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
2528e5c31af7Sopenharmony_ci				<< "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
2529e5c31af7Sopenharmony_ci			return ERROR;
2530e5c31af7Sopenharmony_ci		}
2531e5c31af7Sopenharmony_ci
2532e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2533e5c31af7Sopenharmony_ci		return error;
2534e5c31af7Sopenharmony_ci	}
2535e5c31af7Sopenharmony_ci};
2536e5c31af7Sopenharmony_ci
2537e5c31af7Sopenharmony_ciclass NullLength : public SimpleShaders
2538e5c31af7Sopenharmony_ci{
2539e5c31af7Sopenharmony_ci
2540e5c31af7Sopenharmony_ci	virtual std::string Title()
2541e5c31af7Sopenharmony_ci	{
2542e5c31af7Sopenharmony_ci		return "NULL Length Test";
2543e5c31af7Sopenharmony_ci	}
2544e5c31af7Sopenharmony_ci
2545e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2546e5c31af7Sopenharmony_ci	{
2547e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
2548e5c31af7Sopenharmony_ci			   "crash).\n";
2549e5c31af7Sopenharmony_ci	}
2550e5c31af7Sopenharmony_ci
2551e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
2552e5c31af7Sopenharmony_ci	{
2553e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
2554e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
2555e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
2556e5c31af7Sopenharmony_ci			   "{                                    \n"
2557e5c31af7Sopenharmony_ci			   "    gl_Position = position;          \n"
2558e5c31af7Sopenharmony_ci			   "}";
2559e5c31af7Sopenharmony_ci	}
2560e5c31af7Sopenharmony_ci
2561e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
2562e5c31af7Sopenharmony_ci	{
2563e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
2564e5c31af7Sopenharmony_ci			   "out mediump vec4 color;                \n"
2565e5c31af7Sopenharmony_ci			   "void main() {                  \n"
2566e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1);  \n"
2567e5c31af7Sopenharmony_ci			   "}";
2568e5c31af7Sopenharmony_ci	}
2569e5c31af7Sopenharmony_ci
2570e5c31af7Sopenharmony_ci	virtual long Run()
2571e5c31af7Sopenharmony_ci	{
2572e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2573e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2574e5c31af7Sopenharmony_ci		LinkProgram(program);
2575e5c31af7Sopenharmony_ci
2576e5c31af7Sopenharmony_ci		GLchar name[1024] = { '\0' };
2577e5c31af7Sopenharmony_ci		GLuint index	  = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
2578e5c31af7Sopenharmony_ci		GLenum prop		  = GL_ARRAY_SIZE;
2579e5c31af7Sopenharmony_ci		GLint  res;
2580e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
2581e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
2582e5c31af7Sopenharmony_ci
2583e5c31af7Sopenharmony_ci		std::string expected = "color";
2584e5c31af7Sopenharmony_ci		if (name != expected)
2585e5c31af7Sopenharmony_ci		{
2586e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
2587e5c31af7Sopenharmony_ci												<< ", got: " << name << tcu::TestLog::EndMessage;
2588e5c31af7Sopenharmony_ci			glDeleteProgram(program);
2589e5c31af7Sopenharmony_ci			return ERROR;
2590e5c31af7Sopenharmony_ci		}
2591e5c31af7Sopenharmony_ci		else if (res != 1)
2592e5c31af7Sopenharmony_ci		{
2593e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
2594e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
2595e5c31af7Sopenharmony_ci			glDeleteProgram(program);
2596e5c31af7Sopenharmony_ci			return ERROR;
2597e5c31af7Sopenharmony_ci		}
2598e5c31af7Sopenharmony_ci
2599e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2600e5c31af7Sopenharmony_ci		return NO_ERROR;
2601e5c31af7Sopenharmony_ci	}
2602e5c31af7Sopenharmony_ci};
2603e5c31af7Sopenharmony_ci
2604e5c31af7Sopenharmony_ciclass ArraysOfArrays : public SimpleShaders
2605e5c31af7Sopenharmony_ci{
2606e5c31af7Sopenharmony_ci
2607e5c31af7Sopenharmony_ci	virtual std::string Title()
2608e5c31af7Sopenharmony_ci	{
2609e5c31af7Sopenharmony_ci		return "Arrays Of Arrays Test";
2610e5c31af7Sopenharmony_ci	}
2611e5c31af7Sopenharmony_ci
2612e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
2613e5c31af7Sopenharmony_ci	{
2614e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
2615e5c31af7Sopenharmony_ci	}
2616e5c31af7Sopenharmony_ci
2617e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2618e5c31af7Sopenharmony_ci	{
2619e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays feature.\n";
2620e5c31af7Sopenharmony_ci	}
2621e5c31af7Sopenharmony_ci
2622e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
2623e5c31af7Sopenharmony_ci	{
2624e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
2625e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
2626e5c31af7Sopenharmony_ci			   "uniform mediump vec4 a[3][4][5];             \n"
2627e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
2628e5c31af7Sopenharmony_ci			   "{                                                 \n"
2629e5c31af7Sopenharmony_ci			   "    int i = int(position.x);                      \n"
2630e5c31af7Sopenharmony_ci			   "    if (i < 5)                                    \n"
2631e5c31af7Sopenharmony_ci			   "        gl_Position = position + a[2][1][i];      \n"
2632e5c31af7Sopenharmony_ci			   "    else                                          \n"
2633e5c31af7Sopenharmony_ci			   "        gl_Position = position + a[2][1][0];      \n"
2634e5c31af7Sopenharmony_ci			   "}";
2635e5c31af7Sopenharmony_ci	}
2636e5c31af7Sopenharmony_ci
2637e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
2638e5c31af7Sopenharmony_ci	{
2639e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
2640e5c31af7Sopenharmony_ci			   "out mediump vec4 color;                \n"
2641e5c31af7Sopenharmony_ci			   "void main() {                  \n"
2642e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1);  \n"
2643e5c31af7Sopenharmony_ci			   "}";
2644e5c31af7Sopenharmony_ci	}
2645e5c31af7Sopenharmony_ci
2646e5c31af7Sopenharmony_ci	virtual long Run()
2647e5c31af7Sopenharmony_ci	{
2648e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2649e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2650e5c31af7Sopenharmony_ci		LinkProgram(program);
2651e5c31af7Sopenharmony_ci
2652e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2653e5c31af7Sopenharmony_ci
2654e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
2655e5c31af7Sopenharmony_ci
2656e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
2657e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
2658e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
2659e5c31af7Sopenharmony_ci
2660e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
2661e5c31af7Sopenharmony_ci
2662e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
2663e5c31af7Sopenharmony_ci						   GL_TYPE,
2664e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
2665e5c31af7Sopenharmony_ci						   GL_OFFSET,
2666e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
2667e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
2668e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
2669e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
2670e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
2671e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
2672e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
2673e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
2674e5c31af7Sopenharmony_ci						   GL_LOCATION };
2675e5c31af7Sopenharmony_ci		GLint expected[] = { 11, 35666, 5, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(program, "a[2][1]") };
2676e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 13, props, 13, expected, error);
2677e5c31af7Sopenharmony_ci
2678e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2679e5c31af7Sopenharmony_ci		return error;
2680e5c31af7Sopenharmony_ci	}
2681e5c31af7Sopenharmony_ci};
2682e5c31af7Sopenharmony_ci
2683e5c31af7Sopenharmony_ciclass TopLevelArray : public ComputeShaderTest
2684e5c31af7Sopenharmony_ci{
2685e5c31af7Sopenharmony_ci
2686e5c31af7Sopenharmony_ci	virtual std::string Title()
2687e5c31af7Sopenharmony_ci	{
2688e5c31af7Sopenharmony_ci		return "Top Level Array Test";
2689e5c31af7Sopenharmony_ci	}
2690e5c31af7Sopenharmony_ci
2691e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
2692e5c31af7Sopenharmony_ci	{
2693e5c31af7Sopenharmony_ci		return "compute shader with multi dimensional array used inside storage block";
2694e5c31af7Sopenharmony_ci	}
2695e5c31af7Sopenharmony_ci
2696e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2697e5c31af7Sopenharmony_ci	{
2698e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
2699e5c31af7Sopenharmony_ci			   " and GL_TOP_LEVEL_ARRAY_STRIDE.\n";
2700e5c31af7Sopenharmony_ci	}
2701e5c31af7Sopenharmony_ci
2702e5c31af7Sopenharmony_ci	virtual std::string ComputeShader()
2703e5c31af7Sopenharmony_ci	{
2704e5c31af7Sopenharmony_ci		return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2705e5c31af7Sopenharmony_ci			   "layout(std430) buffer Outp {                   \n"
2706e5c31af7Sopenharmony_ci			   "   mediump vec4 d;                             \n"
2707e5c31af7Sopenharmony_ci			   "} g_out;                                       \n"
2708e5c31af7Sopenharmony_ci			   ""
2709e5c31af7Sopenharmony_ci			   "buffer Block {                       \n"
2710e5c31af7Sopenharmony_ci			   "   mediump vec4 a[5][4][3];          \n"
2711e5c31af7Sopenharmony_ci			   "};                                   \n"
2712e5c31af7Sopenharmony_ci			   ""
2713e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
2714e5c31af7Sopenharmony_ci			   "{                                    \n"
2715e5c31af7Sopenharmony_ci			   "    g_out.d = a[0][0][0];            \n"
2716e5c31af7Sopenharmony_ci			   "}";
2717e5c31af7Sopenharmony_ci	}
2718e5c31af7Sopenharmony_ci
2719e5c31af7Sopenharmony_ci	virtual long Run()
2720e5c31af7Sopenharmony_ci	{
2721e5c31af7Sopenharmony_ci		GLuint program = CreateComputeProgram(ComputeShader());
2722e5c31af7Sopenharmony_ci		glLinkProgram(program);
2723e5c31af7Sopenharmony_ci		if (!CheckProgram(program))
2724e5c31af7Sopenharmony_ci		{
2725e5c31af7Sopenharmony_ci			glDeleteProgram(program);
2726e5c31af7Sopenharmony_ci			return ERROR;
2727e5c31af7Sopenharmony_ci		}
2728e5c31af7Sopenharmony_ci		glUseProgram(program);
2729e5c31af7Sopenharmony_ci
2730e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2731e5c31af7Sopenharmony_ci
2732e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
2733e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
2734e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 2, error);
2735e5c31af7Sopenharmony_ci
2736e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesSSB;
2737e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesBV;
2738e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
2739e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
2740e5c31af7Sopenharmony_ci
2741e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
2742e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
2743e5c31af7Sopenharmony_ci
2744e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
2745e5c31af7Sopenharmony_ci							GL_TYPE,
2746e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
2747e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
2748e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
2749e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
2750e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
2751e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
2752e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_SIZE };
2753e5c31af7Sopenharmony_ci		GLint expected5[] = { 11, 35666, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 1, 0, 0, 5 };
2754e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 9, props3, 9, expected5, error);
2755e5c31af7Sopenharmony_ci
2756e5c31af7Sopenharmony_ci		GLenum  prop = GL_TOP_LEVEL_ARRAY_STRIDE;
2757e5c31af7Sopenharmony_ci		GLsizei len;
2758e5c31af7Sopenharmony_ci		GLint   res;
2759e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
2760e5c31af7Sopenharmony_ci		if (res <= 0)
2761e5c31af7Sopenharmony_ci		{
2762e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
2763e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
2764e5c31af7Sopenharmony_ci				<< "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
2765e5c31af7Sopenharmony_ci				<< "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
2766e5c31af7Sopenharmony_ci			glDeleteProgram(program);
2767e5c31af7Sopenharmony_ci			return ERROR;
2768e5c31af7Sopenharmony_ci		}
2769e5c31af7Sopenharmony_ci
2770e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2771e5c31af7Sopenharmony_ci		return error;
2772e5c31af7Sopenharmony_ci	}
2773e5c31af7Sopenharmony_ci};
2774e5c31af7Sopenharmony_ci
2775e5c31af7Sopenharmony_ciclass SeparateProgramsVertex : public SimpleShaders
2776e5c31af7Sopenharmony_ci{
2777e5c31af7Sopenharmony_cipublic:
2778e5c31af7Sopenharmony_ci	virtual std::string Title()
2779e5c31af7Sopenharmony_ci	{
2780e5c31af7Sopenharmony_ci		return "Separate Program Vertex Shader Test";
2781e5c31af7Sopenharmony_ci	}
2782e5c31af7Sopenharmony_ci
2783e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
2784e5c31af7Sopenharmony_ci	{
2785e5c31af7Sopenharmony_ci		return "vertex shader as separate shader object";
2786e5c31af7Sopenharmony_ci	}
2787e5c31af7Sopenharmony_ci
2788e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2789e5c31af7Sopenharmony_ci	{
2790e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
2791e5c31af7Sopenharmony_ci			   "functionality.\n";
2792e5c31af7Sopenharmony_ci	}
2793e5c31af7Sopenharmony_ci
2794e5c31af7Sopenharmony_ci	virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings)
2795e5c31af7Sopenharmony_ci	{
2796e5c31af7Sopenharmony_ci		GLuint program = glCreateShaderProgramv(type, count, strings);
2797e5c31af7Sopenharmony_ci		GLint  status  = GL_TRUE;
2798e5c31af7Sopenharmony_ci		glGetProgramiv(program, GL_LINK_STATUS, &status);
2799e5c31af7Sopenharmony_ci		if (status == GL_FALSE)
2800e5c31af7Sopenharmony_ci		{
2801e5c31af7Sopenharmony_ci			GLsizei length;
2802e5c31af7Sopenharmony_ci			GLchar  log[1024];
2803e5c31af7Sopenharmony_ci			glGetProgramInfoLog(program, sizeof(log), &length, log);
2804e5c31af7Sopenharmony_ci			if (length > 1)
2805e5c31af7Sopenharmony_ci			{
2806e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
2807e5c31af7Sopenharmony_ci													<< log << tcu::TestLog::EndMessage;
2808e5c31af7Sopenharmony_ci			}
2809e5c31af7Sopenharmony_ci		}
2810e5c31af7Sopenharmony_ci		return program;
2811e5c31af7Sopenharmony_ci	}
2812e5c31af7Sopenharmony_ci
2813e5c31af7Sopenharmony_ci	virtual long Run()
2814e5c31af7Sopenharmony_ci	{
2815e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2816e5c31af7Sopenharmony_ci
2817e5c31af7Sopenharmony_ci		const char* srcVS = "#version 310 es                            \n"
2818e5c31af7Sopenharmony_ci							"layout(location = 0) in vec4 in_vertex;    \n"
2819e5c31af7Sopenharmony_ci							""
2820e5c31af7Sopenharmony_ci							"out mediump float r, g, b;                           \n"
2821e5c31af7Sopenharmony_ci							"out mediump vec4 iLikePie;                           \n"
2822e5c31af7Sopenharmony_ci							""
2823e5c31af7Sopenharmony_ci							"uniform mediump float u;                           \n"
2824e5c31af7Sopenharmony_ci							"uniform mediump vec4 v;                            \n"
2825e5c31af7Sopenharmony_ci							""
2826e5c31af7Sopenharmony_ci							"void main() {                     \n"
2827e5c31af7Sopenharmony_ci							"  gl_Position = in_vertex;        \n"
2828e5c31af7Sopenharmony_ci							"  r = u;                          \n"
2829e5c31af7Sopenharmony_ci							"  g = 0.0;                        \n"
2830e5c31af7Sopenharmony_ci							"  b = 0.0;                        \n"
2831e5c31af7Sopenharmony_ci							"  iLikePie = v;                   \n"
2832e5c31af7Sopenharmony_ci							"}";
2833e5c31af7Sopenharmony_ci
2834e5c31af7Sopenharmony_ci		const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
2835e5c31af7Sopenharmony_ci
2836e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2837e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
2838e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
2839e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2840e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 12, error);
2841e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
2842e5c31af7Sopenharmony_ci
2843e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
2844e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesI;
2845e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesO;
2846e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
2847e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
2848e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
2849e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "r", error);
2850e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "g", error);
2851e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "b", error);
2852e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "iLikePie", error);
2853e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
2854e5c31af7Sopenharmony_ci
2855e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
2856e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
2857e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
2858e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["r"], "r", error);
2859e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["g"], "g", error);
2860e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
2861e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], "iLikePie", error);
2862e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
2863e5c31af7Sopenharmony_ci
2864e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
2865e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
2866e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
2867e5c31af7Sopenharmony_ci
2868e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
2869e5c31af7Sopenharmony_ci						   GL_TYPE,
2870e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
2871e5c31af7Sopenharmony_ci						   GL_OFFSET,
2872e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
2873e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
2874e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
2875e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
2876e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
2877e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
2878e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
2879e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
2880e5c31af7Sopenharmony_ci						   GL_LOCATION };
2881e5c31af7Sopenharmony_ci		GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 0, 1, glGetUniformLocation(vs, "v") };
2882e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 13, props, 13, expected, error);
2883e5c31af7Sopenharmony_ci
2884e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
2885e5c31af7Sopenharmony_ci							GL_TYPE,
2886e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
2887e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
2888e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
2889e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
2890e5c31af7Sopenharmony_ci							GL_LOCATION };
2891e5c31af7Sopenharmony_ci		GLint expected2[] = { 10, 35666, 1, 0, 0, 1, 0 };
2892e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 7, props2, 7, expected2, error);
2893e5c31af7Sopenharmony_ci
2894e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
2895e5c31af7Sopenharmony_ci							GL_TYPE,
2896e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
2897e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
2898e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
2899e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER };
2900e5c31af7Sopenharmony_ci		GLint expected3[] = { 9, 35666, 1, 0, 0, 1 };
2901e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["iLikePie"], 6, props3, 6, expected3, error);
2902e5c31af7Sopenharmony_ci
2903e5c31af7Sopenharmony_ci		glDeleteProgram(vs);
2904e5c31af7Sopenharmony_ci		return error;
2905e5c31af7Sopenharmony_ci	}
2906e5c31af7Sopenharmony_ci};
2907e5c31af7Sopenharmony_ci
2908e5c31af7Sopenharmony_ciclass SeparateProgramsFragment : public SeparateProgramsVertex
2909e5c31af7Sopenharmony_ci{
2910e5c31af7Sopenharmony_ci
2911e5c31af7Sopenharmony_ci	virtual std::string Title()
2912e5c31af7Sopenharmony_ci	{
2913e5c31af7Sopenharmony_ci		return "Separate Program Fragment Shader Test";
2914e5c31af7Sopenharmony_ci	}
2915e5c31af7Sopenharmony_ci
2916e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
2917e5c31af7Sopenharmony_ci	{
2918e5c31af7Sopenharmony_ci		return "fragment shader as separate shader object";
2919e5c31af7Sopenharmony_ci	}
2920e5c31af7Sopenharmony_ci
2921e5c31af7Sopenharmony_ci	virtual long Run()
2922e5c31af7Sopenharmony_ci	{
2923e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2924e5c31af7Sopenharmony_ci
2925e5c31af7Sopenharmony_ci		const char* srcTCS = "#version 310 es                                  \n"
2926e5c31af7Sopenharmony_ci							 "out mediump vec4 fs_color;                       \n"
2927e5c31af7Sopenharmony_ci							 ""
2928e5c31af7Sopenharmony_ci							 "layout(location = 1) uniform mediump vec4 x;     \n"
2929e5c31af7Sopenharmony_ci							 ""
2930e5c31af7Sopenharmony_ci							 "in mediump vec4 vs_color;                        \n"
2931e5c31af7Sopenharmony_ci							 "void main() {                                    \n"
2932e5c31af7Sopenharmony_ci							 "   fs_color = vs_color + x;                      \n"
2933e5c31af7Sopenharmony_ci							 "}";
2934e5c31af7Sopenharmony_ci
2935e5c31af7Sopenharmony_ci		const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
2936e5c31af7Sopenharmony_ci
2937e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
2938e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
2939e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
2940e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
2941e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2942e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2943e5c31af7Sopenharmony_ci
2944e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesI;
2945e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesO;
2946e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
2947e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
2948e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
2949e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
2950e5c31af7Sopenharmony_ci
2951e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
2952e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
2953e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
2954e5c31af7Sopenharmony_ci
2955e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
2956e5c31af7Sopenharmony_ci
2957e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
2958e5c31af7Sopenharmony_ci							GL_TYPE,
2959e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
2960e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
2961e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
2962e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER };
2963e5c31af7Sopenharmony_ci		GLint expected2[] = { 9, 35666, 1, 0, 1, 0 };
2964e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 6, props2, 6, expected2, error);
2965e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 6, props2, 6, expected2, error);
2966e5c31af7Sopenharmony_ci
2967e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
2968e5c31af7Sopenharmony_ci						   GL_TYPE,
2969e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
2970e5c31af7Sopenharmony_ci						   GL_OFFSET,
2971e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
2972e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
2973e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
2974e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
2975e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
2976e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
2977e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
2978e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
2979e5c31af7Sopenharmony_ci						   GL_LOCATION };
2980e5c31af7Sopenharmony_ci		GLint expected[] = { 2, 35666, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1 };
2981e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props, 13, expected, error);
2982e5c31af7Sopenharmony_ci
2983e5c31af7Sopenharmony_ci		glDeleteProgram(tcs);
2984e5c31af7Sopenharmony_ci		return error;
2985e5c31af7Sopenharmony_ci	}
2986e5c31af7Sopenharmony_ci};
2987e5c31af7Sopenharmony_ci
2988e5c31af7Sopenharmony_ciclass UniformBlockAdvanced : public SimpleShaders
2989e5c31af7Sopenharmony_ci{
2990e5c31af7Sopenharmony_ci	virtual std::string Title()
2991e5c31af7Sopenharmony_ci	{
2992e5c31af7Sopenharmony_ci		return "Uniform Block Advanced Test";
2993e5c31af7Sopenharmony_ci	}
2994e5c31af7Sopenharmony_ci
2995e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
2996e5c31af7Sopenharmony_ci	{
2997e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
2998e5c31af7Sopenharmony_ci	}
2999e5c31af7Sopenharmony_ci
3000e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3001e5c31af7Sopenharmony_ci	{
3002e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
3003e5c31af7Sopenharmony_ci			   "verify results of querying offset, strides and row order.\n";
3004e5c31af7Sopenharmony_ci	}
3005e5c31af7Sopenharmony_ci
3006e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
3007e5c31af7Sopenharmony_ci	{
3008e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
3009e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
3010e5c31af7Sopenharmony_ci			   ""
3011e5c31af7Sopenharmony_ci			   "layout(row_major) uniform SimpleBlock {   \n"
3012e5c31af7Sopenharmony_ci			   "   mat4 a;                                \n"
3013e5c31af7Sopenharmony_ci			   "   vec4 b[10];                            \n"
3014e5c31af7Sopenharmony_ci			   "};                                        \n"
3015e5c31af7Sopenharmony_ci			   ""
3016e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
3017e5c31af7Sopenharmony_ci			   "{                                    \n"
3018e5c31af7Sopenharmony_ci			   "    float tmp;                       \n"
3019e5c31af7Sopenharmony_ci			   "    tmp = a[0][0] + b[0].x;          \n"
3020e5c31af7Sopenharmony_ci			   "    gl_Position = position * tmp;    \n"
3021e5c31af7Sopenharmony_ci			   "}";
3022e5c31af7Sopenharmony_ci	}
3023e5c31af7Sopenharmony_ci
3024e5c31af7Sopenharmony_ci	virtual long Run()
3025e5c31af7Sopenharmony_ci	{
3026e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3027e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3028e5c31af7Sopenharmony_ci		LinkProgram(program);
3029e5c31af7Sopenharmony_ci
3030e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3031e5c31af7Sopenharmony_ci
3032e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
3033e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
3034e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
3035e5c31af7Sopenharmony_ci
3036e5c31af7Sopenharmony_ci		GLenum props[]	= { GL_IS_ROW_MAJOR };
3037e5c31af7Sopenharmony_ci		GLint  expected[] = { 1 };
3038e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
3039e5c31af7Sopenharmony_ci
3040e5c31af7Sopenharmony_ci		GLenum  prop = GL_MATRIX_STRIDE;
3041e5c31af7Sopenharmony_ci		GLsizei len;
3042e5c31af7Sopenharmony_ci		GLint   res;
3043e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
3044e5c31af7Sopenharmony_ci		if (res < 1)
3045e5c31af7Sopenharmony_ci		{
3046e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3047e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
3048e5c31af7Sopenharmony_ci				<< "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
3049e5c31af7Sopenharmony_ci				<< "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
3050e5c31af7Sopenharmony_ci		}
3051e5c31af7Sopenharmony_ci		prop = GL_OFFSET;
3052e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
3053e5c31af7Sopenharmony_ci		if (res < 0)
3054e5c31af7Sopenharmony_ci		{
3055e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3056e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
3057e5c31af7Sopenharmony_ci				<< "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
3058e5c31af7Sopenharmony_ci		}
3059e5c31af7Sopenharmony_ci		prop = GL_ARRAY_STRIDE;
3060e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
3061e5c31af7Sopenharmony_ci		if (res < 1)
3062e5c31af7Sopenharmony_ci		{
3063e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3064e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
3065e5c31af7Sopenharmony_ci				<< "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
3066e5c31af7Sopenharmony_ci				<< "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
3067e5c31af7Sopenharmony_ci		}
3068e5c31af7Sopenharmony_ci
3069e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3070e5c31af7Sopenharmony_ci		return error;
3071e5c31af7Sopenharmony_ci	}
3072e5c31af7Sopenharmony_ci};
3073e5c31af7Sopenharmony_ci
3074e5c31af7Sopenharmony_ciclass ArrayNames : public SimpleShaders
3075e5c31af7Sopenharmony_ci{
3076e5c31af7Sopenharmony_ci
3077e5c31af7Sopenharmony_ci	virtual std::string Title()
3078e5c31af7Sopenharmony_ci	{
3079e5c31af7Sopenharmony_ci		return "Array Names Test";
3080e5c31af7Sopenharmony_ci	}
3081e5c31af7Sopenharmony_ci
3082e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3083e5c31af7Sopenharmony_ci	{
3084e5c31af7Sopenharmony_ci		return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
3085e5c31af7Sopenharmony_ci	}
3086e5c31af7Sopenharmony_ci
3087e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3088e5c31af7Sopenharmony_ci	{
3089e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that GetProgramResourceLocation match "
3090e5c31af7Sopenharmony_ci			   "name strings correctly.\n";
3091e5c31af7Sopenharmony_ci	}
3092e5c31af7Sopenharmony_ci
3093e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
3094e5c31af7Sopenharmony_ci	{
3095e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
3096e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
3097e5c31af7Sopenharmony_ci			   ""
3098e5c31af7Sopenharmony_ci			   "uniform mediump vec4 a[2];           \n"
3099e5c31af7Sopenharmony_ci			   ""
3100e5c31af7Sopenharmony_ci			   "void main(void)                            \n"
3101e5c31af7Sopenharmony_ci			   "{                                          \n"
3102e5c31af7Sopenharmony_ci			   "    gl_Position = position + a[0] + a[1];  \n"
3103e5c31af7Sopenharmony_ci			   "}";
3104e5c31af7Sopenharmony_ci	}
3105e5c31af7Sopenharmony_ci
3106e5c31af7Sopenharmony_ci	virtual long Run()
3107e5c31af7Sopenharmony_ci	{
3108e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3109e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3110e5c31af7Sopenharmony_ci		LinkProgram(program);
3111e5c31af7Sopenharmony_ci
3112e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3113e5c31af7Sopenharmony_ci
3114e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
3115e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
3116e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
3117e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
3118e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
3119e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
3120e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
3121e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
3122e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
3123e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
3124e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
3125e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
3126e5c31af7Sopenharmony_ci
3127e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3128e5c31af7Sopenharmony_ci		return error;
3129e5c31af7Sopenharmony_ci	}
3130e5c31af7Sopenharmony_ci};
3131e5c31af7Sopenharmony_ci
3132e5c31af7Sopenharmony_ciclass BuffLength : public SimpleShaders
3133e5c31af7Sopenharmony_ci{
3134e5c31af7Sopenharmony_ci
3135e5c31af7Sopenharmony_ci	virtual std::string Title()
3136e5c31af7Sopenharmony_ci	{
3137e5c31af7Sopenharmony_ci		return "Buff Length Test";
3138e5c31af7Sopenharmony_ci	}
3139e5c31af7Sopenharmony_ci
3140e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3141e5c31af7Sopenharmony_ci	{
3142e5c31af7Sopenharmony_ci		return "fallthrough fragment shader and vertex with uniform of vec4 type used";
3143e5c31af7Sopenharmony_ci	}
3144e5c31af7Sopenharmony_ci
3145e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3146e5c31af7Sopenharmony_ci	{
3147e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
3148e5c31af7Sopenharmony_ci			   "GetProgramResourceiv is respected.\n";
3149e5c31af7Sopenharmony_ci	}
3150e5c31af7Sopenharmony_ci
3151e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
3152e5c31af7Sopenharmony_ci	{
3153e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
3154e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
3155e5c31af7Sopenharmony_ci			   ""
3156e5c31af7Sopenharmony_ci			   "uniform mediump vec4 someLongName;         \n"
3157e5c31af7Sopenharmony_ci			   ""
3158e5c31af7Sopenharmony_ci			   "void main(void)                            \n"
3159e5c31af7Sopenharmony_ci			   "{                                          \n"
3160e5c31af7Sopenharmony_ci			   "    gl_Position = position + someLongName; \n"
3161e5c31af7Sopenharmony_ci			   "}";
3162e5c31af7Sopenharmony_ci	}
3163e5c31af7Sopenharmony_ci
3164e5c31af7Sopenharmony_ci	virtual long Run()
3165e5c31af7Sopenharmony_ci	{
3166e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3167e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3168e5c31af7Sopenharmony_ci		LinkProgram(program);
3169e5c31af7Sopenharmony_ci
3170e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3171e5c31af7Sopenharmony_ci
3172e5c31af7Sopenharmony_ci		GLuint  index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
3173e5c31af7Sopenharmony_ci		GLsizei length;
3174e5c31af7Sopenharmony_ci		GLchar  buff[3] = { 'a', 'b', 'c' };
3175e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
3176e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
3177e5c31af7Sopenharmony_ci		if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
3178e5c31af7Sopenharmony_ci		{
3179e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3180e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
3181e5c31af7Sopenharmony_ci			error = ERROR;
3182e5c31af7Sopenharmony_ci		}
3183e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
3184e5c31af7Sopenharmony_ci		if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
3185e5c31af7Sopenharmony_ci		{
3186e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3187e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
3188e5c31af7Sopenharmony_ci			error = ERROR;
3189e5c31af7Sopenharmony_ci		}
3190e5c31af7Sopenharmony_ci		if (length != 1)
3191e5c31af7Sopenharmony_ci		{
3192e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
3193e5c31af7Sopenharmony_ci												<< length << tcu::TestLog::EndMessage;
3194e5c31af7Sopenharmony_ci			error = ERROR;
3195e5c31af7Sopenharmony_ci		}
3196e5c31af7Sopenharmony_ci
3197e5c31af7Sopenharmony_ci		GLint  params[3] = { 1, 2, 3 };
3198e5c31af7Sopenharmony_ci		GLenum props[]   = { GL_NAME_LENGTH,
3199e5c31af7Sopenharmony_ci						   GL_TYPE,
3200e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
3201e5c31af7Sopenharmony_ci						   GL_OFFSET,
3202e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
3203e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
3204e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
3205e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
3206e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
3207e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
3208e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3209e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
3210e5c31af7Sopenharmony_ci						   GL_LOCATION };
3211e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
3212e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
3213e5c31af7Sopenharmony_ci		if (params[0] != 1 || params[1] != 2 || params[2] != 3)
3214e5c31af7Sopenharmony_ci		{
3215e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3216e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
3217e5c31af7Sopenharmony_ci			error = ERROR;
3218e5c31af7Sopenharmony_ci		}
3219e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
3220e5c31af7Sopenharmony_ci		if (params[0] != 13 || params[1] != 35666 || params[2] != 3)
3221e5c31af7Sopenharmony_ci		{
3222e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3223e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
3224e5c31af7Sopenharmony_ci			error = ERROR;
3225e5c31af7Sopenharmony_ci		}
3226e5c31af7Sopenharmony_ci		if (length != 2)
3227e5c31af7Sopenharmony_ci		{
3228e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
3229e5c31af7Sopenharmony_ci												<< length << tcu::TestLog::EndMessage;
3230e5c31af7Sopenharmony_ci			error = ERROR;
3231e5c31af7Sopenharmony_ci		}
3232e5c31af7Sopenharmony_ci
3233e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3234e5c31af7Sopenharmony_ci		return error;
3235e5c31af7Sopenharmony_ci	}
3236e5c31af7Sopenharmony_ci};
3237e5c31af7Sopenharmony_ci
3238e5c31af7Sopenharmony_ciclass NoLocations : public SimpleShaders
3239e5c31af7Sopenharmony_ci{
3240e5c31af7Sopenharmony_ci
3241e5c31af7Sopenharmony_ci	virtual std::string Title()
3242e5c31af7Sopenharmony_ci	{
3243e5c31af7Sopenharmony_ci		return "No Locations Test";
3244e5c31af7Sopenharmony_ci	}
3245e5c31af7Sopenharmony_ci
3246e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3247e5c31af7Sopenharmony_ci	{
3248e5c31af7Sopenharmony_ci		return "fragment and vertex shaders with no locations set";
3249e5c31af7Sopenharmony_ci	}
3250e5c31af7Sopenharmony_ci
3251e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
3252e5c31af7Sopenharmony_ci	{
3253e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
3254e5c31af7Sopenharmony_ci			   "in vec4 a;                           \n"
3255e5c31af7Sopenharmony_ci			   "in vec4 b;                           \n"
3256e5c31af7Sopenharmony_ci			   "in vec4 c;                           \n"
3257e5c31af7Sopenharmony_ci			   "in vec4 d;                           \n"
3258e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
3259e5c31af7Sopenharmony_ci			   "{                                    \n"
3260e5c31af7Sopenharmony_ci			   "    gl_Position = a + b + c + d;     \n"
3261e5c31af7Sopenharmony_ci			   "}";
3262e5c31af7Sopenharmony_ci	}
3263e5c31af7Sopenharmony_ci
3264e5c31af7Sopenharmony_ci	// fragment shader outputs need an explicit location per spec
3265e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
3266e5c31af7Sopenharmony_ci	{
3267e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
3268e5c31af7Sopenharmony_ci			   "layout (location=0) out mediump vec4 a;            \n"
3269e5c31af7Sopenharmony_ci			   "layout (location=1) out mediump vec4 b;            \n"
3270e5c31af7Sopenharmony_ci			   "layout (location=2) out mediump vec4 c;            \n"
3271e5c31af7Sopenharmony_ci			   "layout (location=3) out mediump vec4 d[1];         \n"
3272e5c31af7Sopenharmony_ci			   "void main() {                  \n"
3273e5c31af7Sopenharmony_ci			   "    a = vec4(0, 1, 0, 1);      \n"
3274e5c31af7Sopenharmony_ci			   "    b = vec4(0, 1, 0, 1);      \n"
3275e5c31af7Sopenharmony_ci			   "    c = vec4(0, 1, 0, 1);      \n"
3276e5c31af7Sopenharmony_ci			   "    d[0] = vec4(0, 1, 0, 1);   \n"
3277e5c31af7Sopenharmony_ci			   "}";
3278e5c31af7Sopenharmony_ci	}
3279e5c31af7Sopenharmony_ci
3280e5c31af7Sopenharmony_ci	virtual long Run()
3281e5c31af7Sopenharmony_ci	{
3282e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3283e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3284e5c31af7Sopenharmony_ci		glLinkProgram(program);
3285e5c31af7Sopenharmony_ci
3286e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3287e5c31af7Sopenharmony_ci
3288e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
3289e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 2, error);
3290e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
3291e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
3292e5c31af7Sopenharmony_ci
3293e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesI;
3294e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesO;
3295e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
3296e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
3297e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
3298e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
3299e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
3300e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
3301e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
3302e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
3303e5c31af7Sopenharmony_ci
3304e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
3305e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
3306e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c", error);
3307e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
3308e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
3309e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
3310e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
3311e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
3312e5c31af7Sopenharmony_ci
3313e5c31af7Sopenharmony_ci		std::map<std::string, GLint> locationsI;
3314e5c31af7Sopenharmony_ci		std::map<std::string, GLint> locationsO;
3315e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
3316e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
3317e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
3318e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
3319e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
3320e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
3321e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
3322e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
3323e5c31af7Sopenharmony_ci
3324e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
3325e5c31af7Sopenharmony_ci						   GL_TYPE,
3326e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
3327e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
3328e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3329e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER };
3330e5c31af7Sopenharmony_ci		GLint expected[] = { 2, 35666, 1, 0, 0, 1 };
3331e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
3332e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
3333e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
3334e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected, error);
3335e5c31af7Sopenharmony_ci		GLint expected3[] = { 2, 35666, 1, 0, 1, 0 };
3336e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
3337e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
3338e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
3339e5c31af7Sopenharmony_ci		GLint expected4[] = { 5, 35666, 1, 0, 1, 0 };
3340e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
3341e5c31af7Sopenharmony_ci
3342e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3343e5c31af7Sopenharmony_ci		return error;
3344e5c31af7Sopenharmony_ci	}
3345e5c31af7Sopenharmony_ci};
3346e5c31af7Sopenharmony_ci
3347e5c31af7Sopenharmony_ciclass OutputBuiltIn : public SimpleShaders
3348e5c31af7Sopenharmony_ci{
3349e5c31af7Sopenharmony_ci
3350e5c31af7Sopenharmony_ci	virtual std::string Title()
3351e5c31af7Sopenharmony_ci	{
3352e5c31af7Sopenharmony_ci		return "Output Built-ins Test";
3353e5c31af7Sopenharmony_ci	}
3354e5c31af7Sopenharmony_ci
3355e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3356e5c31af7Sopenharmony_ci	{
3357e5c31af7Sopenharmony_ci		return "fragment shader using built-in variables and a fallthrough vertex shader";
3358e5c31af7Sopenharmony_ci	}
3359e5c31af7Sopenharmony_ci
3360e5c31af7Sopenharmony_ci	virtual std::string Expectations()
3361e5c31af7Sopenharmony_ci	{
3362e5c31af7Sopenharmony_ci		return ".\n\n In this case we ask for information about built-in variables for the output interface.";
3363e5c31af7Sopenharmony_ci	}
3364e5c31af7Sopenharmony_ci
3365e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
3366e5c31af7Sopenharmony_ci	{
3367e5c31af7Sopenharmony_ci		return "#version 310 es                            \n"
3368e5c31af7Sopenharmony_ci			   "void main(void)                            \n"
3369e5c31af7Sopenharmony_ci			   "{                                          \n"
3370e5c31af7Sopenharmony_ci			   "    gl_FragDepth = 0.1;                    \n"
3371e5c31af7Sopenharmony_ci			   "}";
3372e5c31af7Sopenharmony_ci	}
3373e5c31af7Sopenharmony_ci
3374e5c31af7Sopenharmony_ci	virtual long Run()
3375e5c31af7Sopenharmony_ci	{
3376e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true);
3377e5c31af7Sopenharmony_ci
3378e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3379e5c31af7Sopenharmony_ci
3380e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3381e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 13, error);
3382e5c31af7Sopenharmony_ci
3383e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
3384e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error);
3385e5c31af7Sopenharmony_ci
3386e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error);
3387e5c31af7Sopenharmony_ci
3388e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
3389e5c31af7Sopenharmony_ci
3390e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
3391e5c31af7Sopenharmony_ci						   GL_TYPE,
3392e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
3393e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
3394e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3395e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
3396e5c31af7Sopenharmony_ci						   GL_LOCATION };
3397e5c31af7Sopenharmony_ci		GLint expected[] = { 13, 5126, 1, 0, 1, 0, -1 };
3398e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], DE_LENGTH_OF_ARRAY(props),
3399e5c31af7Sopenharmony_ci								   props, DE_LENGTH_OF_ARRAY(expected), expected, error);
3400e5c31af7Sopenharmony_ci
3401e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3402e5c31af7Sopenharmony_ci		return error;
3403e5c31af7Sopenharmony_ci	}
3404e5c31af7Sopenharmony_ci};
3405e5c31af7Sopenharmony_ci
3406e5c31af7Sopenharmony_ciclass QueryNotUsed : public SimpleShaders
3407e5c31af7Sopenharmony_ci{
3408e5c31af7Sopenharmony_ci
3409e5c31af7Sopenharmony_ci	virtual std::string Title()
3410e5c31af7Sopenharmony_ci	{
3411e5c31af7Sopenharmony_ci		return "Query Not Used Test";
3412e5c31af7Sopenharmony_ci	}
3413e5c31af7Sopenharmony_ci
3414e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
3415e5c31af7Sopenharmony_ci	{
3416e5c31af7Sopenharmony_ci		return "Data from queries matches the not used program.";
3417e5c31af7Sopenharmony_ci	}
3418e5c31af7Sopenharmony_ci
3419e5c31af7Sopenharmony_ci	virtual std::string Purpose()
3420e5c31af7Sopenharmony_ci	{
3421e5c31af7Sopenharmony_ci		return "Verify that program parameter works correctly and proper program is queried when different program is "
3422e5c31af7Sopenharmony_ci			   "used.";
3423e5c31af7Sopenharmony_ci	}
3424e5c31af7Sopenharmony_ci
3425e5c31af7Sopenharmony_ci	virtual std::string Method()
3426e5c31af7Sopenharmony_ci	{
3427e5c31af7Sopenharmony_ci		return "Create 2 programs, use one of them and query the other, verify the results.";
3428e5c31af7Sopenharmony_ci	}
3429e5c31af7Sopenharmony_ci
3430e5c31af7Sopenharmony_ci	virtual std::string VertexShader2()
3431e5c31af7Sopenharmony_ci	{
3432e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
3433e5c31af7Sopenharmony_ci			   "in mediump vec4 p;                   \n"
3434e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
3435e5c31af7Sopenharmony_ci			   "{                                    \n"
3436e5c31af7Sopenharmony_ci			   "    gl_Position = p;                 \n"
3437e5c31af7Sopenharmony_ci			   "}";
3438e5c31af7Sopenharmony_ci	}
3439e5c31af7Sopenharmony_ci
3440e5c31af7Sopenharmony_ci	virtual std::string FragmentShader2()
3441e5c31af7Sopenharmony_ci	{
3442e5c31af7Sopenharmony_ci		return "#version 310 es                \n"
3443e5c31af7Sopenharmony_ci			   "out mediump vec4 c;            \n"
3444e5c31af7Sopenharmony_ci			   "void main() {                  \n"
3445e5c31af7Sopenharmony_ci			   "    c = vec4(0., 1., 0., 1.);  \n"
3446e5c31af7Sopenharmony_ci			   "}";
3447e5c31af7Sopenharmony_ci	}
3448e5c31af7Sopenharmony_ci
3449e5c31af7Sopenharmony_ci	virtual long Run()
3450e5c31af7Sopenharmony_ci	{
3451e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3452e5c31af7Sopenharmony_ci		LinkProgram(program);
3453e5c31af7Sopenharmony_ci
3454e5c31af7Sopenharmony_ci		GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
3455e5c31af7Sopenharmony_ci		LinkProgram(program2);
3456e5c31af7Sopenharmony_ci		glUseProgram(program2);
3457e5c31af7Sopenharmony_ci
3458e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3459e5c31af7Sopenharmony_ci
3460e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
3461e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
3462e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
3463e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
3464e5c31af7Sopenharmony_ci
3465e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3466e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
3467e5c31af7Sopenharmony_ci
3468e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
3469e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
3470e5c31af7Sopenharmony_ci
3471e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
3472e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
3473e5c31af7Sopenharmony_ci
3474e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
3475e5c31af7Sopenharmony_ci						   GL_TYPE,
3476e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
3477e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
3478e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3479e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
3480e5c31af7Sopenharmony_ci						   GL_LOCATION };
3481e5c31af7Sopenharmony_ci		GLint expected[] = { 9, 35666, 1, 0, 0, 1, 0 };
3482e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, DE_LENGTH_OF_ARRAY(props), props,
3483e5c31af7Sopenharmony_ci								   DE_LENGTH_OF_ARRAY(expected), expected, error);
3484e5c31af7Sopenharmony_ci
3485e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
3486e5c31af7Sopenharmony_ci							GL_TYPE,
3487e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3488e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3489e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3490e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3491e5c31af7Sopenharmony_ci							GL_LOCATION };
3492e5c31af7Sopenharmony_ci		GLint expected2[] = { 6, 35666, 1, 0, 1, 0, 0 };
3493e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 7, props2, 7, expected2, error);
3494e5c31af7Sopenharmony_ci
3495e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3496e5c31af7Sopenharmony_ci		glDeleteProgram(program2);
3497e5c31af7Sopenharmony_ci		return error;
3498e5c31af7Sopenharmony_ci	}
3499e5c31af7Sopenharmony_ci};
3500e5c31af7Sopenharmony_ci
3501e5c31af7Sopenharmony_ciclass RelinkFailure : public SimpleShaders
3502e5c31af7Sopenharmony_ci{
3503e5c31af7Sopenharmony_ci
3504e5c31af7Sopenharmony_ci	virtual std::string Title()
3505e5c31af7Sopenharmony_ci	{
3506e5c31af7Sopenharmony_ci		return "Relink Failure Test";
3507e5c31af7Sopenharmony_ci	}
3508e5c31af7Sopenharmony_ci
3509e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
3510e5c31af7Sopenharmony_ci	{
3511e5c31af7Sopenharmony_ci		return "INVALID_OPERATION is generated when asking for locations after failed link.";
3512e5c31af7Sopenharmony_ci	}
3513e5c31af7Sopenharmony_ci
3514e5c31af7Sopenharmony_ci	virtual std::string Purpose()
3515e5c31af7Sopenharmony_ci	{
3516e5c31af7Sopenharmony_ci		return "Verify that queries behave correctly after failed relink of a program.";
3517e5c31af7Sopenharmony_ci	}
3518e5c31af7Sopenharmony_ci
3519e5c31af7Sopenharmony_ci	virtual std::string Method()
3520e5c31af7Sopenharmony_ci	{
3521e5c31af7Sopenharmony_ci		return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
3522e5c31af7Sopenharmony_ci			   "asking for locations.";
3523e5c31af7Sopenharmony_ci	}
3524e5c31af7Sopenharmony_ci
3525e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
3526e5c31af7Sopenharmony_ci	{
3527e5c31af7Sopenharmony_ci		return "#version 310 es                               \n"
3528e5c31af7Sopenharmony_ci			   "in mediump vec4 position;                     \n"
3529e5c31af7Sopenharmony_ci			   "in mediump vec3 pos;                          \n"
3530e5c31af7Sopenharmony_ci			   "void main(void)                               \n"
3531e5c31af7Sopenharmony_ci			   "{                                             \n"
3532e5c31af7Sopenharmony_ci			   "    gl_Position = position + vec4(pos, 1.);   \n"
3533e5c31af7Sopenharmony_ci			   "}";
3534e5c31af7Sopenharmony_ci	}
3535e5c31af7Sopenharmony_ci
3536e5c31af7Sopenharmony_ci	virtual long Run()
3537e5c31af7Sopenharmony_ci	{
3538e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3539e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3540e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 1, "pos");
3541e5c31af7Sopenharmony_ci		LinkProgram(program);
3542e5c31af7Sopenharmony_ci
3543e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3544e5c31af7Sopenharmony_ci
3545e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
3546e5c31af7Sopenharmony_ci		glUseProgram(program);
3547e5c31af7Sopenharmony_ci
3548e5c31af7Sopenharmony_ci		tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3549e5c31af7Sopenharmony_ci						   tcu::Vec4(1, -1, 0, 1) };
3550e5c31af7Sopenharmony_ci		GLuint vao, vbuf;
3551e5c31af7Sopenharmony_ci		glGenVertexArrays(1, &vao);
3552e5c31af7Sopenharmony_ci		glBindVertexArray(vao);
3553e5c31af7Sopenharmony_ci		glGenBuffers(1, &vbuf);
3554e5c31af7Sopenharmony_ci		glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3555e5c31af7Sopenharmony_ci		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3556e5c31af7Sopenharmony_ci		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3557e5c31af7Sopenharmony_ci		glEnableVertexAttribArray(0);
3558e5c31af7Sopenharmony_ci		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3559e5c31af7Sopenharmony_ci
3560e5c31af7Sopenharmony_ci		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3561e5c31af7Sopenharmony_ci		glDisableVertexAttribArray(0);
3562e5c31af7Sopenharmony_ci		glDeleteVertexArrays(1, &vao);
3563e5c31af7Sopenharmony_ci		glBindBuffer(GL_ARRAY_BUFFER, 0);
3564e5c31af7Sopenharmony_ci		glDeleteBuffers(1, &vbuf);
3565e5c31af7Sopenharmony_ci
3566e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "pos");
3567e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3568e5c31af7Sopenharmony_ci		const char* varyings[2] = { "q", "z" };
3569e5c31af7Sopenharmony_ci		glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3570e5c31af7Sopenharmony_ci		LinkProgram(program);
3571e5c31af7Sopenharmony_ci
3572e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3573e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
3574e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
3575e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
3576e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3577e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
3578e5c31af7Sopenharmony_ci
3579e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3580e5c31af7Sopenharmony_ci		return error;
3581e5c31af7Sopenharmony_ci	}
3582e5c31af7Sopenharmony_ci};
3583e5c31af7Sopenharmony_ci
3584e5c31af7Sopenharmony_ciclass LinkFailure : public SimpleShaders
3585e5c31af7Sopenharmony_ci{
3586e5c31af7Sopenharmony_ci
3587e5c31af7Sopenharmony_ci	virtual std::string Title()
3588e5c31af7Sopenharmony_ci	{
3589e5c31af7Sopenharmony_ci		return "Link Failure Test";
3590e5c31af7Sopenharmony_ci	}
3591e5c31af7Sopenharmony_ci
3592e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
3593e5c31af7Sopenharmony_ci	{
3594e5c31af7Sopenharmony_ci		return "INVALID_OPERATION is generated when asking for locations after failed link.";
3595e5c31af7Sopenharmony_ci	}
3596e5c31af7Sopenharmony_ci
3597e5c31af7Sopenharmony_ci	virtual std::string Purpose()
3598e5c31af7Sopenharmony_ci	{
3599e5c31af7Sopenharmony_ci		return "Verify that queries behave correctly after failed relink of a program with changed sources.";
3600e5c31af7Sopenharmony_ci	}
3601e5c31af7Sopenharmony_ci
3602e5c31af7Sopenharmony_ci	virtual std::string Method()
3603e5c31af7Sopenharmony_ci	{
3604e5c31af7Sopenharmony_ci		return "Create a program, use it, relink with failure using different sources and then \n"
3605e5c31af7Sopenharmony_ci			   "verify that INVALID_OPERATION is returned when asking for locations.";
3606e5c31af7Sopenharmony_ci	}
3607e5c31af7Sopenharmony_ci
3608e5c31af7Sopenharmony_ci	virtual const char* VertexShader_prop()
3609e5c31af7Sopenharmony_ci	{
3610e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
3611e5c31af7Sopenharmony_ci			   "in mediump vec4 posit;               \n"
3612e5c31af7Sopenharmony_ci			   "in mediump vec4 p;                   \n"
3613e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
3614e5c31af7Sopenharmony_ci			   "{                                    \n"
3615e5c31af7Sopenharmony_ci			   "    gl_Position = p + posit;         \n"
3616e5c31af7Sopenharmony_ci			   "}";
3617e5c31af7Sopenharmony_ci	}
3618e5c31af7Sopenharmony_ci
3619e5c31af7Sopenharmony_ci	virtual const char* FragmentShader_prop()
3620e5c31af7Sopenharmony_ci	{
3621e5c31af7Sopenharmony_ci		return "#version 310 es                    \n"
3622e5c31af7Sopenharmony_ci			   "out mediump vec4 color;            \n"
3623e5c31af7Sopenharmony_ci			   "void main() {                      \n"
3624e5c31af7Sopenharmony_ci			   "    color = vec4(0., 1., 0., 1.);  \n"
3625e5c31af7Sopenharmony_ci			   "}";
3626e5c31af7Sopenharmony_ci	}
3627e5c31af7Sopenharmony_ci
3628e5c31af7Sopenharmony_ci	virtual const char* VertexShader_fail()
3629e5c31af7Sopenharmony_ci	{
3630e5c31af7Sopenharmony_ci		return "#version 310 es                      \n"
3631e5c31af7Sopenharmony_ci			   "in mediump vec4 position;            \n"
3632e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
3633e5c31af7Sopenharmony_ci			   "{                                    \n"
3634e5c31af7Sopenharmony_ci			   "    gl_Position = position;          \n"
3635e5c31af7Sopenharmony_ci			   "}";
3636e5c31af7Sopenharmony_ci	}
3637e5c31af7Sopenharmony_ci
3638e5c31af7Sopenharmony_ci	virtual long Run()
3639e5c31af7Sopenharmony_ci	{
3640e5c31af7Sopenharmony_ci		const GLuint program = glCreateProgram();
3641e5c31af7Sopenharmony_ci		const char*  src_vs  = VertexShader_prop();
3642e5c31af7Sopenharmony_ci		const char*  src_fs  = FragmentShader_prop();
3643e5c31af7Sopenharmony_ci		const char*  src_vsh = VertexShader_fail();
3644e5c31af7Sopenharmony_ci
3645e5c31af7Sopenharmony_ci		GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
3646e5c31af7Sopenharmony_ci		glAttachShader(program, sh1);
3647e5c31af7Sopenharmony_ci		glDeleteShader(sh1);
3648e5c31af7Sopenharmony_ci		glShaderSource(sh1, 1, &src_vs, NULL);
3649e5c31af7Sopenharmony_ci		glCompileShader(sh1);
3650e5c31af7Sopenharmony_ci
3651e5c31af7Sopenharmony_ci		GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
3652e5c31af7Sopenharmony_ci		glAttachShader(program, sh2);
3653e5c31af7Sopenharmony_ci		glDeleteShader(sh2);
3654e5c31af7Sopenharmony_ci		glShaderSource(sh2, 1, &src_fs, NULL);
3655e5c31af7Sopenharmony_ci		glCompileShader(sh2);
3656e5c31af7Sopenharmony_ci
3657e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "p");
3658e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 1, "posit");
3659e5c31af7Sopenharmony_ci		LinkProgram(program);
3660e5c31af7Sopenharmony_ci
3661e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3662e5c31af7Sopenharmony_ci
3663e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
3664e5c31af7Sopenharmony_ci		glUseProgram(program);
3665e5c31af7Sopenharmony_ci
3666e5c31af7Sopenharmony_ci		tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
3667e5c31af7Sopenharmony_ci						   tcu::Vec4(1, -1, 0, 1) };
3668e5c31af7Sopenharmony_ci		GLuint vao, vbuf;
3669e5c31af7Sopenharmony_ci		glGenVertexArrays(1, &vao);
3670e5c31af7Sopenharmony_ci		glBindVertexArray(vao);
3671e5c31af7Sopenharmony_ci		glGenBuffers(1, &vbuf);
3672e5c31af7Sopenharmony_ci		glBindBuffer(GL_ARRAY_BUFFER, vbuf);
3673e5c31af7Sopenharmony_ci		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
3674e5c31af7Sopenharmony_ci		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
3675e5c31af7Sopenharmony_ci		glEnableVertexAttribArray(0);
3676e5c31af7Sopenharmony_ci		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3677e5c31af7Sopenharmony_ci
3678e5c31af7Sopenharmony_ci		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3679e5c31af7Sopenharmony_ci		glDisableVertexAttribArray(0);
3680e5c31af7Sopenharmony_ci		glDeleteVertexArrays(1, &vao);
3681e5c31af7Sopenharmony_ci		glBindBuffer(GL_ARRAY_BUFFER, 0);
3682e5c31af7Sopenharmony_ci		glDeleteBuffers(1, &vbuf);
3683e5c31af7Sopenharmony_ci
3684e5c31af7Sopenharmony_ci		glDetachShader(program, sh1);
3685e5c31af7Sopenharmony_ci		GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
3686e5c31af7Sopenharmony_ci		glAttachShader(program, vsh);
3687e5c31af7Sopenharmony_ci		glDeleteShader(vsh);
3688e5c31af7Sopenharmony_ci		glShaderSource(vsh, 1, &src_vsh, NULL);
3689e5c31af7Sopenharmony_ci		glCompileShader(vsh);
3690e5c31af7Sopenharmony_ci		const char* varyings[2] = { "q", "z" };
3691e5c31af7Sopenharmony_ci		glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
3692e5c31af7Sopenharmony_ci		LinkProgram(program);
3693e5c31af7Sopenharmony_ci
3694e5c31af7Sopenharmony_ci		GLint res;
3695e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
3696e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
3697e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
3698e5c31af7Sopenharmony_ci		if (res != 0 && res != 1)
3699e5c31af7Sopenharmony_ci		{
3700e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3701e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
3702e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
3703e5c31af7Sopenharmony_ci			error = ERROR;
3704e5c31af7Sopenharmony_ci		}
3705e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
3706e5c31af7Sopenharmony_ci		if (res != 0 && res != 9)
3707e5c31af7Sopenharmony_ci		{
3708e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3709e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
3710e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
3711e5c31af7Sopenharmony_ci			error = ERROR;
3712e5c31af7Sopenharmony_ci		}
3713e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
3714e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
3715e5c31af7Sopenharmony_ci
3716e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3717e5c31af7Sopenharmony_ci		return error;
3718e5c31af7Sopenharmony_ci	}
3719e5c31af7Sopenharmony_ci};
3720e5c31af7Sopenharmony_ci}
3721e5c31af7Sopenharmony_ci
3722e5c31af7Sopenharmony_ciProgramInterfaceQueryTests::ProgramInterfaceQueryTests(glcts::Context& context)
3723e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "program_interface_query", "")
3724e5c31af7Sopenharmony_ci{
3725e5c31af7Sopenharmony_ci}
3726e5c31af7Sopenharmony_ci
3727e5c31af7Sopenharmony_ciProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
3728e5c31af7Sopenharmony_ci{
3729e5c31af7Sopenharmony_ci}
3730e5c31af7Sopenharmony_ci
3731e5c31af7Sopenharmony_civoid ProgramInterfaceQueryTests::init()
3732e5c31af7Sopenharmony_ci{
3733e5c31af7Sopenharmony_ci	using namespace glcts;
3734e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
3735e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
3736e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
3737e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
3738e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
3739e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
3740e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
3741e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
3742e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
3743e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
3744e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-block-array", TestSubcase::Create<UniformBlockArray>));
3745e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
3746e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "transform-feedback-types-full-array-capture",
3747e5c31af7Sopenharmony_ci							 TestSubcase::Create<TransformFeedbackTypesFullArrayCapture>));
3748e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
3749e5c31af7Sopenharmony_ci	addChild(
3750e5c31af7Sopenharmony_ci		new TestSubcase(m_context, "atomic-counters-one-buffer", TestSubcase::Create<AtomicCounterSimpleOneBuffer>));
3751e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
3752e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
3753e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
3754e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
3755e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
3756e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
3757e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
3758e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
3759e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
3760e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
3761e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
3762e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
3763e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
3764e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
3765e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
3766e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
3767e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
3768e5c31af7Sopenharmony_ci}
3769e5c31af7Sopenharmony_ci}
3770