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 "gl4cProgramInterfaceQueryTests.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 gl4cts
32e5c31af7Sopenharmony_ci{
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_ciusing namespace glw;
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_cinamespace
37e5c31af7Sopenharmony_ci{
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_ciclass PIQBase : public deqp::SubcaseBase
40e5c31af7Sopenharmony_ci{
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_cipublic:
43e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
44e5c31af7Sopenharmony_ci	{
45e5c31af7Sopenharmony_ci		return "All called functions return expected values.";
46e5c31af7Sopenharmony_ci	}
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_ci	virtual std::string Purpose()
49e5c31af7Sopenharmony_ci	{
50e5c31af7Sopenharmony_ci		return "Verify that the set of tested functions glGetProgram* return\n"
51e5c31af7Sopenharmony_ci			   "expected results when used to get data from program\n"
52e5c31af7Sopenharmony_ci			   "made of " +
53e5c31af7Sopenharmony_ci			   ShadersDesc() + "." + PurposeExt();
54e5c31af7Sopenharmony_ci	}
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_ci	virtual std::string Method()
57e5c31af7Sopenharmony_ci	{
58e5c31af7Sopenharmony_ci		return "Create a program using " + ShadersDesc() +
59e5c31af7Sopenharmony_ci			   "\n"
60e5c31af7Sopenharmony_ci			   "then use set of tested functions to get an information about it and\n"
61e5c31af7Sopenharmony_ci			   "verify that information with the expected data" +
62e5c31af7Sopenharmony_ci			   Expectations();
63e5c31af7Sopenharmony_ci	}
64e5c31af7Sopenharmony_ci
65e5c31af7Sopenharmony_ci	virtual long Cleanup()
66e5c31af7Sopenharmony_ci	{
67e5c31af7Sopenharmony_ci		glUseProgram(0);
68e5c31af7Sopenharmony_ci		return NO_ERROR;
69e5c31af7Sopenharmony_ci	}
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci	virtual long Setup()
72e5c31af7Sopenharmony_ci	{
73e5c31af7Sopenharmony_ci		return NO_ERROR;
74e5c31af7Sopenharmony_ci	}
75e5c31af7Sopenharmony_ci
76e5c31af7Sopenharmony_ci	virtual ~PIQBase()
77e5c31af7Sopenharmony_ci	{
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	GLuint CreateProgram(const char* src_vs, const char* src_tcs, const char* src_tes, const char* src_gs,
122e5c31af7Sopenharmony_ci						 const char* src_fs, bool link)
123e5c31af7Sopenharmony_ci	{
124e5c31af7Sopenharmony_ci		const GLuint p = glCreateProgram();
125e5c31af7Sopenharmony_ci
126e5c31af7Sopenharmony_ci		if (src_vs)
127e5c31af7Sopenharmony_ci		{
128e5c31af7Sopenharmony_ci			GLuint sh = glCreateShader(GL_VERTEX_SHADER);
129e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
130e5c31af7Sopenharmony_ci			glDeleteShader(sh);
131e5c31af7Sopenharmony_ci			glShaderSource(sh, 1, &src_vs, NULL);
132e5c31af7Sopenharmony_ci			glCompileShader(sh);
133e5c31af7Sopenharmony_ci		}
134e5c31af7Sopenharmony_ci		if (src_tcs)
135e5c31af7Sopenharmony_ci		{
136e5c31af7Sopenharmony_ci			GLuint sh = glCreateShader(GL_TESS_CONTROL_SHADER);
137e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
138e5c31af7Sopenharmony_ci			glDeleteShader(sh);
139e5c31af7Sopenharmony_ci			glShaderSource(sh, 1, &src_tcs, NULL);
140e5c31af7Sopenharmony_ci			glCompileShader(sh);
141e5c31af7Sopenharmony_ci		}
142e5c31af7Sopenharmony_ci		if (src_tes)
143e5c31af7Sopenharmony_ci		{
144e5c31af7Sopenharmony_ci			GLuint sh = glCreateShader(GL_TESS_EVALUATION_SHADER);
145e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
146e5c31af7Sopenharmony_ci			glDeleteShader(sh);
147e5c31af7Sopenharmony_ci			glShaderSource(sh, 1, &src_tes, NULL);
148e5c31af7Sopenharmony_ci			glCompileShader(sh);
149e5c31af7Sopenharmony_ci		}
150e5c31af7Sopenharmony_ci		if (src_gs)
151e5c31af7Sopenharmony_ci		{
152e5c31af7Sopenharmony_ci			GLuint sh = glCreateShader(GL_GEOMETRY_SHADER);
153e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
154e5c31af7Sopenharmony_ci			glDeleteShader(sh);
155e5c31af7Sopenharmony_ci			glShaderSource(sh, 1, &src_gs, NULL);
156e5c31af7Sopenharmony_ci			glCompileShader(sh);
157e5c31af7Sopenharmony_ci		}
158e5c31af7Sopenharmony_ci		if (src_fs)
159e5c31af7Sopenharmony_ci		{
160e5c31af7Sopenharmony_ci			GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
161e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
162e5c31af7Sopenharmony_ci			glDeleteShader(sh);
163e5c31af7Sopenharmony_ci			glShaderSource(sh, 1, &src_fs, NULL);
164e5c31af7Sopenharmony_ci			glCompileShader(sh);
165e5c31af7Sopenharmony_ci		}
166e5c31af7Sopenharmony_ci		if (link)
167e5c31af7Sopenharmony_ci		{
168e5c31af7Sopenharmony_ci			LinkProgram(p);
169e5c31af7Sopenharmony_ci		}
170e5c31af7Sopenharmony_ci		return p;
171e5c31af7Sopenharmony_ci	}
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
174e5c31af7Sopenharmony_ci	{
175e5c31af7Sopenharmony_ci		return "";
176e5c31af7Sopenharmony_ci	}
177e5c31af7Sopenharmony_ci
178e5c31af7Sopenharmony_ci	virtual std::string Expectations()
179e5c31af7Sopenharmony_ci	{
180e5c31af7Sopenharmony_ci		return ".";
181e5c31af7Sopenharmony_ci	}
182e5c31af7Sopenharmony_ci
183e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
184e5c31af7Sopenharmony_ci	{
185e5c31af7Sopenharmony_ci		return "";
186e5c31af7Sopenharmony_ci	}
187e5c31af7Sopenharmony_ci
188e5c31af7Sopenharmony_ci	virtual inline void ExpectError(GLenum expected, long& error)
189e5c31af7Sopenharmony_ci	{
190e5c31af7Sopenharmony_ci		if (error != NO_ERROR)
191e5c31af7Sopenharmony_ci			return;
192e5c31af7Sopenharmony_ci		GLenum tmp = glGetError();
193e5c31af7Sopenharmony_ci		if (tmp == expected)
194e5c31af7Sopenharmony_ci		{
195e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
196e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Found expected error" << tcu::TestLog::EndMessage;
197e5c31af7Sopenharmony_ci			error = NO_ERROR; // Error is expected
198e5c31af7Sopenharmony_ci		}
199e5c31af7Sopenharmony_ci		else
200e5c31af7Sopenharmony_ci		{
201e5c31af7Sopenharmony_ci			error = ERROR;
202e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << expected
203e5c31af7Sopenharmony_ci												<< " error was expected, found: " << tmp << tcu::TestLog::EndMessage;
204e5c31af7Sopenharmony_ci		}
205e5c31af7Sopenharmony_ci	}
206e5c31af7Sopenharmony_ci
207e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, int expected,
208e5c31af7Sopenharmony_ci													long& error)
209e5c31af7Sopenharmony_ci	{
210e5c31af7Sopenharmony_ci		GLint res;
211e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, programInterface, pname, &res);
212e5c31af7Sopenharmony_ci		if (res != expected)
213e5c31af7Sopenharmony_ci		{
214e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
215e5c31af7Sopenharmony_ci												<< expected << tcu::TestLog::EndMessage;
216e5c31af7Sopenharmony_ci			error = ERROR;
217e5c31af7Sopenharmony_ci		}
218e5c31af7Sopenharmony_ci	}
219e5c31af7Sopenharmony_ci
220e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum programInterface, const std::string& name,
221e5c31af7Sopenharmony_ci													  GLuint expected, long& error)
222e5c31af7Sopenharmony_ci	{
223e5c31af7Sopenharmony_ci		GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
224e5c31af7Sopenharmony_ci		if (res != expected)
225e5c31af7Sopenharmony_ci		{
226e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
227e5c31af7Sopenharmony_ci												<< expected << tcu::TestLog::EndMessage;
228e5c31af7Sopenharmony_ci			error = ERROR;
229e5c31af7Sopenharmony_ci		}
230e5c31af7Sopenharmony_ci	}
231e5c31af7Sopenharmony_ci
232e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceIndex(GLuint program, GLenum		 programInterface,
233e5c31af7Sopenharmony_ci													  std::map<std::string, GLuint>& indices, const std::string& name,
234e5c31af7Sopenharmony_ci													  long& error)
235e5c31af7Sopenharmony_ci	{
236e5c31af7Sopenharmony_ci		GLuint res = glGetProgramResourceIndex(program, programInterface, name.c_str());
237e5c31af7Sopenharmony_ci		if (res == GL_INVALID_INDEX)
238e5c31af7Sopenharmony_ci		{
239e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
240e5c31af7Sopenharmony_ci												<< ", expected number other than -1" << tcu::TestLog::EndMessage;
241e5c31af7Sopenharmony_ci			error = ERROR;
242e5c31af7Sopenharmony_ci			return;
243e5c31af7Sopenharmony_ci		}
244e5c31af7Sopenharmony_ci		std::map<std::string, GLuint>::iterator it = indices.begin();
245e5c31af7Sopenharmony_ci		while (it != indices.end())
246e5c31af7Sopenharmony_ci		{
247e5c31af7Sopenharmony_ci			if (it->second == res)
248e5c31af7Sopenharmony_ci			{
249e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
250e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
251e5c31af7Sopenharmony_ci				error = ERROR;
252e5c31af7Sopenharmony_ci				return;
253e5c31af7Sopenharmony_ci			}
254e5c31af7Sopenharmony_ci			++it;
255e5c31af7Sopenharmony_ci		}
256e5c31af7Sopenharmony_ci		indices[name] = res;
257e5c31af7Sopenharmony_ci	}
258e5c31af7Sopenharmony_ci
259e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index,
260e5c31af7Sopenharmony_ci													 const std::string& expected, long& error)
261e5c31af7Sopenharmony_ci	{
262e5c31af7Sopenharmony_ci		GLchar  name[1024] = { '\0' };
263e5c31af7Sopenharmony_ci		GLsizei len;
264e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, programInterface, index, 1024, &len, name);
265e5c31af7Sopenharmony_ci		if (len <= 0 || len > 1023 || name[len - 1] == '\0')
266e5c31af7Sopenharmony_ci		{
267e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
268e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
269e5c31af7Sopenharmony_ci				<< "ERROR: Length in glGetProgramResourceName should not count null terminator!"
270e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
271e5c31af7Sopenharmony_ci			error = ERROR;
272e5c31af7Sopenharmony_ci		}
273e5c31af7Sopenharmony_ci		else if (name != expected || name[len] != '\0')
274e5c31af7Sopenharmony_ci		{
275e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << name << ", expected "
276e5c31af7Sopenharmony_ci												<< expected << tcu::TestLog::EndMessage;
277e5c31af7Sopenharmony_ci			error = ERROR;
278e5c31af7Sopenharmony_ci		}
279e5c31af7Sopenharmony_ci	}
280e5c31af7Sopenharmony_ci
281e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum programInterface,
282e5c31af7Sopenharmony_ci														 const std::string& name, GLint expected, long& error)
283e5c31af7Sopenharmony_ci	{
284e5c31af7Sopenharmony_ci		GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
285e5c31af7Sopenharmony_ci		if (res != expected)
286e5c31af7Sopenharmony_ci		{
287e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
288e5c31af7Sopenharmony_ci												<< expected << tcu::TestLog::EndMessage;
289e5c31af7Sopenharmony_ci			error = ERROR;
290e5c31af7Sopenharmony_ci		}
291e5c31af7Sopenharmony_ci	}
292e5c31af7Sopenharmony_ci
293e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceLocation(GLuint program, GLenum		   programInterface,
294e5c31af7Sopenharmony_ci														 std::map<std::string, GLint>& locations,
295e5c31af7Sopenharmony_ci														 const std::string& name, long& error)
296e5c31af7Sopenharmony_ci	{
297e5c31af7Sopenharmony_ci		GLint res = glGetProgramResourceLocation(program, programInterface, name.c_str());
298e5c31af7Sopenharmony_ci		if (res < 0)
299e5c31af7Sopenharmony_ci		{
300e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res
301e5c31af7Sopenharmony_ci												<< ", expected not less than 0" << tcu::TestLog::EndMessage;
302e5c31af7Sopenharmony_ci			error = ERROR;
303e5c31af7Sopenharmony_ci			return;
304e5c31af7Sopenharmony_ci		}
305e5c31af7Sopenharmony_ci		std::map<std::string, GLint>::iterator it = locations.begin();
306e5c31af7Sopenharmony_ci		while (it != locations.end())
307e5c31af7Sopenharmony_ci		{
308e5c31af7Sopenharmony_ci			if (it->second == res)
309e5c31af7Sopenharmony_ci			{
310e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
311e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "ERROR: Duplicated value found: " << res << tcu::TestLog::EndMessage;
312e5c31af7Sopenharmony_ci				error = ERROR;
313e5c31af7Sopenharmony_ci				return;
314e5c31af7Sopenharmony_ci			}
315e5c31af7Sopenharmony_ci			++it;
316e5c31af7Sopenharmony_ci		}
317e5c31af7Sopenharmony_ci		locations[name] = res;
318e5c31af7Sopenharmony_ci	}
319e5c31af7Sopenharmony_ci
320e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index,
321e5c31af7Sopenharmony_ci												   GLsizei propCount, const GLenum props[], GLsizei expectedLength,
322e5c31af7Sopenharmony_ci												   const GLint expected[], long& error)
323e5c31af7Sopenharmony_ci	{
324e5c31af7Sopenharmony_ci		const GLsizei bufSize = 1000;
325e5c31af7Sopenharmony_ci		GLsizei		  length;
326e5c31af7Sopenharmony_ci		GLint		  params[bufSize];
327e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, &length, params);
328e5c31af7Sopenharmony_ci		if (length != expectedLength || length <= 0)
329e5c31af7Sopenharmony_ci		{
330e5c31af7Sopenharmony_ci			error = ERROR;
331e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
332e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: Got length " << length << ", expected " << expectedLength
333e5c31af7Sopenharmony_ci				<< "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
334e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
335e5c31af7Sopenharmony_ci			return;
336e5c31af7Sopenharmony_ci		}
337e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
338e5c31af7Sopenharmony_ci		{
339e5c31af7Sopenharmony_ci			if (params[i] != expected[i])
340e5c31af7Sopenharmony_ci			{
341e5c31af7Sopenharmony_ci				error = ERROR;
342e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
343e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "ERROR: Got " << params[i] << ", expected " << expected[i]
344e5c31af7Sopenharmony_ci					<< " at: " << i << "\nCALL: glGetProgramResourceiv, with " << programInterface << ", " << index
345e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
346e5c31af7Sopenharmony_ci			}
347e5c31af7Sopenharmony_ci		}
348e5c31af7Sopenharmony_ci	}
349e5c31af7Sopenharmony_ci
350e5c31af7Sopenharmony_ci	virtual inline void VerifyGetProgramResourceLocationIndex(GLuint program, GLenum programInterface,
351e5c31af7Sopenharmony_ci															  const std::string& name, GLint expected, long& error)
352e5c31af7Sopenharmony_ci	{
353e5c31af7Sopenharmony_ci		GLint res = glGetProgramResourceLocationIndex(program, programInterface, name.c_str());
354e5c31af7Sopenharmony_ci		if (res != expected)
355e5c31af7Sopenharmony_ci		{
356e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: Got " << res << ", expected "
357e5c31af7Sopenharmony_ci												<< expected << "\nCALL: glGetProgramResourceLocationIndex, with "
358e5c31af7Sopenharmony_ci												<< programInterface << ", " << name << tcu::TestLog::EndMessage;
359e5c31af7Sopenharmony_ci			error = ERROR;
360e5c31af7Sopenharmony_ci		}
361e5c31af7Sopenharmony_ci	}
362e5c31af7Sopenharmony_ci
363e5c31af7Sopenharmony_ci	virtual inline GLint GetProgramivRetValue(GLuint program, GLenum pname)
364e5c31af7Sopenharmony_ci	{
365e5c31af7Sopenharmony_ci		GLint ret;
366e5c31af7Sopenharmony_ci		glGetProgramiv(program, pname, &ret);
367e5c31af7Sopenharmony_ci		return ret;
368e5c31af7Sopenharmony_ci	}
369e5c31af7Sopenharmony_ci
370e5c31af7Sopenharmony_ci	static const GLenum interfaces[];
371e5c31af7Sopenharmony_ci};
372e5c31af7Sopenharmony_ci
373e5c31af7Sopenharmony_ciconst GLenum PIQBase::interfaces[] = { GL_PROGRAM_INPUT,
374e5c31af7Sopenharmony_ci									   GL_PROGRAM_OUTPUT,
375e5c31af7Sopenharmony_ci									   GL_UNIFORM,
376e5c31af7Sopenharmony_ci									   GL_UNIFORM_BLOCK,
377e5c31af7Sopenharmony_ci									   GL_BUFFER_VARIABLE,
378e5c31af7Sopenharmony_ci									   GL_SHADER_STORAGE_BLOCK,
379e5c31af7Sopenharmony_ci									   GL_VERTEX_SUBROUTINE,
380e5c31af7Sopenharmony_ci									   GL_TESS_CONTROL_SUBROUTINE,
381e5c31af7Sopenharmony_ci									   GL_TESS_EVALUATION_SUBROUTINE,
382e5c31af7Sopenharmony_ci									   GL_GEOMETRY_SUBROUTINE,
383e5c31af7Sopenharmony_ci									   GL_FRAGMENT_SUBROUTINE,
384e5c31af7Sopenharmony_ci									   GL_COMPUTE_SUBROUTINE,
385e5c31af7Sopenharmony_ci									   GL_VERTEX_SUBROUTINE_UNIFORM,
386e5c31af7Sopenharmony_ci									   GL_TESS_CONTROL_SUBROUTINE_UNIFORM,
387e5c31af7Sopenharmony_ci									   GL_TESS_EVALUATION_SUBROUTINE_UNIFORM,
388e5c31af7Sopenharmony_ci									   GL_GEOMETRY_SUBROUTINE_UNIFORM,
389e5c31af7Sopenharmony_ci									   GL_FRAGMENT_SUBROUTINE_UNIFORM,
390e5c31af7Sopenharmony_ci									   GL_COMPUTE_SUBROUTINE_UNIFORM,
391e5c31af7Sopenharmony_ci									   GL_TRANSFORM_FEEDBACK_VARYING };
392e5c31af7Sopenharmony_ci
393e5c31af7Sopenharmony_ciclass NoShaders : public PIQBase
394e5c31af7Sopenharmony_ci{
395e5c31af7Sopenharmony_ci
396e5c31af7Sopenharmony_ci	virtual std::string Title()
397e5c31af7Sopenharmony_ci	{
398e5c31af7Sopenharmony_ci		return "No Shaders Test";
399e5c31af7Sopenharmony_ci	}
400e5c31af7Sopenharmony_ci
401e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
402e5c31af7Sopenharmony_ci	{
403e5c31af7Sopenharmony_ci		return "no shaders";
404e5c31af7Sopenharmony_ci	}
405e5c31af7Sopenharmony_ci
406e5c31af7Sopenharmony_ci	virtual long Run()
407e5c31af7Sopenharmony_ci	{
408e5c31af7Sopenharmony_ci		const GLuint program = glCreateProgram();
409e5c31af7Sopenharmony_ci
410e5c31af7Sopenharmony_ci		long error = NO_ERROR;
411e5c31af7Sopenharmony_ci		int  size  = sizeof(PIQBase::interfaces) / sizeof(PIQBase::interfaces[0]);
412e5c31af7Sopenharmony_ci
413e5c31af7Sopenharmony_ci		for (int i = 0; i < size; ++i)
414e5c31af7Sopenharmony_ci		{
415e5c31af7Sopenharmony_ci			VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_ACTIVE_RESOURCES, 0, error);
416e5c31af7Sopenharmony_ci			if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
417e5c31af7Sopenharmony_ci				continue;
418e5c31af7Sopenharmony_ci			VerifyGetProgramInterfaceiv(program, PIQBase::interfaces[i], GL_MAX_NAME_LENGTH, 0, error);
419e5c31af7Sopenharmony_ci		}
420e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
421e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
422e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 0, error);
423e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
424e5c31af7Sopenharmony_ci									error);
425e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
426e5c31af7Sopenharmony_ci									error);
427e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
428e5c31af7Sopenharmony_ci									error);
429e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES,
430e5c31af7Sopenharmony_ci									0, error);
431e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0,
432e5c31af7Sopenharmony_ci									error);
433e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 0, error);
434e5c31af7Sopenharmony_ci
435e5c31af7Sopenharmony_ci		for (int i = 0; i < size; ++i)
436e5c31af7Sopenharmony_ci		{
437e5c31af7Sopenharmony_ci			if (PIQBase::interfaces[i] == GL_ATOMIC_COUNTER_BUFFER)
438e5c31af7Sopenharmony_ci				continue;
439e5c31af7Sopenharmony_ci			VerifyGetProgramResourceIndex(program, PIQBase::interfaces[i], "", GL_INVALID_INDEX, error);
440e5c31af7Sopenharmony_ci		}
441e5c31af7Sopenharmony_ci
442e5c31af7Sopenharmony_ci		// can't test GetProgramResourceLocation* here since program has to be linked
443e5c31af7Sopenharmony_ci		// can't test GetProgramResourceiv, need valid index
444e5c31af7Sopenharmony_ci
445e5c31af7Sopenharmony_ci		glDeleteProgram(program);
446e5c31af7Sopenharmony_ci		return error;
447e5c31af7Sopenharmony_ci	}
448e5c31af7Sopenharmony_ci};
449e5c31af7Sopenharmony_ci
450e5c31af7Sopenharmony_ciclass SimpleShaders : public PIQBase
451e5c31af7Sopenharmony_ci{
452e5c31af7Sopenharmony_ci
453e5c31af7Sopenharmony_cipublic:
454e5c31af7Sopenharmony_ci	virtual std::string Title()
455e5c31af7Sopenharmony_ci	{
456e5c31af7Sopenharmony_ci		return "Simple Shaders Test";
457e5c31af7Sopenharmony_ci	}
458e5c31af7Sopenharmony_ci
459e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
460e5c31af7Sopenharmony_ci	{
461e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders";
462e5c31af7Sopenharmony_ci	}
463e5c31af7Sopenharmony_ci
464e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
465e5c31af7Sopenharmony_ci	{
466e5c31af7Sopenharmony_ci		return "#version 430                         \n"
467e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
468e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
469e5c31af7Sopenharmony_ci			   "{                                    \n"
470e5c31af7Sopenharmony_ci			   "    gl_Position = position;          \n"
471e5c31af7Sopenharmony_ci			   "}";
472e5c31af7Sopenharmony_ci	}
473e5c31af7Sopenharmony_ci
474e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
475e5c31af7Sopenharmony_ci	{
476e5c31af7Sopenharmony_ci		return "#version 430                   \n"
477e5c31af7Sopenharmony_ci			   "out vec4 color;                \n"
478e5c31af7Sopenharmony_ci			   "void main() {                  \n"
479e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1);  \n"
480e5c31af7Sopenharmony_ci			   "}";
481e5c31af7Sopenharmony_ci	}
482e5c31af7Sopenharmony_ci
483e5c31af7Sopenharmony_ci	virtual long Run()
484e5c31af7Sopenharmony_ci	{
485e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
486e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
487e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
488e5c31af7Sopenharmony_ci		LinkProgram(program);
489e5c31af7Sopenharmony_ci
490e5c31af7Sopenharmony_ci		long error = NO_ERROR;
491e5c31af7Sopenharmony_ci
492e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
493e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
494e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
495e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
496e5c31af7Sopenharmony_ci
497e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
498e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
499e5c31af7Sopenharmony_ci
500e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
501e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
502e5c31af7Sopenharmony_ci
503e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
504e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
505e5c31af7Sopenharmony_ci
506e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
507e5c31af7Sopenharmony_ci
508e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
509e5c31af7Sopenharmony_ci						   GL_TYPE,
510e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
511e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
512e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
513e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
514e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
515e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
516e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
517e5c31af7Sopenharmony_ci						   GL_LOCATION,
518e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH };
519e5c31af7Sopenharmony_ci		GLint expected[] = { 9, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
520e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 11, props, 11, expected, error);
521e5c31af7Sopenharmony_ci
522e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
523e5c31af7Sopenharmony_ci							GL_TYPE,
524e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
525e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
526e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
527e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
528e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
529e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
530e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
531e5c31af7Sopenharmony_ci							GL_LOCATION,
532e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH,
533e5c31af7Sopenharmony_ci							GL_LOCATION_INDEX };
534e5c31af7Sopenharmony_ci		GLint expected2[] = { 6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
535e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props2, 12, expected2, error);
536e5c31af7Sopenharmony_ci
537e5c31af7Sopenharmony_ci		glDeleteProgram(program);
538e5c31af7Sopenharmony_ci		return error;
539e5c31af7Sopenharmony_ci	}
540e5c31af7Sopenharmony_ci};
541e5c31af7Sopenharmony_ci
542e5c31af7Sopenharmony_ciclass InputTypes : public SimpleShaders
543e5c31af7Sopenharmony_ci{
544e5c31af7Sopenharmony_ci	virtual std::string Title()
545e5c31af7Sopenharmony_ci	{
546e5c31af7Sopenharmony_ci		return "Input Types Test";
547e5c31af7Sopenharmony_ci	}
548e5c31af7Sopenharmony_ci
549e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
550e5c31af7Sopenharmony_ci	{
551e5c31af7Sopenharmony_ci		return "vertex shader with different `in` types and a fallthrough fragment shader";
552e5c31af7Sopenharmony_ci	}
553e5c31af7Sopenharmony_ci
554e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
555e5c31af7Sopenharmony_ci	{
556e5c31af7Sopenharmony_ci		return "#version 430                         \n"
557e5c31af7Sopenharmony_ci			   "in mat4 a;                           \n"
558e5c31af7Sopenharmony_ci			   "in ivec4 b;                          \n"
559e5c31af7Sopenharmony_ci			   "in float c[2];                       \n"
560e5c31af7Sopenharmony_ci			   "in mat2x3 d[2];                      \n"
561e5c31af7Sopenharmony_ci			   "in uvec2 e;                          \n"
562e5c31af7Sopenharmony_ci			   "in uint f;                           \n"
563e5c31af7Sopenharmony_ci			   "in vec3 g[2];                        \n"
564e5c31af7Sopenharmony_ci			   "in int h;                            \n"
565e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
566e5c31af7Sopenharmony_ci			   "{                                    \n"
567e5c31af7Sopenharmony_ci			   "   vec4 pos;                                           \n"
568e5c31af7Sopenharmony_ci			   "   pos.w = h + g[0].x + g[1].y + d[1][1].y;            \n"
569e5c31af7Sopenharmony_ci			   "   pos.y = b.x * c[0] + c[1] + d[0][0].x;              \n"
570e5c31af7Sopenharmony_ci			   "   pos.x = a[0].x + a[1].y + a[2].z + a[3].w;          \n"
571e5c31af7Sopenharmony_ci			   "   pos.z = d[0][1].z + e.x * f + d[1][0].z;            \n"
572e5c31af7Sopenharmony_ci			   "   gl_Position = pos;                                  \n"
573e5c31af7Sopenharmony_ci			   "}";
574e5c31af7Sopenharmony_ci	}
575e5c31af7Sopenharmony_ci
576e5c31af7Sopenharmony_ci	virtual long Run()
577e5c31af7Sopenharmony_ci	{
578e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
579e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "a");
580e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 4, "b");
581e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 5, "c");
582e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 7, "d");
583e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 11, "e");
584e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 12, "f");
585e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 13, "g");
586e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 15, "h");
587e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
588e5c31af7Sopenharmony_ci		LinkProgram(program);
589e5c31af7Sopenharmony_ci
590e5c31af7Sopenharmony_ci		long error = NO_ERROR;
591e5c31af7Sopenharmony_ci
592e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
593e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
594e5c31af7Sopenharmony_ci
595e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
596e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
597e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
598e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c[0]", error);
599e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
600e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
601e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
602e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
603e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
604e5c31af7Sopenharmony_ci
605e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
606e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
607e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c[0]"], "c[0]", error);
608e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d[0]", error);
609e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
610e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
611e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g[0]", error);
612e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
613e5c31af7Sopenharmony_ci
614e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
615e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
616e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[0]", 5, error);
617e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
618e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[1]", 6, error);
619e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d[0]", 7, error);
620e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
621e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
622e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
623e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[0]", 13, error);
624e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
625e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[1]", 14, error);
626e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
627e5c31af7Sopenharmony_ci
628e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
629e5c31af7Sopenharmony_ci						   GL_TYPE,
630e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
631e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
632e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
633e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
634e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
635e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
636e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
637e5c31af7Sopenharmony_ci						   GL_LOCATION,
638e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH };
639e5c31af7Sopenharmony_ci		GLint expected[] = { 2, GL_FLOAT_MAT4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
640e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 11, props, 11, expected, error);
641e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, GL_INT_VEC4, 1, 0, 0, 0, 0, 0, 1, 4, 0 };
642e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 11, props, 11, expected2, error);
643e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, GL_FLOAT, 2, 0, 0, 0, 0, 0, 1, 5, 0 };
644e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c[0]"], 11, props, 11, expected3, error);
645e5c31af7Sopenharmony_ci		GLint expected4[] = { 5, GL_FLOAT_MAT2x3, 2, 0, 0, 0, 0, 0, 1, 7, 0 };
646e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 11, props, 11, expected4, error);
647e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, GL_UNSIGNED_INT_VEC2, 1, 0, 0, 0, 0, 0, 1, 11, 0 };
648e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 11, props, 11, expected5, error);
649e5c31af7Sopenharmony_ci		GLint expected6[] = { 2, GL_UNSIGNED_INT, 1, 0, 0, 0, 0, 0, 1, 12, 0 };
650e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 11, props, 11, expected6, error);
651e5c31af7Sopenharmony_ci		GLint expected7[] = { 5, GL_FLOAT_VEC3, 2, 0, 0, 0, 0, 0, 1, 13, 0 };
652e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 11, props, 11, expected7, error);
653e5c31af7Sopenharmony_ci		GLint expected8[] = { 2, GL_INT, 1, 0, 0, 0, 0, 0, 1, 15, 0 };
654e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 11, props, 11, expected8, error);
655e5c31af7Sopenharmony_ci
656e5c31af7Sopenharmony_ci		glDeleteProgram(program);
657e5c31af7Sopenharmony_ci		return error;
658e5c31af7Sopenharmony_ci	}
659e5c31af7Sopenharmony_ci};
660e5c31af7Sopenharmony_ci
661e5c31af7Sopenharmony_ciclass OutputTypes : public SimpleShaders
662e5c31af7Sopenharmony_ci{
663e5c31af7Sopenharmony_ci	virtual std::string Title()
664e5c31af7Sopenharmony_ci	{
665e5c31af7Sopenharmony_ci		return "Output Types Test";
666e5c31af7Sopenharmony_ci	}
667e5c31af7Sopenharmony_ci
668e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
669e5c31af7Sopenharmony_ci	{
670e5c31af7Sopenharmony_ci		return "fragment shader with different `out` types and a fallthrough vertex shader";
671e5c31af7Sopenharmony_ci	}
672e5c31af7Sopenharmony_ci
673e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
674e5c31af7Sopenharmony_ci	{
675e5c31af7Sopenharmony_ci		return "#version 430                   \n"
676e5c31af7Sopenharmony_ci			   "out vec3 a[2];                 \n"
677e5c31af7Sopenharmony_ci			   "out uint b;                    \n"
678e5c31af7Sopenharmony_ci			   "out float c[2];                \n"
679e5c31af7Sopenharmony_ci			   "out int d[2];                  \n"
680e5c31af7Sopenharmony_ci			   "out vec2 e;                    \n"
681e5c31af7Sopenharmony_ci			   "void main() {                  \n"
682e5c31af7Sopenharmony_ci			   "    c[1] = -0.6;               \n"
683e5c31af7Sopenharmony_ci			   "    d[0] = 0;                  \n"
684e5c31af7Sopenharmony_ci			   "    b = 12u;                   \n"
685e5c31af7Sopenharmony_ci			   "    c[0] = 1.1;                \n"
686e5c31af7Sopenharmony_ci			   "    e = vec2(0, 1);            \n"
687e5c31af7Sopenharmony_ci			   "    d[1] = -19;                \n"
688e5c31af7Sopenharmony_ci			   "    a[1] = vec3(0, 1, 0);      \n"
689e5c31af7Sopenharmony_ci			   "    a[0] = vec3(0, 1, 0);      \n"
690e5c31af7Sopenharmony_ci			   "}";
691e5c31af7Sopenharmony_ci	}
692e5c31af7Sopenharmony_ci
693e5c31af7Sopenharmony_ci	virtual long Run()
694e5c31af7Sopenharmony_ci	{
695e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
696e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
697e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "a");
698e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 2, "b");
699e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 3, "c");
700e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 5, "d");
701e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 7, "e");
702e5c31af7Sopenharmony_ci		LinkProgram(program);
703e5c31af7Sopenharmony_ci
704e5c31af7Sopenharmony_ci		long error = NO_ERROR;
705e5c31af7Sopenharmony_ci
706e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
707e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
708e5c31af7Sopenharmony_ci
709e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
710e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error);
711e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error);
712e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "c[0]", error);
713e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "d", error);
714e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error);
715e5c31af7Sopenharmony_ci
716e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error);
717e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error);
718e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["c[0]"], "c[0]", error);
719e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["d"], "d[0]", error);
720e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error);
721e5c31af7Sopenharmony_ci
722e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
723e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error);
724e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error);
725e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error);
726e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[0]", 3, error);
727e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c", 3, error);
728e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[1]", 4, error);
729e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[0]", 5, error);
730e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d", 5, error);
731e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[1]", 6, error);
732e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 7, error);
733e5c31af7Sopenharmony_ci
734e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
735e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a", 0, error);
736e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "b", 0, error);
737e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c[0]", 0, error);
738e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c", 0, error);
739e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d[0]", 0, error);
740e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d", 0, error);
741e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "e", 0, error);
742e5c31af7Sopenharmony_ci
743e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
744e5c31af7Sopenharmony_ci						   GL_TYPE,
745e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
746e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
747e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
748e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
749e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
750e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
751e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
752e5c31af7Sopenharmony_ci						   GL_LOCATION,
753e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH,
754e5c31af7Sopenharmony_ci						   GL_LOCATION_INDEX };
755e5c31af7Sopenharmony_ci		GLint expected[] = { 5, GL_FLOAT_VEC3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
756e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 12, props, 12, expected, error);
757e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, GL_UNSIGNED_INT, 1, 0, 1, 0, 0, 0, 0, 2, 0, 0 };
758e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 12, props, 12, expected2, error);
759e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, GL_FLOAT, 2, 0, 1, 0, 0, 0, 0, 3, 0, 0 };
760e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["c[0]"], 12, props, 12, expected3, error);
761e5c31af7Sopenharmony_ci		GLint expected4[] = { 5, GL_INT, 2, 0, 1, 0, 0, 0, 0, 5, 0, 0 };
762e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["d"], 12, props, 12, expected4, error);
763e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, GL_FLOAT_VEC2, 1, 0, 1, 0, 0, 0, 0, 7, 0, 0 };
764e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 12, props, 12, expected5, error);
765e5c31af7Sopenharmony_ci
766e5c31af7Sopenharmony_ci		glDeleteProgram(program);
767e5c31af7Sopenharmony_ci		return error;
768e5c31af7Sopenharmony_ci	}
769e5c31af7Sopenharmony_ci};
770e5c31af7Sopenharmony_ci
771e5c31af7Sopenharmony_ciclass OutputLocationIndex : public SimpleShaders
772e5c31af7Sopenharmony_ci{
773e5c31af7Sopenharmony_ci	virtual std::string Title()
774e5c31af7Sopenharmony_ci	{
775e5c31af7Sopenharmony_ci		return "Output Location Index Test";
776e5c31af7Sopenharmony_ci	}
777e5c31af7Sopenharmony_ci
778e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
779e5c31af7Sopenharmony_ci	{
780e5c31af7Sopenharmony_ci		return "fragment shader with `out` location index different from 0 and a fallthrough vertex shader";
781e5c31af7Sopenharmony_ci	}
782e5c31af7Sopenharmony_ci
783e5c31af7Sopenharmony_ci	virtual long Run()
784e5c31af7Sopenharmony_ci	{
785e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
786e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
787e5c31af7Sopenharmony_ci		glBindFragDataLocationIndexed(program, 0, 1, "color");
788e5c31af7Sopenharmony_ci		LinkProgram(program);
789e5c31af7Sopenharmony_ci
790e5c31af7Sopenharmony_ci		long error = NO_ERROR;
791e5c31af7Sopenharmony_ci
792e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
793e5c31af7Sopenharmony_ci
794e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 1, error);
795e5c31af7Sopenharmony_ci
796e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
797e5c31af7Sopenharmony_ci						   GL_TYPE,
798e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
799e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
800e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
801e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
802e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
803e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
804e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
805e5c31af7Sopenharmony_ci						   GL_LOCATION,
806e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH,
807e5c31af7Sopenharmony_ci						   GL_LOCATION_INDEX };
808e5c31af7Sopenharmony_ci		GLint expected[] = { 6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
809e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props, 12, expected, error);
810e5c31af7Sopenharmony_ci
811e5c31af7Sopenharmony_ci		glDeleteProgram(program);
812e5c31af7Sopenharmony_ci		return error;
813e5c31af7Sopenharmony_ci	}
814e5c31af7Sopenharmony_ci};
815e5c31af7Sopenharmony_ci
816e5c31af7Sopenharmony_ciclass InputBuiltIn : public SimpleShaders
817e5c31af7Sopenharmony_ci{
818e5c31af7Sopenharmony_ci
819e5c31af7Sopenharmony_ci	virtual std::string Title()
820e5c31af7Sopenharmony_ci	{
821e5c31af7Sopenharmony_ci		return "Input Built-ins Test";
822e5c31af7Sopenharmony_ci	}
823e5c31af7Sopenharmony_ci
824e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
825e5c31af7Sopenharmony_ci	{
826e5c31af7Sopenharmony_ci		return "vertex shader using built-in variables and a fallthrough fragment shader";
827e5c31af7Sopenharmony_ci	}
828e5c31af7Sopenharmony_ci
829e5c31af7Sopenharmony_ci	virtual std::string Expectations()
830e5c31af7Sopenharmony_ci	{
831e5c31af7Sopenharmony_ci		return ".\n\n In this case we ask for information about built-in variables for the input interface.";
832e5c31af7Sopenharmony_ci	}
833e5c31af7Sopenharmony_ci
834e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
835e5c31af7Sopenharmony_ci	{
836e5c31af7Sopenharmony_ci		return "#version 430                         \n"
837e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
838e5c31af7Sopenharmony_ci			   "{                                    \n"
839e5c31af7Sopenharmony_ci			   "    gl_Position = (gl_VertexID + gl_InstanceID) * vec4(0.1);          \n"
840e5c31af7Sopenharmony_ci			   "}";
841e5c31af7Sopenharmony_ci	}
842e5c31af7Sopenharmony_ci
843e5c31af7Sopenharmony_ci	virtual long Run()
844e5c31af7Sopenharmony_ci	{
845e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
846e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
847e5c31af7Sopenharmony_ci		LinkProgram(program);
848e5c31af7Sopenharmony_ci
849e5c31af7Sopenharmony_ci		long error = NO_ERROR;
850e5c31af7Sopenharmony_ci
851e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 2, error);
852e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 14, error);
853e5c31af7Sopenharmony_ci
854e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
855e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_VertexID", error);
856e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "gl_InstanceID", error);
857e5c31af7Sopenharmony_ci
858e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], "gl_VertexID", error);
859e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], "gl_InstanceID", error);
860e5c31af7Sopenharmony_ci
861e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_VertexID", -1, error);
862e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "gl_InstanceID", -1, error);
863e5c31af7Sopenharmony_ci
864e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
865e5c31af7Sopenharmony_ci						   GL_TYPE,
866e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
867e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
868e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
869e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
870e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
871e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
872e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
873e5c31af7Sopenharmony_ci						   GL_LOCATION,
874e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH };
875e5c31af7Sopenharmony_ci		GLint expected[] = { 12, GL_INT, 1, 0, 0, 0, 0, 0, 1, -1, 0 };
876e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_VertexID"], 11, props, 11, expected, error);
877e5c31af7Sopenharmony_ci		GLint expected2[] = { 14, GL_INT, 1, 0, 0, 0, 0, 0, 1, -1, 0 };
878e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["gl_InstanceID"], 11, props, 11, expected2,
879e5c31af7Sopenharmony_ci								   error);
880e5c31af7Sopenharmony_ci
881e5c31af7Sopenharmony_ci		glDeleteProgram(program);
882e5c31af7Sopenharmony_ci		return error;
883e5c31af7Sopenharmony_ci	}
884e5c31af7Sopenharmony_ci};
885e5c31af7Sopenharmony_ci
886e5c31af7Sopenharmony_ciclass OutputBuiltIn : public SimpleShaders
887e5c31af7Sopenharmony_ci{
888e5c31af7Sopenharmony_ci
889e5c31af7Sopenharmony_ci	virtual std::string Title()
890e5c31af7Sopenharmony_ci	{
891e5c31af7Sopenharmony_ci		return "Output Built-ins Test";
892e5c31af7Sopenharmony_ci	}
893e5c31af7Sopenharmony_ci
894e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
895e5c31af7Sopenharmony_ci	{
896e5c31af7Sopenharmony_ci		return "fragment shader using built-in variables and a fallthrough vertex shader";
897e5c31af7Sopenharmony_ci	}
898e5c31af7Sopenharmony_ci
899e5c31af7Sopenharmony_ci	virtual std::string Expectations()
900e5c31af7Sopenharmony_ci	{
901e5c31af7Sopenharmony_ci		return ".\n\n In this case we ask for information about built-in variables for the output interface.";
902e5c31af7Sopenharmony_ci	}
903e5c31af7Sopenharmony_ci
904e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
905e5c31af7Sopenharmony_ci	{
906e5c31af7Sopenharmony_ci		return "#version 430                               \n"
907e5c31af7Sopenharmony_ci			   "void main(void)                            \n"
908e5c31af7Sopenharmony_ci			   "{                                          \n"
909e5c31af7Sopenharmony_ci			   "    gl_FragDepth = 0.1;                    \n"
910e5c31af7Sopenharmony_ci			   "    gl_SampleMask[0] = 1;                  \n"
911e5c31af7Sopenharmony_ci			   "}";
912e5c31af7Sopenharmony_ci	}
913e5c31af7Sopenharmony_ci
914e5c31af7Sopenharmony_ci	virtual long Run()
915e5c31af7Sopenharmony_ci	{
916e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), true);
917e5c31af7Sopenharmony_ci
918e5c31af7Sopenharmony_ci		long error = NO_ERROR;
919e5c31af7Sopenharmony_ci
920e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 2, error);
921e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 17, error);
922e5c31af7Sopenharmony_ci
923e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
924e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_FragDepth", error);
925e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "gl_SampleMask[0]", error);
926e5c31af7Sopenharmony_ci
927e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], "gl_FragDepth", error);
928e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["gl_SampleMask[0]"], "gl_SampleMask[0]",
929e5c31af7Sopenharmony_ci									 error);
930e5c31af7Sopenharmony_ci
931e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
932e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_SampleMask", -1, error);
933e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "gl_SampleMask[0]", -1, error);
934e5c31af7Sopenharmony_ci
935e5c31af7Sopenharmony_ci		// spec is not clear what to require here
936e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "gl_FragDepth", -1, error);
937e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "gl_SampleMask", -1, error);
938e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "gl_SampleMask[0]", -1, error);
939e5c31af7Sopenharmony_ci
940e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
941e5c31af7Sopenharmony_ci						   GL_TYPE,
942e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
943e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
944e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
945e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
946e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
947e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
948e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
949e5c31af7Sopenharmony_ci						   GL_LOCATION,
950e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH,
951e5c31af7Sopenharmony_ci						   GL_LOCATION_INDEX };
952e5c31af7Sopenharmony_ci		GLint expected[] = { 13, GL_FLOAT, 1, 0, 1, 0, 0, 0, 0, -1, 0, -1 };
953e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_FragDepth"], 12, props, 12, expected, error);
954e5c31af7Sopenharmony_ci		GLint expected2[] = { 17, GL_INT, 1, 0, 1, 0, 0, 0, 0, -1, 0, -1 };
955e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["gl_SampleMask[0]"], 12, props, 12, expected2,
956e5c31af7Sopenharmony_ci								   error);
957e5c31af7Sopenharmony_ci
958e5c31af7Sopenharmony_ci		glDeleteProgram(program);
959e5c31af7Sopenharmony_ci		return error;
960e5c31af7Sopenharmony_ci	}
961e5c31af7Sopenharmony_ci};
962e5c31af7Sopenharmony_ci
963e5c31af7Sopenharmony_ciclass InputLayout : public SimpleShaders
964e5c31af7Sopenharmony_ci{
965e5c31af7Sopenharmony_ci	virtual std::string Title()
966e5c31af7Sopenharmony_ci	{
967e5c31af7Sopenharmony_ci		return "Input Layout Test";
968e5c31af7Sopenharmony_ci	}
969e5c31af7Sopenharmony_ci
970e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
971e5c31af7Sopenharmony_ci	{
972e5c31af7Sopenharmony_ci		return "vertex shader with different `in` variables locations set through layout and a fallthrough fragment "
973e5c31af7Sopenharmony_ci			   "shader";
974e5c31af7Sopenharmony_ci	}
975e5c31af7Sopenharmony_ci
976e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
977e5c31af7Sopenharmony_ci	{
978e5c31af7Sopenharmony_ci		return "#version 430                         \n"
979e5c31af7Sopenharmony_ci			   "layout(location = 4) in ivec4 b;     \n"
980e5c31af7Sopenharmony_ci			   "layout(location = 7) in mat2x3 d[2]; \n"
981e5c31af7Sopenharmony_ci			   "layout(location = 5) in float c[2];  \n"
982e5c31af7Sopenharmony_ci			   "layout(location = 12) in uint f;     \n"
983e5c31af7Sopenharmony_ci			   "layout(location = 13) in vec3 g[2];  \n"
984e5c31af7Sopenharmony_ci			   "layout(location = 0) in mat4 a;      \n"
985e5c31af7Sopenharmony_ci			   "layout(location = 15) in int h;      \n"
986e5c31af7Sopenharmony_ci			   "layout(location = 11) in uvec2 e;    \n"
987e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
988e5c31af7Sopenharmony_ci			   "{                                    \n"
989e5c31af7Sopenharmony_ci			   "   vec4 pos;                                           \n"
990e5c31af7Sopenharmony_ci			   "   pos.w = h + g[0].x + g[1].y + d[1][1].y;            \n"
991e5c31af7Sopenharmony_ci			   "   pos.y = b.x * c[0] + c[1] + d[0][0].x;              \n"
992e5c31af7Sopenharmony_ci			   "   pos.x = a[0].x + a[1].y + a[2].z + a[3].w;          \n"
993e5c31af7Sopenharmony_ci			   "   pos.z = d[0][1].z + e.x * f + d[1][0].z;            \n"
994e5c31af7Sopenharmony_ci			   "   gl_Position = pos;                                  \n"
995e5c31af7Sopenharmony_ci			   "}";
996e5c31af7Sopenharmony_ci	}
997e5c31af7Sopenharmony_ci
998e5c31af7Sopenharmony_ci	virtual long Run()
999e5c31af7Sopenharmony_ci	{
1000e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1001e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
1002e5c31af7Sopenharmony_ci		LinkProgram(program);
1003e5c31af7Sopenharmony_ci
1004e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1005e5c31af7Sopenharmony_ci
1006e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 8, error);
1007e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
1008e5c31af7Sopenharmony_ci
1009e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
1010e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "a", error);
1011e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "b", error);
1012e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "c[0]", error);
1013e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "d", error);
1014e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "e", error);
1015e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "f", error);
1016e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "g", error);
1017e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indices, "h", error);
1018e5c31af7Sopenharmony_ci
1019e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["a"], "a", error);
1020e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["b"], "b", error);
1021e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["c[0]"], "c[0]", error);
1022e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["d"], "d[0]", error);
1023e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["e"], "e", error);
1024e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["f"], "f", error);
1025e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["g"], "g[0]", error);
1026e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indices["h"], "h", error);
1027e5c31af7Sopenharmony_ci
1028e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "a", 0, error);
1029e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "b", 4, error);
1030e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[0]", 5, error);
1031e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c", 5, error);
1032e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "c[1]", 6, error);
1033e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d[0]", 7, error);
1034e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "d", 7, error);
1035e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "e", 11, error);
1036e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "f", 12, error);
1037e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[0]", 13, error);
1038e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g", 13, error);
1039e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "g[1]", 14, error);
1040e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "h", 15, error);
1041e5c31af7Sopenharmony_ci
1042e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
1043e5c31af7Sopenharmony_ci						   GL_TYPE,
1044e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
1045e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
1046e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
1047e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
1048e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1049e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1050e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
1051e5c31af7Sopenharmony_ci						   GL_LOCATION,
1052e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH };
1053e5c31af7Sopenharmony_ci		GLint expected[] = { 2, GL_FLOAT_MAT4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
1054e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["a"], 11, props, 11, expected, error);
1055e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, GL_INT_VEC4, 1, 0, 0, 0, 0, 0, 1, 4, 0 };
1056e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["b"], 11, props, 11, expected2, error);
1057e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, GL_FLOAT, 2, 0, 0, 0, 0, 0, 1, 5, 0 };
1058e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["c[0]"], 11, props, 11, expected3, error);
1059e5c31af7Sopenharmony_ci		GLint expected4[] = { 5, GL_FLOAT_MAT2x3, 2, 0, 0, 0, 0, 0, 1, 7, 0 };
1060e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["d"], 11, props, 11, expected4, error);
1061e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, GL_UNSIGNED_INT_VEC2, 1, 0, 0, 0, 0, 0, 1, 11, 0 };
1062e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["e"], 11, props, 11, expected5, error);
1063e5c31af7Sopenharmony_ci		GLint expected6[] = { 2, GL_UNSIGNED_INT, 1, 0, 0, 0, 0, 0, 1, 12, 0 };
1064e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["f"], 11, props, 11, expected6, error);
1065e5c31af7Sopenharmony_ci		GLint expected7[] = { 5, GL_FLOAT_VEC3, 2, 0, 0, 0, 0, 0, 1, 13, 0 };
1066e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["g"], 11, props, 11, expected7, error);
1067e5c31af7Sopenharmony_ci		GLint expected8[] = { 2, GL_INT, 1, 0, 0, 0, 0, 0, 1, 15, 0 };
1068e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indices["h"], 11, props, 11, expected8, error);
1069e5c31af7Sopenharmony_ci
1070e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1071e5c31af7Sopenharmony_ci		return error;
1072e5c31af7Sopenharmony_ci	}
1073e5c31af7Sopenharmony_ci};
1074e5c31af7Sopenharmony_ci
1075e5c31af7Sopenharmony_ciclass OutputLayout : public SimpleShaders
1076e5c31af7Sopenharmony_ci{
1077e5c31af7Sopenharmony_ci	virtual std::string Title()
1078e5c31af7Sopenharmony_ci	{
1079e5c31af7Sopenharmony_ci		return "Output Layout Test";
1080e5c31af7Sopenharmony_ci	}
1081e5c31af7Sopenharmony_ci
1082e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1083e5c31af7Sopenharmony_ci	{
1084e5c31af7Sopenharmony_ci		return "fragment shader with different `out` variables locations set through layout and a fallthrough vertex "
1085e5c31af7Sopenharmony_ci			   "shader";
1086e5c31af7Sopenharmony_ci	}
1087e5c31af7Sopenharmony_ci
1088e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1089e5c31af7Sopenharmony_ci	{
1090e5c31af7Sopenharmony_ci		return "#version 430                   \n"
1091e5c31af7Sopenharmony_ci			   "layout(location = 2) out uint b;                    \n"
1092e5c31af7Sopenharmony_ci			   "layout(location = 7) out vec2 e;                    \n"
1093e5c31af7Sopenharmony_ci			   "layout(location = 3) out float c[2];                \n"
1094e5c31af7Sopenharmony_ci			   "layout(location = 5) out int d[2];                  \n"
1095e5c31af7Sopenharmony_ci			   "layout(location = 0) out vec3 a[2];                 \n"
1096e5c31af7Sopenharmony_ci			   "void main() {                  \n"
1097e5c31af7Sopenharmony_ci			   "    c[1] = -0.6;               \n"
1098e5c31af7Sopenharmony_ci			   "    d[0] = 0;                  \n"
1099e5c31af7Sopenharmony_ci			   "    b = 12u;                   \n"
1100e5c31af7Sopenharmony_ci			   "    c[0] = 1.1;                \n"
1101e5c31af7Sopenharmony_ci			   "    e = vec2(0, 1);            \n"
1102e5c31af7Sopenharmony_ci			   "    d[1] = -19;                \n"
1103e5c31af7Sopenharmony_ci			   "    a[1] = vec3(0, 1, 0);      \n"
1104e5c31af7Sopenharmony_ci			   "    a[0] = vec3(0, 1, 0);      \n"
1105e5c31af7Sopenharmony_ci			   "}";
1106e5c31af7Sopenharmony_ci	}
1107e5c31af7Sopenharmony_ci
1108e5c31af7Sopenharmony_ci	virtual long Run()
1109e5c31af7Sopenharmony_ci	{
1110e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1111e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1112e5c31af7Sopenharmony_ci		LinkProgram(program);
1113e5c31af7Sopenharmony_ci
1114e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1115e5c31af7Sopenharmony_ci
1116e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
1117e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
1118e5c31af7Sopenharmony_ci
1119e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
1120e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "a", error);
1121e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "b", error);
1122e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "c[0]", error);
1123e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "d", error);
1124e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indices, "e", error);
1125e5c31af7Sopenharmony_ci
1126e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["a"], "a[0]", error);
1127e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["b"], "b", error);
1128e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["c[0]"], "c[0]", error);
1129e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["d"], "d[0]", error);
1130e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indices["e"], "e", error);
1131e5c31af7Sopenharmony_ci
1132e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
1133e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a", 0, error);
1134e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "a[1]", 1, error);
1135e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "b", 2, error);
1136e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[0]", 3, error);
1137e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c", 3, error);
1138e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "c[1]", 4, error);
1139e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[0]", 5, error);
1140e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d", 5, error);
1141e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "d[1]", 6, error);
1142e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "e", 7, error);
1143e5c31af7Sopenharmony_ci
1144e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a[0]", 0, error);
1145e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "a", 0, error);
1146e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "b", 0, error);
1147e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c[0]", 0, error);
1148e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "c", 0, error);
1149e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d[0]", 0, error);
1150e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "d", 0, error);
1151e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "e", 0, error);
1152e5c31af7Sopenharmony_ci
1153e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
1154e5c31af7Sopenharmony_ci						   GL_TYPE,
1155e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
1156e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
1157e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
1158e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
1159e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1160e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1161e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
1162e5c31af7Sopenharmony_ci						   GL_LOCATION,
1163e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH,
1164e5c31af7Sopenharmony_ci						   GL_LOCATION_INDEX };
1165e5c31af7Sopenharmony_ci		GLint expected[] = { 5, GL_FLOAT_VEC3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
1166e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["a"], 12, props, 12, expected, error);
1167e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, GL_UNSIGNED_INT, 1, 0, 1, 0, 0, 0, 0, 2, 0, 0 };
1168e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["b"], 12, props, 12, expected2, error);
1169e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, GL_FLOAT, 2, 0, 1, 0, 0, 0, 0, 3, 0, 0 };
1170e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["c[0]"], 12, props, 12, expected3, error);
1171e5c31af7Sopenharmony_ci		GLint expected4[] = { 5, GL_INT, 2, 0, 1, 0, 0, 0, 0, 5, 0, 0 };
1172e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["d"], 12, props, 12, expected4, error);
1173e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, GL_FLOAT_VEC2, 1, 0, 1, 0, 0, 0, 0, 7, 0, 0 };
1174e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indices["e"], 12, props, 12, expected5, error);
1175e5c31af7Sopenharmony_ci
1176e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1177e5c31af7Sopenharmony_ci		return error;
1178e5c31af7Sopenharmony_ci	}
1179e5c31af7Sopenharmony_ci};
1180e5c31af7Sopenharmony_ci
1181e5c31af7Sopenharmony_ciclass OutputLayoutIndex : public SimpleShaders
1182e5c31af7Sopenharmony_ci{
1183e5c31af7Sopenharmony_ci	virtual std::string Title()
1184e5c31af7Sopenharmony_ci	{
1185e5c31af7Sopenharmony_ci		return "Output Layout Index Test";
1186e5c31af7Sopenharmony_ci	}
1187e5c31af7Sopenharmony_ci
1188e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1189e5c31af7Sopenharmony_ci	{
1190e5c31af7Sopenharmony_ci		return "fragment shader with different `out` variables fragment color index\n"
1191e5c31af7Sopenharmony_ci			   "locations set through layout and a fallthrough vertex shader";
1192e5c31af7Sopenharmony_ci	}
1193e5c31af7Sopenharmony_ci
1194e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1195e5c31af7Sopenharmony_ci	{
1196e5c31af7Sopenharmony_ci		return "#version 430                   \n"
1197e5c31af7Sopenharmony_ci			   "layout(location = 0, index = 1) out vec4 color;                \n"
1198e5c31af7Sopenharmony_ci			   "void main() {                  \n"
1199e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1);  \n"
1200e5c31af7Sopenharmony_ci			   "}";
1201e5c31af7Sopenharmony_ci	}
1202e5c31af7Sopenharmony_ci
1203e5c31af7Sopenharmony_ci	virtual long Run()
1204e5c31af7Sopenharmony_ci	{
1205e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1206e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1207e5c31af7Sopenharmony_ci		LinkProgram(program);
1208e5c31af7Sopenharmony_ci
1209e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1210e5c31af7Sopenharmony_ci
1211e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
1212e5c31af7Sopenharmony_ci
1213e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 1, error);
1214e5c31af7Sopenharmony_ci
1215e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
1216e5c31af7Sopenharmony_ci						   GL_TYPE,
1217e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
1218e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
1219e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
1220e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
1221e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1222e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1223e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
1224e5c31af7Sopenharmony_ci						   GL_LOCATION,
1225e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH,
1226e5c31af7Sopenharmony_ci						   GL_LOCATION_INDEX };
1227e5c31af7Sopenharmony_ci		GLint expected[] = { 6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
1228e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props, 12, expected, error);
1229e5c31af7Sopenharmony_ci
1230e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1231e5c31af7Sopenharmony_ci		return error;
1232e5c31af7Sopenharmony_ci	}
1233e5c31af7Sopenharmony_ci};
1234e5c31af7Sopenharmony_ci
1235e5c31af7Sopenharmony_ciclass UniformSimple : public PIQBase
1236e5c31af7Sopenharmony_ci{
1237e5c31af7Sopenharmony_ci	virtual std::string Title()
1238e5c31af7Sopenharmony_ci	{
1239e5c31af7Sopenharmony_ci		return "Uniform Simple Test";
1240e5c31af7Sopenharmony_ci	}
1241e5c31af7Sopenharmony_ci
1242e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1243e5c31af7Sopenharmony_ci	{
1244e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with uniforms used";
1245e5c31af7Sopenharmony_ci	}
1246e5c31af7Sopenharmony_ci
1247e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1248e5c31af7Sopenharmony_ci	{
1249e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.";
1250e5c31af7Sopenharmony_ci	}
1251e5c31af7Sopenharmony_ci
1252e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1253e5c31af7Sopenharmony_ci	{
1254e5c31af7Sopenharmony_ci		return "#version 430                         \n"
1255e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
1256e5c31af7Sopenharmony_ci			   "uniform vec4 repos;                  \n"
1257e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
1258e5c31af7Sopenharmony_ci			   "{                                    \n"
1259e5c31af7Sopenharmony_ci			   "    gl_Position = position + repos;  \n"
1260e5c31af7Sopenharmony_ci			   "}";
1261e5c31af7Sopenharmony_ci	}
1262e5c31af7Sopenharmony_ci
1263e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1264e5c31af7Sopenharmony_ci	{
1265e5c31af7Sopenharmony_ci		return "#version 430                   \n"
1266e5c31af7Sopenharmony_ci			   "uniform vec4 recolor;          \n"
1267e5c31af7Sopenharmony_ci			   "out vec4 color;                \n"
1268e5c31af7Sopenharmony_ci			   "void main() {                  \n"
1269e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1) + recolor;  \n"
1270e5c31af7Sopenharmony_ci			   "}";
1271e5c31af7Sopenharmony_ci	}
1272e5c31af7Sopenharmony_ci
1273e5c31af7Sopenharmony_ci	virtual long Run()
1274e5c31af7Sopenharmony_ci	{
1275e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1276e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1277e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
1278e5c31af7Sopenharmony_ci		LinkProgram(program);
1279e5c31af7Sopenharmony_ci
1280e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1281e5c31af7Sopenharmony_ci
1282e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1283e5c31af7Sopenharmony_ci									GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1284e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 8, error);
1285e5c31af7Sopenharmony_ci
1286e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
1287e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "repos", error);
1288e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "recolor", error);
1289e5c31af7Sopenharmony_ci
1290e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["repos"], "repos", error);
1291e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["recolor"], "recolor", error);
1292e5c31af7Sopenharmony_ci
1293e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "repos", glGetUniformLocation(program, "repos"), error);
1294e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "recolor", glGetUniformLocation(program, "recolor"),
1295e5c31af7Sopenharmony_ci										 error);
1296e5c31af7Sopenharmony_ci
1297e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
1298e5c31af7Sopenharmony_ci						   GL_TYPE,
1299e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
1300e5c31af7Sopenharmony_ci						   GL_OFFSET,
1301e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
1302e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
1303e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
1304e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
1305e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
1306e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
1307e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
1308e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
1309e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1310e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1311e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
1312e5c31af7Sopenharmony_ci						   GL_LOCATION };
1313e5c31af7Sopenharmony_ci		GLint expected[] = {
1314e5c31af7Sopenharmony_ci			6, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "repos")
1315e5c31af7Sopenharmony_ci		};
1316e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["repos"], 16, props, 16, expected, error);
1317e5c31af7Sopenharmony_ci
1318e5c31af7Sopenharmony_ci		GLint expected2[] = {
1319e5c31af7Sopenharmony_ci			8, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "recolor")
1320e5c31af7Sopenharmony_ci		};
1321e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["recolor"], 16, props, 16, expected2, error);
1322e5c31af7Sopenharmony_ci
1323e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1324e5c31af7Sopenharmony_ci		return error;
1325e5c31af7Sopenharmony_ci	}
1326e5c31af7Sopenharmony_ci};
1327e5c31af7Sopenharmony_ci
1328e5c31af7Sopenharmony_ciclass UniformTypes : public PIQBase
1329e5c31af7Sopenharmony_ci{
1330e5c31af7Sopenharmony_ci	virtual std::string Title()
1331e5c31af7Sopenharmony_ci	{
1332e5c31af7Sopenharmony_ci		return "Uniform Types Test";
1333e5c31af7Sopenharmony_ci	}
1334e5c31af7Sopenharmony_ci
1335e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1336e5c31af7Sopenharmony_ci	{
1337e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different uniform types used";
1338e5c31af7Sopenharmony_ci	}
1339e5c31af7Sopenharmony_ci
1340e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1341e5c31af7Sopenharmony_ci	{
1342e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_UNIFORM as an interface param.\n";
1343e5c31af7Sopenharmony_ci	}
1344e5c31af7Sopenharmony_ci
1345e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1346e5c31af7Sopenharmony_ci	{
1347e5c31af7Sopenharmony_ci		return "#version 430                         \n"
1348e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
1349e5c31af7Sopenharmony_ci			   "uniform vec4 a;                      \n"
1350e5c31af7Sopenharmony_ci			   "uniform ivec3 b;                     \n"
1351e5c31af7Sopenharmony_ci			   "uniform uvec2 c[3];                  \n"
1352e5c31af7Sopenharmony_ci			   "uniform mat2 g[8];                   \n"
1353e5c31af7Sopenharmony_ci			   "uniform mat3x2 i;                    \n"
1354e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
1355e5c31af7Sopenharmony_ci			   "{                                    \n"
1356e5c31af7Sopenharmony_ci			   "    float tmp;                       \n"
1357e5c31af7Sopenharmony_ci			   "    tmp =  g[0][1][1] + a.z + b.y + c[0].x;   \n"
1358e5c31af7Sopenharmony_ci			   "    tmp += g[1][1][1] + c[1].x;      \n"
1359e5c31af7Sopenharmony_ci			   "    tmp += g[2][1][1] + c[2].x;      \n"
1360e5c31af7Sopenharmony_ci			   "    for (int i = 3; i < 8; ++i)      \n"
1361e5c31af7Sopenharmony_ci			   "        tmp += g[i][1][1];           \n"
1362e5c31af7Sopenharmony_ci			   "    tmp = tmp + i[1][1];             \n"
1363e5c31af7Sopenharmony_ci			   "    gl_Position = position * tmp;    \n"
1364e5c31af7Sopenharmony_ci			   "}";
1365e5c31af7Sopenharmony_ci	}
1366e5c31af7Sopenharmony_ci
1367e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1368e5c31af7Sopenharmony_ci	{
1369e5c31af7Sopenharmony_ci		return "#version 430                   \n"
1370e5c31af7Sopenharmony_ci			   "struct U {                     \n"
1371e5c31af7Sopenharmony_ci			   "   bool a[3];                  \n"
1372e5c31af7Sopenharmony_ci			   "   vec4 b;                     \n"
1373e5c31af7Sopenharmony_ci			   "   mat3 c;                     \n"
1374e5c31af7Sopenharmony_ci			   "   float d[2];                 \n"
1375e5c31af7Sopenharmony_ci			   "};                             \n"
1376e5c31af7Sopenharmony_ci			   "struct UU {                    \n"
1377e5c31af7Sopenharmony_ci			   "   U a;                        \n"
1378e5c31af7Sopenharmony_ci			   "   U b[2];                     \n"
1379e5c31af7Sopenharmony_ci			   "   uvec2 c;                    \n"
1380e5c31af7Sopenharmony_ci			   "};                             \n"
1381e5c31af7Sopenharmony_ci			   "uniform mat4 d;                \n"
1382e5c31af7Sopenharmony_ci			   "uniform mat3 e;                \n"
1383e5c31af7Sopenharmony_ci			   "uniform float h;               \n"
1384e5c31af7Sopenharmony_ci			   "uniform int f;                 \n"
1385e5c31af7Sopenharmony_ci			   "uniform U j;                   \n"
1386e5c31af7Sopenharmony_ci			   "uniform UU k;                  \n"
1387e5c31af7Sopenharmony_ci			   "uniform UU l[3];               \n"
1388e5c31af7Sopenharmony_ci			   "out vec4 color;                \n"
1389e5c31af7Sopenharmony_ci			   "void main() {                  \n"
1390e5c31af7Sopenharmony_ci			   "    float tmp;                 \n"
1391e5c31af7Sopenharmony_ci			   "    tmp = h + f + e[2][2];           \n"
1392e5c31af7Sopenharmony_ci			   "    tmp = tmp + d[0][0] + j.b.x;     \n"
1393e5c31af7Sopenharmony_ci			   "    tmp = tmp + k.b[0].c[0][0];      \n"
1394e5c31af7Sopenharmony_ci			   "    tmp = tmp + l[2].a.c[0][1];      \n"
1395e5c31af7Sopenharmony_ci			   "    tmp = tmp + l[2].b[1].d[0];      \n"
1396e5c31af7Sopenharmony_ci			   "    tmp = tmp + l[2].b[1].d[1];      \n"
1397e5c31af7Sopenharmony_ci			   "    tmp = tmp + l[0].c.x;            \n"
1398e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1) * tmp;  \n"
1399e5c31af7Sopenharmony_ci			   "}";
1400e5c31af7Sopenharmony_ci	}
1401e5c31af7Sopenharmony_ci
1402e5c31af7Sopenharmony_ci	virtual long Run()
1403e5c31af7Sopenharmony_ci	{
1404e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1405e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1406e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
1407e5c31af7Sopenharmony_ci		LinkProgram(program);
1408e5c31af7Sopenharmony_ci
1409e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1410e5c31af7Sopenharmony_ci
1411e5c31af7Sopenharmony_ci		// only active structure members
1412e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1413e5c31af7Sopenharmony_ci									GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1414e5c31af7Sopenharmony_ci		// l[2].b[1].d[0] and \0
1415e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 15, error);
1416e5c31af7Sopenharmony_ci
1417e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
1418e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a", error);
1419e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "b", error);
1420e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "c", error);
1421e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "d", error);
1422e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "e", error);
1423e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "f", error);
1424e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "g", error);
1425e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "h", error);
1426e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "i", error);
1427e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "j.b", error);
1428e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "k.b[0].c", error);
1429e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[0].c", error);
1430e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].b[1].d[0]", error);
1431e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "l[2].a.c", error);
1432e5c31af7Sopenharmony_ci
1433e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a"], "a", error);
1434e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["b"], "b", error);
1435e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["c"], "c[0]", error);
1436e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["d"], "d", error);
1437e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["e"], "e", error);
1438e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["f"], "f", error);
1439e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["g"], "g[0]", error);
1440e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["h"], "h", error);
1441e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["i"], "i", error);
1442e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["j.b"], "j.b", error);
1443e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["k.b[0].c"], "k.b[0].c", error);
1444e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[0].c"], "l[0].c", error);
1445e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], "l[2].b[1].d[0]", error);
1446e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["l[2].a.c"], "l[2].a.c", error);
1447e5c31af7Sopenharmony_ci
1448e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
1449e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", glGetUniformLocation(program, "b"), error);
1450e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", glGetUniformLocation(program, "c"), error);
1451e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", glGetUniformLocation(program, "d"), error);
1452e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", glGetUniformLocation(program, "e"), error);
1453e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "f", glGetUniformLocation(program, "f"), error);
1454e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "g", glGetUniformLocation(program, "g"), error);
1455e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "h", glGetUniformLocation(program, "h"), error);
1456e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "i", glGetUniformLocation(program, "i"), error);
1457e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "j.b", glGetUniformLocation(program, "j.b"), error);
1458e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "k.b[0].c", glGetUniformLocation(program, "k.b[0].c"),
1459e5c31af7Sopenharmony_ci										 error);
1460e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[0].c", glGetUniformLocation(program, "l[0].c"), error);
1461e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].b[1].d[0]",
1462e5c31af7Sopenharmony_ci										 glGetUniformLocation(program, "l[2].b[1].d[0]"), error);
1463e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "l[2].a.c", glGetUniformLocation(program, "l[2].a.c"),
1464e5c31af7Sopenharmony_ci										 error);
1465e5c31af7Sopenharmony_ci
1466e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
1467e5c31af7Sopenharmony_ci						   GL_TYPE,
1468e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
1469e5c31af7Sopenharmony_ci						   GL_OFFSET,
1470e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
1471e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
1472e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
1473e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
1474e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
1475e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
1476e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
1477e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
1478e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1479e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1480e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
1481e5c31af7Sopenharmony_ci						   GL_LOCATION };
1482e5c31af7Sopenharmony_ci		GLint expected[] = {
1483e5c31af7Sopenharmony_ci			2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "a")
1484e5c31af7Sopenharmony_ci		};
1485e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a"], 16, props, 16, expected, error);
1486e5c31af7Sopenharmony_ci		GLint expected2[] = { 2,  GL_INT_VEC3, 1, -1, -1, -1, -1, 0,
1487e5c31af7Sopenharmony_ci							  -1, 0,		   0, 0,  0,  0,  1,  glGetUniformLocation(program, "b") };
1488e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["b"], 16, props, 16, expected2, error);
1489e5c31af7Sopenharmony_ci		GLint expected3[] = {
1490e5c31af7Sopenharmony_ci			5, GL_UNSIGNED_INT_VEC2, 3, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "c")
1491e5c31af7Sopenharmony_ci		};
1492e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["c"], 16, props, 16, expected3, error);
1493e5c31af7Sopenharmony_ci		GLint expected4[] = {
1494e5c31af7Sopenharmony_ci			2, GL_FLOAT_MAT4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "d")
1495e5c31af7Sopenharmony_ci		};
1496e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["d"], 16, props, 16, expected4, error);
1497e5c31af7Sopenharmony_ci		GLint expected5[] = {
1498e5c31af7Sopenharmony_ci			2, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "e")
1499e5c31af7Sopenharmony_ci		};
1500e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["e"], 16, props, 16, expected5, error);
1501e5c31af7Sopenharmony_ci		GLint expected6[] = {
1502e5c31af7Sopenharmony_ci			2, GL_INT, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "f")
1503e5c31af7Sopenharmony_ci		};
1504e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["f"], 16, props, 16, expected6, error);
1505e5c31af7Sopenharmony_ci		GLint expected7[] = {
1506e5c31af7Sopenharmony_ci			5, GL_FLOAT_MAT2, 8, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "g")
1507e5c31af7Sopenharmony_ci		};
1508e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["g"], 16, props, 16, expected7, error);
1509e5c31af7Sopenharmony_ci		GLint expected8[] = { 2,  GL_FLOAT, 1, -1, -1, -1, -1, 0,
1510e5c31af7Sopenharmony_ci							  -1, 0,		1, 0,  0,  0,  0,  glGetUniformLocation(program, "h") };
1511e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["h"], 16, props, 16, expected8, error);
1512e5c31af7Sopenharmony_ci		GLint expected9[] = {
1513e5c31af7Sopenharmony_ci			2, GL_FLOAT_MAT3x2, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "i")
1514e5c31af7Sopenharmony_ci		};
1515e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["i"], 16, props, 16, expected9, error);
1516e5c31af7Sopenharmony_ci		GLint expected10[] = {
1517e5c31af7Sopenharmony_ci			4, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "j.b")
1518e5c31af7Sopenharmony_ci		};
1519e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["j.b"], 16, props, 16, expected10, error);
1520e5c31af7Sopenharmony_ci		GLint expected11[] = {
1521e5c31af7Sopenharmony_ci			9, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "k.b[0].c")
1522e5c31af7Sopenharmony_ci		};
1523e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["k.b[0].c"], 16, props, 16, expected11, error);
1524e5c31af7Sopenharmony_ci		GLint expected12[] = { 7,  GL_UNSIGNED_INT_VEC2,
1525e5c31af7Sopenharmony_ci							   1,  -1,
1526e5c31af7Sopenharmony_ci							   -1, -1,
1527e5c31af7Sopenharmony_ci							   -1, 0,
1528e5c31af7Sopenharmony_ci							   -1, 0,
1529e5c31af7Sopenharmony_ci							   1,  0,
1530e5c31af7Sopenharmony_ci							   0,  0,
1531e5c31af7Sopenharmony_ci							   0,  glGetUniformLocation(program, "l[0].c") };
1532e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[0].c"], 16, props, 16, expected12, error);
1533e5c31af7Sopenharmony_ci		GLint expected13[] = { 15, GL_FLOAT, 2, -1, -1, -1, -1, 0,
1534e5c31af7Sopenharmony_ci							   -1, 0,		 1, 0,  0,  0,  0,  glGetUniformLocation(program, "l[2].b[1].d[0]") };
1535e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].b[1].d[0]"], 16, props, 16, expected13, error);
1536e5c31af7Sopenharmony_ci		GLint expected14[] = {
1537e5c31af7Sopenharmony_ci			9, GL_FLOAT_MAT3, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 0, 0, 0, glGetUniformLocation(program, "l[2].a.c")
1538e5c31af7Sopenharmony_ci		};
1539e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["l[2].a.c"], 16, props, 16, expected14, error);
1540e5c31af7Sopenharmony_ci
1541e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1542e5c31af7Sopenharmony_ci		return error;
1543e5c31af7Sopenharmony_ci	}
1544e5c31af7Sopenharmony_ci};
1545e5c31af7Sopenharmony_ci
1546e5c31af7Sopenharmony_ciclass UniformBlockTypes : public PIQBase
1547e5c31af7Sopenharmony_ci{
1548e5c31af7Sopenharmony_ci	virtual std::string Title()
1549e5c31af7Sopenharmony_ci	{
1550e5c31af7Sopenharmony_ci		return "Uniform Block Types Test";
1551e5c31af7Sopenharmony_ci	}
1552e5c31af7Sopenharmony_ci
1553e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1554e5c31af7Sopenharmony_ci	{
1555e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
1556e5c31af7Sopenharmony_ci	}
1557e5c31af7Sopenharmony_ci
1558e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1559e5c31af7Sopenharmony_ci	{
1560e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param.\n";
1561e5c31af7Sopenharmony_ci	}
1562e5c31af7Sopenharmony_ci
1563e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1564e5c31af7Sopenharmony_ci	{
1565e5c31af7Sopenharmony_ci		return "#version 430                         \n"
1566e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
1567e5c31af7Sopenharmony_ci			   ""
1568e5c31af7Sopenharmony_ci			   "uniform SimpleBlock {                \n"
1569e5c31af7Sopenharmony_ci			   "   mat3x2 a;                         \n"
1570e5c31af7Sopenharmony_ci			   "   mat4 b;                           \n"
1571e5c31af7Sopenharmony_ci			   "   vec4 c;                           \n"
1572e5c31af7Sopenharmony_ci			   "};                                   \n"
1573e5c31af7Sopenharmony_ci			   ""
1574e5c31af7Sopenharmony_ci			   "uniform NotSoSimpleBlockk {          \n"
1575e5c31af7Sopenharmony_ci			   "   ivec2 a[4];                       \n"
1576e5c31af7Sopenharmony_ci			   "   mat3 b[2];                        \n"
1577e5c31af7Sopenharmony_ci			   "   mat2 c;                           \n"
1578e5c31af7Sopenharmony_ci			   "} d;                                 \n"
1579e5c31af7Sopenharmony_ci			   ""
1580e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
1581e5c31af7Sopenharmony_ci			   "{                                    \n"
1582e5c31af7Sopenharmony_ci			   "    float tmp;                       \n"
1583e5c31af7Sopenharmony_ci			   "    tmp =  a[0][1] * b[1][2] * c.x;  \n"
1584e5c31af7Sopenharmony_ci			   "    tmp = tmp + d.a[2].y + d.b[0][1][1] + d.c[1][1];             \n"
1585e5c31af7Sopenharmony_ci			   "    gl_Position = position * tmp;    \n"
1586e5c31af7Sopenharmony_ci			   "}";
1587e5c31af7Sopenharmony_ci	}
1588e5c31af7Sopenharmony_ci
1589e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1590e5c31af7Sopenharmony_ci	{
1591e5c31af7Sopenharmony_ci		return "#version 430                   \n"
1592e5c31af7Sopenharmony_ci			   "struct U {                     \n"
1593e5c31af7Sopenharmony_ci			   "   bool a[3];                  \n"
1594e5c31af7Sopenharmony_ci			   "   vec4 b;                     \n"
1595e5c31af7Sopenharmony_ci			   "   mat3 c;                     \n"
1596e5c31af7Sopenharmony_ci			   "   float d[2];                 \n"
1597e5c31af7Sopenharmony_ci			   "};                             \n"
1598e5c31af7Sopenharmony_ci			   "struct UU {                    \n"
1599e5c31af7Sopenharmony_ci			   "   U a;                        \n"
1600e5c31af7Sopenharmony_ci			   "   U b[2];                     \n"
1601e5c31af7Sopenharmony_ci			   "   uvec2 c;                    \n"
1602e5c31af7Sopenharmony_ci			   "};                             \n"
1603e5c31af7Sopenharmony_ci			   ""
1604e5c31af7Sopenharmony_ci			   "uniform TrickyBlock {                            \n"
1605e5c31af7Sopenharmony_ci			   "   UU a[3];                                      \n"
1606e5c31af7Sopenharmony_ci			   "   mat4 b;                                       \n"
1607e5c31af7Sopenharmony_ci			   "   uint c;                                       \n"
1608e5c31af7Sopenharmony_ci			   "} e[2];                                          \n"
1609e5c31af7Sopenharmony_ci			   ""
1610e5c31af7Sopenharmony_ci			   "out vec4 color;                                \n"
1611e5c31af7Sopenharmony_ci			   "void main() {                                  \n"
1612e5c31af7Sopenharmony_ci			   "    float tmp;                                 \n"
1613e5c31af7Sopenharmony_ci			   "    tmp = e[0].a[2].b[0].d[1];                 \n"
1614e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1) * tmp;            \n"
1615e5c31af7Sopenharmony_ci			   "}";
1616e5c31af7Sopenharmony_ci	}
1617e5c31af7Sopenharmony_ci
1618e5c31af7Sopenharmony_ci	virtual long Run()
1619e5c31af7Sopenharmony_ci	{
1620e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1621e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1622e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
1623e5c31af7Sopenharmony_ci		LinkProgram(program);
1624e5c31af7Sopenharmony_ci
1625e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1626e5c31af7Sopenharmony_ci
1627e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES,
1628e5c31af7Sopenharmony_ci									GetProgramivRetValue(program, GL_ACTIVE_UNIFORMS), error);
1629e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
1630e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
1631e5c31af7Sopenharmony_ci
1632e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesUB;
1633e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
1634e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "SimpleBlock", error);
1635e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "NotSoSimpleBlockk", error);
1636e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock", error);
1637e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TrickyBlock[1]", error);
1638e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1639e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1640e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1641e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.a[0]", error);
1642e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.c", error);
1643e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "NotSoSimpleBlockk.b[0]", error);
1644e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TrickyBlock.a[2].b[0].d", error);
1645e5c31af7Sopenharmony_ci
1646e5c31af7Sopenharmony_ci		glUniformBlockBinding(program, indicesUB["SimpleBlock"], 0);
1647e5c31af7Sopenharmony_ci		glUniformBlockBinding(program, indicesUB["NotSoSimpleBlockk"], 2);
1648e5c31af7Sopenharmony_ci		glUniformBlockBinding(program, indicesUB["TrickyBlock"], 3);
1649e5c31af7Sopenharmony_ci		glUniformBlockBinding(program, indicesUB["TrickyBlock[1]"], 4);
1650e5c31af7Sopenharmony_ci
1651e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], "SimpleBlock", error);
1652e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], "NotSoSimpleBlockk",
1653e5c31af7Sopenharmony_ci									 error);
1654e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], "TrickyBlock[0]", error);
1655e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], "TrickyBlock[1]", error);
1656e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1657e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1658e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1659e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.a[0]"], "NotSoSimpleBlockk.a[0]",
1660e5c31af7Sopenharmony_ci									 error);
1661e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.c"], "NotSoSimpleBlockk.c",
1662e5c31af7Sopenharmony_ci									 error);
1663e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["NotSoSimpleBlockk.b[0]"], "NotSoSimpleBlockk.b[0]",
1664e5c31af7Sopenharmony_ci									 error);
1665e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"],
1666e5c31af7Sopenharmony_ci									 "TrickyBlock.a[2].b[0].d[0]", error);
1667e5c31af7Sopenharmony_ci
1668e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1669e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1670e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1671e5c31af7Sopenharmony_ci
1672e5c31af7Sopenharmony_ci		GLenum props[] = {
1673e5c31af7Sopenharmony_ci			GL_NAME_LENGTH,
1674e5c31af7Sopenharmony_ci			GL_BUFFER_BINDING,
1675e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_COMPUTE_SHADER,
1676e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_FRAGMENT_SHADER,
1677e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_GEOMETRY_SHADER,
1678e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1679e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1680e5c31af7Sopenharmony_ci			GL_REFERENCED_BY_VERTEX_SHADER,
1681e5c31af7Sopenharmony_ci			GL_BUFFER_DATA_SIZE,
1682e5c31af7Sopenharmony_ci		};
1683e5c31af7Sopenharmony_ci		GLint size;
1684e5c31af7Sopenharmony_ci		glGetActiveUniformBlockiv(program, indicesUB["SimpleBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1685e5c31af7Sopenharmony_ci		GLint expected[] = { 12, 0, 0, 0, 0, 0, 0, 1, size };
1686e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 9, props, 9, expected, error);
1687e5c31af7Sopenharmony_ci		glGetActiveUniformBlockiv(program, indicesUB["NotSoSimpleBlockk"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1688e5c31af7Sopenharmony_ci		GLint expected2[] = { 18, 2, 0, 0, 0, 0, 0, 1, size };
1689e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 9, props, 9, expected2,
1690e5c31af7Sopenharmony_ci								   error);
1691e5c31af7Sopenharmony_ci		glGetActiveUniformBlockiv(program, indicesUB["TrickyBlock"], GL_UNIFORM_BLOCK_DATA_SIZE, &size);
1692e5c31af7Sopenharmony_ci		GLint expected3[] = { 15, 3, 0, 1, 0, 0, 0, 0, size };
1693e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock"], 9, props, 9, expected3, error);
1694e5c31af7Sopenharmony_ci		GLint expected4[] = { 15, 4, 0, 0, 0, 0, 0, 0, size };
1695e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["TrickyBlock[1]"], 9, props, 9, expected4,
1696e5c31af7Sopenharmony_ci								   error);
1697e5c31af7Sopenharmony_ci
1698e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
1699e5c31af7Sopenharmony_ci							GL_TYPE,
1700e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
1701e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
1702e5c31af7Sopenharmony_ci							GL_ARRAY_STRIDE,
1703e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
1704e5c31af7Sopenharmony_ci							GL_ATOMIC_COUNTER_BUFFER_INDEX,
1705e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
1706e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
1707e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
1708e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1709e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1710e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
1711e5c31af7Sopenharmony_ci							GL_LOCATION };
1712e5c31af7Sopenharmony_ci		GLint expected5[] = {
1713e5c31af7Sopenharmony_ci			2, GL_FLOAT_MAT3x2, 1, static_cast<GLint>(indicesUB["SimpleBlock"]), 0, 0, -1, 0, 0, 0, 0, 0, 1, -1
1714e5c31af7Sopenharmony_ci		};
1715e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 14, props2, 14, expected5, error);
1716e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
1717e5c31af7Sopenharmony_ci							GL_TYPE,
1718e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
1719e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
1720e5c31af7Sopenharmony_ci							GL_MATRIX_STRIDE,
1721e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
1722e5c31af7Sopenharmony_ci							GL_ATOMIC_COUNTER_BUFFER_INDEX,
1723e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
1724e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
1725e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
1726e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
1727e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
1728e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
1729e5c31af7Sopenharmony_ci							GL_LOCATION };
1730e5c31af7Sopenharmony_ci		GLint expected6[] = { 27, GL_FLOAT, 2, static_cast<GLint>(indicesUB["TrickyBlock"]), 0, 0, -1, 0, 1, 0, 0,
1731e5c31af7Sopenharmony_ci							  0,  0,		-1 };
1732e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TrickyBlock.a[2].b[0].d"], 14, props3, 14, expected6,
1733e5c31af7Sopenharmony_ci								   error);
1734e5c31af7Sopenharmony_ci
1735e5c31af7Sopenharmony_ci		GLenum			 prop	= GL_ACTIVE_VARIABLES;
1736e5c31af7Sopenharmony_ci		const GLsizei	bufSize = 1000;
1737e5c31af7Sopenharmony_ci		GLsizei			 length;
1738e5c31af7Sopenharmony_ci		GLint			 param[bufSize];
1739e5c31af7Sopenharmony_ci		std::set<GLuint> exp;
1740e5c31af7Sopenharmony_ci		exp.insert(indicesU["a"]);
1741e5c31af7Sopenharmony_ci		exp.insert(indicesU["b"]);
1742e5c31af7Sopenharmony_ci		exp.insert(indicesU["c"]);
1743e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["SimpleBlock"], 1, &prop, bufSize, &length, param);
1744e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
1745e5c31af7Sopenharmony_ci		{
1746e5c31af7Sopenharmony_ci			if (exp.find(param[i]) == exp.end())
1747e5c31af7Sopenharmony_ci			{
1748e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1749e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1750e5c31af7Sopenharmony_ci					<< "Unexpected index found in active variables of SimpleBlock: " << param[i]
1751e5c31af7Sopenharmony_ci					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1752e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
1753e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1754e5c31af7Sopenharmony_ci				return ERROR;
1755e5c31af7Sopenharmony_ci			}
1756e5c31af7Sopenharmony_ci			else if (length != 3)
1757e5c31af7Sopenharmony_ci			{
1758e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1759e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1760e5c31af7Sopenharmony_ci					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK\n"
1761e5c31af7Sopenharmony_ci					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1762e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1763e5c31af7Sopenharmony_ci				return ERROR;
1764e5c31af7Sopenharmony_ci			}
1765e5c31af7Sopenharmony_ci		}
1766e5c31af7Sopenharmony_ci		std::set<GLuint> exp2;
1767e5c31af7Sopenharmony_ci		exp2.insert(indicesU["NotSoSimpleBlockk.a[0]"]);
1768e5c31af7Sopenharmony_ci		exp2.insert(indicesU["NotSoSimpleBlockk.b[0]"]);
1769e5c31af7Sopenharmony_ci		exp2.insert(indicesU["NotSoSimpleBlockk.c"]);
1770e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, indicesUB["NotSoSimpleBlockk"], 1, &prop, bufSize, &length,
1771e5c31af7Sopenharmony_ci							   param);
1772e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
1773e5c31af7Sopenharmony_ci		{
1774e5c31af7Sopenharmony_ci			if (exp2.find(param[i]) == exp2.end())
1775e5c31af7Sopenharmony_ci			{
1776e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1777e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1778e5c31af7Sopenharmony_ci					<< "Unexpected index found in active variables of NotSoSimpleBlockk: " << param[i]
1779e5c31af7Sopenharmony_ci					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1780e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
1781e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1782e5c31af7Sopenharmony_ci				return ERROR;
1783e5c31af7Sopenharmony_ci			}
1784e5c31af7Sopenharmony_ci			else if (length != 3)
1785e5c31af7Sopenharmony_ci			{
1786e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
1787e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
1788e5c31af7Sopenharmony_ci					<< "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: GL_UNIFORM_BLOCK"
1789e5c31af7Sopenharmony_ci					<< "\nExpected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
1790e5c31af7Sopenharmony_ci				glDeleteProgram(program);
1791e5c31af7Sopenharmony_ci				return ERROR;
1792e5c31af7Sopenharmony_ci			}
1793e5c31af7Sopenharmony_ci		}
1794e5c31af7Sopenharmony_ci
1795e5c31af7Sopenharmony_ci		GLint res;
1796e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
1797e5c31af7Sopenharmony_ci		if (res < 3)
1798e5c31af7Sopenharmony_ci		{
1799e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
1800e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!"
1801e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
1802e5c31af7Sopenharmony_ci			glDeleteProgram(program);
1803e5c31af7Sopenharmony_ci			return ERROR;
1804e5c31af7Sopenharmony_ci		}
1805e5c31af7Sopenharmony_ci
1806e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1807e5c31af7Sopenharmony_ci		return error;
1808e5c31af7Sopenharmony_ci	}
1809e5c31af7Sopenharmony_ci};
1810e5c31af7Sopenharmony_ci
1811e5c31af7Sopenharmony_ciclass TransformFeedbackTypes : public SimpleShaders
1812e5c31af7Sopenharmony_ci{
1813e5c31af7Sopenharmony_ci	virtual std::string Title()
1814e5c31af7Sopenharmony_ci	{
1815e5c31af7Sopenharmony_ci		return "Transform Feedback Varying Types";
1816e5c31af7Sopenharmony_ci	}
1817e5c31af7Sopenharmony_ci
1818e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1819e5c31af7Sopenharmony_ci	{
1820e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different types of out variables used";
1821e5c31af7Sopenharmony_ci	}
1822e5c31af7Sopenharmony_ci
1823e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1824e5c31af7Sopenharmony_ci	{
1825e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param.\n";
1826e5c31af7Sopenharmony_ci	}
1827e5c31af7Sopenharmony_ci
1828e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
1829e5c31af7Sopenharmony_ci	{
1830e5c31af7Sopenharmony_ci		return "#version 430                         \n"
1831e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
1832e5c31af7Sopenharmony_ci			   ""
1833e5c31af7Sopenharmony_ci			   "flat out ivec4 a;                    \n"
1834e5c31af7Sopenharmony_ci			   "out float b[2];                      \n"
1835e5c31af7Sopenharmony_ci			   "flat out uvec2 c;                    \n"
1836e5c31af7Sopenharmony_ci			   "flat out uint d;                     \n"
1837e5c31af7Sopenharmony_ci			   "out vec3 e[2];                       \n"
1838e5c31af7Sopenharmony_ci			   "flat out int f;                      \n"
1839e5c31af7Sopenharmony_ci			   ""
1840e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
1841e5c31af7Sopenharmony_ci			   "{                                    \n"
1842e5c31af7Sopenharmony_ci			   "   vec4 pos;                         \n"
1843e5c31af7Sopenharmony_ci			   "   a = ivec4(1);                     \n"
1844e5c31af7Sopenharmony_ci			   "   b[0] = 1.1;                       \n"
1845e5c31af7Sopenharmony_ci			   "   b[1] = 1.1;                       \n"
1846e5c31af7Sopenharmony_ci			   "   c = uvec2(1u);                    \n"
1847e5c31af7Sopenharmony_ci			   "   d = 1u;                           \n"
1848e5c31af7Sopenharmony_ci			   "   e[0] = vec3(1.1);                 \n"
1849e5c31af7Sopenharmony_ci			   "   e[1] = vec3(1.1);                 \n"
1850e5c31af7Sopenharmony_ci			   "   f = 1;                            \n"
1851e5c31af7Sopenharmony_ci			   "   gl_Position = position;           \n"
1852e5c31af7Sopenharmony_ci			   "}";
1853e5c31af7Sopenharmony_ci	}
1854e5c31af7Sopenharmony_ci
1855e5c31af7Sopenharmony_ci	virtual long Run()
1856e5c31af7Sopenharmony_ci	{
1857e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1858e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1859e5c31af7Sopenharmony_ci		const char* varyings[6] = { "a", "b[0]", "b[1]", "c", "d", "e" };
1860e5c31af7Sopenharmony_ci		glTransformFeedbackVaryings(program, 6, varyings, GL_INTERLEAVED_ATTRIBS);
1861e5c31af7Sopenharmony_ci		LinkProgram(program);
1862e5c31af7Sopenharmony_ci
1863e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1864e5c31af7Sopenharmony_ci
1865e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 6, error);
1866e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 5, error);
1867e5c31af7Sopenharmony_ci
1868e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
1869e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "a", error);
1870e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[0]", error);
1871e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "b[1]", error);
1872e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "c", error);
1873e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "d", error);
1874e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, indices, "e", error);
1875e5c31af7Sopenharmony_ci
1876e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], "a", error);
1877e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], "b[0]", error);
1878e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], "b[1]", error);
1879e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], "c", error);
1880e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], "d", error);
1881e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], "e", error);
1882e5c31af7Sopenharmony_ci
1883e5c31af7Sopenharmony_ci		GLenum props[]	= { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
1884e5c31af7Sopenharmony_ci		GLint  expected[] = { 2, GL_INT_VEC4, 1 };
1885e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["a"], 3, props, 3, expected, error);
1886e5c31af7Sopenharmony_ci		GLint expected2[] = { 5, GL_FLOAT, 1 };
1887e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[0]"], 3, props, 3, expected2,
1888e5c31af7Sopenharmony_ci								   error);
1889e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, GL_FLOAT, 1 };
1890e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["b[1]"], 3, props, 3, expected3,
1891e5c31af7Sopenharmony_ci								   error);
1892e5c31af7Sopenharmony_ci		GLint expected4[] = { 2, GL_UNSIGNED_INT_VEC2, 1 };
1893e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["c"], 3, props, 3, expected4, error);
1894e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, GL_UNSIGNED_INT, 1 };
1895e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["d"], 3, props, 3, expected5, error);
1896e5c31af7Sopenharmony_ci		GLint expected6[] = { 2, GL_FLOAT_VEC3, 2 };
1897e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["e"], 3, props, 3, expected6, error);
1898e5c31af7Sopenharmony_ci
1899e5c31af7Sopenharmony_ci		glDeleteProgram(program);
1900e5c31af7Sopenharmony_ci		return error;
1901e5c31af7Sopenharmony_ci	}
1902e5c31af7Sopenharmony_ci};
1903e5c31af7Sopenharmony_ci
1904e5c31af7Sopenharmony_ciclass AtomicCounterSimple : public SimpleShaders
1905e5c31af7Sopenharmony_ci{
1906e5c31af7Sopenharmony_cipublic:
1907e5c31af7Sopenharmony_ci	virtual std::string Title()
1908e5c31af7Sopenharmony_ci	{
1909e5c31af7Sopenharmony_ci		return "Atomic Counter Buffer Simple Test";
1910e5c31af7Sopenharmony_ci	}
1911e5c31af7Sopenharmony_ci
1912e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
1913e5c31af7Sopenharmony_ci	{
1914e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with atomic counters used";
1915e5c31af7Sopenharmony_ci	}
1916e5c31af7Sopenharmony_ci
1917e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
1918e5c31af7Sopenharmony_ci	{
1919e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_ATOMIC_COUNTER_BUFFER as an interface param.\n";
1920e5c31af7Sopenharmony_ci	}
1921e5c31af7Sopenharmony_ci
1922e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
1923e5c31af7Sopenharmony_ci	{
1924e5c31af7Sopenharmony_ci		return "#version 430                   \n"
1925e5c31af7Sopenharmony_ci			   "out vec4 color;                \n"
1926e5c31af7Sopenharmony_ci			   ""
1927e5c31af7Sopenharmony_ci			   "layout (binding = 1, offset = 0) uniform atomic_uint a;    \n"
1928e5c31af7Sopenharmony_ci			   "layout (binding = 2, offset = 0) uniform atomic_uint b;    \n"
1929e5c31af7Sopenharmony_ci			   "layout (binding = 2, offset = 4) uniform atomic_uint c;    \n"
1930e5c31af7Sopenharmony_ci			   "layout (binding = 5, offset = 0) uniform atomic_uint d[3]; \n"
1931e5c31af7Sopenharmony_ci			   "layout (binding = 5, offset = 12) uniform atomic_uint e;   \n"
1932e5c31af7Sopenharmony_ci			   ""
1933e5c31af7Sopenharmony_ci			   "void main() {                                                         \n"
1934e5c31af7Sopenharmony_ci			   "   uint x = atomicCounterIncrement(d[0]) + atomicCounterIncrement(a); \n"
1935e5c31af7Sopenharmony_ci			   "   uint y = atomicCounterIncrement(d[1]) + atomicCounterIncrement(b); \n"
1936e5c31af7Sopenharmony_ci			   "   uint z = atomicCounterIncrement(d[2]) + atomicCounterIncrement(c); \n"
1937e5c31af7Sopenharmony_ci			   "   uint w = atomicCounterIncrement(e);                                \n"
1938e5c31af7Sopenharmony_ci			   "   color = vec4(float(x), float(y), float(z), float(w));              \n"
1939e5c31af7Sopenharmony_ci			   "}";
1940e5c31af7Sopenharmony_ci	}
1941e5c31af7Sopenharmony_ci
1942e5c31af7Sopenharmony_ci	virtual long Run()
1943e5c31af7Sopenharmony_ci	{
1944e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
1945e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
1946e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
1947e5c31af7Sopenharmony_ci		LinkProgram(program);
1948e5c31af7Sopenharmony_ci
1949e5c31af7Sopenharmony_ci		long error = NO_ERROR;
1950e5c31af7Sopenharmony_ci
1951e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, 3, error);
1952e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, 2, error);
1953e5c31af7Sopenharmony_ci
1954e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
1955e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
1956e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
1957e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "c", error);
1958e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "d", error);
1959e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "e", error);
1960e5c31af7Sopenharmony_ci
1961e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["a"], "a", error);
1962e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["b"], "b", error);
1963e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["c"], "c", error);
1964e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["d"], "d[0]", error);
1965e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indicesU["e"], "e", error);
1966e5c31af7Sopenharmony_ci
1967e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", -1, error);
1968e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "b", -1, error);
1969e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "c", -1, error);
1970e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d", -1, error);
1971e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "e", -1, error);
1972e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[0]", -1, error);
1973e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[1]", -1, error);
1974e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "d[2]", -1, error);
1975e5c31af7Sopenharmony_ci
1976e5c31af7Sopenharmony_ci		GLenum		  prop	= GL_ATOMIC_COUNTER_BUFFER_INDEX;
1977e5c31af7Sopenharmony_ci		const GLsizei bufSize = 1000;
1978e5c31af7Sopenharmony_ci		GLsizei		  length;
1979e5c31af7Sopenharmony_ci		GLint		  res;
1980e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1981e5c31af7Sopenharmony_ci
1982e5c31af7Sopenharmony_ci		GLenum props[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_ACTIVE_VARIABLES };
1983e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, &res);
1984e5c31af7Sopenharmony_ci		GLint expected[] = { 1, 4, 1, static_cast<GLint>(indicesU["a"]) };
1985e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 4, props, 4, expected, error);
1986e5c31af7Sopenharmony_ci
1987e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES };
1988e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
1989e5c31af7Sopenharmony_ci		GLint expected2[] = { 2, 8, 2 };
1990e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1991e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["c"], 1, &prop, bufSize, &length, &res);
1992e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected2, error);
1993e5c31af7Sopenharmony_ci
1994e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
1995e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, 16, 2 };
1996e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1997e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["e"], 1, &prop, bufSize, &length, &res);
1998e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 3, props2, 3, expected3, error);
1999e5c31af7Sopenharmony_ci
2000e5c31af7Sopenharmony_ci		GLenum			 prop2 = GL_ACTIVE_VARIABLES;
2001e5c31af7Sopenharmony_ci		GLint			 param[bufSize];
2002e5c31af7Sopenharmony_ci		std::set<GLuint> exp;
2003e5c31af7Sopenharmony_ci		exp.insert(indicesU["b"]);
2004e5c31af7Sopenharmony_ci		exp.insert(indicesU["c"]);
2005e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, bufSize, &length, &res);
2006e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param);
2007e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
2008e5c31af7Sopenharmony_ci		{
2009e5c31af7Sopenharmony_ci			if (exp.find(param[i]) == exp.end() || length != 2)
2010e5c31af7Sopenharmony_ci			{
2011e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
2012e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "Length: " << length
2013e5c31af7Sopenharmony_ci					<< "\nUnexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param[i]
2014e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
2015e5c31af7Sopenharmony_ci				glDeleteProgram(program);
2016e5c31af7Sopenharmony_ci				return ERROR;
2017e5c31af7Sopenharmony_ci			}
2018e5c31af7Sopenharmony_ci		}
2019e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2020e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "GL_ACTIVE_VARIABLES ok for 1st ATOMIC_COUNTER_BUFFER"
2021e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2022e5c31af7Sopenharmony_ci		std::set<GLuint> exp2;
2023e5c31af7Sopenharmony_ci		GLint			 param2[bufSize];
2024e5c31af7Sopenharmony_ci		exp2.insert(indicesU["d"]);
2025e5c31af7Sopenharmony_ci		exp2.insert(indicesU["e"]);
2026e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["d"], 1, &prop, bufSize, &length, &res);
2027e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, res, 1, &prop2, bufSize, &length, param2);
2028e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
2029e5c31af7Sopenharmony_ci		{
2030e5c31af7Sopenharmony_ci			if (exp2.find(param2[i]) == exp2.end() || length != 2)
2031e5c31af7Sopenharmony_ci			{
2032e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
2033e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "Length: " << length
2034e5c31af7Sopenharmony_ci					<< "\nUnexpected index/length found in active variables of ATOMIC_COUNTER_BUFFER: " << param2[i]
2035e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
2036e5c31af7Sopenharmony_ci				glDeleteProgram(program);
2037e5c31af7Sopenharmony_ci				return ERROR;
2038e5c31af7Sopenharmony_ci			}
2039e5c31af7Sopenharmony_ci		}
2040e5c31af7Sopenharmony_ci
2041e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2042e5c31af7Sopenharmony_ci		return error;
2043e5c31af7Sopenharmony_ci	}
2044e5c31af7Sopenharmony_ci};
2045e5c31af7Sopenharmony_ci
2046e5c31af7Sopenharmony_ciclass SubroutinesBase : public SimpleShaders
2047e5c31af7Sopenharmony_ci{
2048e5c31af7Sopenharmony_ciprotected:
2049e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
2050e5c31af7Sopenharmony_ci	{
2051e5c31af7Sopenharmony_ci		return "fallthrough vertex, geometry, tesselation and fragment shaders with subroutines used";
2052e5c31af7Sopenharmony_ci	}
2053e5c31af7Sopenharmony_ci
2054e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
2055e5c31af7Sopenharmony_ci	{
2056e5c31af7Sopenharmony_ci		return "#version 430                         \n"
2057e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
2058e5c31af7Sopenharmony_ci			   ""
2059e5c31af7Sopenharmony_ci			   "subroutine vec4 a_t();               \n"
2060e5c31af7Sopenharmony_ci			   "subroutine uniform a_t a;            \n"
2061e5c31af7Sopenharmony_ci			   "subroutine(a_t) vec4 x() {           \n"
2062e5c31af7Sopenharmony_ci			   "   return vec4(1);                   \n"
2063e5c31af7Sopenharmony_ci			   "}                                    \n"
2064e5c31af7Sopenharmony_ci			   "subroutine(a_t) vec4 y() {           \n"
2065e5c31af7Sopenharmony_ci			   "   return vec4(0);                   \n"
2066e5c31af7Sopenharmony_ci			   "}                                    \n"
2067e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
2068e5c31af7Sopenharmony_ci			   "{                                    \n"
2069e5c31af7Sopenharmony_ci			   "   gl_Position = a();                \n"
2070e5c31af7Sopenharmony_ci			   "}";
2071e5c31af7Sopenharmony_ci	}
2072e5c31af7Sopenharmony_ci
2073e5c31af7Sopenharmony_ci	virtual std::string TessControlShader()
2074e5c31af7Sopenharmony_ci	{
2075e5c31af7Sopenharmony_ci		return "#version 430                                                  \n"
2076e5c31af7Sopenharmony_ci			   "layout(vertices = 3) out;                                     \n"
2077e5c31af7Sopenharmony_ci			   ""
2078e5c31af7Sopenharmony_ci			   "subroutine vec4 a_t();               \n"
2079e5c31af7Sopenharmony_ci			   "subroutine uniform a_t a;            \n"
2080e5c31af7Sopenharmony_ci			   "subroutine(a_t) vec4 x() {           \n"
2081e5c31af7Sopenharmony_ci			   "   return vec4(1);                   \n"
2082e5c31af7Sopenharmony_ci			   "}                                    \n"
2083e5c31af7Sopenharmony_ci			   ""
2084e5c31af7Sopenharmony_ci			   "void main() {                                                                   \n"
2085e5c31af7Sopenharmony_ci			   "   gl_out[gl_InvocationID].gl_Position = a();                                   \n"
2086e5c31af7Sopenharmony_ci			   "   gl_TessLevelInner[0] = 1.0;                                                  \n"
2087e5c31af7Sopenharmony_ci			   "   gl_TessLevelInner[1] = 1.0;                                                  \n"
2088e5c31af7Sopenharmony_ci			   "   gl_TessLevelOuter[0] = 1.0;                                                  \n"
2089e5c31af7Sopenharmony_ci			   "   gl_TessLevelOuter[1] = 1.0;                                                  \n"
2090e5c31af7Sopenharmony_ci			   "   gl_TessLevelOuter[2] = 1.0;                                                  \n"
2091e5c31af7Sopenharmony_ci			   "}";
2092e5c31af7Sopenharmony_ci	}
2093e5c31af7Sopenharmony_ci
2094e5c31af7Sopenharmony_ci	virtual std::string TessEvalShader()
2095e5c31af7Sopenharmony_ci	{
2096e5c31af7Sopenharmony_ci		return "#version 430                                                  \n"
2097e5c31af7Sopenharmony_ci			   "layout(triangles, equal_spacing) in;                          \n"
2098e5c31af7Sopenharmony_ci			   ""
2099e5c31af7Sopenharmony_ci			   "subroutine vec4 a_t();               \n"
2100e5c31af7Sopenharmony_ci			   "subroutine uniform a_t a;            \n"
2101e5c31af7Sopenharmony_ci			   "subroutine(a_t) vec4 x() {           \n"
2102e5c31af7Sopenharmony_ci			   "   return vec4(1);                   \n"
2103e5c31af7Sopenharmony_ci			   "}                                    \n"
2104e5c31af7Sopenharmony_ci			   ""
2105e5c31af7Sopenharmony_ci			   "void main() {                                \n"
2106e5c31af7Sopenharmony_ci			   "   vec4 p0 = gl_in[0].gl_Position;           \n"
2107e5c31af7Sopenharmony_ci			   "   vec4 p1 = gl_in[1].gl_Position;           \n"
2108e5c31af7Sopenharmony_ci			   "   vec4 p2 = gl_in[2].gl_Position;           \n"
2109e5c31af7Sopenharmony_ci			   "   vec3 p = gl_TessCoord.xyz;                \n"
2110e5c31af7Sopenharmony_ci			   "   gl_Position = a();                        \n"
2111e5c31af7Sopenharmony_ci			   "}";
2112e5c31af7Sopenharmony_ci	}
2113e5c31af7Sopenharmony_ci
2114e5c31af7Sopenharmony_ci	virtual std::string GeometryShader()
2115e5c31af7Sopenharmony_ci	{
2116e5c31af7Sopenharmony_ci		return "#version 430                                                  \n"
2117e5c31af7Sopenharmony_ci			   "layout(triangles) in;                                         \n"
2118e5c31af7Sopenharmony_ci			   "layout(triangle_strip, max_vertices = 4) out;                 \n"
2119e5c31af7Sopenharmony_ci			   ""
2120e5c31af7Sopenharmony_ci			   "subroutine vec4 a_t();               \n"
2121e5c31af7Sopenharmony_ci			   "subroutine uniform a_t a;            \n"
2122e5c31af7Sopenharmony_ci			   "subroutine(a_t) vec4 x() {           \n"
2123e5c31af7Sopenharmony_ci			   "   return vec4(1);                   \n"
2124e5c31af7Sopenharmony_ci			   "}                                    \n"
2125e5c31af7Sopenharmony_ci			   ""
2126e5c31af7Sopenharmony_ci			   "void main() {                              \n"
2127e5c31af7Sopenharmony_ci			   "   gl_Position = vec4(-1, 1, 0, 1);        \n"
2128e5c31af7Sopenharmony_ci			   "   EmitVertex();                           \n"
2129e5c31af7Sopenharmony_ci			   "   gl_Position = vec4(-1, -1, 0, 1);       \n"
2130e5c31af7Sopenharmony_ci			   "   EmitVertex();                           \n"
2131e5c31af7Sopenharmony_ci			   "   gl_Position = vec4(1, 1, 0, 1);         \n"
2132e5c31af7Sopenharmony_ci			   "   EmitVertex();                           \n"
2133e5c31af7Sopenharmony_ci			   "   gl_Position = a();                      \n"
2134e5c31af7Sopenharmony_ci			   "   EmitVertex();                           \n"
2135e5c31af7Sopenharmony_ci			   "   EndPrimitive();                         \n"
2136e5c31af7Sopenharmony_ci			   "}";
2137e5c31af7Sopenharmony_ci	}
2138e5c31af7Sopenharmony_ci
2139e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
2140e5c31af7Sopenharmony_ci	{
2141e5c31af7Sopenharmony_ci		return "#version 430                   \n"
2142e5c31af7Sopenharmony_ci			   "out vec4 color;                \n"
2143e5c31af7Sopenharmony_ci			   ""
2144e5c31af7Sopenharmony_ci			   "subroutine vec4 a_t();               \n"
2145e5c31af7Sopenharmony_ci			   "subroutine uniform a_t a;            \n"
2146e5c31af7Sopenharmony_ci			   "subroutine(a_t) vec4 x() {           \n"
2147e5c31af7Sopenharmony_ci			   "   return vec4(1);                   \n"
2148e5c31af7Sopenharmony_ci			   "}                                    \n"
2149e5c31af7Sopenharmony_ci			   ""
2150e5c31af7Sopenharmony_ci			   "void main() {                             \n"
2151e5c31af7Sopenharmony_ci			   "   color = a();                           \n"
2152e5c31af7Sopenharmony_ci			   "}";
2153e5c31af7Sopenharmony_ci	}
2154e5c31af7Sopenharmony_ci
2155e5c31af7Sopenharmony_ci	virtual void inline VerifyVS(GLuint program, long& error)
2156e5c31af7Sopenharmony_ci	{
2157e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE, GL_ACTIVE_RESOURCES, 2, error);
2158e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2159e5c31af7Sopenharmony_ci
2160e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2161e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2162e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 2, error);
2163e5c31af7Sopenharmony_ci
2164e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesS;
2165e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE, indicesS, "x", error);
2166e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE, indicesS, "y", error);
2167e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
2168e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU, "a", error);
2169e5c31af7Sopenharmony_ci
2170e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE, indicesS["x"], "x", error);
2171e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE, indicesS["y"], "y", error);
2172e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], "a", error);
2173e5c31af7Sopenharmony_ci
2174e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_VERTEX_SUBROUTINE_UNIFORM, "a",
2175e5c31af7Sopenharmony_ci										 glGetSubroutineUniformLocation(program, GL_VERTEX_SHADER, "a"), error);
2176e5c31af7Sopenharmony_ci
2177e5c31af7Sopenharmony_ci		GLenum propsS[]	= { GL_NAME_LENGTH };
2178e5c31af7Sopenharmony_ci		GLint  expectedS[] = { 2 };
2179e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE, indicesS["x"], 1, propsS, 1, expectedS, error);
2180e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE, indicesS["y"], 1, propsS, 1, expectedS, error);
2181e5c31af7Sopenharmony_ci
2182e5c31af7Sopenharmony_ci		GLenum propsU[]	= { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION };
2183e5c31af7Sopenharmony_ci		GLint  expectedU[] = { 2, 1, 2, glGetSubroutineUniformLocation(program, GL_VERTEX_SHADER, "a") };
2184e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], 4, propsU, 4, expectedU,
2185e5c31af7Sopenharmony_ci								   error);
2186e5c31af7Sopenharmony_ci
2187e5c31af7Sopenharmony_ci		GLenum			 prop	= GL_COMPATIBLE_SUBROUTINES;
2188e5c31af7Sopenharmony_ci		const GLsizei	bufSize = 1000;
2189e5c31af7Sopenharmony_ci		GLint			 param[bufSize];
2190e5c31af7Sopenharmony_ci		GLsizei			 length;
2191e5c31af7Sopenharmony_ci		std::set<GLuint> exp;
2192e5c31af7Sopenharmony_ci		exp.insert(indicesS["x"]);
2193e5c31af7Sopenharmony_ci		exp.insert(indicesS["y"]);
2194e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_VERTEX_SUBROUTINE_UNIFORM, indicesU["a"], 1, &prop, bufSize, &length, param);
2195e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
2196e5c31af7Sopenharmony_ci		{
2197e5c31af7Sopenharmony_ci			if (exp.find(param[i]) == exp.end() || length != 2)
2198e5c31af7Sopenharmony_ci			{
2199e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
2200e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "Length: " << length
2201e5c31af7Sopenharmony_ci					<< "\nUnexpected index/length found in active variables of GL_VERTEX_SUBROUTINE_UNIFORM: "
2202e5c31af7Sopenharmony_ci					<< param[i] << tcu::TestLog::EndMessage;
2203e5c31af7Sopenharmony_ci				error = ERROR;
2204e5c31af7Sopenharmony_ci			}
2205e5c31af7Sopenharmony_ci		}
2206e5c31af7Sopenharmony_ci	}
2207e5c31af7Sopenharmony_ci
2208e5c31af7Sopenharmony_ci	virtual void inline VerifyTCS(GLuint program, long& error)
2209e5c31af7Sopenharmony_ci	{
2210e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2211e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2212e5c31af7Sopenharmony_ci
2213e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2214e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2215e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2216e5c31af7Sopenharmony_ci									error);
2217e5c31af7Sopenharmony_ci
2218e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTS;
2219e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TESS_CONTROL_SUBROUTINE, indicesTS, "x", error);
2220e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTU;
2221e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2222e5c31af7Sopenharmony_ci
2223e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TESS_CONTROL_SUBROUTINE, indicesTS["x"], "x", error);
2224e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2225e5c31af7Sopenharmony_ci
2226e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, "a",
2227e5c31af7Sopenharmony_ci										 glGetSubroutineUniformLocation(program, GL_TESS_CONTROL_SHADER, "a"), error);
2228e5c31af7Sopenharmony_ci
2229e5c31af7Sopenharmony_ci		GLenum propsS[]	= { GL_NAME_LENGTH };
2230e5c31af7Sopenharmony_ci		GLint  expectedS[] = { 2 };
2231e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TESS_CONTROL_SUBROUTINE, static_cast<GLint>(indicesTS["x"]), 1, propsS,
2232e5c31af7Sopenharmony_ci								   1, expectedS, error);
2233e5c31af7Sopenharmony_ci
2234e5c31af7Sopenharmony_ci		GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2235e5c31af7Sopenharmony_ci							GL_COMPATIBLE_SUBROUTINES };
2236e5c31af7Sopenharmony_ci		GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_TESS_CONTROL_SHADER, "a"),
2237e5c31af7Sopenharmony_ci							  static_cast<GLint>(indicesTS["x"]) };
2238e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TESS_CONTROL_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2239e5c31af7Sopenharmony_ci								   error);
2240e5c31af7Sopenharmony_ci	}
2241e5c31af7Sopenharmony_ci};
2242e5c31af7Sopenharmony_ci
2243e5c31af7Sopenharmony_ciclass SubroutinesVertex : public SubroutinesBase
2244e5c31af7Sopenharmony_ci{
2245e5c31af7Sopenharmony_ci	virtual std::string Title()
2246e5c31af7Sopenharmony_ci	{
2247e5c31af7Sopenharmony_ci		return "Vertex Shader Subroutines Test";
2248e5c31af7Sopenharmony_ci	}
2249e5c31af7Sopenharmony_ci
2250e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2251e5c31af7Sopenharmony_ci	{
2252e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using *VERTEX_SUBROUTINE* as an interface params.\n";
2253e5c31af7Sopenharmony_ci	}
2254e5c31af7Sopenharmony_ci
2255e5c31af7Sopenharmony_ci	virtual long Run()
2256e5c31af7Sopenharmony_ci	{
2257e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2258e5c31af7Sopenharmony_ci									   GeometryShader().c_str(), FragmentShader().c_str(), false);
2259e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2260e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
2261e5c31af7Sopenharmony_ci		LinkProgram(program);
2262e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2263e5c31af7Sopenharmony_ci
2264e5c31af7Sopenharmony_ci		VerifyVS(program, error);
2265e5c31af7Sopenharmony_ci
2266e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2267e5c31af7Sopenharmony_ci		return error;
2268e5c31af7Sopenharmony_ci	}
2269e5c31af7Sopenharmony_ci};
2270e5c31af7Sopenharmony_ci
2271e5c31af7Sopenharmony_ciclass SubroutinesTessControl : public SubroutinesBase
2272e5c31af7Sopenharmony_ci{
2273e5c31af7Sopenharmony_ci	virtual std::string Title()
2274e5c31af7Sopenharmony_ci	{
2275e5c31af7Sopenharmony_ci		return "Tess Control Subroutines Test";
2276e5c31af7Sopenharmony_ci	}
2277e5c31af7Sopenharmony_ci
2278e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2279e5c31af7Sopenharmony_ci	{
2280e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using *TESS_CONTROL_SUBROUTINE* as an interface params.\n";
2281e5c31af7Sopenharmony_ci	}
2282e5c31af7Sopenharmony_ci
2283e5c31af7Sopenharmony_ci	virtual long Run()
2284e5c31af7Sopenharmony_ci	{
2285e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2286e5c31af7Sopenharmony_ci									   GeometryShader().c_str(), FragmentShader().c_str(), false);
2287e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2288e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
2289e5c31af7Sopenharmony_ci		LinkProgram(program);
2290e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2291e5c31af7Sopenharmony_ci
2292e5c31af7Sopenharmony_ci		VerifyTCS(program, error);
2293e5c31af7Sopenharmony_ci
2294e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2295e5c31af7Sopenharmony_ci		return error;
2296e5c31af7Sopenharmony_ci	}
2297e5c31af7Sopenharmony_ci};
2298e5c31af7Sopenharmony_ci
2299e5c31af7Sopenharmony_ciclass SubroutinesTessEval : public SubroutinesBase
2300e5c31af7Sopenharmony_ci{
2301e5c31af7Sopenharmony_ci	virtual std::string Title()
2302e5c31af7Sopenharmony_ci	{
2303e5c31af7Sopenharmony_ci		return "Tess Evaluation Subroutines Test";
2304e5c31af7Sopenharmony_ci	}
2305e5c31af7Sopenharmony_ci
2306e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2307e5c31af7Sopenharmony_ci	{
2308e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using *TESS_EVALUATION_SUBROUTINE* as an interface params.\n";
2309e5c31af7Sopenharmony_ci	}
2310e5c31af7Sopenharmony_ci
2311e5c31af7Sopenharmony_ci	virtual void inline VerifyTES(GLuint program, long& error)
2312e5c31af7Sopenharmony_ci	{
2313e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2314e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2315e5c31af7Sopenharmony_ci
2316e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2317e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2318e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES,
2319e5c31af7Sopenharmony_ci									1, error);
2320e5c31af7Sopenharmony_ci
2321e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTS;
2322e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS, "x", error);
2323e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTU;
2324e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2325e5c31af7Sopenharmony_ci
2326e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS["x"], "x", error);
2327e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2328e5c31af7Sopenharmony_ci
2329e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, "a",
2330e5c31af7Sopenharmony_ci										 glGetSubroutineUniformLocation(program, GL_TESS_EVALUATION_SHADER, "a"),
2331e5c31af7Sopenharmony_ci										 error);
2332e5c31af7Sopenharmony_ci
2333e5c31af7Sopenharmony_ci		GLenum propsS[]	= { GL_NAME_LENGTH };
2334e5c31af7Sopenharmony_ci		GLint  expectedS[] = { 2 };
2335e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TESS_EVALUATION_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS,
2336e5c31af7Sopenharmony_ci								   error);
2337e5c31af7Sopenharmony_ci
2338e5c31af7Sopenharmony_ci		GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2339e5c31af7Sopenharmony_ci							GL_COMPATIBLE_SUBROUTINES };
2340e5c31af7Sopenharmony_ci		GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_TESS_EVALUATION_SHADER, "a"),
2341e5c31af7Sopenharmony_ci							  static_cast<GLint>(indicesTS["x"]) };
2342e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TESS_EVALUATION_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5,
2343e5c31af7Sopenharmony_ci								   expectedU, error);
2344e5c31af7Sopenharmony_ci	}
2345e5c31af7Sopenharmony_ci
2346e5c31af7Sopenharmony_ci	virtual long Run()
2347e5c31af7Sopenharmony_ci	{
2348e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2349e5c31af7Sopenharmony_ci									   GeometryShader().c_str(), FragmentShader().c_str(), false);
2350e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2351e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
2352e5c31af7Sopenharmony_ci		LinkProgram(program);
2353e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2354e5c31af7Sopenharmony_ci
2355e5c31af7Sopenharmony_ci		VerifyTES(program, error);
2356e5c31af7Sopenharmony_ci
2357e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2358e5c31af7Sopenharmony_ci		return error;
2359e5c31af7Sopenharmony_ci	}
2360e5c31af7Sopenharmony_ci};
2361e5c31af7Sopenharmony_ci
2362e5c31af7Sopenharmony_ciclass SubroutinesGeometry : public SubroutinesBase
2363e5c31af7Sopenharmony_ci{
2364e5c31af7Sopenharmony_ci	virtual std::string Title()
2365e5c31af7Sopenharmony_ci	{
2366e5c31af7Sopenharmony_ci		return "Geometry Shader Subroutines Test";
2367e5c31af7Sopenharmony_ci	}
2368e5c31af7Sopenharmony_ci
2369e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2370e5c31af7Sopenharmony_ci	{
2371e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using *GEOMETRY_SUBROUTINE* as an interface params.\n";
2372e5c31af7Sopenharmony_ci	}
2373e5c31af7Sopenharmony_ci
2374e5c31af7Sopenharmony_ci	virtual void inline VerifyGEO(GLuint program, long& error)
2375e5c31af7Sopenharmony_ci	{
2376e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2377e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2378e5c31af7Sopenharmony_ci
2379e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2380e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2381e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2382e5c31af7Sopenharmony_ci									error);
2383e5c31af7Sopenharmony_ci
2384e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTS;
2385e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_GEOMETRY_SUBROUTINE, indicesTS, "x", error);
2386e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTU;
2387e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2388e5c31af7Sopenharmony_ci
2389e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_GEOMETRY_SUBROUTINE, indicesTS["x"], "x", error);
2390e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2391e5c31af7Sopenharmony_ci
2392e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, "a",
2393e5c31af7Sopenharmony_ci										 glGetSubroutineUniformLocation(program, GL_GEOMETRY_SHADER, "a"), error);
2394e5c31af7Sopenharmony_ci
2395e5c31af7Sopenharmony_ci		GLenum propsS[]	= { GL_NAME_LENGTH };
2396e5c31af7Sopenharmony_ci		GLint  expectedS[] = { 2 };
2397e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_GEOMETRY_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS, error);
2398e5c31af7Sopenharmony_ci
2399e5c31af7Sopenharmony_ci		GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2400e5c31af7Sopenharmony_ci							GL_COMPATIBLE_SUBROUTINES };
2401e5c31af7Sopenharmony_ci		GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_GEOMETRY_SHADER, "a"),
2402e5c31af7Sopenharmony_ci							  static_cast<GLint>(indicesTS["x"]) };
2403e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_GEOMETRY_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2404e5c31af7Sopenharmony_ci								   error);
2405e5c31af7Sopenharmony_ci	}
2406e5c31af7Sopenharmony_ci
2407e5c31af7Sopenharmony_ci	virtual long Run()
2408e5c31af7Sopenharmony_ci	{
2409e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2410e5c31af7Sopenharmony_ci									   GeometryShader().c_str(), FragmentShader().c_str(), false);
2411e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2412e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
2413e5c31af7Sopenharmony_ci		LinkProgram(program);
2414e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2415e5c31af7Sopenharmony_ci
2416e5c31af7Sopenharmony_ci		VerifyGEO(program, error);
2417e5c31af7Sopenharmony_ci
2418e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2419e5c31af7Sopenharmony_ci		return error;
2420e5c31af7Sopenharmony_ci	}
2421e5c31af7Sopenharmony_ci};
2422e5c31af7Sopenharmony_ci
2423e5c31af7Sopenharmony_ciclass SubroutinesFragment : public SubroutinesBase
2424e5c31af7Sopenharmony_ci{
2425e5c31af7Sopenharmony_ci	virtual std::string Title()
2426e5c31af7Sopenharmony_ci	{
2427e5c31af7Sopenharmony_ci		return "Fragment Shader Subroutines Test";
2428e5c31af7Sopenharmony_ci	}
2429e5c31af7Sopenharmony_ci
2430e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2431e5c31af7Sopenharmony_ci	{
2432e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using *FRAGMENT_SUBROUTINE* as an interface params.\n";
2433e5c31af7Sopenharmony_ci	}
2434e5c31af7Sopenharmony_ci
2435e5c31af7Sopenharmony_ci	virtual void inline VerifyFS(GLuint program, long& error)
2436e5c31af7Sopenharmony_ci	{
2437e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE, GL_ACTIVE_RESOURCES, 1, error);
2438e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE, GL_MAX_NAME_LENGTH, 2, error);
2439e5c31af7Sopenharmony_ci
2440e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
2441e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
2442e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 1,
2443e5c31af7Sopenharmony_ci									error);
2444e5c31af7Sopenharmony_ci
2445e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTS;
2446e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_FRAGMENT_SUBROUTINE, indicesTS, "x", error);
2447e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTU;
2448e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2449e5c31af7Sopenharmony_ci
2450e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_FRAGMENT_SUBROUTINE, indicesTS["x"], "x", error);
2451e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2452e5c31af7Sopenharmony_ci
2453e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, "a",
2454e5c31af7Sopenharmony_ci										 glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "a"), error);
2455e5c31af7Sopenharmony_ci
2456e5c31af7Sopenharmony_ci		GLenum propsS[]	= { GL_NAME_LENGTH };
2457e5c31af7Sopenharmony_ci		GLint  expectedS[] = { 2 };
2458e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_FRAGMENT_SUBROUTINE, indicesTS["x"], 1, propsS, 1, expectedS, error);
2459e5c31af7Sopenharmony_ci
2460e5c31af7Sopenharmony_ci		GLenum propsU[] = { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION,
2461e5c31af7Sopenharmony_ci							GL_COMPATIBLE_SUBROUTINES };
2462e5c31af7Sopenharmony_ci		GLint expectedU[] = { 2, 1, 1, glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "a"),
2463e5c31af7Sopenharmony_ci							  static_cast<GLint>(indicesTS["x"]) };
2464e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_FRAGMENT_SUBROUTINE_UNIFORM, indicesTU["a"], 5, propsU, 5, expectedU,
2465e5c31af7Sopenharmony_ci								   error);
2466e5c31af7Sopenharmony_ci	}
2467e5c31af7Sopenharmony_ci
2468e5c31af7Sopenharmony_ci	virtual long Run()
2469e5c31af7Sopenharmony_ci	{
2470e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), TessControlShader().c_str(), TessEvalShader().c_str(),
2471e5c31af7Sopenharmony_ci									   GeometryShader().c_str(), FragmentShader().c_str(), false);
2472e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2473e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
2474e5c31af7Sopenharmony_ci		LinkProgram(program);
2475e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2476e5c31af7Sopenharmony_ci
2477e5c31af7Sopenharmony_ci		VerifyFS(program, error);
2478e5c31af7Sopenharmony_ci
2479e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2480e5c31af7Sopenharmony_ci		return error;
2481e5c31af7Sopenharmony_ci	}
2482e5c31af7Sopenharmony_ci};
2483e5c31af7Sopenharmony_ci
2484e5c31af7Sopenharmony_ciclass SoubroutinesCompute : public PIQBase
2485e5c31af7Sopenharmony_ci{
2486e5c31af7Sopenharmony_ci	virtual std::string Title()
2487e5c31af7Sopenharmony_ci	{
2488e5c31af7Sopenharmony_ci		return "Compute Shader Subroutines Test";
2489e5c31af7Sopenharmony_ci	}
2490e5c31af7Sopenharmony_ci
2491e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
2492e5c31af7Sopenharmony_ci	{
2493e5c31af7Sopenharmony_ci		return "compute shader with subroutines used";
2494e5c31af7Sopenharmony_ci	}
2495e5c31af7Sopenharmony_ci
2496e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2497e5c31af7Sopenharmony_ci	{
2498e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using *COMPUTE_SUBROUTINE* as an interface params.\n";
2499e5c31af7Sopenharmony_ci	}
2500e5c31af7Sopenharmony_ci
2501e5c31af7Sopenharmony_ci	virtual std::string ComputeShader()
2502e5c31af7Sopenharmony_ci	{
2503e5c31af7Sopenharmony_ci		return "layout(local_size_x = 1, local_size_y = 1) in; \n"
2504e5c31af7Sopenharmony_ci
2505e5c31af7Sopenharmony_ci			   "layout(std430) buffer Output {                 \n"
2506e5c31af7Sopenharmony_ci			   "  vec4 data;                                   \n"
2507e5c31af7Sopenharmony_ci			   "} g_out;                                       \n"
2508e5c31af7Sopenharmony_ci			   ""
2509e5c31af7Sopenharmony_ci			   "subroutine vec4 a_t();               \n"
2510e5c31af7Sopenharmony_ci			   "subroutine uniform a_t a;            \n"
2511e5c31af7Sopenharmony_ci			   "subroutine(a_t) vec4 ax() {          \n"
2512e5c31af7Sopenharmony_ci			   "   return vec4(1);                   \n"
2513e5c31af7Sopenharmony_ci			   "}                                    \n"
2514e5c31af7Sopenharmony_ci			   "subroutine(a_t) vec4 ay() {          \n"
2515e5c31af7Sopenharmony_ci			   "   return vec4(0);                   \n"
2516e5c31af7Sopenharmony_ci			   "}                                    \n"
2517e5c31af7Sopenharmony_ci			   ""
2518e5c31af7Sopenharmony_ci			   "subroutine vec4 b_t();               \n"
2519e5c31af7Sopenharmony_ci			   "subroutine uniform b_t b[3];         \n"
2520e5c31af7Sopenharmony_ci			   "subroutine(b_t) vec4 bx() {          \n"
2521e5c31af7Sopenharmony_ci			   "   return vec4(1);                   \n"
2522e5c31af7Sopenharmony_ci			   "}                                    \n"
2523e5c31af7Sopenharmony_ci			   "subroutine(b_t) vec4 by() {          \n"
2524e5c31af7Sopenharmony_ci			   "   return vec4(0);                   \n"
2525e5c31af7Sopenharmony_ci			   "}                                    \n"
2526e5c31af7Sopenharmony_ci			   "subroutine(b_t) vec4 bz() {          \n"
2527e5c31af7Sopenharmony_ci			   "   return vec4(-1);                   \n"
2528e5c31af7Sopenharmony_ci			   "}                                    \n"
2529e5c31af7Sopenharmony_ci			   ""
2530e5c31af7Sopenharmony_ci			   "void main() {                                    \n"
2531e5c31af7Sopenharmony_ci			   "   g_out.data = a() + b[0]() + b[1]() + b[2]();  \n"
2532e5c31af7Sopenharmony_ci			   "}";
2533e5c31af7Sopenharmony_ci	}
2534e5c31af7Sopenharmony_ci
2535e5c31af7Sopenharmony_ci	GLuint CreateComputeProgram(const std::string& cs)
2536e5c31af7Sopenharmony_ci	{
2537e5c31af7Sopenharmony_ci		const GLuint p = glCreateProgram();
2538e5c31af7Sopenharmony_ci
2539e5c31af7Sopenharmony_ci		const char* const kGLSLVer = "#version 430 core\n";
2540e5c31af7Sopenharmony_ci
2541e5c31af7Sopenharmony_ci		if (!cs.empty())
2542e5c31af7Sopenharmony_ci		{
2543e5c31af7Sopenharmony_ci			const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
2544e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
2545e5c31af7Sopenharmony_ci			glDeleteShader(sh);
2546e5c31af7Sopenharmony_ci			const char* const src[2] = { kGLSLVer, cs.c_str() };
2547e5c31af7Sopenharmony_ci			glShaderSource(sh, 2, src, NULL);
2548e5c31af7Sopenharmony_ci			glCompileShader(sh);
2549e5c31af7Sopenharmony_ci		}
2550e5c31af7Sopenharmony_ci
2551e5c31af7Sopenharmony_ci		return p;
2552e5c31af7Sopenharmony_ci	}
2553e5c31af7Sopenharmony_ci
2554e5c31af7Sopenharmony_ci	bool CheckProgram(GLuint program, bool* compile_error = NULL)
2555e5c31af7Sopenharmony_ci	{
2556e5c31af7Sopenharmony_ci		GLint compile_status = GL_TRUE;
2557e5c31af7Sopenharmony_ci		GLint status;
2558e5c31af7Sopenharmony_ci		glGetProgramiv(program, GL_LINK_STATUS, &status);
2559e5c31af7Sopenharmony_ci
2560e5c31af7Sopenharmony_ci		if (status == GL_FALSE)
2561e5c31af7Sopenharmony_ci		{
2562e5c31af7Sopenharmony_ci			GLint attached_shaders;
2563e5c31af7Sopenharmony_ci			glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
2564e5c31af7Sopenharmony_ci
2565e5c31af7Sopenharmony_ci			if (attached_shaders > 0)
2566e5c31af7Sopenharmony_ci			{
2567e5c31af7Sopenharmony_ci				std::vector<GLuint> shaders(attached_shaders);
2568e5c31af7Sopenharmony_ci				glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
2569e5c31af7Sopenharmony_ci
2570e5c31af7Sopenharmony_ci				for (GLint i = 0; i < attached_shaders; ++i)
2571e5c31af7Sopenharmony_ci				{
2572e5c31af7Sopenharmony_ci					GLenum type;
2573e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
2574e5c31af7Sopenharmony_ci					switch (type)
2575e5c31af7Sopenharmony_ci					{
2576e5c31af7Sopenharmony_ci					case GL_VERTEX_SHADER:
2577e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
2578e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
2579e5c31af7Sopenharmony_ci						break;
2580e5c31af7Sopenharmony_ci					case GL_TESS_CONTROL_SHADER:
2581e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
2582e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Tessellation Control Shader ***"
2583e5c31af7Sopenharmony_ci							<< tcu::TestLog::EndMessage;
2584e5c31af7Sopenharmony_ci						break;
2585e5c31af7Sopenharmony_ci					case GL_TESS_EVALUATION_SHADER:
2586e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
2587e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
2588e5c31af7Sopenharmony_ci							<< tcu::TestLog::EndMessage;
2589e5c31af7Sopenharmony_ci						break;
2590e5c31af7Sopenharmony_ci					case GL_GEOMETRY_SHADER:
2591e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
2592e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
2593e5c31af7Sopenharmony_ci						break;
2594e5c31af7Sopenharmony_ci					case GL_FRAGMENT_SHADER:
2595e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
2596e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
2597e5c31af7Sopenharmony_ci						break;
2598e5c31af7Sopenharmony_ci					case GL_COMPUTE_SHADER:
2599e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
2600e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
2601e5c31af7Sopenharmony_ci						break;
2602e5c31af7Sopenharmony_ci					default:
2603e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
2604e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
2605e5c31af7Sopenharmony_ci					}
2606e5c31af7Sopenharmony_ci
2607e5c31af7Sopenharmony_ci					GLint res;
2608e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
2609e5c31af7Sopenharmony_ci					if (res != GL_TRUE)
2610e5c31af7Sopenharmony_ci						compile_status = res;
2611e5c31af7Sopenharmony_ci
2612e5c31af7Sopenharmony_ci					// shader source
2613e5c31af7Sopenharmony_ci					GLint length;
2614e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
2615e5c31af7Sopenharmony_ci					if (length > 0)
2616e5c31af7Sopenharmony_ci					{
2617e5c31af7Sopenharmony_ci						std::vector<GLchar> source(length);
2618e5c31af7Sopenharmony_ci						glGetShaderSource(shaders[i], length, NULL, &source[0]);
2619e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
2620e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
2621e5c31af7Sopenharmony_ci					}
2622e5c31af7Sopenharmony_ci
2623e5c31af7Sopenharmony_ci					// shader info log
2624e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
2625e5c31af7Sopenharmony_ci					if (length > 0)
2626e5c31af7Sopenharmony_ci					{
2627e5c31af7Sopenharmony_ci						std::vector<GLchar> log(length);
2628e5c31af7Sopenharmony_ci						glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
2629e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
2630e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
2631e5c31af7Sopenharmony_ci					}
2632e5c31af7Sopenharmony_ci				}
2633e5c31af7Sopenharmony_ci			}
2634e5c31af7Sopenharmony_ci
2635e5c31af7Sopenharmony_ci			// program info log
2636e5c31af7Sopenharmony_ci			GLint length;
2637e5c31af7Sopenharmony_ci			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
2638e5c31af7Sopenharmony_ci			if (length > 0)
2639e5c31af7Sopenharmony_ci			{
2640e5c31af7Sopenharmony_ci				std::vector<GLchar> log(length);
2641e5c31af7Sopenharmony_ci				glGetProgramInfoLog(program, length, NULL, &log[0]);
2642e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
2643e5c31af7Sopenharmony_ci			}
2644e5c31af7Sopenharmony_ci		}
2645e5c31af7Sopenharmony_ci
2646e5c31af7Sopenharmony_ci		if (compile_error)
2647e5c31af7Sopenharmony_ci			*compile_error = (compile_status == GL_TRUE ? false : true);
2648e5c31af7Sopenharmony_ci		if (compile_status != GL_TRUE)
2649e5c31af7Sopenharmony_ci			return false;
2650e5c31af7Sopenharmony_ci		return status == GL_TRUE ? true : false;
2651e5c31af7Sopenharmony_ci	}
2652e5c31af7Sopenharmony_ci
2653e5c31af7Sopenharmony_ci	virtual void inline VerifyCompute(GLuint program, long& error)
2654e5c31af7Sopenharmony_ci	{
2655e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE, GL_ACTIVE_RESOURCES, 5, error);
2656e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE, GL_MAX_NAME_LENGTH, 3, error);
2657e5c31af7Sopenharmony_ci
2658e5c31af7Sopenharmony_ci		GLint res;
2659e5c31af7Sopenharmony_ci		glGetProgramStageiv(program, GL_COMPUTE_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &res);
2660e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_ACTIVE_RESOURCES, res, error);
2661e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NAME_LENGTH, 5, error);
2662e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, GL_MAX_NUM_COMPATIBLE_SUBROUTINES, 3,
2663e5c31af7Sopenharmony_ci									error);
2664e5c31af7Sopenharmony_ci
2665e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTS;
2666e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "ax", error);
2667e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "ay", error);
2668e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "bx", error);
2669e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "by", error);
2670e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE, indicesTS, "bz", error);
2671e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesTU;
2672e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU, "a", error);
2673e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU, "b[0]", error);
2674e5c31af7Sopenharmony_ci
2675e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["ax"], "ax", error);
2676e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["ay"], "ay", error);
2677e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["bx"], "bx", error);
2678e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["by"], "by", error);
2679e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE, indicesTS["bz"], "bz", error);
2680e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["a"], "a", error);
2681e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["b[0]"], "b[0]", error);
2682e5c31af7Sopenharmony_ci
2683e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_COMPUTE_SUBROUTINE_UNIFORM, "a",
2684e5c31af7Sopenharmony_ci										 glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "a"), error);
2685e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_COMPUTE_SUBROUTINE_UNIFORM, "b",
2686e5c31af7Sopenharmony_ci										 glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "b"), error);
2687e5c31af7Sopenharmony_ci
2688e5c31af7Sopenharmony_ci		GLenum propsS[]	= { GL_NAME_LENGTH };
2689e5c31af7Sopenharmony_ci		GLint  expectedS[] = { 3 };
2690e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["ax"], 1, propsS, 1, expectedS, error);
2691e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["ay"], 1, propsS, 1, expectedS, error);
2692e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["bx"], 1, propsS, 1, expectedS, error);
2693e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["by"], 1, propsS, 1, expectedS, error);
2694e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE, indicesTS["bz"], 1, propsS, 1, expectedS, error);
2695e5c31af7Sopenharmony_ci
2696e5c31af7Sopenharmony_ci		GLenum propsU[]	= { GL_NAME_LENGTH, GL_ARRAY_SIZE, GL_NUM_COMPATIBLE_SUBROUTINES, GL_LOCATION };
2697e5c31af7Sopenharmony_ci		GLint  expectedU[] = { 2, 1, 2, glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "a") };
2698e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["a"], 4, propsU, 4, expectedU,
2699e5c31af7Sopenharmony_ci								   error);
2700e5c31af7Sopenharmony_ci		GLint expectedU2[] = { 5, 3, 3, glGetSubroutineUniformLocation(program, GL_COMPUTE_SHADER, "b") };
2701e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_COMPUTE_SUBROUTINE_UNIFORM, indicesTU["b[0]"], 4, propsU, 4, expectedU2,
2702e5c31af7Sopenharmony_ci								   error);
2703e5c31af7Sopenharmony_ci	}
2704e5c31af7Sopenharmony_ci
2705e5c31af7Sopenharmony_ci	virtual long Run()
2706e5c31af7Sopenharmony_ci	{
2707e5c31af7Sopenharmony_ci		GLuint program = CreateComputeProgram(ComputeShader());
2708e5c31af7Sopenharmony_ci		glLinkProgram(program);
2709e5c31af7Sopenharmony_ci		if (!CheckProgram(program))
2710e5c31af7Sopenharmony_ci		{
2711e5c31af7Sopenharmony_ci			glDeleteProgram(program);
2712e5c31af7Sopenharmony_ci			return ERROR;
2713e5c31af7Sopenharmony_ci		}
2714e5c31af7Sopenharmony_ci		glUseProgram(program);
2715e5c31af7Sopenharmony_ci
2716e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2717e5c31af7Sopenharmony_ci
2718e5c31af7Sopenharmony_ci		VerifyCompute(program, error);
2719e5c31af7Sopenharmony_ci
2720e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2721e5c31af7Sopenharmony_ci		return error;
2722e5c31af7Sopenharmony_ci	}
2723e5c31af7Sopenharmony_ci};
2724e5c31af7Sopenharmony_ci
2725e5c31af7Sopenharmony_ciclass InvalidValueTest : public SimpleShaders
2726e5c31af7Sopenharmony_ci{
2727e5c31af7Sopenharmony_ci	virtual std::string Title()
2728e5c31af7Sopenharmony_ci	{
2729e5c31af7Sopenharmony_ci		return "Invalid Value Test";
2730e5c31af7Sopenharmony_ci	}
2731e5c31af7Sopenharmony_ci
2732e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
2733e5c31af7Sopenharmony_ci	{
2734e5c31af7Sopenharmony_ci		return "GL_INVALID_VALUE error is generated after every function call.";
2735e5c31af7Sopenharmony_ci	}
2736e5c31af7Sopenharmony_ci
2737e5c31af7Sopenharmony_ci	virtual std::string Purpose()
2738e5c31af7Sopenharmony_ci	{
2739e5c31af7Sopenharmony_ci		return "Verify that wrong use of functions generates GL_INVALID_VALUE as described in spec.";
2740e5c31af7Sopenharmony_ci	}
2741e5c31af7Sopenharmony_ci
2742e5c31af7Sopenharmony_ci	virtual std::string Method()
2743e5c31af7Sopenharmony_ci	{
2744e5c31af7Sopenharmony_ci		return "Call functions with invalid values and check if GL_INVALID_VALUE was generated.";
2745e5c31af7Sopenharmony_ci	}
2746e5c31af7Sopenharmony_ci
2747e5c31af7Sopenharmony_ci	virtual long Run()
2748e5c31af7Sopenharmony_ci	{
2749e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2750e5c31af7Sopenharmony_ci
2751e5c31af7Sopenharmony_ci		GLint   res = 0;
2752e5c31af7Sopenharmony_ci		GLsizei len = 0;
2753e5c31af7Sopenharmony_ci		GLchar  name[100] = { '\0' };
2754e5c31af7Sopenharmony_ci		GLenum  props[1]  = { GL_NAME_LENGTH };
2755e5c31af7Sopenharmony_ci
2756e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2757e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 1: <program> not a name of shader/program object"
2758e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2759e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(1337u, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2760e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2761e5c31af7Sopenharmony_ci		glGetProgramResourceIndex(31337u, GL_PROGRAM_INPUT, "pie");
2762e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2763e5c31af7Sopenharmony_ci		glGetProgramResourceName(1337u, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2764e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2765e5c31af7Sopenharmony_ci		glGetProgramResourceiv(1337u, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2766e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2767e5c31af7Sopenharmony_ci		glGetProgramResourceLocation(1337u, GL_PROGRAM_INPUT, "pie");
2768e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2769e5c31af7Sopenharmony_ci		glGetProgramResourceLocationIndex(1337u, GL_PROGRAM_OUTPUT, "pie");
2770e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2771e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2772e5c31af7Sopenharmony_ci
2773e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2774e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2775e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
2776e5c31af7Sopenharmony_ci		LinkProgram(program);
2777e5c31af7Sopenharmony_ci
2778e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2779e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message
2780e5c31af7Sopenharmony_ci			<< "Case 2: <index> is greater than the number of the active resources in GetProgramResourceName"
2781e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2782e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_PROGRAM_INPUT, 3000, 1024, &len, name);
2783e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2784e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2785e5c31af7Sopenharmony_ci
2786e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2787e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 3: <propCount> is zero in GetProgramResourceiv"
2788e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2789e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 0, props, 1024, &len, &res);
2790e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2791e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 3 finished" << tcu::TestLog::EndMessage;
2792e5c31af7Sopenharmony_ci
2793e5c31af7Sopenharmony_ci		std::string str = "position";
2794e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, -100, NULL, const_cast<char*>(str.c_str()));
2795e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2796e5c31af7Sopenharmony_ci		GLenum prop = GL_NAME_LENGTH;
2797e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, &prop, -100, &len, &res);
2798e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_VALUE, error);
2799e5c31af7Sopenharmony_ci
2800e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2801e5c31af7Sopenharmony_ci		return error;
2802e5c31af7Sopenharmony_ci	}
2803e5c31af7Sopenharmony_ci};
2804e5c31af7Sopenharmony_ci
2805e5c31af7Sopenharmony_ciclass InvalidEnumTest : public AtomicCounterSimple
2806e5c31af7Sopenharmony_ci{
2807e5c31af7Sopenharmony_ci	virtual std::string Title()
2808e5c31af7Sopenharmony_ci	{
2809e5c31af7Sopenharmony_ci		return "Invalid Enum Test";
2810e5c31af7Sopenharmony_ci	}
2811e5c31af7Sopenharmony_ci
2812e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
2813e5c31af7Sopenharmony_ci	{
2814e5c31af7Sopenharmony_ci		return "GL_INVALID_ENUM error is generated after every function call.";
2815e5c31af7Sopenharmony_ci	}
2816e5c31af7Sopenharmony_ci
2817e5c31af7Sopenharmony_ci	virtual std::string Purpose()
2818e5c31af7Sopenharmony_ci	{
2819e5c31af7Sopenharmony_ci		return "Verify that wrong use of functions generates GL_INVALID_ENUM as described in spec.";
2820e5c31af7Sopenharmony_ci	}
2821e5c31af7Sopenharmony_ci
2822e5c31af7Sopenharmony_ci	virtual std::string Method()
2823e5c31af7Sopenharmony_ci	{
2824e5c31af7Sopenharmony_ci		return "Call functions with invalid enums and check if GL_INVALID_ENUM was generated.";
2825e5c31af7Sopenharmony_ci	}
2826e5c31af7Sopenharmony_ci
2827e5c31af7Sopenharmony_ci	virtual long Run()
2828e5c31af7Sopenharmony_ci	{
2829e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2830e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2831e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
2832e5c31af7Sopenharmony_ci		LinkProgram(program);
2833e5c31af7Sopenharmony_ci
2834e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2835e5c31af7Sopenharmony_ci
2836e5c31af7Sopenharmony_ci		GLint   res = 0;
2837e5c31af7Sopenharmony_ci		GLsizei len = 0;
2838e5c31af7Sopenharmony_ci		GLchar  name[100] = { '\0' };
2839e5c31af7Sopenharmony_ci		GLenum  props[1]  = { GL_TEXTURE_1D };
2840e5c31af7Sopenharmony_ci
2841e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2842e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 1: <programInterface> is ATOMIC_COUNTER_BUFFER "
2843e5c31af7Sopenharmony_ci			<< "in GetProgramResourceIndex or GetProgramResourceName" << tcu::TestLog::EndMessage;
2844e5c31af7Sopenharmony_ci		glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, name);
2845e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_ENUM, error);
2846e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_ATOMIC_COUNTER_BUFFER, 0, 1024, &len, name);
2847e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_ENUM, error);
2848e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 1 finished" << tcu::TestLog::EndMessage;
2849e5c31af7Sopenharmony_ci
2850e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2851e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 2: <props> is not a property name supported by "
2852e5c31af7Sopenharmony_ci			<< "the command GetProgramResourceiv" << tcu::TestLog::EndMessage;
2853e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2854e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_ENUM, error);
2855e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 2 finished" << tcu::TestLog::EndMessage;
2856e5c31af7Sopenharmony_ci
2857e5c31af7Sopenharmony_ci		glGetProgramResourceLocation(program, GL_ATOMIC_COUNTER_BUFFER, "position");
2858e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_ENUM, error);
2859e5c31af7Sopenharmony_ci
2860e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2861e5c31af7Sopenharmony_ci		return error;
2862e5c31af7Sopenharmony_ci	}
2863e5c31af7Sopenharmony_ci};
2864e5c31af7Sopenharmony_ci
2865e5c31af7Sopenharmony_ciclass InvalidOperationTest : public SimpleShaders
2866e5c31af7Sopenharmony_ci{
2867e5c31af7Sopenharmony_ci	virtual std::string Title()
2868e5c31af7Sopenharmony_ci	{
2869e5c31af7Sopenharmony_ci		return "Invalid Operation Test";
2870e5c31af7Sopenharmony_ci	}
2871e5c31af7Sopenharmony_ci
2872e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
2873e5c31af7Sopenharmony_ci	{
2874e5c31af7Sopenharmony_ci		return "GL_INVALID_OPERATION error is generated after every function call.";
2875e5c31af7Sopenharmony_ci	}
2876e5c31af7Sopenharmony_ci
2877e5c31af7Sopenharmony_ci	virtual std::string Purpose()
2878e5c31af7Sopenharmony_ci	{
2879e5c31af7Sopenharmony_ci		return "Verify that wrong use of functions generates GL_INVALID_OPERATION as described in spec.";
2880e5c31af7Sopenharmony_ci	}
2881e5c31af7Sopenharmony_ci
2882e5c31af7Sopenharmony_ci	virtual std::string Method()
2883e5c31af7Sopenharmony_ci	{
2884e5c31af7Sopenharmony_ci		return "Perform invalid operation and check if GL_INVALID_OPERATION was generated.";
2885e5c31af7Sopenharmony_ci	}
2886e5c31af7Sopenharmony_ci
2887e5c31af7Sopenharmony_ci	virtual long Run()
2888e5c31af7Sopenharmony_ci	{
2889e5c31af7Sopenharmony_ci		long error = NO_ERROR;
2890e5c31af7Sopenharmony_ci
2891e5c31af7Sopenharmony_ci		GLuint program  = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2892e5c31af7Sopenharmony_ci		GLuint program2 = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
2893e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
2894e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
2895e5c31af7Sopenharmony_ci		LinkProgram(program);
2896e5c31af7Sopenharmony_ci
2897e5c31af7Sopenharmony_ci		const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
2898e5c31af7Sopenharmony_ci		GLint		 res = 0;
2899e5c31af7Sopenharmony_ci		GLsizei		 len = 0;
2900e5c31af7Sopenharmony_ci		GLchar		 name[100] = { '\0' };
2901e5c31af7Sopenharmony_ci		GLenum		 props[1]  = { GL_OFFSET };
2902e5c31af7Sopenharmony_ci
2903e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2904e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 1: <program> is the name of a shader object" << tcu::TestLog::EndMessage;
2905e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(sh, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
2906e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2907e5c31af7Sopenharmony_ci		glGetProgramResourceIndex(sh, GL_PROGRAM_INPUT, "pie");
2908e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2909e5c31af7Sopenharmony_ci		glGetProgramResourceName(sh, GL_PROGRAM_INPUT, 0, 1024, &len, name);
2910e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2911e5c31af7Sopenharmony_ci		glGetProgramResourceiv(sh, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2912e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2913e5c31af7Sopenharmony_ci		glGetProgramResourceLocation(sh, GL_PROGRAM_INPUT, "pie");
2914e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2915e5c31af7Sopenharmony_ci		glGetProgramResourceLocationIndex(sh, GL_PROGRAM_OUTPUT, "pie");
2916e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2917e5c31af7Sopenharmony_ci		glDeleteShader(sh);
2918e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2919e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 1 finished\n"
2920e5c31af7Sopenharmony_ci			<< "Case 2: <pname> is not supported in GetProgramInterfacei" << tcu::TestLog::EndMessage;
2921e5c31af7Sopenharmony_ci
2922e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
2923e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2924e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2925e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 2 finished\n"
2926e5c31af7Sopenharmony_ci			<< "Case 3: <props> is not supported in GetProgramResourceiv" << tcu::TestLog::EndMessage;
2927e5c31af7Sopenharmony_ci
2928e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 1, props, 1024, &len, &res);
2929e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2930e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog()
2931e5c31af7Sopenharmony_ci			<< tcu::TestLog::Message << "Case 3 finished\n"
2932e5c31af7Sopenharmony_ci			<< "Case 4: <program> has not been linked in GetProgramResourceLocation/GetProgramResourceLocationIndex"
2933e5c31af7Sopenharmony_ci			<< tcu::TestLog::EndMessage;
2934e5c31af7Sopenharmony_ci
2935e5c31af7Sopenharmony_ci		glGetProgramResourceLocation(program2, GL_PROGRAM_INPUT, "pie");
2936e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2937e5c31af7Sopenharmony_ci		glGetProgramResourceLocationIndex(program2, GL_PROGRAM_OUTPUT, "pie");
2938e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
2939e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Case 4 finished\n" << tcu::TestLog::EndMessage;
2940e5c31af7Sopenharmony_ci
2941e5c31af7Sopenharmony_ci		glDeleteProgram(program);
2942e5c31af7Sopenharmony_ci		glDeleteProgram(program2);
2943e5c31af7Sopenharmony_ci		return error;
2944e5c31af7Sopenharmony_ci	}
2945e5c31af7Sopenharmony_ci};
2946e5c31af7Sopenharmony_ci
2947e5c31af7Sopenharmony_ciclass ShaderStorageBlock : public SimpleShaders
2948e5c31af7Sopenharmony_ci{
2949e5c31af7Sopenharmony_ci	virtual std::string Title()
2950e5c31af7Sopenharmony_ci	{
2951e5c31af7Sopenharmony_ci		return "Shader Storage Block Test";
2952e5c31af7Sopenharmony_ci	}
2953e5c31af7Sopenharmony_ci
2954e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
2955e5c31af7Sopenharmony_ci	{
2956e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different types of storage blocks used";
2957e5c31af7Sopenharmony_ci	}
2958e5c31af7Sopenharmony_ci
2959e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
2960e5c31af7Sopenharmony_ci	{
2961e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_BUFFER_VARIABLE and GL_SHADER_STORAGE_BLOCK as an interface "
2962e5c31af7Sopenharmony_ci			   "params.\n";
2963e5c31af7Sopenharmony_ci	}
2964e5c31af7Sopenharmony_ci
2965e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
2966e5c31af7Sopenharmony_ci	{
2967e5c31af7Sopenharmony_ci		return "#version 430                   \n"
2968e5c31af7Sopenharmony_ci			   ""
2969e5c31af7Sopenharmony_ci			   "struct U {                     \n"
2970e5c31af7Sopenharmony_ci			   "   bool a[3];                  \n"
2971e5c31af7Sopenharmony_ci			   "   mediump vec4 b;             \n"
2972e5c31af7Sopenharmony_ci			   "   mediump mat3 c;             \n"
2973e5c31af7Sopenharmony_ci			   "   mediump float d[2];         \n"
2974e5c31af7Sopenharmony_ci			   "};                             \n"
2975e5c31af7Sopenharmony_ci			   ""
2976e5c31af7Sopenharmony_ci			   "struct UU {                    \n"
2977e5c31af7Sopenharmony_ci			   "   U a;                        \n"
2978e5c31af7Sopenharmony_ci			   "   U b[2];                     \n"
2979e5c31af7Sopenharmony_ci			   "   uvec2 c;                    \n"
2980e5c31af7Sopenharmony_ci			   "};                             \n"
2981e5c31af7Sopenharmony_ci			   ""
2982e5c31af7Sopenharmony_ci			   "layout(binding=4) buffer TrickyBuffer {          \n"
2983e5c31af7Sopenharmony_ci			   "   UU a[3];                                      \n"
2984e5c31af7Sopenharmony_ci			   "   mediump mat4 b;                               \n"
2985e5c31af7Sopenharmony_ci			   "   uint c;                                       \n"
2986e5c31af7Sopenharmony_ci			   "} e[2];                                          \n"
2987e5c31af7Sopenharmony_ci			   ""
2988e5c31af7Sopenharmony_ci			   "layout(binding = 0) buffer SimpleBuffer {        \n"
2989e5c31af7Sopenharmony_ci			   "   mediump mat3x2 a;                             \n"
2990e5c31af7Sopenharmony_ci			   "   mediump mat4 b;                               \n"
2991e5c31af7Sopenharmony_ci			   "   mediump vec4 c;                               \n"
2992e5c31af7Sopenharmony_ci			   "};                                               \n"
2993e5c31af7Sopenharmony_ci			   ""
2994e5c31af7Sopenharmony_ci			   "layout(binding = 1) buffer NotSoSimpleBuffer {   \n"
2995e5c31af7Sopenharmony_ci			   "   ivec2 a[4];                                   \n"
2996e5c31af7Sopenharmony_ci			   "   mediump mat3 b[2];                            \n"
2997e5c31af7Sopenharmony_ci			   "   mediump mat2 c;                               \n"
2998e5c31af7Sopenharmony_ci			   "} d;                                             \n"
2999e5c31af7Sopenharmony_ci			   ""
3000e5c31af7Sopenharmony_ci			   "out mediump vec4 color;                          \n"
3001e5c31af7Sopenharmony_ci			   ""
3002e5c31af7Sopenharmony_ci			   "void main() {                                    \n"
3003e5c31af7Sopenharmony_ci			   "    mediump float tmp;                           \n"
3004e5c31af7Sopenharmony_ci			   "    mediump float tmp2;                          \n"
3005e5c31af7Sopenharmony_ci			   "    tmp = e[0].a[0].b[0].d[0] * float(e[1].c);   \n"
3006e5c31af7Sopenharmony_ci			   "    tmp2 = a[0][0] * b[0][0] * c.x;                                \n"
3007e5c31af7Sopenharmony_ci			   "    tmp2 = tmp2 + float(d.a[0].y) + d.b[0][0][0] + d.c[0][0];      \n"
3008e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1) * tmp * tmp2;                         \n"
3009e5c31af7Sopenharmony_ci			   "}";
3010e5c31af7Sopenharmony_ci	}
3011e5c31af7Sopenharmony_ci
3012e5c31af7Sopenharmony_ci	virtual long Run()
3013e5c31af7Sopenharmony_ci	{
3014e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3015e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3016e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
3017e5c31af7Sopenharmony_ci		LinkProgram(program);
3018e5c31af7Sopenharmony_ci
3019e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3020e5c31af7Sopenharmony_ci
3021e5c31af7Sopenharmony_ci		GLint res;
3022e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 28, error);
3023e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &res);
3024e5c31af7Sopenharmony_ci		if (res < 7)
3025e5c31af7Sopenharmony_ci		{
3026e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3027e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
3028e5c31af7Sopenharmony_ci				<< "Error on: glGetProgramInterfaceiv, if: GL_BUFFER_VARIABLE, param: GL_ACTIVE_RESOURCES\n"
3029e5c31af7Sopenharmony_ci				<< "Expected value greater or equal to 7, got " << res << tcu::TestLog::EndMessage;
3030e5c31af7Sopenharmony_ci			error = ERROR;
3031e5c31af7Sopenharmony_ci		}
3032e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 4, error);
3033e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 18, error);
3034e5c31af7Sopenharmony_ci
3035e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesSSB;
3036e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesBV;
3037e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
3038e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "NotSoSimpleBuffer", error);
3039e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer", error);
3040e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "TrickyBuffer[1]", error);
3041e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a", error);
3042e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "b", error);
3043e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "c", error);
3044e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.a[0]", error);
3045e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.c", error);
3046e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "NotSoSimpleBuffer.b[0]", error);
3047e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.a[0].b[0].d", error);
3048e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.b", error);
3049e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "TrickyBuffer.c", error);
3050e5c31af7Sopenharmony_ci
3051e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer",
3052e5c31af7Sopenharmony_ci									 error);
3053e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"],
3054e5c31af7Sopenharmony_ci									 "NotSoSimpleBuffer", error);
3055e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], "TrickyBuffer[0]",
3056e5c31af7Sopenharmony_ci									 error);
3057e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], "TrickyBuffer[1]",
3058e5c31af7Sopenharmony_ci									 error);
3059e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
3060e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["b"], "b", error);
3061e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["c"], "c", error);
3062e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.a[0]"],
3063e5c31af7Sopenharmony_ci									 "NotSoSimpleBuffer.a[0]", error);
3064e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.c"],
3065e5c31af7Sopenharmony_ci									 "NotSoSimpleBuffer.c", error);
3066e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["NotSoSimpleBuffer.b[0]"],
3067e5c31af7Sopenharmony_ci									 "NotSoSimpleBuffer.b[0]", error);
3068e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"],
3069e5c31af7Sopenharmony_ci									 "TrickyBuffer.a[0].b[0].d[0]", error);
3070e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.b"], "TrickyBuffer.b", error);
3071e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.c"], "TrickyBuffer.c", error);
3072e5c31af7Sopenharmony_ci
3073e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
3074e5c31af7Sopenharmony_ci						   GL_BUFFER_BINDING,
3075e5c31af7Sopenharmony_ci						   GL_NUM_ACTIVE_VARIABLES,
3076e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
3077e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3078e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
3079e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3080e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3081e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER };
3082e5c31af7Sopenharmony_ci		GLint expected[] = { 13, 0, 3, 0, 1, 0, 0, 0, 0 };
3083e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 9, props, 9, expected,
3084e5c31af7Sopenharmony_ci								   error);
3085e5c31af7Sopenharmony_ci
3086e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
3087e5c31af7Sopenharmony_ci							GL_BUFFER_BINDING,
3088e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3089e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3090e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3091e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3092e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3093e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER };
3094e5c31af7Sopenharmony_ci		GLint expected2[] = { 18, 1, 0, 1, 0, 0, 0, 0 };
3095e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 8, props2, 8,
3096e5c31af7Sopenharmony_ci								   expected2, error);
3097e5c31af7Sopenharmony_ci		GLint expected3[] = { 16, 4, 0, 1, 0, 0, 0, 0 };
3098e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer"], 8, props2, 8,
3099e5c31af7Sopenharmony_ci								   expected3, error);
3100e5c31af7Sopenharmony_ci		GLint expected4[] = { 16, 5, 0, 1, 0, 0, 0, 0 };
3101e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["TrickyBuffer[1]"], 8, props2, 8,
3102e5c31af7Sopenharmony_ci								   expected4, error);
3103e5c31af7Sopenharmony_ci
3104e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
3105e5c31af7Sopenharmony_ci							GL_TYPE,
3106e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3107e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
3108e5c31af7Sopenharmony_ci							GL_ARRAY_STRIDE,
3109e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
3110e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3111e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3112e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3113e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3114e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3115e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3116e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_SIZE,
3117e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_STRIDE };
3118e5c31af7Sopenharmony_ci		GLint expected5[] = {
3119e5c31af7Sopenharmony_ci			2, GL_FLOAT_MAT3x2, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0
3120e5c31af7Sopenharmony_ci		};
3121e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a"], 14, props3, 14, expected5, error);
3122e5c31af7Sopenharmony_ci
3123e5c31af7Sopenharmony_ci		GLenum props4[] = { GL_NAME_LENGTH,
3124e5c31af7Sopenharmony_ci							GL_TYPE,
3125e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3126e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
3127e5c31af7Sopenharmony_ci							GL_MATRIX_STRIDE,
3128e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
3129e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3130e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3131e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3132e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3133e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3134e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3135e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_SIZE };
3136e5c31af7Sopenharmony_ci		GLint expected6[] = {
3137e5c31af7Sopenharmony_ci			28, GL_FLOAT, 2, static_cast<GLint>(indicesSSB["TrickyBuffer"]), 0, 0, 0, 1, 0, 0, 0, 0, 3
3138e5c31af7Sopenharmony_ci		};
3139e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["TrickyBuffer.a[0].b[0].d"], 13, props4, 13,
3140e5c31af7Sopenharmony_ci								   expected6, error);
3141e5c31af7Sopenharmony_ci
3142e5c31af7Sopenharmony_ci		GLenum			 prop	= GL_ACTIVE_VARIABLES;
3143e5c31af7Sopenharmony_ci		const GLsizei	bufSize = 1000;
3144e5c31af7Sopenharmony_ci		GLsizei			 length;
3145e5c31af7Sopenharmony_ci		GLint			 param[bufSize];
3146e5c31af7Sopenharmony_ci		std::set<GLuint> exp;
3147e5c31af7Sopenharmony_ci		exp.insert(indicesBV["a"]);
3148e5c31af7Sopenharmony_ci		exp.insert(indicesBV["b"]);
3149e5c31af7Sopenharmony_ci		exp.insert(indicesBV["c"]);
3150e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 1, &prop, bufSize, &length,
3151e5c31af7Sopenharmony_ci							   param);
3152e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
3153e5c31af7Sopenharmony_ci		{
3154e5c31af7Sopenharmony_ci			if (exp.find(param[i]) == exp.end())
3155e5c31af7Sopenharmony_ci			{
3156e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
3157e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
3158e5c31af7Sopenharmony_ci					<< "Unexpected index found in active variables of SimpleBuffer: " << param[i]
3159e5c31af7Sopenharmony_ci					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
3160e5c31af7Sopenharmony_ci					   "GL_SHADER_STORAGE_BLOCK"
3161e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
3162e5c31af7Sopenharmony_ci				glDeleteProgram(program);
3163e5c31af7Sopenharmony_ci				return ERROR;
3164e5c31af7Sopenharmony_ci			}
3165e5c31af7Sopenharmony_ci			else if (length != 3)
3166e5c31af7Sopenharmony_ci			{
3167e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
3168e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES "
3169e5c31af7Sopenharmony_ci												"interface: GL_SHADER_STORAGE_BLOCK\n"
3170e5c31af7Sopenharmony_ci					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
3171e5c31af7Sopenharmony_ci				glDeleteProgram(program);
3172e5c31af7Sopenharmony_ci				return ERROR;
3173e5c31af7Sopenharmony_ci			}
3174e5c31af7Sopenharmony_ci		}
3175e5c31af7Sopenharmony_ci		std::set<GLuint> exp2;
3176e5c31af7Sopenharmony_ci		exp2.insert(indicesBV["NotSoSimpleBuffer.a[0]"]);
3177e5c31af7Sopenharmony_ci		exp2.insert(indicesBV["NotSoSimpleBuffer.b[0]"]);
3178e5c31af7Sopenharmony_ci		exp2.insert(indicesBV["NotSoSimpleBuffer.c"]);
3179e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["NotSoSimpleBuffer"], 1, &prop, bufSize,
3180e5c31af7Sopenharmony_ci							   &length, param);
3181e5c31af7Sopenharmony_ci		for (int i = 0; i < length; ++i)
3182e5c31af7Sopenharmony_ci		{
3183e5c31af7Sopenharmony_ci			if (exp2.find(param[i]) == exp2.end())
3184e5c31af7Sopenharmony_ci			{
3185e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
3186e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message
3187e5c31af7Sopenharmony_ci					<< "Unexpected index found in active variables of NotSoSimpleBuffer: " << param[i]
3188e5c31af7Sopenharmony_ci					<< "\nCall: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES interface: "
3189e5c31af7Sopenharmony_ci					   "GL_SHADER_STORAGE_BLOCK"
3190e5c31af7Sopenharmony_ci					<< tcu::TestLog::EndMessage;
3191e5c31af7Sopenharmony_ci				glDeleteProgram(program);
3192e5c31af7Sopenharmony_ci				return ERROR;
3193e5c31af7Sopenharmony_ci			}
3194e5c31af7Sopenharmony_ci			else if (length != 3)
3195e5c31af7Sopenharmony_ci			{
3196e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog()
3197e5c31af7Sopenharmony_ci					<< tcu::TestLog::Message << "Call: glGetProgramResourceiv, property: GL_ACTIVE_VARIABLES "
3198e5c31af7Sopenharmony_ci												"interface: GL_SHADER_STORAGE_BLOCK\n"
3199e5c31af7Sopenharmony_ci					<< "Expected length: 3, actual length: " << length << tcu::TestLog::EndMessage;
3200e5c31af7Sopenharmony_ci				glDeleteProgram(program);
3201e5c31af7Sopenharmony_ci				return ERROR;
3202e5c31af7Sopenharmony_ci			}
3203e5c31af7Sopenharmony_ci		}
3204e5c31af7Sopenharmony_ci
3205e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &res);
3206e5c31af7Sopenharmony_ci		if (res < 3)
3207e5c31af7Sopenharmony_ci		{
3208e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3209e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Value of GL_MAX_NUM_ACTIVE_VARIABLES less than 3!\n"
3210e5c31af7Sopenharmony_ci				<< "Call: glGetProgramInterfaceiv, interface: GL_SHADER_STORAGE_BLOCK" << tcu::TestLog::EndMessage;
3211e5c31af7Sopenharmony_ci			return ERROR;
3212e5c31af7Sopenharmony_ci		}
3213e5c31af7Sopenharmony_ci
3214e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3215e5c31af7Sopenharmony_ci		return error;
3216e5c31af7Sopenharmony_ci	}
3217e5c31af7Sopenharmony_ci};
3218e5c31af7Sopenharmony_ci
3219e5c31af7Sopenharmony_ciclass UniformBlockArray : public SimpleShaders
3220e5c31af7Sopenharmony_ci{
3221e5c31af7Sopenharmony_ci	virtual std::string Title()
3222e5c31af7Sopenharmony_ci	{
3223e5c31af7Sopenharmony_ci		return "Uniform Block Array Test";
3224e5c31af7Sopenharmony_ci	}
3225e5c31af7Sopenharmony_ci
3226e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3227e5c31af7Sopenharmony_ci	{
3228e5c31af7Sopenharmony_ci		return "verify BLOCK_INDEX property when an interface block is declared as an array of block instances";
3229e5c31af7Sopenharmony_ci	}
3230e5c31af7Sopenharmony_ci
3231e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3232e5c31af7Sopenharmony_ci	{
3233e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_BLOCK_INDEX as an interface param.\n";
3234e5c31af7Sopenharmony_ci	}
3235e5c31af7Sopenharmony_ci
3236e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
3237e5c31af7Sopenharmony_ci	{
3238e5c31af7Sopenharmony_ci		return "#version 430                    \n"
3239e5c31af7Sopenharmony_ci			   "void main(void)                 \n"
3240e5c31af7Sopenharmony_ci			   "{                               \n"
3241e5c31af7Sopenharmony_ci			   "    gl_Position = vec4(1.0);    \n"
3242e5c31af7Sopenharmony_ci			   "}";
3243e5c31af7Sopenharmony_ci	}
3244e5c31af7Sopenharmony_ci
3245e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
3246e5c31af7Sopenharmony_ci	{
3247e5c31af7Sopenharmony_ci		return "#version 430                   \n"
3248e5c31af7Sopenharmony_ci			   "uniform TestBlock {            \n"
3249e5c31af7Sopenharmony_ci			   "   mediump vec4 color;         \n"
3250e5c31af7Sopenharmony_ci			   "} blockInstance[4];            \n"
3251e5c31af7Sopenharmony_ci			   ""
3252e5c31af7Sopenharmony_ci			   "out mediump vec4 color;                                      \n"
3253e5c31af7Sopenharmony_ci			   "void main() {                                                \n"
3254e5c31af7Sopenharmony_ci			   "    color = blockInstance[2].color + blockInstance[3].color; \n"
3255e5c31af7Sopenharmony_ci			   "}";
3256e5c31af7Sopenharmony_ci	}
3257e5c31af7Sopenharmony_ci
3258e5c31af7Sopenharmony_ci	virtual long Run()
3259e5c31af7Sopenharmony_ci	{
3260e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3261e5c31af7Sopenharmony_ci		LinkProgram(program);
3262e5c31af7Sopenharmony_ci
3263e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3264e5c31af7Sopenharmony_ci
3265e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesUB;
3266e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, indicesUB, "TestBlock", error);
3267e5c31af7Sopenharmony_ci
3268e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
3269e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "TestBlock.color", error);
3270e5c31af7Sopenharmony_ci
3271e5c31af7Sopenharmony_ci		GLenum props[]	= { GL_BLOCK_INDEX };
3272e5c31af7Sopenharmony_ci		GLint  expected[] = { static_cast<GLint>(indicesUB["TestBlock"]) };
3273e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["TestBlock.color"], 1, props, 1, expected, error);
3274e5c31af7Sopenharmony_ci
3275e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3276e5c31af7Sopenharmony_ci		return error;
3277e5c31af7Sopenharmony_ci	}
3278e5c31af7Sopenharmony_ci};
3279e5c31af7Sopenharmony_ci
3280e5c31af7Sopenharmony_ciclass TransformFeedbackBuiltin : public SimpleShaders
3281e5c31af7Sopenharmony_ci{
3282e5c31af7Sopenharmony_ci	virtual std::string Title()
3283e5c31af7Sopenharmony_ci	{
3284e5c31af7Sopenharmony_ci		return "Transform Feedback Built-in Variables";
3285e5c31af7Sopenharmony_ci	}
3286e5c31af7Sopenharmony_ci
3287e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3288e5c31af7Sopenharmony_ci	{
3289e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different types of out variables used";
3290e5c31af7Sopenharmony_ci	}
3291e5c31af7Sopenharmony_ci
3292e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3293e5c31af7Sopenharmony_ci	{
3294e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_TRANSFORM_FEEDBACK_VARYING as an interface param with"
3295e5c31af7Sopenharmony_ci			   " built-in variables (gl_NextBuffer, gl_SkipComponents) used.\n";
3296e5c31af7Sopenharmony_ci	}
3297e5c31af7Sopenharmony_ci
3298e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
3299e5c31af7Sopenharmony_ci	{
3300e5c31af7Sopenharmony_ci		return "#version 430                         \n"
3301e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
3302e5c31af7Sopenharmony_ci			   ""
3303e5c31af7Sopenharmony_ci			   "out ivec4 a;                         \n"
3304e5c31af7Sopenharmony_ci			   "out uvec2 c;                         \n"
3305e5c31af7Sopenharmony_ci			   "out uint d;                          \n"
3306e5c31af7Sopenharmony_ci			   "out int f;                           \n"
3307e5c31af7Sopenharmony_ci			   "out uint e;                          \n"
3308e5c31af7Sopenharmony_ci			   "out int g;                           \n"
3309e5c31af7Sopenharmony_ci			   ""
3310e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
3311e5c31af7Sopenharmony_ci			   "{                                    \n"
3312e5c31af7Sopenharmony_ci			   "   vec4 pos;                         \n"
3313e5c31af7Sopenharmony_ci			   "   a = ivec4(1);                     \n"
3314e5c31af7Sopenharmony_ci			   "   c = uvec2(1u);                    \n"
3315e5c31af7Sopenharmony_ci			   "   d = 1u;                           \n"
3316e5c31af7Sopenharmony_ci			   "   f = 1;                            \n"
3317e5c31af7Sopenharmony_ci			   "   e = 1u;                           \n"
3318e5c31af7Sopenharmony_ci			   "   g = 1;                            \n"
3319e5c31af7Sopenharmony_ci			   "   gl_Position = position;           \n"
3320e5c31af7Sopenharmony_ci			   "}";
3321e5c31af7Sopenharmony_ci	}
3322e5c31af7Sopenharmony_ci
3323e5c31af7Sopenharmony_ci	virtual long Run()
3324e5c31af7Sopenharmony_ci	{
3325e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3326e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3327e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
3328e5c31af7Sopenharmony_ci		const char* varyings[11] = { "a", "gl_NextBuffer",		"c", "gl_SkipComponents1", "d", "gl_SkipComponents2",
3329e5c31af7Sopenharmony_ci									 "f", "gl_SkipComponents3", "e", "gl_SkipComponents4", "g" };
3330e5c31af7Sopenharmony_ci		glTransformFeedbackVaryings(program, 11, varyings, GL_INTERLEAVED_ATTRIBS);
3331e5c31af7Sopenharmony_ci		LinkProgram(program);
3332e5c31af7Sopenharmony_ci
3333e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3334e5c31af7Sopenharmony_ci
3335e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, 11, error);
3336e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, 19, error);
3337e5c31af7Sopenharmony_ci
3338e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_NextBuffer", GL_INVALID_INDEX, error);
3339e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents1", GL_INVALID_INDEX,
3340e5c31af7Sopenharmony_ci									  error);
3341e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents2", GL_INVALID_INDEX,
3342e5c31af7Sopenharmony_ci									  error);
3343e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents3", GL_INVALID_INDEX,
3344e5c31af7Sopenharmony_ci									  error);
3345e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "gl_SkipComponents4", GL_INVALID_INDEX,
3346e5c31af7Sopenharmony_ci									  error);
3347e5c31af7Sopenharmony_ci
3348e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
3349e5c31af7Sopenharmony_ci		for (int i = 0; i < 11; i++)
3350e5c31af7Sopenharmony_ci		{
3351e5c31af7Sopenharmony_ci			GLsizei length;
3352e5c31af7Sopenharmony_ci			GLchar  name[1024] = { '\0' };
3353e5c31af7Sopenharmony_ci			glGetProgramResourceName(program, GL_TRANSFORM_FEEDBACK_VARYING, i, 1024, &length, name);
3354e5c31af7Sopenharmony_ci			indices[name] = i;
3355e5c31af7Sopenharmony_ci		}
3356e5c31af7Sopenharmony_ci
3357e5c31af7Sopenharmony_ci		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Indices of builtins:\n"
3358e5c31af7Sopenharmony_ci											<< indices["gl_NextBuffer"] << ", " << indices["gl_SkipComponents1"] << ", "
3359e5c31af7Sopenharmony_ci											<< indices["gl_SkipComponents2"] << ", " << indices["gl_SkipComponents3"]
3360e5c31af7Sopenharmony_ci											<< ", " << indices["gl_SkipComponents4"] << tcu::TestLog::EndMessage;
3361e5c31af7Sopenharmony_ci
3362e5c31af7Sopenharmony_ci		GLenum props[]	= { GL_NAME_LENGTH, GL_TYPE, GL_ARRAY_SIZE };
3363e5c31af7Sopenharmony_ci		GLint  expected[] = { 14, GL_NONE, 0 };
3364e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_NextBuffer"], 3, props, 3,
3365e5c31af7Sopenharmony_ci								   expected, error);
3366e5c31af7Sopenharmony_ci		GLint expected2[] = { 19, GL_NONE, 1 };
3367e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents1"], 3, props, 3,
3368e5c31af7Sopenharmony_ci								   expected2, error);
3369e5c31af7Sopenharmony_ci		GLint expected3[] = { 19, GL_NONE, 2 };
3370e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents2"], 3, props, 3,
3371e5c31af7Sopenharmony_ci								   expected3, error);
3372e5c31af7Sopenharmony_ci		GLint expected4[] = { 19, GL_NONE, 3 };
3373e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents3"], 3, props, 3,
3374e5c31af7Sopenharmony_ci								   expected4, error);
3375e5c31af7Sopenharmony_ci		GLint expected5[] = { 19, GL_NONE, 4 };
3376e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, indices["gl_SkipComponents4"], 3, props, 3,
3377e5c31af7Sopenharmony_ci								   expected5, error);
3378e5c31af7Sopenharmony_ci
3379e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3380e5c31af7Sopenharmony_ci		return error;
3381e5c31af7Sopenharmony_ci	}
3382e5c31af7Sopenharmony_ci};
3383e5c31af7Sopenharmony_ci
3384e5c31af7Sopenharmony_ciclass NullLength : public SimpleShaders
3385e5c31af7Sopenharmony_ci{
3386e5c31af7Sopenharmony_ci
3387e5c31af7Sopenharmony_ci	virtual std::string Title()
3388e5c31af7Sopenharmony_ci	{
3389e5c31af7Sopenharmony_ci		return "NULL Length Test";
3390e5c31af7Sopenharmony_ci	}
3391e5c31af7Sopenharmony_ci
3392e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3393e5c31af7Sopenharmony_ci	{
3394e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that GetProgramResourceName with null length doesn't return length (doesn't "
3395e5c31af7Sopenharmony_ci			   "crash).\n";
3396e5c31af7Sopenharmony_ci	}
3397e5c31af7Sopenharmony_ci
3398e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
3399e5c31af7Sopenharmony_ci	{
3400e5c31af7Sopenharmony_ci		return "#version 430                         \n"
3401e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
3402e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
3403e5c31af7Sopenharmony_ci			   "{                                    \n"
3404e5c31af7Sopenharmony_ci			   "    gl_Position = position;          \n"
3405e5c31af7Sopenharmony_ci			   "}";
3406e5c31af7Sopenharmony_ci	}
3407e5c31af7Sopenharmony_ci
3408e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
3409e5c31af7Sopenharmony_ci	{
3410e5c31af7Sopenharmony_ci		return "#version 430                   \n"
3411e5c31af7Sopenharmony_ci			   "out vec4 color;                \n"
3412e5c31af7Sopenharmony_ci			   "void main() {                  \n"
3413e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1);  \n"
3414e5c31af7Sopenharmony_ci			   "}";
3415e5c31af7Sopenharmony_ci	}
3416e5c31af7Sopenharmony_ci
3417e5c31af7Sopenharmony_ci	virtual long Run()
3418e5c31af7Sopenharmony_ci	{
3419e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3420e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3421e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
3422e5c31af7Sopenharmony_ci		LinkProgram(program);
3423e5c31af7Sopenharmony_ci
3424e5c31af7Sopenharmony_ci		GLchar name[1024] = { '\0' };
3425e5c31af7Sopenharmony_ci		GLuint index	  = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color");
3426e5c31af7Sopenharmony_ci		GLenum prop		  = GL_ARRAY_SIZE;
3427e5c31af7Sopenharmony_ci		GLint  res;
3428e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, 1024, NULL, name);
3429e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &prop, 1, NULL, &res);
3430e5c31af7Sopenharmony_ci
3431e5c31af7Sopenharmony_ci		std::string expected = "color";
3432e5c31af7Sopenharmony_ci		if (name != expected)
3433e5c31af7Sopenharmony_ci		{
3434e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected name: " << expected
3435e5c31af7Sopenharmony_ci												<< ", got: " << name << tcu::TestLog::EndMessage;
3436e5c31af7Sopenharmony_ci			glDeleteProgram(program);
3437e5c31af7Sopenharmony_ci			return ERROR;
3438e5c31af7Sopenharmony_ci		}
3439e5c31af7Sopenharmony_ci		else if (res != 1)
3440e5c31af7Sopenharmony_ci		{
3441e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3442e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Expected array_size: 1, got: " << res << tcu::TestLog::EndMessage;
3443e5c31af7Sopenharmony_ci			glDeleteProgram(program);
3444e5c31af7Sopenharmony_ci			return ERROR;
3445e5c31af7Sopenharmony_ci		}
3446e5c31af7Sopenharmony_ci
3447e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3448e5c31af7Sopenharmony_ci		return NO_ERROR;
3449e5c31af7Sopenharmony_ci	}
3450e5c31af7Sopenharmony_ci};
3451e5c31af7Sopenharmony_ci
3452e5c31af7Sopenharmony_ciclass ArraysOfArrays : public SimpleShaders
3453e5c31af7Sopenharmony_ci{
3454e5c31af7Sopenharmony_ci
3455e5c31af7Sopenharmony_ci	virtual std::string Title()
3456e5c31af7Sopenharmony_ci	{
3457e5c31af7Sopenharmony_ci		return "Arrays Of Arrays Test";
3458e5c31af7Sopenharmony_ci	}
3459e5c31af7Sopenharmony_ci
3460e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3461e5c31af7Sopenharmony_ci	{
3462e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with multi dimensional uniform array used";
3463e5c31af7Sopenharmony_ci	}
3464e5c31af7Sopenharmony_ci
3465e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3466e5c31af7Sopenharmony_ci	{
3467e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that feature works correctly with arrays_of_arrays extension.\n";
3468e5c31af7Sopenharmony_ci	}
3469e5c31af7Sopenharmony_ci
3470e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
3471e5c31af7Sopenharmony_ci	{
3472e5c31af7Sopenharmony_ci		return "#version 430                         \n"
3473e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
3474e5c31af7Sopenharmony_ci			   "uniform vec4 a[3][4][5];             \n"
3475e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
3476e5c31af7Sopenharmony_ci			   "{                                    \n"
3477e5c31af7Sopenharmony_ci			   "    gl_Position = position;          \n"
3478e5c31af7Sopenharmony_ci			   "    for (int i = 0; i < 5; ++i)      \n"
3479e5c31af7Sopenharmony_ci			   "        gl_Position += a[2][1][i];   \n"
3480e5c31af7Sopenharmony_ci			   "}";
3481e5c31af7Sopenharmony_ci	}
3482e5c31af7Sopenharmony_ci
3483e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
3484e5c31af7Sopenharmony_ci	{
3485e5c31af7Sopenharmony_ci		return "#version 430                   \n"
3486e5c31af7Sopenharmony_ci			   "out vec4 color;                \n"
3487e5c31af7Sopenharmony_ci			   "void main() {                  \n"
3488e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1);  \n"
3489e5c31af7Sopenharmony_ci			   "}";
3490e5c31af7Sopenharmony_ci	}
3491e5c31af7Sopenharmony_ci
3492e5c31af7Sopenharmony_ci	virtual long Run()
3493e5c31af7Sopenharmony_ci	{
3494e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3495e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3496e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
3497e5c31af7Sopenharmony_ci		LinkProgram(program);
3498e5c31af7Sopenharmony_ci
3499e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3500e5c31af7Sopenharmony_ci
3501e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, 11, error);
3502e5c31af7Sopenharmony_ci
3503e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indices;
3504e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indices, "a[2][1]", error);
3505e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, "a[2][1][0]", indices["a[2][1]"], error);
3506e5c31af7Sopenharmony_ci
3507e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_UNIFORM, indices["a[2][1]"], "a[2][1][0]", error);
3508e5c31af7Sopenharmony_ci
3509e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
3510e5c31af7Sopenharmony_ci						   GL_TYPE,
3511e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
3512e5c31af7Sopenharmony_ci						   GL_OFFSET,
3513e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
3514e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
3515e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
3516e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
3517e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
3518e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
3519e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3520e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
3521e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3522e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3523e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
3524e5c31af7Sopenharmony_ci						   GL_LOCATION };
3525e5c31af7Sopenharmony_ci		GLint expected[] = {
3526e5c31af7Sopenharmony_ci			11, GL_FLOAT_VEC4, 5, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(program, "a[2][1]")
3527e5c31af7Sopenharmony_ci		};
3528e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indices["a[2][1]"], 16, props, 16, expected, error);
3529e5c31af7Sopenharmony_ci
3530e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3531e5c31af7Sopenharmony_ci		return error;
3532e5c31af7Sopenharmony_ci	}
3533e5c31af7Sopenharmony_ci};
3534e5c31af7Sopenharmony_ci
3535e5c31af7Sopenharmony_ciclass TopLevelArray : public SimpleShaders
3536e5c31af7Sopenharmony_ci{
3537e5c31af7Sopenharmony_ci
3538e5c31af7Sopenharmony_ci	virtual std::string Title()
3539e5c31af7Sopenharmony_ci	{
3540e5c31af7Sopenharmony_ci		return "Top Level Array Test";
3541e5c31af7Sopenharmony_ci	}
3542e5c31af7Sopenharmony_ci
3543e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3544e5c31af7Sopenharmony_ci	{
3545e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with multi dimensional array used inside storage block";
3546e5c31af7Sopenharmony_ci	}
3547e5c31af7Sopenharmony_ci
3548e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3549e5c31af7Sopenharmony_ci	{
3550e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that feature works correctly when querying for GL_TOP_LEVEL_ARRAY_SIZE\n"
3551e5c31af7Sopenharmony_ci			   " and GL_TOP_LEVEL_ARRAY_STRIDE extension.\n";
3552e5c31af7Sopenharmony_ci	}
3553e5c31af7Sopenharmony_ci
3554e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
3555e5c31af7Sopenharmony_ci	{
3556e5c31af7Sopenharmony_ci		return "#version 430                   \n"
3557e5c31af7Sopenharmony_ci			   "buffer Block {                       \n"
3558e5c31af7Sopenharmony_ci			   "   vec4 a[5][4][3];                  \n"
3559e5c31af7Sopenharmony_ci			   "};                                   \n"
3560e5c31af7Sopenharmony_ci			   "out vec4 color;                             \n"
3561e5c31af7Sopenharmony_ci			   "void main() {                               \n"
3562e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1) + a[0][0][0];  \n"
3563e5c31af7Sopenharmony_ci			   "}";
3564e5c31af7Sopenharmony_ci	}
3565e5c31af7Sopenharmony_ci
3566e5c31af7Sopenharmony_ci	virtual long Run()
3567e5c31af7Sopenharmony_ci	{
3568e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
3569e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
3570e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
3571e5c31af7Sopenharmony_ci		LinkProgram(program);
3572e5c31af7Sopenharmony_ci
3573e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3574e5c31af7Sopenharmony_ci
3575e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 11, error);
3576e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 6, error);
3577e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
3578e5c31af7Sopenharmony_ci
3579e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesSSB;
3580e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesBV;
3581e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "a[0][0]", error);
3582e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Block", error);
3583e5c31af7Sopenharmony_ci
3584e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], "a[0][0][0]", error);
3585e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Block"], "Block", error);
3586e5c31af7Sopenharmony_ci
3587e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
3588e5c31af7Sopenharmony_ci							GL_TYPE,
3589e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3590e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
3591e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
3592e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3593e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3594e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3595e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3596e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3597e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3598e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_SIZE };
3599e5c31af7Sopenharmony_ci		GLint expected5[] = { 11, GL_FLOAT_VEC4, 3, static_cast<GLint>(indicesSSB["Block"]), 0, 0, 1, 0, 0, 0, 0, 5 };
3600e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 12, props3, 12, expected5, error);
3601e5c31af7Sopenharmony_ci
3602e5c31af7Sopenharmony_ci		GLenum  prop = GL_TOP_LEVEL_ARRAY_STRIDE;
3603e5c31af7Sopenharmony_ci		GLsizei len;
3604e5c31af7Sopenharmony_ci		GLint   res;
3605e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["a[0][0]"], 1, &prop, 1024, &len, &res);
3606e5c31af7Sopenharmony_ci		if (res <= 0)
3607e5c31af7Sopenharmony_ci		{
3608e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
3609e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
3610e5c31af7Sopenharmony_ci				<< "Call: glGetProgramResourceiv, interface: GL_BUFFER_VARIABLE, param: GL_TOP_LEVEL_ARRAY_STRIDE\n"
3611e5c31af7Sopenharmony_ci				<< "Expected value greater than 0, got: " << res << tcu::TestLog::EndMessage;
3612e5c31af7Sopenharmony_ci			glDeleteProgram(program);
3613e5c31af7Sopenharmony_ci			return ERROR;
3614e5c31af7Sopenharmony_ci		}
3615e5c31af7Sopenharmony_ci
3616e5c31af7Sopenharmony_ci		glDeleteProgram(program);
3617e5c31af7Sopenharmony_ci		return error;
3618e5c31af7Sopenharmony_ci	}
3619e5c31af7Sopenharmony_ci};
3620e5c31af7Sopenharmony_ci
3621e5c31af7Sopenharmony_ciclass SeparateProgramsVertex : public SimpleShaders
3622e5c31af7Sopenharmony_ci{
3623e5c31af7Sopenharmony_cipublic:
3624e5c31af7Sopenharmony_ci	virtual std::string Title()
3625e5c31af7Sopenharmony_ci	{
3626e5c31af7Sopenharmony_ci		return "Separate Program Vertex Shader Test";
3627e5c31af7Sopenharmony_ci	}
3628e5c31af7Sopenharmony_ci
3629e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3630e5c31af7Sopenharmony_ci	{
3631e5c31af7Sopenharmony_ci		return "vertex shader as separate shader object";
3632e5c31af7Sopenharmony_ci	}
3633e5c31af7Sopenharmony_ci
3634e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3635e5c31af7Sopenharmony_ci	{
3636e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
3637e5c31af7Sopenharmony_ci			   "functionality.\n";
3638e5c31af7Sopenharmony_ci	}
3639e5c31af7Sopenharmony_ci
3640e5c31af7Sopenharmony_ci	virtual GLuint CreateShaderProgram(GLenum type, GLsizei count, const GLchar** strings)
3641e5c31af7Sopenharmony_ci	{
3642e5c31af7Sopenharmony_ci		GLuint program = glCreateShaderProgramv(type, count, strings);
3643e5c31af7Sopenharmony_ci		GLint  status  = GL_TRUE;
3644e5c31af7Sopenharmony_ci		glGetProgramiv(program, GL_LINK_STATUS, &status);
3645e5c31af7Sopenharmony_ci		if (status == GL_FALSE)
3646e5c31af7Sopenharmony_ci		{
3647e5c31af7Sopenharmony_ci			GLsizei length;
3648e5c31af7Sopenharmony_ci			GLchar  log[1024];
3649e5c31af7Sopenharmony_ci			glGetProgramInfoLog(program, sizeof(log), &length, log);
3650e5c31af7Sopenharmony_ci			if (length > 1)
3651e5c31af7Sopenharmony_ci			{
3652e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
3653e5c31af7Sopenharmony_ci													<< log << tcu::TestLog::EndMessage;
3654e5c31af7Sopenharmony_ci			}
3655e5c31af7Sopenharmony_ci		}
3656e5c31af7Sopenharmony_ci		return program;
3657e5c31af7Sopenharmony_ci	}
3658e5c31af7Sopenharmony_ci
3659e5c31af7Sopenharmony_ci	virtual long Run()
3660e5c31af7Sopenharmony_ci	{
3661e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3662e5c31af7Sopenharmony_ci
3663e5c31af7Sopenharmony_ci		const char* srcVS = "#version 430 core                          \n"
3664e5c31af7Sopenharmony_ci							"layout(location = 0) in vec4 in_vertex;    \n"
3665e5c31af7Sopenharmony_ci							""
3666e5c31af7Sopenharmony_ci							"out Color {                                \n"
3667e5c31af7Sopenharmony_ci							"  float r, g, b;                           \n"
3668e5c31af7Sopenharmony_ci							"  vec4 iLikePie;                           \n"
3669e5c31af7Sopenharmony_ci							"} vs_color;                                \n"
3670e5c31af7Sopenharmony_ci							"out gl_PerVertex {                         \n"
3671e5c31af7Sopenharmony_ci							"  vec4 gl_Position;                        \n"
3672e5c31af7Sopenharmony_ci							"};                                         \n"
3673e5c31af7Sopenharmony_ci							""
3674e5c31af7Sopenharmony_ci							"uniform float u;                           \n"
3675e5c31af7Sopenharmony_ci							"uniform vec4 v;                            \n"
3676e5c31af7Sopenharmony_ci							""
3677e5c31af7Sopenharmony_ci							"void main() {                              \n"
3678e5c31af7Sopenharmony_ci							"  gl_Position = in_vertex;                 \n"
3679e5c31af7Sopenharmony_ci							"  vs_color.r = u;                          \n"
3680e5c31af7Sopenharmony_ci							"  vs_color.g = 0.0;                        \n"
3681e5c31af7Sopenharmony_ci							"  vs_color.b = 0.0;                        \n"
3682e5c31af7Sopenharmony_ci							"  vs_color.iLikePie = v;                   \n"
3683e5c31af7Sopenharmony_ci							"}";
3684e5c31af7Sopenharmony_ci
3685e5c31af7Sopenharmony_ci		const GLuint vs = CreateShaderProgram(GL_VERTEX_SHADER, 1, &srcVS);
3686e5c31af7Sopenharmony_ci
3687e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
3688e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 2, error);
3689e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 10, error);
3690e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
3691e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 15, error);
3692e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(vs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 5, error);
3693e5c31af7Sopenharmony_ci
3694e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
3695e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesI;
3696e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesO;
3697e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "u", error);
3698e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_UNIFORM, indicesU, "v", error);
3699e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_INPUT, indicesI, "in_vertex", error);
3700e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.r", error);
3701e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.g", error);
3702e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.b", error);
3703e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "Color.iLikePie", error);
3704e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(vs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
3705e5c31af7Sopenharmony_ci
3706e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["u"], "u", error);
3707e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_UNIFORM, indicesU["v"], "v", error);
3708e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], "in_vertex", error);
3709e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.r"], "Color.r", error);
3710e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.g"], "Color.g", error);
3711e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.b"], "Color.b", error);
3712e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["Color.iLikePie"], "Color.iLikePie", error);
3713e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(vs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
3714e5c31af7Sopenharmony_ci
3715e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "u", glGetUniformLocation(vs, "u"), error);
3716e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(vs, GL_UNIFORM, "v", glGetUniformLocation(vs, "v"), error);
3717e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(vs, GL_PROGRAM_INPUT, "in_vertex", 0, error);
3718e5c31af7Sopenharmony_ci
3719e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.r", -1, error);
3720e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.g", -1, error);
3721e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.b", -1, error);
3722e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "Color.iLikePie", -1, error);
3723e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(vs, GL_PROGRAM_OUTPUT, "gl_Position", -1, error);
3724e5c31af7Sopenharmony_ci
3725e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
3726e5c31af7Sopenharmony_ci						   GL_TYPE,
3727e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
3728e5c31af7Sopenharmony_ci						   GL_OFFSET,
3729e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
3730e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
3731e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
3732e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
3733e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
3734e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
3735e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
3736e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
3737e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3738e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3739e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
3740e5c31af7Sopenharmony_ci						   GL_LOCATION };
3741e5c31af7Sopenharmony_ci		GLint expected[] = {
3742e5c31af7Sopenharmony_ci			2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, 0, 1, glGetUniformLocation(vs, "v")
3743e5c31af7Sopenharmony_ci		};
3744e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(vs, GL_UNIFORM, indicesU["v"], 16, props, 16, expected, error);
3745e5c31af7Sopenharmony_ci
3746e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
3747e5c31af7Sopenharmony_ci							GL_TYPE,
3748e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3749e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3750e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3751e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3752e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3753e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3754e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3755e5c31af7Sopenharmony_ci							GL_LOCATION,
3756e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH };
3757e5c31af7Sopenharmony_ci		GLint expected2[] = { 10, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
3758e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(vs, GL_PROGRAM_INPUT, indicesI["in_vertex"], 11, props2, 11, expected2, error);
3759e5c31af7Sopenharmony_ci
3760e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
3761e5c31af7Sopenharmony_ci							GL_TYPE,
3762e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3763e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3764e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3765e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3766e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3767e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3768e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3769e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH,
3770e5c31af7Sopenharmony_ci							GL_LOCATION_INDEX };
3771e5c31af7Sopenharmony_ci		GLint expected3[] = { 15, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, -1 };
3772e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(vs, GL_PROGRAM_OUTPUT, indicesO["Color.iLikePie"], 11, props3, 11, expected3, error);
3773e5c31af7Sopenharmony_ci
3774e5c31af7Sopenharmony_ci		glDeleteProgram(vs);
3775e5c31af7Sopenharmony_ci		return error;
3776e5c31af7Sopenharmony_ci	}
3777e5c31af7Sopenharmony_ci};
3778e5c31af7Sopenharmony_ci
3779e5c31af7Sopenharmony_ciclass SeparateProgramsTessControl : public SeparateProgramsVertex
3780e5c31af7Sopenharmony_ci{
3781e5c31af7Sopenharmony_ci
3782e5c31af7Sopenharmony_ci	virtual std::string Title()
3783e5c31af7Sopenharmony_ci	{
3784e5c31af7Sopenharmony_ci		return "Separate Program Tess Control Shader Test";
3785e5c31af7Sopenharmony_ci	}
3786e5c31af7Sopenharmony_ci
3787e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3788e5c31af7Sopenharmony_ci	{
3789e5c31af7Sopenharmony_ci		return "tess control shader as separate shader object";
3790e5c31af7Sopenharmony_ci	}
3791e5c31af7Sopenharmony_ci
3792e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
3793e5c31af7Sopenharmony_ci	{
3794e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that feature works correctly when using separate_shader_objects "
3795e5c31af7Sopenharmony_ci			   "functionality.\n";
3796e5c31af7Sopenharmony_ci	}
3797e5c31af7Sopenharmony_ci
3798e5c31af7Sopenharmony_ci	virtual long Run()
3799e5c31af7Sopenharmony_ci	{
3800e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3801e5c31af7Sopenharmony_ci
3802e5c31af7Sopenharmony_ci		const char* srcTCS = "#version 430                                                  \n"
3803e5c31af7Sopenharmony_ci							 "layout(vertices = 3) out;                                     \n"
3804e5c31af7Sopenharmony_ci							 "layout(location = 0) patch out vec4 data;                     \n"
3805e5c31af7Sopenharmony_ci							 "out gl_PerVertex {                                            \n"
3806e5c31af7Sopenharmony_ci							 "   vec4 gl_Position;                                          \n"
3807e5c31af7Sopenharmony_ci							 "   float gl_PointSize;                                        \n"
3808e5c31af7Sopenharmony_ci							 "   float gl_ClipDistance[];                                   \n"
3809e5c31af7Sopenharmony_ci							 "} gl_out[];                                                   \n"
3810e5c31af7Sopenharmony_ci							 ""
3811e5c31af7Sopenharmony_ci							 "in Color {                                 \n"
3812e5c31af7Sopenharmony_ci							 "  float r, g, b;                           \n"
3813e5c31af7Sopenharmony_ci							 "  vec4 iLikePie;                           \n"
3814e5c31af7Sopenharmony_ci							 "} vs_color[];                              \n"
3815e5c31af7Sopenharmony_ci							 ""
3816e5c31af7Sopenharmony_ci							 "void main() {                                                                   \n"
3817e5c31af7Sopenharmony_ci							 "   data = vec4(1);                                                              \n"
3818e5c31af7Sopenharmony_ci							 "   gl_out[gl_InvocationID].gl_Position =                                        \n"
3819e5c31af7Sopenharmony_ci							 "           vec4(vs_color[0].r, vs_color[0].g, vs_color[0].b, vs_color[0].iLikePie.x + "
3820e5c31af7Sopenharmony_ci							 "float(gl_InvocationID));       \n"
3821e5c31af7Sopenharmony_ci							 "   gl_TessLevelInner[0] = 1.0;                                                  \n"
3822e5c31af7Sopenharmony_ci							 "   gl_TessLevelInner[1] = 1.0;                                                  \n"
3823e5c31af7Sopenharmony_ci							 "   gl_TessLevelOuter[0] = 1.0;                                                  \n"
3824e5c31af7Sopenharmony_ci							 "   gl_TessLevelOuter[1] = 1.0;                                                  \n"
3825e5c31af7Sopenharmony_ci							 "   gl_TessLevelOuter[2] = 1.0;                                                  \n"
3826e5c31af7Sopenharmony_ci							 "}";
3827e5c31af7Sopenharmony_ci
3828e5c31af7Sopenharmony_ci		const GLuint tcs = CreateShaderProgram(GL_TESS_CONTROL_SHADER, 1, &srcTCS);
3829e5c31af7Sopenharmony_ci
3830e5c31af7Sopenharmony_ci		// gl_InvocationID should be included
3831e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 16, error);
3832e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 5, error);
3833e5c31af7Sopenharmony_ci
3834e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesI;
3835e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesO;
3836e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_PerVertex.gl_Position", error);
3837e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "data", error);
3838e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.r", error);
3839e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.g", error);
3840e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.b", error);
3841e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "Color.iLikePie", error);
3842e5c31af7Sopenharmony_ci
3843e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_PerVertex.gl_Position"],
3844e5c31af7Sopenharmony_ci									 "gl_PerVertex.gl_Position", error);
3845e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["data"], "data", error);
3846e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.r"], "Color.r", error);
3847e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.g"], "Color.g", error);
3848e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.b"], "Color.b", error);
3849e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["Color.iLikePie"], "Color.iLikePie", error);
3850e5c31af7Sopenharmony_ci
3851e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
3852e5c31af7Sopenharmony_ci							GL_TYPE,
3853e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3854e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3855e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3856e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3857e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3858e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3859e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3860e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH };
3861e5c31af7Sopenharmony_ci		GLint expected2[] = { 15, GL_FLOAT_VEC4, 1, 0, 0, 0, 1, 0, 0, 0 };
3862e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["Color.iLikePie"], 10, props2, 10, expected2, error);
3863e5c31af7Sopenharmony_ci
3864e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
3865e5c31af7Sopenharmony_ci							GL_TYPE,
3866e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3867e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3868e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3869e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3870e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3871e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3872e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3873e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH,
3874e5c31af7Sopenharmony_ci							GL_LOCATION,
3875e5c31af7Sopenharmony_ci							GL_LOCATION_INDEX };
3876e5c31af7Sopenharmony_ci		GLint expected3[] = { 5, GL_FLOAT_VEC4, 1, 0, 0, 0, 1, 0, 0, 1, 0, -1 };
3877e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["data"], 12, props3, 12, expected3, error);
3878e5c31af7Sopenharmony_ci
3879e5c31af7Sopenharmony_ci		glDeleteProgram(tcs);
3880e5c31af7Sopenharmony_ci		return error;
3881e5c31af7Sopenharmony_ci	}
3882e5c31af7Sopenharmony_ci};
3883e5c31af7Sopenharmony_ci
3884e5c31af7Sopenharmony_ciclass SeparateProgramsTessEval : public SeparateProgramsVertex
3885e5c31af7Sopenharmony_ci{
3886e5c31af7Sopenharmony_ci
3887e5c31af7Sopenharmony_ci	virtual std::string Title()
3888e5c31af7Sopenharmony_ci	{
3889e5c31af7Sopenharmony_ci		return "Separate Program Tess Eval Shader Test";
3890e5c31af7Sopenharmony_ci	}
3891e5c31af7Sopenharmony_ci
3892e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3893e5c31af7Sopenharmony_ci	{
3894e5c31af7Sopenharmony_ci		return "tess eval shader as separate shader object";
3895e5c31af7Sopenharmony_ci	}
3896e5c31af7Sopenharmony_ci
3897e5c31af7Sopenharmony_ci	virtual long Run()
3898e5c31af7Sopenharmony_ci	{
3899e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3900e5c31af7Sopenharmony_ci
3901e5c31af7Sopenharmony_ci		const char* srcTCS = "#version 430                                                  \n"
3902e5c31af7Sopenharmony_ci							 "layout(quads, equal_spacing, ccw) in;                         \n"
3903e5c31af7Sopenharmony_ci							 "out gl_PerVertex {                                            \n"
3904e5c31af7Sopenharmony_ci							 "   vec4 gl_Position;                                          \n"
3905e5c31af7Sopenharmony_ci							 "   float gl_PointSize;                                        \n"
3906e5c31af7Sopenharmony_ci							 "   float gl_ClipDistance[];                                   \n"
3907e5c31af7Sopenharmony_ci							 "};                                                            \n"
3908e5c31af7Sopenharmony_ci							 ""
3909e5c31af7Sopenharmony_ci							 "in gl_PerVertex {                   \n"
3910e5c31af7Sopenharmony_ci							 "   vec4 gl_Position;                \n"
3911e5c31af7Sopenharmony_ci							 "   float gl_PointSize;              \n"
3912e5c31af7Sopenharmony_ci							 "   float gl_ClipDistance[];         \n"
3913e5c31af7Sopenharmony_ci							 "} gl_in[];                          \n"
3914e5c31af7Sopenharmony_ci							 ""
3915e5c31af7Sopenharmony_ci							 "void main() {                                \n"
3916e5c31af7Sopenharmony_ci							 "   vec4 p0 = gl_in[0].gl_Position;           \n"
3917e5c31af7Sopenharmony_ci							 "   vec4 p1 = gl_in[1].gl_Position;           \n"
3918e5c31af7Sopenharmony_ci							 "   vec4 p2 = gl_in[2].gl_Position;           \n"
3919e5c31af7Sopenharmony_ci							 "   gl_Position = vec4(p0.x, p1.y, p2.z, p0.x);                 \n"
3920e5c31af7Sopenharmony_ci							 "}";
3921e5c31af7Sopenharmony_ci
3922e5c31af7Sopenharmony_ci		const GLuint tcs = CreateShaderProgram(GL_TESS_EVALUATION_SHADER, 1, &srcTCS);
3923e5c31af7Sopenharmony_ci
3924e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesI;
3925e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesO;
3926e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "gl_PerVertex.gl_Position", error);
3927e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
3928e5c31af7Sopenharmony_ci
3929e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"],
3930e5c31af7Sopenharmony_ci									 "gl_PerVertex.gl_Position", error);
3931e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
3932e5c31af7Sopenharmony_ci
3933e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
3934e5c31af7Sopenharmony_ci							GL_TYPE,
3935e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3936e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3937e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3938e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3939e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3940e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3941e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3942e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH };
3943e5c31af7Sopenharmony_ci		GLint expected2[] = { 25, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 1, 0, 0 };
3944e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"], 10, props2, 10,
3945e5c31af7Sopenharmony_ci								   expected2, error);
3946e5c31af7Sopenharmony_ci
3947e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
3948e5c31af7Sopenharmony_ci							GL_TYPE,
3949e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
3950e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
3951e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
3952e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
3953e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
3954e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
3955e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
3956e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH,
3957e5c31af7Sopenharmony_ci							GL_LOCATION_INDEX };
3958e5c31af7Sopenharmony_ci		GLint expected3[] = { 12, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 1, 0, 0, -1 };
3959e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], 11, props3, 11, expected3, error);
3960e5c31af7Sopenharmony_ci
3961e5c31af7Sopenharmony_ci		glDeleteProgram(tcs);
3962e5c31af7Sopenharmony_ci		return error;
3963e5c31af7Sopenharmony_ci	}
3964e5c31af7Sopenharmony_ci};
3965e5c31af7Sopenharmony_ci
3966e5c31af7Sopenharmony_ciclass SeparateProgramsGeometry : public SeparateProgramsVertex
3967e5c31af7Sopenharmony_ci{
3968e5c31af7Sopenharmony_ci
3969e5c31af7Sopenharmony_ci	virtual std::string Title()
3970e5c31af7Sopenharmony_ci	{
3971e5c31af7Sopenharmony_ci		return "Separate Program Geometry Shader Test";
3972e5c31af7Sopenharmony_ci	}
3973e5c31af7Sopenharmony_ci
3974e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
3975e5c31af7Sopenharmony_ci	{
3976e5c31af7Sopenharmony_ci		return "geometry shader as separate shader object";
3977e5c31af7Sopenharmony_ci	}
3978e5c31af7Sopenharmony_ci
3979e5c31af7Sopenharmony_ci	virtual long Run()
3980e5c31af7Sopenharmony_ci	{
3981e5c31af7Sopenharmony_ci		long error = NO_ERROR;
3982e5c31af7Sopenharmony_ci
3983e5c31af7Sopenharmony_ci		const char* srcTCS = "#version 430                                                  \n"
3984e5c31af7Sopenharmony_ci							 "layout(triangles) in;                                         \n"
3985e5c31af7Sopenharmony_ci							 "layout(triangle_strip, max_vertices = 4) out;                 \n"
3986e5c31af7Sopenharmony_ci							 ""
3987e5c31af7Sopenharmony_ci							 "out gl_PerVertex {                                            \n"
3988e5c31af7Sopenharmony_ci							 "   vec4 gl_Position;                                          \n"
3989e5c31af7Sopenharmony_ci							 "   float gl_PointSize;                                        \n"
3990e5c31af7Sopenharmony_ci							 "   float gl_ClipDistance[];                                   \n"
3991e5c31af7Sopenharmony_ci							 "};                                                            \n"
3992e5c31af7Sopenharmony_ci							 ""
3993e5c31af7Sopenharmony_ci							 "in gl_PerVertex {                                             \n"
3994e5c31af7Sopenharmony_ci							 "   vec4 gl_Position;                                          \n"
3995e5c31af7Sopenharmony_ci							 "   float gl_PointSize;                                        \n"
3996e5c31af7Sopenharmony_ci							 "   float gl_ClipDistance[];                                   \n"
3997e5c31af7Sopenharmony_ci							 "} gl_in[];                                                    \n"
3998e5c31af7Sopenharmony_ci							 ""
3999e5c31af7Sopenharmony_ci							 "void main() {                              \n"
4000e5c31af7Sopenharmony_ci							 "   gl_Position = vec4(-1, 1, 0, 1);        \n"
4001e5c31af7Sopenharmony_ci							 "   EmitVertex();                           \n"
4002e5c31af7Sopenharmony_ci							 "   gl_Position = vec4(-1, -1, 0, 1);       \n"
4003e5c31af7Sopenharmony_ci							 "   EmitVertex();                           \n"
4004e5c31af7Sopenharmony_ci							 "   gl_Position = vec4(1, 1, 0, 1);         \n"
4005e5c31af7Sopenharmony_ci							 "   EmitVertex();                           \n"
4006e5c31af7Sopenharmony_ci							 "   gl_Position = gl_in[0].gl_Position;     \n"
4007e5c31af7Sopenharmony_ci							 "   EmitVertex();                           \n"
4008e5c31af7Sopenharmony_ci							 "   EndPrimitive();                         \n"
4009e5c31af7Sopenharmony_ci							 "}";
4010e5c31af7Sopenharmony_ci
4011e5c31af7Sopenharmony_ci		const GLuint tcs = CreateShaderProgram(GL_GEOMETRY_SHADER, 1, &srcTCS);
4012e5c31af7Sopenharmony_ci
4013e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesI;
4014e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesO;
4015e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "gl_PerVertex.gl_Position", error);
4016e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "gl_Position", error);
4017e5c31af7Sopenharmony_ci
4018e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"],
4019e5c31af7Sopenharmony_ci									 "gl_PerVertex.gl_Position", error);
4020e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], "gl_Position", error);
4021e5c31af7Sopenharmony_ci
4022e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
4023e5c31af7Sopenharmony_ci							GL_TYPE,
4024e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
4025e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4026e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4027e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
4028e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4029e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4030e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4031e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH };
4032e5c31af7Sopenharmony_ci		GLint expected2[] = { 25, GL_FLOAT_VEC4, 1, 0, 0, 1, 0, 0, 0, 0 };
4033e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["gl_PerVertex.gl_Position"], 10, props2, 10,
4034e5c31af7Sopenharmony_ci								   expected2, error);
4035e5c31af7Sopenharmony_ci
4036e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
4037e5c31af7Sopenharmony_ci							GL_TYPE,
4038e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
4039e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4040e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4041e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
4042e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4043e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4044e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4045e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH,
4046e5c31af7Sopenharmony_ci							GL_LOCATION_INDEX };
4047e5c31af7Sopenharmony_ci		GLint expected3[] = { 12, GL_FLOAT_VEC4, 1, 0, 0, 1, 0, 0, 0, 0, -1 };
4048e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["gl_Position"], 11, props3, 11, expected3, error);
4049e5c31af7Sopenharmony_ci
4050e5c31af7Sopenharmony_ci		glDeleteProgram(tcs);
4051e5c31af7Sopenharmony_ci		return error;
4052e5c31af7Sopenharmony_ci	}
4053e5c31af7Sopenharmony_ci};
4054e5c31af7Sopenharmony_ci
4055e5c31af7Sopenharmony_ciclass SeparateProgramsFragment : public SeparateProgramsVertex
4056e5c31af7Sopenharmony_ci{
4057e5c31af7Sopenharmony_ci
4058e5c31af7Sopenharmony_ci	virtual std::string Title()
4059e5c31af7Sopenharmony_ci	{
4060e5c31af7Sopenharmony_ci		return "Separate Program Fragment Shader Test";
4061e5c31af7Sopenharmony_ci	}
4062e5c31af7Sopenharmony_ci
4063e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
4064e5c31af7Sopenharmony_ci	{
4065e5c31af7Sopenharmony_ci		return "fragment shader as separate shader object";
4066e5c31af7Sopenharmony_ci	}
4067e5c31af7Sopenharmony_ci
4068e5c31af7Sopenharmony_ci	virtual long Run()
4069e5c31af7Sopenharmony_ci	{
4070e5c31af7Sopenharmony_ci		long error = NO_ERROR;
4071e5c31af7Sopenharmony_ci
4072e5c31af7Sopenharmony_ci		const char* srcTCS = "#version 430                                     \n"
4073e5c31af7Sopenharmony_ci							 "out vec4 fs_color;                               \n"
4074e5c31af7Sopenharmony_ci							 ""
4075e5c31af7Sopenharmony_ci							 "layout(location = 1) uniform vec4 x;             \n"
4076e5c31af7Sopenharmony_ci							 ""
4077e5c31af7Sopenharmony_ci							 "layout(binding = 0) buffer SimpleBuffer {        \n"
4078e5c31af7Sopenharmony_ci							 "   vec4 a;                                       \n"
4079e5c31af7Sopenharmony_ci							 "};                                               \n"
4080e5c31af7Sopenharmony_ci							 ""
4081e5c31af7Sopenharmony_ci							 "in vec4 vs_color;                                \n"
4082e5c31af7Sopenharmony_ci							 "void main() {                                    \n"
4083e5c31af7Sopenharmony_ci							 "   fs_color = vs_color + x + a;                  \n"
4084e5c31af7Sopenharmony_ci							 "}";
4085e5c31af7Sopenharmony_ci
4086e5c31af7Sopenharmony_ci		const GLuint tcs = CreateShaderProgram(GL_FRAGMENT_SHADER, 1, &srcTCS);
4087e5c31af7Sopenharmony_ci
4088e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
4089e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
4090e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 9, error);
4091e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
4092e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_MAX_NAME_LENGTH, 2, error);
4093e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_UNIFORM, GL_ACTIVE_RESOURCES, 1, error);
4094e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 2, error);
4095e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
4096e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
4097e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 13, error);
4098e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(tcs, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
4099e5c31af7Sopenharmony_ci
4100e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesSSB;
4101e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesBV;
4102e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesI;
4103e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesO;
4104e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
4105e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_INPUT, indicesI, "vs_color", error);
4106e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_PROGRAM_OUTPUT, indicesO, "fs_color", error);
4107e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_UNIFORM, indicesU, "x", error);
4108e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB, "SimpleBuffer", error);
4109e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(tcs, GL_BUFFER_VARIABLE, indicesBV, "a", error);
4110e5c31af7Sopenharmony_ci
4111e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], "SimpleBuffer", error);
4112e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_BUFFER_VARIABLE, indicesBV["a"], "a", error);
4113e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], "vs_color", error);
4114e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], "fs_color", error);
4115e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(tcs, GL_UNIFORM, indicesU["x"], "x", error);
4116e5c31af7Sopenharmony_ci
4117e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(tcs, GL_UNIFORM, "x", 1, error);
4118e5c31af7Sopenharmony_ci
4119e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
4120e5c31af7Sopenharmony_ci							GL_TYPE,
4121e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
4122e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4123e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4124e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
4125e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4126e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4127e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4128e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH };
4129e5c31af7Sopenharmony_ci		GLint expected2[] = { 9, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0 };
4130e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_INPUT, indicesI["vs_color"], 10, props2, 10, expected2, error);
4131e5c31af7Sopenharmony_ci
4132e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
4133e5c31af7Sopenharmony_ci							GL_TYPE,
4134e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
4135e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4136e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4137e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
4138e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4139e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4140e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4141e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH,
4142e5c31af7Sopenharmony_ci							GL_LOCATION_INDEX };
4143e5c31af7Sopenharmony_ci		GLint expected3[] = { 9, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0 };
4144e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_PROGRAM_OUTPUT, indicesO["fs_color"], 11, props3, 11, expected3, error);
4145e5c31af7Sopenharmony_ci
4146e5c31af7Sopenharmony_ci		GLenum props5[] = { GL_NAME_LENGTH,
4147e5c31af7Sopenharmony_ci							GL_TYPE,
4148e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
4149e5c31af7Sopenharmony_ci							GL_OFFSET,
4150e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
4151e5c31af7Sopenharmony_ci							GL_ARRAY_STRIDE,
4152e5c31af7Sopenharmony_ci							GL_MATRIX_STRIDE,
4153e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
4154e5c31af7Sopenharmony_ci							GL_ATOMIC_COUNTER_BUFFER_INDEX,
4155e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4156e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4157e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4158e5c31af7Sopenharmony_ci							GL_LOCATION };
4159e5c31af7Sopenharmony_ci		GLint expected5[] = { 2, GL_FLOAT_VEC4, 1, -1, -1, -1, -1, 0, -1, 0, 1, 0, 1 };
4160e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_UNIFORM, indicesU["x"], 13, props5, 13, expected5, error);
4161e5c31af7Sopenharmony_ci
4162e5c31af7Sopenharmony_ci		GLenum props6[] = { GL_NAME_LENGTH,
4163e5c31af7Sopenharmony_ci							GL_BUFFER_BINDING,
4164e5c31af7Sopenharmony_ci							GL_NUM_ACTIVE_VARIABLES,
4165e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4166e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4167e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4168e5c31af7Sopenharmony_ci							GL_ACTIVE_VARIABLES };
4169e5c31af7Sopenharmony_ci		GLint expected6[] = { 13, 0, 1, 0, 1, 0, static_cast<GLint>(indicesBV["a"]) };
4170e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_SHADER_STORAGE_BLOCK, indicesSSB["SimpleBuffer"], 7, props6, 7, expected6,
4171e5c31af7Sopenharmony_ci								   error);
4172e5c31af7Sopenharmony_ci
4173e5c31af7Sopenharmony_ci		GLenum props7[] = { GL_NAME_LENGTH,
4174e5c31af7Sopenharmony_ci							GL_TYPE,
4175e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
4176e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
4177e5c31af7Sopenharmony_ci							GL_ARRAY_STRIDE,
4178e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
4179e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4180e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4181e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4182e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_SIZE,
4183e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_STRIDE };
4184e5c31af7Sopenharmony_ci		GLint expected7[] = {
4185e5c31af7Sopenharmony_ci			2, GL_FLOAT_VEC4, 1, static_cast<GLint>(indicesSSB["SimpleBuffer"]), 0, 0, 0, 1, 0, 1, 0
4186e5c31af7Sopenharmony_ci		};
4187e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(tcs, GL_BUFFER_VARIABLE, indicesBV["a"], 11, props7, 11, expected7, error);
4188e5c31af7Sopenharmony_ci
4189e5c31af7Sopenharmony_ci		glDeleteProgram(tcs);
4190e5c31af7Sopenharmony_ci		return error;
4191e5c31af7Sopenharmony_ci	}
4192e5c31af7Sopenharmony_ci};
4193e5c31af7Sopenharmony_ci
4194e5c31af7Sopenharmony_ciclass UniformBlockAdvanced : public SimpleShaders
4195e5c31af7Sopenharmony_ci{
4196e5c31af7Sopenharmony_ci	virtual std::string Title()
4197e5c31af7Sopenharmony_ci	{
4198e5c31af7Sopenharmony_ci		return "Uniform Block Advanced Test";
4199e5c31af7Sopenharmony_ci	}
4200e5c31af7Sopenharmony_ci
4201e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
4202e5c31af7Sopenharmony_ci	{
4203e5c31af7Sopenharmony_ci		return "fallthrough fragment and vertex shaders with different types of uniform blocks used";
4204e5c31af7Sopenharmony_ci	}
4205e5c31af7Sopenharmony_ci
4206e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
4207e5c31af7Sopenharmony_ci	{
4208e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify calls using GL_UNIFORM_BLOCK as an interface param and\n"
4209e5c31af7Sopenharmony_ci			   "verify results of querying offset, strides and row order.\n";
4210e5c31af7Sopenharmony_ci	}
4211e5c31af7Sopenharmony_ci
4212e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
4213e5c31af7Sopenharmony_ci	{
4214e5c31af7Sopenharmony_ci		return "#version 430                         \n"
4215e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
4216e5c31af7Sopenharmony_ci			   ""
4217e5c31af7Sopenharmony_ci			   "layout(row_major) uniform SimpleBlock {   \n"
4218e5c31af7Sopenharmony_ci			   "   mat4 a;                                \n"
4219e5c31af7Sopenharmony_ci			   "   vec4 b[10];                            \n"
4220e5c31af7Sopenharmony_ci			   "};                                        \n"
4221e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
4222e5c31af7Sopenharmony_ci			   "{                                    \n"
4223e5c31af7Sopenharmony_ci			   "    float tmp;                       \n"
4224e5c31af7Sopenharmony_ci			   "    tmp = a[0][0] + b[0].x;          \n"
4225e5c31af7Sopenharmony_ci			   "    gl_Position = position * tmp;    \n"
4226e5c31af7Sopenharmony_ci			   "}";
4227e5c31af7Sopenharmony_ci	}
4228e5c31af7Sopenharmony_ci
4229e5c31af7Sopenharmony_ci	virtual long Run()
4230e5c31af7Sopenharmony_ci	{
4231e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4232e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
4233e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
4234e5c31af7Sopenharmony_ci		LinkProgram(program);
4235e5c31af7Sopenharmony_ci
4236e5c31af7Sopenharmony_ci		long error = NO_ERROR;
4237e5c31af7Sopenharmony_ci
4238e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesU;
4239e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "a", error);
4240e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_UNIFORM, indicesU, "b", error);
4241e5c31af7Sopenharmony_ci
4242e5c31af7Sopenharmony_ci		GLenum props[]	= { GL_IS_ROW_MAJOR };
4243e5c31af7Sopenharmony_ci		GLint  expected[] = { 1 };
4244e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, props, 1, expected, error);
4245e5c31af7Sopenharmony_ci
4246e5c31af7Sopenharmony_ci		GLenum  prop = GL_MATRIX_STRIDE;
4247e5c31af7Sopenharmony_ci		GLsizei len;
4248e5c31af7Sopenharmony_ci		GLint   res;
4249e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
4250e5c31af7Sopenharmony_ci		if (res < 1)
4251e5c31af7Sopenharmony_ci		{
4252e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
4253e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
4254e5c31af7Sopenharmony_ci				<< "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_MATRIX_STRIDE\n"
4255e5c31af7Sopenharmony_ci				<< "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
4256e5c31af7Sopenharmony_ci		}
4257e5c31af7Sopenharmony_ci		prop = GL_OFFSET;
4258e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["a"], 1, &prop, 1024, &len, &res);
4259e5c31af7Sopenharmony_ci		if (res < 0)
4260e5c31af7Sopenharmony_ci		{
4261e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
4262e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_OFFSET\n"
4263e5c31af7Sopenharmony_ci				<< "Expected value not less than 0, got " << res << tcu::TestLog::EndMessage;
4264e5c31af7Sopenharmony_ci		}
4265e5c31af7Sopenharmony_ci		prop = GL_ARRAY_STRIDE;
4266e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, indicesU["b"], 1, &prop, 1024, &len, &res);
4267e5c31af7Sopenharmony_ci		if (res < 1)
4268e5c31af7Sopenharmony_ci		{
4269e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
4270e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message
4271e5c31af7Sopenharmony_ci				<< "ERROR: glGetProgramResourceiv, interface GL_UNIFORM, prop GL_ARRAY_STRIDE\n"
4272e5c31af7Sopenharmony_ci				<< "Expected value greater than 0, got " << res << tcu::TestLog::EndMessage;
4273e5c31af7Sopenharmony_ci		}
4274e5c31af7Sopenharmony_ci
4275e5c31af7Sopenharmony_ci		glDeleteProgram(program);
4276e5c31af7Sopenharmony_ci		return error;
4277e5c31af7Sopenharmony_ci	}
4278e5c31af7Sopenharmony_ci};
4279e5c31af7Sopenharmony_ci
4280e5c31af7Sopenharmony_ciclass ArrayNames : public SimpleShaders
4281e5c31af7Sopenharmony_ci{
4282e5c31af7Sopenharmony_ci
4283e5c31af7Sopenharmony_ci	virtual std::string Title()
4284e5c31af7Sopenharmony_ci	{
4285e5c31af7Sopenharmony_ci		return "Array Names Test";
4286e5c31af7Sopenharmony_ci	}
4287e5c31af7Sopenharmony_ci
4288e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
4289e5c31af7Sopenharmony_ci	{
4290e5c31af7Sopenharmony_ci		return "fallthrough fragment shader and a vertex shader with array of vec4 uniform used";
4291e5c31af7Sopenharmony_ci	}
4292e5c31af7Sopenharmony_ci
4293e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
4294e5c31af7Sopenharmony_ci	{
4295e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that GetProgramResourceLocation match "
4296e5c31af7Sopenharmony_ci			   "name strings correctly.\n";
4297e5c31af7Sopenharmony_ci	}
4298e5c31af7Sopenharmony_ci
4299e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
4300e5c31af7Sopenharmony_ci	{
4301e5c31af7Sopenharmony_ci		return "#version 430                         \n"
4302e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
4303e5c31af7Sopenharmony_ci			   ""
4304e5c31af7Sopenharmony_ci			   "uniform vec4 a[2];           \n"
4305e5c31af7Sopenharmony_ci			   ""
4306e5c31af7Sopenharmony_ci			   "void main(void)                            \n"
4307e5c31af7Sopenharmony_ci			   "{                                          \n"
4308e5c31af7Sopenharmony_ci			   "    gl_Position = position + a[0] + a[1];  \n"
4309e5c31af7Sopenharmony_ci			   "}";
4310e5c31af7Sopenharmony_ci	}
4311e5c31af7Sopenharmony_ci
4312e5c31af7Sopenharmony_ci	virtual long Run()
4313e5c31af7Sopenharmony_ci	{
4314e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4315e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
4316e5c31af7Sopenharmony_ci		LinkProgram(program);
4317e5c31af7Sopenharmony_ci
4318e5c31af7Sopenharmony_ci		long error = NO_ERROR;
4319e5c31af7Sopenharmony_ci
4320e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a", glGetUniformLocation(program, "a"), error);
4321e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0]", glGetUniformLocation(program, "a"), error);
4322e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[1]", glGetUniformLocation(program, "a[1]"), error);
4323e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[2]", -1, error);
4324e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 + 0]", -1, error);
4325e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0+0]", -1, error);
4326e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[ 0]", -1, error);
4327e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[0 ]", -1, error);
4328e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\n0]", -1, error);
4329e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[\t0]", -1, error);
4330e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[01]", -1, error);
4331e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_UNIFORM, "a[00]", -1, error);
4332e5c31af7Sopenharmony_ci
4333e5c31af7Sopenharmony_ci		glDeleteProgram(program);
4334e5c31af7Sopenharmony_ci		return error;
4335e5c31af7Sopenharmony_ci	}
4336e5c31af7Sopenharmony_ci};
4337e5c31af7Sopenharmony_ci
4338e5c31af7Sopenharmony_ciclass BuffLength : public SimpleShaders
4339e5c31af7Sopenharmony_ci{
4340e5c31af7Sopenharmony_ci
4341e5c31af7Sopenharmony_ci	virtual std::string Title()
4342e5c31af7Sopenharmony_ci	{
4343e5c31af7Sopenharmony_ci		return "Buff Length Test";
4344e5c31af7Sopenharmony_ci	}
4345e5c31af7Sopenharmony_ci
4346e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
4347e5c31af7Sopenharmony_ci	{
4348e5c31af7Sopenharmony_ci		return "fallthrough fragment shader and vertex with uniform of vec4 type used";
4349e5c31af7Sopenharmony_ci	}
4350e5c31af7Sopenharmony_ci
4351e5c31af7Sopenharmony_ci	virtual std::string PurposeExt()
4352e5c31af7Sopenharmony_ci	{
4353e5c31af7Sopenharmony_ci		return "\n\n Purpose is to verify that bufsize of GetProgramResourceName and "
4354e5c31af7Sopenharmony_ci			   "GetProgramResourceiv is respected.\n";
4355e5c31af7Sopenharmony_ci	}
4356e5c31af7Sopenharmony_ci
4357e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
4358e5c31af7Sopenharmony_ci	{
4359e5c31af7Sopenharmony_ci		return "#version 430                         \n"
4360e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
4361e5c31af7Sopenharmony_ci			   ""
4362e5c31af7Sopenharmony_ci			   "uniform vec4 someLongName;           \n"
4363e5c31af7Sopenharmony_ci			   ""
4364e5c31af7Sopenharmony_ci			   "void main(void)                            \n"
4365e5c31af7Sopenharmony_ci			   "{                                          \n"
4366e5c31af7Sopenharmony_ci			   "    gl_Position = position + someLongName; \n"
4367e5c31af7Sopenharmony_ci			   "}";
4368e5c31af7Sopenharmony_ci	}
4369e5c31af7Sopenharmony_ci
4370e5c31af7Sopenharmony_ci	virtual long Run()
4371e5c31af7Sopenharmony_ci	{
4372e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4373e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
4374e5c31af7Sopenharmony_ci		LinkProgram(program);
4375e5c31af7Sopenharmony_ci
4376e5c31af7Sopenharmony_ci		long error = NO_ERROR;
4377e5c31af7Sopenharmony_ci
4378e5c31af7Sopenharmony_ci		GLuint  index = glGetProgramResourceIndex(program, GL_UNIFORM, "someLongName");
4379e5c31af7Sopenharmony_ci		GLsizei length;
4380e5c31af7Sopenharmony_ci		GLchar  buff[3] = { 'a', 'b', 'c' };
4381e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, NULL);
4382e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_UNIFORM, index, 0, NULL, buff);
4383e5c31af7Sopenharmony_ci		if (buff[0] != 'a' || buff[1] != 'b' || buff[2] != 'c')
4384e5c31af7Sopenharmony_ci		{
4385e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
4386e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: buff has changed" << tcu::TestLog::EndMessage;
4387e5c31af7Sopenharmony_ci			error = ERROR;
4388e5c31af7Sopenharmony_ci		}
4389e5c31af7Sopenharmony_ci		glGetProgramResourceName(program, GL_UNIFORM, index, 2, &length, buff);
4390e5c31af7Sopenharmony_ci		if (buff[0] != 's' || buff[1] != '\0' || buff[2] != 'c')
4391e5c31af7Sopenharmony_ci		{
4392e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
4393e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: buff different then expected" << tcu::TestLog::EndMessage;
4394e5c31af7Sopenharmony_ci			error = ERROR;
4395e5c31af7Sopenharmony_ci		}
4396e5c31af7Sopenharmony_ci		if (length != 1)
4397e5c31af7Sopenharmony_ci		{
4398e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 1, got "
4399e5c31af7Sopenharmony_ci												<< length << tcu::TestLog::EndMessage;
4400e5c31af7Sopenharmony_ci			error = ERROR;
4401e5c31af7Sopenharmony_ci		}
4402e5c31af7Sopenharmony_ci
4403e5c31af7Sopenharmony_ci		GLint  params[3] = { 1, 2, 3 };
4404e5c31af7Sopenharmony_ci		GLenum props[]   = { GL_NAME_LENGTH,
4405e5c31af7Sopenharmony_ci						   GL_TYPE,
4406e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
4407e5c31af7Sopenharmony_ci						   GL_OFFSET,
4408e5c31af7Sopenharmony_ci						   GL_BLOCK_INDEX,
4409e5c31af7Sopenharmony_ci						   GL_ARRAY_STRIDE,
4410e5c31af7Sopenharmony_ci						   GL_MATRIX_STRIDE,
4411e5c31af7Sopenharmony_ci						   GL_IS_ROW_MAJOR,
4412e5c31af7Sopenharmony_ci						   GL_ATOMIC_COUNTER_BUFFER_INDEX,
4413e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
4414e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
4415e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
4416e5c31af7Sopenharmony_ci						   GL_LOCATION };
4417e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, NULL);
4418e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 0, NULL, params);
4419e5c31af7Sopenharmony_ci		if (params[0] != 1 || params[1] != 2 || params[2] != 3)
4420e5c31af7Sopenharmony_ci		{
4421e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
4422e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: params has changed" << tcu::TestLog::EndMessage;
4423e5c31af7Sopenharmony_ci			error = ERROR;
4424e5c31af7Sopenharmony_ci		}
4425e5c31af7Sopenharmony_ci		glGetProgramResourceiv(program, GL_UNIFORM, index, 13, props, 2, &length, params);
4426e5c31af7Sopenharmony_ci		if (params[0] != 13 || params[1] != GL_FLOAT_VEC4 || params[2] != 3)
4427e5c31af7Sopenharmony_ci		{
4428e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
4429e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "ERROR: params has incorrect values" << tcu::TestLog::EndMessage;
4430e5c31af7Sopenharmony_ci			error = ERROR;
4431e5c31af7Sopenharmony_ci		}
4432e5c31af7Sopenharmony_ci		if (length != 2)
4433e5c31af7Sopenharmony_ci		{
4434e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << "ERROR: incorrect length, expected 2, got "
4435e5c31af7Sopenharmony_ci												<< length << tcu::TestLog::EndMessage;
4436e5c31af7Sopenharmony_ci			error = ERROR;
4437e5c31af7Sopenharmony_ci		}
4438e5c31af7Sopenharmony_ci
4439e5c31af7Sopenharmony_ci		glDeleteProgram(program);
4440e5c31af7Sopenharmony_ci		return error;
4441e5c31af7Sopenharmony_ci	}
4442e5c31af7Sopenharmony_ci};
4443e5c31af7Sopenharmony_ci
4444e5c31af7Sopenharmony_ciclass NoLocations : public SimpleShaders
4445e5c31af7Sopenharmony_ci{
4446e5c31af7Sopenharmony_ci
4447e5c31af7Sopenharmony_ci	virtual std::string Title()
4448e5c31af7Sopenharmony_ci	{
4449e5c31af7Sopenharmony_ci		return "No Locations Test";
4450e5c31af7Sopenharmony_ci	}
4451e5c31af7Sopenharmony_ci
4452e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
4453e5c31af7Sopenharmony_ci	{
4454e5c31af7Sopenharmony_ci		return "fragment and vertex shaders with no locations set";
4455e5c31af7Sopenharmony_ci	}
4456e5c31af7Sopenharmony_ci
4457e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
4458e5c31af7Sopenharmony_ci	{
4459e5c31af7Sopenharmony_ci		return "#version 430                         \n"
4460e5c31af7Sopenharmony_ci			   "in vec4 a;                           \n"
4461e5c31af7Sopenharmony_ci			   "in vec4 b;                           \n"
4462e5c31af7Sopenharmony_ci			   "in vec4 c[1];                        \n"
4463e5c31af7Sopenharmony_ci			   "in vec4 d;                           \n"
4464e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
4465e5c31af7Sopenharmony_ci			   "{                                    \n"
4466e5c31af7Sopenharmony_ci			   "    gl_Position = a + b + c[0] + d;  \n"
4467e5c31af7Sopenharmony_ci			   "}";
4468e5c31af7Sopenharmony_ci	}
4469e5c31af7Sopenharmony_ci
4470e5c31af7Sopenharmony_ci	virtual std::string FragmentShader()
4471e5c31af7Sopenharmony_ci	{
4472e5c31af7Sopenharmony_ci		return "#version 430                   \n"
4473e5c31af7Sopenharmony_ci			   "out vec4 a;                    \n"
4474e5c31af7Sopenharmony_ci			   "out vec4 b;                    \n"
4475e5c31af7Sopenharmony_ci			   "out vec4 c;                    \n"
4476e5c31af7Sopenharmony_ci			   "out vec4 d[1];                 \n"
4477e5c31af7Sopenharmony_ci			   "void main() {                  \n"
4478e5c31af7Sopenharmony_ci			   "    a = vec4(0, 1, 0, 1);      \n"
4479e5c31af7Sopenharmony_ci			   "    b = vec4(0, 1, 0, 1);      \n"
4480e5c31af7Sopenharmony_ci			   "    c = vec4(0, 1, 0, 1);      \n"
4481e5c31af7Sopenharmony_ci			   "    d[0] = vec4(0, 1, 0, 1);   \n"
4482e5c31af7Sopenharmony_ci			   "}";
4483e5c31af7Sopenharmony_ci	}
4484e5c31af7Sopenharmony_ci
4485e5c31af7Sopenharmony_ci	virtual long Run()
4486e5c31af7Sopenharmony_ci	{
4487e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4488e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
4489e5c31af7Sopenharmony_ci		glLinkProgram(program);
4490e5c31af7Sopenharmony_ci
4491e5c31af7Sopenharmony_ci		long error = NO_ERROR;
4492e5c31af7Sopenharmony_ci
4493e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 4, error);
4494e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 5, error);
4495e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 4, error);
4496e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 5, error);
4497e5c31af7Sopenharmony_ci
4498e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesI;
4499e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesO;
4500e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "a", error);
4501e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "b", error);
4502e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "c", error);
4503e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, indicesI, "d", error);
4504e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "a", error);
4505e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "b", error);
4506e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "c", error);
4507e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, indicesO, "d[0]", error);
4508e5c31af7Sopenharmony_ci
4509e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["a"], "a", error);
4510e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["b"], "b", error);
4511e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["c"], "c[0]", error);
4512e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, indicesI["d"], "d", error);
4513e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["a"], "a", error);
4514e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["b"], "b", error);
4515e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["c"], "c", error);
4516e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], "d[0]", error);
4517e5c31af7Sopenharmony_ci
4518e5c31af7Sopenharmony_ci		std::map<std::string, GLint> locationsI;
4519e5c31af7Sopenharmony_ci		std::map<std::string, GLint> locationsO;
4520e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "a", error);
4521e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "b", error);
4522e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "c", error);
4523e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, locationsI, "d", error);
4524e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "a", error);
4525e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "b", error);
4526e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "c", error);
4527e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, locationsO, "d[0]", error);
4528e5c31af7Sopenharmony_ci
4529e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
4530e5c31af7Sopenharmony_ci						   GL_TYPE,
4531e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
4532e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
4533e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
4534e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER };
4535e5c31af7Sopenharmony_ci		GLint expected[] = { 2, GL_FLOAT_VEC4, 1, 0, 0, 1 };
4536e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["a"], 6, props, 6, expected, error);
4537e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["b"], 6, props, 6, expected, error);
4538e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["d"], 6, props, 6, expected, error);
4539e5c31af7Sopenharmony_ci		GLint expected2[] = { 5, GL_FLOAT_VEC4, 1, 0, 0, 1 };
4540e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, indicesI["c"], 6, props, 6, expected2, error);
4541e5c31af7Sopenharmony_ci		GLint expected3[] = { 2, GL_FLOAT_VEC4, 1, 0, 1, 0 };
4542e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["a"], 6, props, 6, expected3, error);
4543e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["b"], 6, props, 6, expected3, error);
4544e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["c"], 6, props, 6, expected3, error);
4545e5c31af7Sopenharmony_ci		GLint expected4[] = { 5, GL_FLOAT_VEC4, 1, 0, 1, 0 };
4546e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, indicesO["d[0]"], 6, props, 6, expected4, error);
4547e5c31af7Sopenharmony_ci
4548e5c31af7Sopenharmony_ci		glDeleteProgram(program);
4549e5c31af7Sopenharmony_ci		return error;
4550e5c31af7Sopenharmony_ci	}
4551e5c31af7Sopenharmony_ci};
4552e5c31af7Sopenharmony_ci
4553e5c31af7Sopenharmony_ciclass ComputeShaderTest : public PIQBase
4554e5c31af7Sopenharmony_ci{
4555e5c31af7Sopenharmony_ci	virtual std::string Title()
4556e5c31af7Sopenharmony_ci	{
4557e5c31af7Sopenharmony_ci		return "Compute Shader Test";
4558e5c31af7Sopenharmony_ci	}
4559e5c31af7Sopenharmony_ci
4560e5c31af7Sopenharmony_ci	virtual std::string ShadersDesc()
4561e5c31af7Sopenharmony_ci	{
4562e5c31af7Sopenharmony_ci		return "compute shader";
4563e5c31af7Sopenharmony_ci	}
4564e5c31af7Sopenharmony_ci
4565e5c31af7Sopenharmony_ci	virtual std::string ComputeShader()
4566e5c31af7Sopenharmony_ci	{
4567e5c31af7Sopenharmony_ci		return "layout(local_size_x = 1, local_size_y = 1) in; \n"
4568e5c31af7Sopenharmony_ci			   "layout(std430) buffer Output {                 \n"
4569e5c31af7Sopenharmony_ci			   "   vec4 data[];                                \n"
4570e5c31af7Sopenharmony_ci			   "} g_out;                                       \n"
4571e5c31af7Sopenharmony_ci			   ""
4572e5c31af7Sopenharmony_ci			   "void main() {                                   \n"
4573e5c31af7Sopenharmony_ci			   "   g_out.data[0] = vec4(1.0, 2.0, 3.0, 4.0);    \n"
4574e5c31af7Sopenharmony_ci			   "   g_out.data[100] = vec4(1.0, 2.0, 3.0, 4.0);  \n"
4575e5c31af7Sopenharmony_ci			   "}";
4576e5c31af7Sopenharmony_ci	}
4577e5c31af7Sopenharmony_ci
4578e5c31af7Sopenharmony_ci	GLuint CreateComputeProgram(const std::string& cs)
4579e5c31af7Sopenharmony_ci	{
4580e5c31af7Sopenharmony_ci		const GLuint p = glCreateProgram();
4581e5c31af7Sopenharmony_ci
4582e5c31af7Sopenharmony_ci		const char* const kGLSLVer = "#version 430  core \n";
4583e5c31af7Sopenharmony_ci
4584e5c31af7Sopenharmony_ci		if (!cs.empty())
4585e5c31af7Sopenharmony_ci		{
4586e5c31af7Sopenharmony_ci			const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
4587e5c31af7Sopenharmony_ci			glAttachShader(p, sh);
4588e5c31af7Sopenharmony_ci			glDeleteShader(sh);
4589e5c31af7Sopenharmony_ci			const char* const src[2] = { kGLSLVer, cs.c_str() };
4590e5c31af7Sopenharmony_ci			glShaderSource(sh, 2, src, NULL);
4591e5c31af7Sopenharmony_ci			glCompileShader(sh);
4592e5c31af7Sopenharmony_ci		}
4593e5c31af7Sopenharmony_ci
4594e5c31af7Sopenharmony_ci		return p;
4595e5c31af7Sopenharmony_ci	}
4596e5c31af7Sopenharmony_ci
4597e5c31af7Sopenharmony_ci	bool CheckProgram(GLuint program, bool* compile_error = NULL)
4598e5c31af7Sopenharmony_ci	{
4599e5c31af7Sopenharmony_ci		GLint compile_status = GL_TRUE;
4600e5c31af7Sopenharmony_ci		GLint status;
4601e5c31af7Sopenharmony_ci		glGetProgramiv(program, GL_LINK_STATUS, &status);
4602e5c31af7Sopenharmony_ci
4603e5c31af7Sopenharmony_ci		if (status == GL_FALSE)
4604e5c31af7Sopenharmony_ci		{
4605e5c31af7Sopenharmony_ci			GLint attached_shaders;
4606e5c31af7Sopenharmony_ci			glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
4607e5c31af7Sopenharmony_ci
4608e5c31af7Sopenharmony_ci			if (attached_shaders > 0)
4609e5c31af7Sopenharmony_ci			{
4610e5c31af7Sopenharmony_ci				std::vector<GLuint> shaders(attached_shaders);
4611e5c31af7Sopenharmony_ci				glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
4612e5c31af7Sopenharmony_ci
4613e5c31af7Sopenharmony_ci				for (GLint i = 0; i < attached_shaders; ++i)
4614e5c31af7Sopenharmony_ci				{
4615e5c31af7Sopenharmony_ci					GLenum type;
4616e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
4617e5c31af7Sopenharmony_ci					switch (type)
4618e5c31af7Sopenharmony_ci					{
4619e5c31af7Sopenharmony_ci					case GL_VERTEX_SHADER:
4620e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
4621e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
4622e5c31af7Sopenharmony_ci						break;
4623e5c31af7Sopenharmony_ci					case GL_TESS_CONTROL_SHADER:
4624e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
4625e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Tessellation Control Shader ***"
4626e5c31af7Sopenharmony_ci							<< tcu::TestLog::EndMessage;
4627e5c31af7Sopenharmony_ci						break;
4628e5c31af7Sopenharmony_ci					case GL_TESS_EVALUATION_SHADER:
4629e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
4630e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
4631e5c31af7Sopenharmony_ci							<< tcu::TestLog::EndMessage;
4632e5c31af7Sopenharmony_ci						break;
4633e5c31af7Sopenharmony_ci					case GL_GEOMETRY_SHADER:
4634e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
4635e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
4636e5c31af7Sopenharmony_ci						break;
4637e5c31af7Sopenharmony_ci					case GL_FRAGMENT_SHADER:
4638e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
4639e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
4640e5c31af7Sopenharmony_ci						break;
4641e5c31af7Sopenharmony_ci					case GL_COMPUTE_SHADER:
4642e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
4643e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
4644e5c31af7Sopenharmony_ci						break;
4645e5c31af7Sopenharmony_ci					default:
4646e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
4647e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
4648e5c31af7Sopenharmony_ci					}
4649e5c31af7Sopenharmony_ci
4650e5c31af7Sopenharmony_ci					GLint res;
4651e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
4652e5c31af7Sopenharmony_ci					if (res != GL_TRUE)
4653e5c31af7Sopenharmony_ci						compile_status = res;
4654e5c31af7Sopenharmony_ci
4655e5c31af7Sopenharmony_ci					// shader source
4656e5c31af7Sopenharmony_ci					GLint length;
4657e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
4658e5c31af7Sopenharmony_ci					if (length > 0)
4659e5c31af7Sopenharmony_ci					{
4660e5c31af7Sopenharmony_ci						std::vector<GLchar> source(length);
4661e5c31af7Sopenharmony_ci						glGetShaderSource(shaders[i], length, NULL, &source[0]);
4662e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
4663e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
4664e5c31af7Sopenharmony_ci					}
4665e5c31af7Sopenharmony_ci
4666e5c31af7Sopenharmony_ci					// shader info log
4667e5c31af7Sopenharmony_ci					glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
4668e5c31af7Sopenharmony_ci					if (length > 0)
4669e5c31af7Sopenharmony_ci					{
4670e5c31af7Sopenharmony_ci						std::vector<GLchar> log(length);
4671e5c31af7Sopenharmony_ci						glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
4672e5c31af7Sopenharmony_ci						m_context.getTestContext().getLog()
4673e5c31af7Sopenharmony_ci							<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
4674e5c31af7Sopenharmony_ci					}
4675e5c31af7Sopenharmony_ci				}
4676e5c31af7Sopenharmony_ci			}
4677e5c31af7Sopenharmony_ci
4678e5c31af7Sopenharmony_ci			// program info log
4679e5c31af7Sopenharmony_ci			GLint length;
4680e5c31af7Sopenharmony_ci			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
4681e5c31af7Sopenharmony_ci			if (length > 0)
4682e5c31af7Sopenharmony_ci			{
4683e5c31af7Sopenharmony_ci				std::vector<GLchar> log(length);
4684e5c31af7Sopenharmony_ci				glGetProgramInfoLog(program, length, NULL, &log[0]);
4685e5c31af7Sopenharmony_ci				m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
4686e5c31af7Sopenharmony_ci			}
4687e5c31af7Sopenharmony_ci		}
4688e5c31af7Sopenharmony_ci
4689e5c31af7Sopenharmony_ci		if (compile_error)
4690e5c31af7Sopenharmony_ci			*compile_error = (compile_status == GL_TRUE ? false : true);
4691e5c31af7Sopenharmony_ci		if (compile_status != GL_TRUE)
4692e5c31af7Sopenharmony_ci			return false;
4693e5c31af7Sopenharmony_ci		return status == GL_TRUE ? true : false;
4694e5c31af7Sopenharmony_ci	}
4695e5c31af7Sopenharmony_ci
4696e5c31af7Sopenharmony_ci	virtual void inline VerifyCompute(GLuint program, long& error)
4697e5c31af7Sopenharmony_ci	{
4698e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_MAX_NAME_LENGTH, 15, error);
4699e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, 1, error);
4700e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, 1, error);
4701e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, 7, error);
4702e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, 1, error);
4703e5c31af7Sopenharmony_ci
4704e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesSSB;
4705e5c31af7Sopenharmony_ci		std::map<std::string, GLuint> indicesBV;
4706e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, indicesSSB, "Output", error);
4707e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, indicesBV, "Output.data", error);
4708e5c31af7Sopenharmony_ci
4709e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], "Output", error);
4710e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], "Output.data[0]", error);
4711e5c31af7Sopenharmony_ci
4712e5c31af7Sopenharmony_ci		GLenum props3[] = { GL_NAME_LENGTH,
4713e5c31af7Sopenharmony_ci							GL_BUFFER_BINDING,
4714e5c31af7Sopenharmony_ci							GL_NUM_ACTIVE_VARIABLES,
4715e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4716e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4717e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4718e5c31af7Sopenharmony_ci							GL_ACTIVE_VARIABLES };
4719e5c31af7Sopenharmony_ci		GLint expected3[] = { 7, 0, 1, 1, 0, 0, static_cast<GLint>(indicesBV["Outputa.data"]) };
4720e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, indicesSSB["Output"], 7, props3, 7, expected3,
4721e5c31af7Sopenharmony_ci								   error);
4722e5c31af7Sopenharmony_ci
4723e5c31af7Sopenharmony_ci		GLenum props4[] = { GL_NAME_LENGTH,
4724e5c31af7Sopenharmony_ci							GL_TYPE,
4725e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
4726e5c31af7Sopenharmony_ci							GL_BLOCK_INDEX,
4727e5c31af7Sopenharmony_ci							GL_IS_ROW_MAJOR,
4728e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4729e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4730e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4731e5c31af7Sopenharmony_ci							GL_TOP_LEVEL_ARRAY_SIZE };
4732e5c31af7Sopenharmony_ci		GLint expected4[] = { 15, GL_FLOAT_VEC4, 0, static_cast<GLint>(indicesSSB["Output"]), 0, 1, 0, 0, 1 };
4733e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_BUFFER_VARIABLE, indicesBV["Outputa.data"], 9, props4, 9, expected4,
4734e5c31af7Sopenharmony_ci								   error);
4735e5c31af7Sopenharmony_ci	}
4736e5c31af7Sopenharmony_ci
4737e5c31af7Sopenharmony_ci	virtual long Run()
4738e5c31af7Sopenharmony_ci	{
4739e5c31af7Sopenharmony_ci		GLuint program = CreateComputeProgram(ComputeShader());
4740e5c31af7Sopenharmony_ci		glLinkProgram(program);
4741e5c31af7Sopenharmony_ci		if (!CheckProgram(program))
4742e5c31af7Sopenharmony_ci		{
4743e5c31af7Sopenharmony_ci			glDeleteProgram(program);
4744e5c31af7Sopenharmony_ci			return ERROR;
4745e5c31af7Sopenharmony_ci		}
4746e5c31af7Sopenharmony_ci		glUseProgram(program);
4747e5c31af7Sopenharmony_ci
4748e5c31af7Sopenharmony_ci		long error = NO_ERROR;
4749e5c31af7Sopenharmony_ci
4750e5c31af7Sopenharmony_ci		VerifyCompute(program, error);
4751e5c31af7Sopenharmony_ci
4752e5c31af7Sopenharmony_ci		glDeleteProgram(program);
4753e5c31af7Sopenharmony_ci		return error;
4754e5c31af7Sopenharmony_ci	}
4755e5c31af7Sopenharmony_ci};
4756e5c31af7Sopenharmony_ci
4757e5c31af7Sopenharmony_ciclass QueryNotUsed : public SimpleShaders
4758e5c31af7Sopenharmony_ci{
4759e5c31af7Sopenharmony_ci
4760e5c31af7Sopenharmony_ci	virtual std::string Title()
4761e5c31af7Sopenharmony_ci	{
4762e5c31af7Sopenharmony_ci		return "Query Not Used Test";
4763e5c31af7Sopenharmony_ci	}
4764e5c31af7Sopenharmony_ci
4765e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
4766e5c31af7Sopenharmony_ci	{
4767e5c31af7Sopenharmony_ci		return "Data from queries matches the not used program.";
4768e5c31af7Sopenharmony_ci	}
4769e5c31af7Sopenharmony_ci
4770e5c31af7Sopenharmony_ci	virtual std::string Purpose()
4771e5c31af7Sopenharmony_ci	{
4772e5c31af7Sopenharmony_ci		return "Verify that program parameter works correctly and proper program is queried when different program is "
4773e5c31af7Sopenharmony_ci			   "used.";
4774e5c31af7Sopenharmony_ci	}
4775e5c31af7Sopenharmony_ci
4776e5c31af7Sopenharmony_ci	virtual std::string Method()
4777e5c31af7Sopenharmony_ci	{
4778e5c31af7Sopenharmony_ci		return "Create 2 programs, use one of them and query the other, verify the results.";
4779e5c31af7Sopenharmony_ci	}
4780e5c31af7Sopenharmony_ci
4781e5c31af7Sopenharmony_ci	virtual std::string VertexShader2()
4782e5c31af7Sopenharmony_ci	{
4783e5c31af7Sopenharmony_ci		return "#version 430                         \n"
4784e5c31af7Sopenharmony_ci			   "in vec4 p;                           \n"
4785e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
4786e5c31af7Sopenharmony_ci			   "{                                    \n"
4787e5c31af7Sopenharmony_ci			   "    gl_Position = p;                 \n"
4788e5c31af7Sopenharmony_ci			   "}";
4789e5c31af7Sopenharmony_ci	}
4790e5c31af7Sopenharmony_ci
4791e5c31af7Sopenharmony_ci	virtual std::string FragmentShader2()
4792e5c31af7Sopenharmony_ci	{
4793e5c31af7Sopenharmony_ci		return "#version 430                   \n"
4794e5c31af7Sopenharmony_ci			   "out vec4 c;                    \n"
4795e5c31af7Sopenharmony_ci			   "void main() {                  \n"
4796e5c31af7Sopenharmony_ci			   "    c = vec4(0, 1, 0, 1);      \n"
4797e5c31af7Sopenharmony_ci			   "}";
4798e5c31af7Sopenharmony_ci	}
4799e5c31af7Sopenharmony_ci
4800e5c31af7Sopenharmony_ci	virtual long Run()
4801e5c31af7Sopenharmony_ci	{
4802e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4803e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
4804e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
4805e5c31af7Sopenharmony_ci		LinkProgram(program);
4806e5c31af7Sopenharmony_ci
4807e5c31af7Sopenharmony_ci		GLuint program2 = CreateProgram(VertexShader2().c_str(), FragmentShader2().c_str(), false);
4808e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "p");
4809e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "c");
4810e5c31af7Sopenharmony_ci		LinkProgram(program2);
4811e5c31af7Sopenharmony_ci		glUseProgram(program2);
4812e5c31af7Sopenharmony_ci
4813e5c31af7Sopenharmony_ci		long error = NO_ERROR;
4814e5c31af7Sopenharmony_ci
4815e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, 1, error);
4816e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, 9, error);
4817e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, 1, error);
4818e5c31af7Sopenharmony_ci		VerifyGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, 6, error);
4819e5c31af7Sopenharmony_ci
4820e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4821e5c31af7Sopenharmony_ci		VerifyGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position", 0, error);
4822e5c31af7Sopenharmony_ci
4823e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_OUTPUT, 0, "color", error);
4824e5c31af7Sopenharmony_ci		VerifyGetProgramResourceName(program, GL_PROGRAM_INPUT, 0, "position", error);
4825e5c31af7Sopenharmony_ci
4826e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", 0, error);
4827e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4828e5c31af7Sopenharmony_ci
4829e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocationIndex(program, GL_PROGRAM_OUTPUT, "color", 0, error);
4830e5c31af7Sopenharmony_ci
4831e5c31af7Sopenharmony_ci		GLenum props[] = { GL_NAME_LENGTH,
4832e5c31af7Sopenharmony_ci						   GL_TYPE,
4833e5c31af7Sopenharmony_ci						   GL_ARRAY_SIZE,
4834e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_COMPUTE_SHADER,
4835e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_FRAGMENT_SHADER,
4836e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_GEOMETRY_SHADER,
4837e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4838e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4839e5c31af7Sopenharmony_ci						   GL_REFERENCED_BY_VERTEX_SHADER,
4840e5c31af7Sopenharmony_ci						   GL_LOCATION,
4841e5c31af7Sopenharmony_ci						   GL_IS_PER_PATCH };
4842e5c31af7Sopenharmony_ci		GLint expected[] = { 9, GL_FLOAT_VEC4, 1, 0, 0, 0, 0, 0, 1, 0, 0 };
4843e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_INPUT, 0, 11, props, 11, expected, error);
4844e5c31af7Sopenharmony_ci
4845e5c31af7Sopenharmony_ci		GLenum props2[] = { GL_NAME_LENGTH,
4846e5c31af7Sopenharmony_ci							GL_TYPE,
4847e5c31af7Sopenharmony_ci							GL_ARRAY_SIZE,
4848e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_COMPUTE_SHADER,
4849e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_FRAGMENT_SHADER,
4850e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_GEOMETRY_SHADER,
4851e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_CONTROL_SHADER,
4852e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
4853e5c31af7Sopenharmony_ci							GL_REFERENCED_BY_VERTEX_SHADER,
4854e5c31af7Sopenharmony_ci							GL_LOCATION,
4855e5c31af7Sopenharmony_ci							GL_IS_PER_PATCH,
4856e5c31af7Sopenharmony_ci							GL_LOCATION_INDEX };
4857e5c31af7Sopenharmony_ci		GLint expected2[] = { 6, GL_FLOAT_VEC4, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
4858e5c31af7Sopenharmony_ci		VerifyGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, 0, 12, props2, 12, expected2, error);
4859e5c31af7Sopenharmony_ci
4860e5c31af7Sopenharmony_ci		glDeleteProgram(program);
4861e5c31af7Sopenharmony_ci		glDeleteProgram(program2);
4862e5c31af7Sopenharmony_ci		return error;
4863e5c31af7Sopenharmony_ci	}
4864e5c31af7Sopenharmony_ci};
4865e5c31af7Sopenharmony_ci
4866e5c31af7Sopenharmony_ciclass RelinkFailure : public SimpleShaders
4867e5c31af7Sopenharmony_ci{
4868e5c31af7Sopenharmony_ci
4869e5c31af7Sopenharmony_ci	virtual std::string Title()
4870e5c31af7Sopenharmony_ci	{
4871e5c31af7Sopenharmony_ci		return "Relink Failure Test";
4872e5c31af7Sopenharmony_ci	}
4873e5c31af7Sopenharmony_ci
4874e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
4875e5c31af7Sopenharmony_ci	{
4876e5c31af7Sopenharmony_ci		return "INVALID_OPERATION is generated when asking for locations after failed link.";
4877e5c31af7Sopenharmony_ci	}
4878e5c31af7Sopenharmony_ci
4879e5c31af7Sopenharmony_ci	virtual std::string Purpose()
4880e5c31af7Sopenharmony_ci	{
4881e5c31af7Sopenharmony_ci		return "Verify that queries behave correctly after failed relink of a program.";
4882e5c31af7Sopenharmony_ci	}
4883e5c31af7Sopenharmony_ci
4884e5c31af7Sopenharmony_ci	virtual std::string Method()
4885e5c31af7Sopenharmony_ci	{
4886e5c31af7Sopenharmony_ci		return "Create a program, use it, relink with failure and then verify that INVALID_OPERATION is returned when "
4887e5c31af7Sopenharmony_ci			   "asking for locations.";
4888e5c31af7Sopenharmony_ci	}
4889e5c31af7Sopenharmony_ci
4890e5c31af7Sopenharmony_ci	virtual std::string VertexShader()
4891e5c31af7Sopenharmony_ci	{
4892e5c31af7Sopenharmony_ci		return "#version 430                                  \n"
4893e5c31af7Sopenharmony_ci			   "in vec4 position;                             \n"
4894e5c31af7Sopenharmony_ci			   "in vec3 pos;                                  \n"
4895e5c31af7Sopenharmony_ci			   "void main(void)                               \n"
4896e5c31af7Sopenharmony_ci			   "{                                             \n"
4897e5c31af7Sopenharmony_ci			   "    gl_Position = position + vec4(pos, 1);    \n"
4898e5c31af7Sopenharmony_ci			   "}";
4899e5c31af7Sopenharmony_ci	}
4900e5c31af7Sopenharmony_ci
4901e5c31af7Sopenharmony_ci	virtual long Run()
4902e5c31af7Sopenharmony_ci	{
4903e5c31af7Sopenharmony_ci		GLuint program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str(), false);
4904e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
4905e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 1, "pos");
4906e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
4907e5c31af7Sopenharmony_ci		LinkProgram(program);
4908e5c31af7Sopenharmony_ci
4909e5c31af7Sopenharmony_ci		long error = NO_ERROR;
4910e5c31af7Sopenharmony_ci
4911e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", 1, error);
4912e5c31af7Sopenharmony_ci		glUseProgram(program);
4913e5c31af7Sopenharmony_ci
4914e5c31af7Sopenharmony_ci		tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
4915e5c31af7Sopenharmony_ci						   tcu::Vec4(1, -1, 0, 1) };
4916e5c31af7Sopenharmony_ci		GLuint vao, vbuf;
4917e5c31af7Sopenharmony_ci		glGenVertexArrays(1, &vao);
4918e5c31af7Sopenharmony_ci		glBindVertexArray(vao);
4919e5c31af7Sopenharmony_ci		glGenBuffers(1, &vbuf);
4920e5c31af7Sopenharmony_ci		glBindBuffer(GL_ARRAY_BUFFER, vbuf);
4921e5c31af7Sopenharmony_ci		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
4922e5c31af7Sopenharmony_ci		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
4923e5c31af7Sopenharmony_ci		glEnableVertexAttribArray(0);
4924e5c31af7Sopenharmony_ci		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4925e5c31af7Sopenharmony_ci
4926e5c31af7Sopenharmony_ci		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4927e5c31af7Sopenharmony_ci		glDisableVertexAttribArray(0);
4928e5c31af7Sopenharmony_ci		glDeleteVertexArrays(1, &vao);
4929e5c31af7Sopenharmony_ci		glBindBuffer(GL_ARRAY_BUFFER, 0);
4930e5c31af7Sopenharmony_ci		glDeleteBuffers(1, &vbuf);
4931e5c31af7Sopenharmony_ci
4932e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "pos");
4933e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "position");
4934e5c31af7Sopenharmony_ci		const char* varyings[2] = { "q", "z" };
4935e5c31af7Sopenharmony_ci		glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
4936e5c31af7Sopenharmony_ci		LinkProgram(program);
4937e5c31af7Sopenharmony_ci
4938e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
4939e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
4940e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "pos", -1, error);
4941e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
4942e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
4943e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
4944e5c31af7Sopenharmony_ci
4945e5c31af7Sopenharmony_ci		glDeleteProgram(program);
4946e5c31af7Sopenharmony_ci		return error;
4947e5c31af7Sopenharmony_ci	}
4948e5c31af7Sopenharmony_ci};
4949e5c31af7Sopenharmony_ci
4950e5c31af7Sopenharmony_ciclass LinkFailure : public SimpleShaders
4951e5c31af7Sopenharmony_ci{
4952e5c31af7Sopenharmony_ci
4953e5c31af7Sopenharmony_ci	virtual std::string Title()
4954e5c31af7Sopenharmony_ci	{
4955e5c31af7Sopenharmony_ci		return "Link Failure Test";
4956e5c31af7Sopenharmony_ci	}
4957e5c31af7Sopenharmony_ci
4958e5c31af7Sopenharmony_ci	virtual std::string PassCriteria()
4959e5c31af7Sopenharmony_ci	{
4960e5c31af7Sopenharmony_ci		return "INVALID_OPERATION is generated when asking for locations after failed link.";
4961e5c31af7Sopenharmony_ci	}
4962e5c31af7Sopenharmony_ci
4963e5c31af7Sopenharmony_ci	virtual std::string Purpose()
4964e5c31af7Sopenharmony_ci	{
4965e5c31af7Sopenharmony_ci		return "Verify that queries behave correctly after failed relink of a program with changed sources.";
4966e5c31af7Sopenharmony_ci	}
4967e5c31af7Sopenharmony_ci
4968e5c31af7Sopenharmony_ci	virtual std::string Method()
4969e5c31af7Sopenharmony_ci	{
4970e5c31af7Sopenharmony_ci		return "Create a program, use it, relink with failure using different sources and then \n"
4971e5c31af7Sopenharmony_ci			   "verify that INVALID_OPERATION is returned when asking for locations.";
4972e5c31af7Sopenharmony_ci	}
4973e5c31af7Sopenharmony_ci
4974e5c31af7Sopenharmony_ci	virtual const char* VertexShader_prop()
4975e5c31af7Sopenharmony_ci	{
4976e5c31af7Sopenharmony_ci		return "#version 430                         \n"
4977e5c31af7Sopenharmony_ci			   "in vec4 posit;                       \n"
4978e5c31af7Sopenharmony_ci			   "in vec4 p;                           \n"
4979e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
4980e5c31af7Sopenharmony_ci			   "{                                    \n"
4981e5c31af7Sopenharmony_ci			   "    gl_Position = p + posit;         \n"
4982e5c31af7Sopenharmony_ci			   "}";
4983e5c31af7Sopenharmony_ci	}
4984e5c31af7Sopenharmony_ci
4985e5c31af7Sopenharmony_ci	virtual const char* FragmentShader_prop()
4986e5c31af7Sopenharmony_ci	{
4987e5c31af7Sopenharmony_ci		return "#version 430                   \n"
4988e5c31af7Sopenharmony_ci			   "out vec4 color;                \n"
4989e5c31af7Sopenharmony_ci			   "void main() {                  \n"
4990e5c31af7Sopenharmony_ci			   "    color = vec4(0, 1, 0, 1);  \n"
4991e5c31af7Sopenharmony_ci			   "}";
4992e5c31af7Sopenharmony_ci	}
4993e5c31af7Sopenharmony_ci
4994e5c31af7Sopenharmony_ci	virtual const char* VertexShader_fail()
4995e5c31af7Sopenharmony_ci	{
4996e5c31af7Sopenharmony_ci		return "#version 430                         \n"
4997e5c31af7Sopenharmony_ci			   "in vec4 position;                    \n"
4998e5c31af7Sopenharmony_ci			   "void main(void)                      \n"
4999e5c31af7Sopenharmony_ci			   "{                                    \n"
5000e5c31af7Sopenharmony_ci			   "    gl_Position = position;          \n"
5001e5c31af7Sopenharmony_ci			   "}";
5002e5c31af7Sopenharmony_ci	}
5003e5c31af7Sopenharmony_ci
5004e5c31af7Sopenharmony_ci	virtual long Run()
5005e5c31af7Sopenharmony_ci	{
5006e5c31af7Sopenharmony_ci		const GLuint program = glCreateProgram();
5007e5c31af7Sopenharmony_ci		const char*  src_vs  = VertexShader_prop();
5008e5c31af7Sopenharmony_ci		const char*  src_fs  = FragmentShader_prop();
5009e5c31af7Sopenharmony_ci		const char*  src_vsh = VertexShader_fail();
5010e5c31af7Sopenharmony_ci
5011e5c31af7Sopenharmony_ci		GLuint sh1 = glCreateShader(GL_VERTEX_SHADER);
5012e5c31af7Sopenharmony_ci		glAttachShader(program, sh1);
5013e5c31af7Sopenharmony_ci		glDeleteShader(sh1);
5014e5c31af7Sopenharmony_ci		glShaderSource(sh1, 1, &src_vs, NULL);
5015e5c31af7Sopenharmony_ci		glCompileShader(sh1);
5016e5c31af7Sopenharmony_ci
5017e5c31af7Sopenharmony_ci		GLuint sh2 = glCreateShader(GL_FRAGMENT_SHADER);
5018e5c31af7Sopenharmony_ci		glAttachShader(program, sh2);
5019e5c31af7Sopenharmony_ci		glDeleteShader(sh2);
5020e5c31af7Sopenharmony_ci		glShaderSource(sh2, 1, &src_fs, NULL);
5021e5c31af7Sopenharmony_ci		glCompileShader(sh2);
5022e5c31af7Sopenharmony_ci
5023e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 0, "p");
5024e5c31af7Sopenharmony_ci		glBindAttribLocation(program, 1, "posit");
5025e5c31af7Sopenharmony_ci		glBindFragDataLocation(program, 0, "color");
5026e5c31af7Sopenharmony_ci		LinkProgram(program);
5027e5c31af7Sopenharmony_ci
5028e5c31af7Sopenharmony_ci		long error = NO_ERROR;
5029e5c31af7Sopenharmony_ci
5030e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "posit", 1, error);
5031e5c31af7Sopenharmony_ci		glUseProgram(program);
5032e5c31af7Sopenharmony_ci
5033e5c31af7Sopenharmony_ci		tcu::Vec4 v[4] = { tcu::Vec4(-1, 1, 0, 1), tcu::Vec4(-1, -1, 0, 1), tcu::Vec4(1, 1, 0, 1),
5034e5c31af7Sopenharmony_ci						   tcu::Vec4(1, -1, 0, 1) };
5035e5c31af7Sopenharmony_ci		GLuint vao, vbuf;
5036e5c31af7Sopenharmony_ci		glGenVertexArrays(1, &vao);
5037e5c31af7Sopenharmony_ci		glBindVertexArray(vao);
5038e5c31af7Sopenharmony_ci		glGenBuffers(1, &vbuf);
5039e5c31af7Sopenharmony_ci		glBindBuffer(GL_ARRAY_BUFFER, vbuf);
5040e5c31af7Sopenharmony_ci		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
5041e5c31af7Sopenharmony_ci		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0);
5042e5c31af7Sopenharmony_ci		glEnableVertexAttribArray(0);
5043e5c31af7Sopenharmony_ci		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5044e5c31af7Sopenharmony_ci
5045e5c31af7Sopenharmony_ci		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
5046e5c31af7Sopenharmony_ci		glDisableVertexAttribArray(0);
5047e5c31af7Sopenharmony_ci		glDeleteVertexArrays(1, &vao);
5048e5c31af7Sopenharmony_ci		glBindBuffer(GL_ARRAY_BUFFER, 0);
5049e5c31af7Sopenharmony_ci		glDeleteBuffers(1, &vbuf);
5050e5c31af7Sopenharmony_ci
5051e5c31af7Sopenharmony_ci		glDetachShader(program, sh1);
5052e5c31af7Sopenharmony_ci		GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
5053e5c31af7Sopenharmony_ci		glAttachShader(program, vsh);
5054e5c31af7Sopenharmony_ci		glDeleteShader(vsh);
5055e5c31af7Sopenharmony_ci		glShaderSource(vsh, 1, &src_vsh, NULL);
5056e5c31af7Sopenharmony_ci		glCompileShader(vsh);
5057e5c31af7Sopenharmony_ci		const char* varyings[2] = { "q", "z" };
5058e5c31af7Sopenharmony_ci		glTransformFeedbackVaryings(program, 2, varyings, GL_INTERLEAVED_ATTRIBS);
5059e5c31af7Sopenharmony_ci		LinkProgram(program);
5060e5c31af7Sopenharmony_ci
5061e5c31af7Sopenharmony_ci		GLint res;
5062e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position", -1, error);
5063e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
5064e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &res);
5065e5c31af7Sopenharmony_ci		if (res != 0 && res != 1)
5066e5c31af7Sopenharmony_ci		{
5067e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
5068e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Error, expected 0 or 1 active resources, got: " << res
5069e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
5070e5c31af7Sopenharmony_ci			error = ERROR;
5071e5c31af7Sopenharmony_ci		}
5072e5c31af7Sopenharmony_ci		glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &res);
5073e5c31af7Sopenharmony_ci		if (res != 0 && res != 9)
5074e5c31af7Sopenharmony_ci		{
5075e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog()
5076e5c31af7Sopenharmony_ci				<< tcu::TestLog::Message << "Error, expected 1 or 9 GL_MAX_NAME_LENGTH, got: " << res
5077e5c31af7Sopenharmony_ci				<< tcu::TestLog::EndMessage;
5078e5c31af7Sopenharmony_ci			error = ERROR;
5079e5c31af7Sopenharmony_ci		}
5080e5c31af7Sopenharmony_ci		VerifyGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "color", -1, error);
5081e5c31af7Sopenharmony_ci		ExpectError(GL_INVALID_OPERATION, error);
5082e5c31af7Sopenharmony_ci
5083e5c31af7Sopenharmony_ci		glDeleteProgram(program);
5084e5c31af7Sopenharmony_ci		return error;
5085e5c31af7Sopenharmony_ci	}
5086e5c31af7Sopenharmony_ci};
5087e5c31af7Sopenharmony_ci
5088e5c31af7Sopenharmony_ci} // anonymous namespace
5089e5c31af7Sopenharmony_ci
5090e5c31af7Sopenharmony_ciProgramInterfaceQueryTests::ProgramInterfaceQueryTests(deqp::Context& context)
5091e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "program_interface_query", "")
5092e5c31af7Sopenharmony_ci{
5093e5c31af7Sopenharmony_ci}
5094e5c31af7Sopenharmony_ci
5095e5c31af7Sopenharmony_ciProgramInterfaceQueryTests::~ProgramInterfaceQueryTests(void)
5096e5c31af7Sopenharmony_ci{
5097e5c31af7Sopenharmony_ci}
5098e5c31af7Sopenharmony_ci
5099e5c31af7Sopenharmony_civoid ProgramInterfaceQueryTests::init()
5100e5c31af7Sopenharmony_ci{
5101e5c31af7Sopenharmony_ci	using namespace deqp;
5102e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "empty-shaders", TestSubcase::Create<NoShaders>));
5103e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "simple-shaders", TestSubcase::Create<SimpleShaders>));
5104e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "input-types", TestSubcase::Create<InputTypes>));
5105e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "input-built-in", TestSubcase::Create<InputBuiltIn>));
5106e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "input-layout", TestSubcase::Create<InputLayout>));
5107e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "output-types", TestSubcase::Create<OutputTypes>));
5108e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "output-location-index", TestSubcase::Create<OutputLocationIndex>));
5109e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "output-built-in", TestSubcase::Create<OutputBuiltIn>));
5110e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "output-layout", TestSubcase::Create<OutputLayout>));
5111e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "output-layout-index", TestSubcase::Create<OutputLayoutIndex>));
5112e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-simple", TestSubcase::Create<UniformSimple>));
5113e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-types", TestSubcase::Create<UniformTypes>));
5114e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-block-types", TestSubcase::Create<UniformBlockTypes>));
5115e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "transform-feedback-types", TestSubcase::Create<TransformFeedbackTypes>));
5116e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "atomic-counters", TestSubcase::Create<AtomicCounterSimple>));
5117e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "subroutines-vertex", TestSubcase::Create<SubroutinesVertex>));
5118e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "subroutines-tess-control", TestSubcase::Create<SubroutinesTessControl>));
5119e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "subroutines-tess-eval", TestSubcase::Create<SubroutinesTessEval>));
5120e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "subroutines-geometry", TestSubcase::Create<SubroutinesGeometry>));
5121e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "subroutines-fragment", TestSubcase::Create<SubroutinesFragment>));
5122e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "subroutines-compute", TestSubcase::Create<SoubroutinesCompute>));
5123e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "ssb-types", TestSubcase::Create<ShaderStorageBlock>));
5124e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "transform-feedback-built-in", TestSubcase::Create<TransformFeedbackBuiltin>));
5125e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "null-length", TestSubcase::Create<NullLength>));
5126e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "arrays-of-arrays", TestSubcase::Create<ArraysOfArrays>));
5127e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "top-level-array", TestSubcase::Create<TopLevelArray>));
5128e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "separate-programs-vertex", TestSubcase::Create<SeparateProgramsVertex>));
5129e5c31af7Sopenharmony_ci	addChild(
5130e5c31af7Sopenharmony_ci		new TestSubcase(m_context, "separate-programs-tess-control", TestSubcase::Create<SeparateProgramsTessControl>));
5131e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "separate-programs-tess-eval", TestSubcase::Create<SeparateProgramsTessEval>));
5132e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "separate-programs-geometry", TestSubcase::Create<SeparateProgramsGeometry>));
5133e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "separate-programs-fragment", TestSubcase::Create<SeparateProgramsFragment>));
5134e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-block", TestSubcase::Create<UniformBlockAdvanced>));
5135e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "uniform-block-array", TestSubcase::Create<UniformBlockArray>));
5136e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "array-names", TestSubcase::Create<ArrayNames>));
5137e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "buff-length", TestSubcase::Create<BuffLength>));
5138e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "no-locations", TestSubcase::Create<NoLocations>));
5139e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "query-not-used", TestSubcase::Create<QueryNotUsed>));
5140e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "relink-failure", TestSubcase::Create<RelinkFailure>));
5141e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "link-failure", TestSubcase::Create<LinkFailure>));
5142e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "compute-shader", TestSubcase::Create<ComputeShaderTest>));
5143e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "invalid-value", TestSubcase::Create<InvalidValueTest>));
5144e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "invalid-operation", TestSubcase::Create<InvalidOperationTest>));
5145e5c31af7Sopenharmony_ci	addChild(new TestSubcase(m_context, "invalid-enum", TestSubcase::Create<InvalidEnumTest>));
5146e5c31af7Sopenharmony_ci}
5147e5c31af7Sopenharmony_ci
5148e5c31af7Sopenharmony_ci} // gl4cts namespace
5149