• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "es31cTextureGatherTests.hpp"
25 #include "glwEnums.hpp"
26 #include "glwFunctions.hpp"
27 #include "tcuMatrix.hpp"
28 #include "tcuMatrixUtil.hpp"
29 #include "tcuRenderTarget.hpp"
30 #include <cstdarg>
31 #include <sstream>
32 #include <string>
33 #include <vector>
34 
35 namespace glcts
36 {
37 
38 using namespace glw;
39 using tcu::Vec4;
40 using tcu::Vec3;
41 using tcu::Vec2;
42 using tcu::IVec4;
43 using tcu::UVec4;
44 
45 namespace
46 {
47 
48 class TGBase : public glcts::SubcaseBase
49 {
50 public:
~TGBase()51 	virtual ~TGBase()
52 	{
53 	}
54 
TGBase()55 	TGBase() : renderTarget(m_context.getRenderContext().getRenderTarget()), pixelFormat(renderTarget.getPixelFormat())
56 	{
57 	}
58 
59 	const tcu::RenderTarget& renderTarget;
60 	const tcu::PixelFormat&  pixelFormat;
61 
GetWindowWidth()62 	int GetWindowWidth()
63 	{
64 		return renderTarget.getWidth();
65 	}
66 
GetWindowHeight()67 	int GetWindowHeight()
68 	{
69 		return renderTarget.getHeight();
70 	}
71 
Title()72 	virtual std::string Title()
73 	{
74 		return "";
75 	}
76 
Purpose()77 	virtual std::string Purpose()
78 	{
79 		return "";
80 	}
81 
Method()82 	virtual std::string Method()
83 	{
84 		return "";
85 	}
86 
PassCriteria()87 	virtual std::string PassCriteria()
88 	{
89 		return "";
90 	}
91 
CreateProgram(const char * src_vs,const char * src_fs)92 	GLuint CreateProgram(const char* src_vs, const char* src_fs)
93 	{
94 		const GLuint p = glCreateProgram();
95 		if (src_vs)
96 		{
97 			GLuint sh = glCreateShader(GL_VERTEX_SHADER);
98 			glAttachShader(p, sh);
99 			glDeleteShader(sh);
100 			glShaderSource(sh, 1, &src_vs, NULL);
101 			glCompileShader(sh);
102 		}
103 		if (src_fs)
104 		{
105 			GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
106 			glAttachShader(p, sh);
107 			glDeleteShader(sh);
108 			glShaderSource(sh, 1, &src_fs, NULL);
109 			glCompileShader(sh);
110 		}
111 		return p;
112 	}
113 
CreateComputeProgram(const std::string & cs)114 	GLuint CreateComputeProgram(const std::string& cs)
115 	{
116 		const GLuint p = glCreateProgram();
117 		if (!cs.empty())
118 		{
119 			const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
120 			glAttachShader(p, sh);
121 			glDeleteShader(sh);
122 			const char* const src[1] = { cs.c_str() };
123 			glShaderSource(sh, 1, src, NULL);
124 			glCompileShader(sh);
125 		}
126 		return p;
127 	}
128 
CheckProgram(GLuint program,bool * compile_error=NULL)129 	bool CheckProgram(GLuint program, bool* compile_error = NULL)
130 	{
131 		GLint compile_status = GL_TRUE;
132 		GLint status;
133 		glGetProgramiv(program, GL_LINK_STATUS, &status);
134 
135 		if (status == GL_FALSE)
136 		{
137 			GLint attached_shaders;
138 			glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
139 
140 			if (attached_shaders > 0)
141 			{
142 				std::vector<GLuint> shaders(attached_shaders);
143 				glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
144 
145 				for (GLint i = 0; i < attached_shaders; ++i)
146 				{
147 					GLenum type;
148 					glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
149 					switch (type)
150 					{
151 					case GL_VERTEX_SHADER:
152 						m_context.getTestContext().getLog()
153 							<< tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
154 						break;
155 					case GL_FRAGMENT_SHADER:
156 						m_context.getTestContext().getLog()
157 							<< tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
158 						break;
159 					case GL_COMPUTE_SHADER:
160 						m_context.getTestContext().getLog()
161 							<< tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
162 						break;
163 					default:
164 						m_context.getTestContext().getLog()
165 							<< tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
166 					}
167 
168 					GLint res;
169 					glGetShaderiv(shaders[i], GL_COMPILE_STATUS, &res);
170 					if (res != GL_TRUE)
171 						compile_status = res;
172 
173 					GLint length;
174 					glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
175 					if (length > 0)
176 					{
177 						std::vector<GLchar> source(length);
178 						glGetShaderSource(shaders[i], length, NULL, &source[0]);
179 						m_context.getTestContext().getLog()
180 							<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
181 					}
182 
183 					glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
184 					if (length > 0)
185 					{
186 						std::vector<GLchar> log(length);
187 						glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
188 						m_context.getTestContext().getLog()
189 							<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
190 					}
191 				}
192 			}
193 
194 			GLint length;
195 			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
196 			if (length > 0)
197 			{
198 				std::vector<GLchar> log(length);
199 				glGetProgramInfoLog(program, length, NULL, &log[0]);
200 				m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
201 			}
202 		}
203 
204 		if (compile_error)
205 			*compile_error = (compile_status == GL_TRUE ? false : true);
206 		if (compile_status != GL_TRUE)
207 			return false;
208 		return status == GL_TRUE ? true : false;
209 	}
210 
Setup()211 	virtual long Setup()
212 	{
213 		return NO_ERROR;
214 	}
215 
Cleanup()216 	virtual long Cleanup()
217 	{
218 		return NO_ERROR;
219 	}
220 };
221 
222 class GatherEnumsTest : public TGBase
223 {
Title()224 	virtual std::string Title()
225 	{
226 		return "Basic Enum Test";
227 	}
228 
Purpose()229 	virtual std::string Purpose()
230 	{
231 		return "Verify that gather related enums are correct.";
232 	}
233 
Method()234 	virtual std::string Method()
235 	{
236 		return "Query GL_*_TEXTURE_GATHER_OFFSET enums.";
237 	}
238 
PassCriteria()239 	virtual std::string PassCriteria()
240 	{
241 		return "Values of enums meet GL spec requirements.";
242 	}
243 
Run()244 	virtual long Run()
245 	{
246 		GLint res;
247 		glGetIntegerv(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, &res);
248 		if (res > -8)
249 		{
250 			return ERROR;
251 		}
252 		glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, &res);
253 		if (res < 7)
254 		{
255 			return ERROR;
256 		}
257 		return NO_ERROR;
258 	}
259 };
260 
261 class GatherGLSLCompile : public TGBase
262 {
263 	GLuint program;
264 
Title()265 	virtual std::string Title()
266 	{
267 		return "GLSL Compile Test";
268 	}
269 
Purpose()270 	virtual std::string Purpose()
271 	{
272 		return "Verify that gather functions are visible in the shaders.";
273 	}
274 
Method()275 	virtual std::string Method()
276 	{
277 		return "Create shaders which use all types of gather functions.";
278 	}
279 
PassCriteria()280 	virtual std::string PassCriteria()
281 	{
282 		return "Programs compile and link successfuly.";
283 	}
284 
Uniforms()285 	virtual std::string Uniforms()
286 	{
287 		return "uniform mediump sampler2D tex_2d;                  \n"
288 			   "uniform mediump isamplerCube itex_cube;            \n"
289 			   "uniform mediump usampler2DArray utex_2da;          \n"
290 			   ""
291 			   "uniform mediump sampler2DShadow tex_2ds;           \n"
292 			   "uniform mediump samplerCubeShadow tex_cubes;       \n"
293 			   "uniform mediump sampler2DArrayShadow tex_2das;     \n";
294 	}
295 
Sampling()296 	virtual std::string Sampling()
297 	{
298 		return "    textureGather(tex_2d,vec2(1));          \n"
299 			   "    textureGather(itex_cube,vec3(1));       \n"
300 			   "    textureGather(utex_2da,vec3(1));        \n"
301 			   ""
302 			   "    textureGather(tex_2ds,vec2(1), 0.5);    \n"
303 			   "    textureGather(tex_cubes,vec3(1), 0.5);  \n"
304 			   "    textureGather(tex_2das,vec3(1), 0.5);   \n"
305 			   ""
306 			   "    textureGatherOffset(tex_2d,vec2(1), ivec2(0));          \n"
307 			   "    textureGatherOffset(utex_2da,vec3(1), ivec2(0));        \n"
308 			   ""
309 			   "    textureGatherOffset(tex_2ds,vec2(1), 0.5, ivec2(0));    \n"
310 			   "    textureGatherOffset(tex_2das,vec3(1), 0.5, ivec2(0));   \n";
311 	}
312 
VertexShader()313 	virtual std::string VertexShader()
314 	{
315 		return "#version 310 es                               \n" + Uniforms() +
316 			   "  void main() {                            \n" + Sampling() +
317 			   "    gl_Position = vec4(1);                 \n"
318 			   "  }                                        \n";
319 	}
320 
FragmentShader()321 	virtual std::string FragmentShader()
322 	{
323 		return "#version 310 es                            \n"
324 			   "precision highp float;                     \n"
325 			   "out mediump vec4 color;                    \n" +
326 			   Uniforms() + "  void main() {                            \n" + Sampling() +
327 			   "    color = vec4(1);                       \n"
328 			   "  }                                        \n";
329 	}
330 
Run()331 	virtual long Run()
332 	{
333 		program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str());
334 		glLinkProgram(program);
335 		if (!CheckProgram(program))
336 			return ERROR;
337 		return NO_ERROR;
338 	}
339 
Cleanup()340 	virtual long Cleanup()
341 	{
342 		glDeleteProgram(program);
343 		return NO_ERROR;
344 	}
345 };
346 
347 class GatherBase : public TGBase
348 {
349 public:
350 	GLuint tex, fbo, rbo, program, vao, vbo;
351 
IsFloatingPointTexture(GLenum internal_format)352 	bool IsFloatingPointTexture(GLenum internal_format)
353 	{
354 		switch (internal_format)
355 		{
356 		case GL_R32F:
357 		case GL_RG32F:
358 		case GL_RGB32F:
359 		case GL_RGBA32F:
360 		case GL_DEPTH_COMPONENT32F:
361 			return true;
362 		}
363 
364 		return false;
365 	}
366 
CreateTexture2DRgb(bool base_level=false)367 	virtual GLvoid CreateTexture2DRgb(bool base_level = false)
368 	{
369 		GLenum		internal_format = GL_RGB32F;
370 		GLenum		format			= GL_RGB;
371 		const GLint csize			= base_level ? 64 : 32;
372 		GLint		size			= csize;
373 		GLenum		target			= GL_TEXTURE_2D;
374 		GLenum		tex_type		= GL_FLOAT;
375 
376 		glGenTextures(1, &tex);
377 		glBindTexture(target, tex);
378 		for (int i = 0; size > 0; ++i, size /= 2)
379 		{
380 			std::vector<Vec3> pixels(size * size, Vec3(1.0));
381 			glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, &pixels[0]);
382 		}
383 
384 		Vec3 data[4] = { Vec3(12. / 16, 13. / 16, 14. / 16), Vec3(8. / 16, 9. / 16, 10. / 16),
385 						 Vec3(0. / 16, 1. / 16, 2. / 16), Vec3(4. / 16, 5. / 16, 6. / 16) };
386 
387 		glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
388 		glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
389 		glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
390 		glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
391 		glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
392 
393 		glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
394 		glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
395 		glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
396 
397 		if (IsFloatingPointTexture(internal_format))
398 		{
399 			glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
400 			glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
401 		}
402 	}
403 
CreateTexture2DRg(bool base_level=false)404 	virtual GLvoid CreateTexture2DRg(bool base_level = false)
405 	{
406 		GLenum		internal_format = GL_RG32F;
407 		GLenum		format			= GL_RG;
408 		const GLint csize			= base_level ? 64 : 32;
409 		GLint		size			= csize;
410 		GLenum		target			= GL_TEXTURE_2D;
411 		GLenum		tex_type		= GL_FLOAT;
412 
413 		glGenTextures(1, &tex);
414 		glBindTexture(target, tex);
415 		for (int i = 0; size > 0; ++i, size /= 2)
416 		{
417 			glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, 0);
418 			std::vector<Vec2> pixels(size * size, Vec2(1.0));
419 			glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, &pixels[0]);
420 		}
421 
422 		Vec2 data[4] = { Vec2(12. / 16, 13. / 16), Vec2(8. / 16, 9. / 16), Vec2(0. / 16, 1. / 16),
423 						 Vec2(4. / 16, 5. / 16) };
424 
425 		glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
426 		glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
427 		glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
428 		glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
429 		glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
430 
431 		glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
432 		glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
433 		glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
434 
435 		if (IsFloatingPointTexture(internal_format))
436 		{
437 			glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
438 			glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
439 		}
440 	}
441 
CreateTexture2DR(bool base_level=false)442 	virtual GLvoid CreateTexture2DR(bool base_level = false)
443 	{
444 		GLenum		internal_format = GL_R32F;
445 		GLenum		format			= GL_RED;
446 		const GLint csize			= base_level ? 64 : 32;
447 		GLint		size			= csize;
448 		GLenum		target			= GL_TEXTURE_2D;
449 		GLenum		tex_type		= GL_FLOAT;
450 
451 		glGenTextures(1, &tex);
452 		glBindTexture(target, tex);
453 		for (int i = 0; size > 0; ++i, size /= 2)
454 		{
455 			std::vector<GLfloat> pixels(size * size, 1.0);
456 			glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, &pixels[0]);
457 		}
458 
459 		GLfloat data[4] = { 12. / 16., 8. / 16., 0. / 16., 4. / 16. };
460 
461 		glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
462 		glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
463 		glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
464 		glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
465 		glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
466 
467 		glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
468 		glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
469 		glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
470 
471 		if (IsFloatingPointTexture(internal_format))
472 		{
473 			glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
474 			glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
475 		}
476 	}
477 
CreateTexture2DInt()478 	virtual GLvoid CreateTexture2DInt()
479 	{
480 		GLenum		internal_format = InternalFormat();
481 		const GLint csize			= 32;
482 		GLint		size			= csize;
483 		GLenum		target			= GL_TEXTURE_2D;
484 		GLenum		tex_type		= Type().find('u') != std::string::npos ? GL_UNSIGNED_INT : GL_INT;
485 
486 		glGenTextures(1, &tex);
487 		glBindTexture(target, tex);
488 		for (int i = 0; size > 0; ++i, size /= 2)
489 		{
490 			glTexImage2D(target, i, internal_format, size, size, 0, GL_RGBA_INTEGER, tex_type, 0);
491 		}
492 		std::vector<IVec4> pixels(csize * csize, IVec4(999));
493 		glTexSubImage2D(target, 0, 0, 0, csize, csize, GL_RGBA_INTEGER, tex_type, &pixels[0]);
494 
495 		IVec4 data[4] = { IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7) };
496 
497 		glTexSubImage2D(target, 0, 22, 25, 2, 2, GL_RGBA_INTEGER, tex_type, data);
498 		glTexSubImage2D(target, 0, 16, 10, 1, 1, GL_RGBA_INTEGER, tex_type, data + 0);
499 		glTexSubImage2D(target, 0, 11, 2, 1, 1, GL_RGBA_INTEGER, tex_type, data + 1);
500 		glTexSubImage2D(target, 0, 24, 13, 1, 1, GL_RGBA_INTEGER, tex_type, data + 2);
501 		glTexSubImage2D(target, 0, 9, 14, 1, 1, GL_RGBA_INTEGER, tex_type, data + 3);
502 
503 		glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
504 		glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
505 		glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
506 		glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
507 		glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
508 	}
509 
CreateTexture2DArrayInt(int slices,int data_slice)510 	virtual GLvoid CreateTexture2DArrayInt(int slices, int data_slice)
511 	{
512 		GLenum		internal_format = InternalFormat();
513 		const GLint csize			= 32;
514 		GLint		size			= csize;
515 		GLenum		tex_type		= Type().find('u') != std::string::npos ? GL_UNSIGNED_INT : GL_INT;
516 
517 		glGenTextures(1, &tex);
518 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
519 		for (int i = 0; size > 0; ++i, size /= 2)
520 		{
521 			glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, size, size, slices, 0, GL_RGBA_INTEGER, tex_type, 0);
522 		}
523 		std::vector<IVec4> pixels(csize * csize, IVec4(999));
524 		for (int i = 0; i < slices; ++i)
525 		{
526 			glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, csize, csize, 1, GL_RGBA_INTEGER, tex_type, &pixels[0]);
527 		}
528 
529 		IVec4 data[4] = { IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7) };
530 
531 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 22, 25, data_slice, 2, 2, 1, GL_RGBA_INTEGER, tex_type, data);
532 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 16, 10, data_slice, 1, 1, 1, GL_RGBA_INTEGER, tex_type, data + 0);
533 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 11, 2, data_slice, 1, 1, 1, GL_RGBA_INTEGER, tex_type, data + 1);
534 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 24, 13, data_slice, 1, 1, 1, GL_RGBA_INTEGER, tex_type, data + 2);
535 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 9, 14, data_slice, 1, 1, 1, GL_RGBA_INTEGER, tex_type, data + 3);
536 
537 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
538 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
539 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
540 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
541 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
542 	}
543 
CreateTexture2DArray(int slices,int data_slice)544 	virtual GLvoid CreateTexture2DArray(int slices, int data_slice)
545 	{
546 		GLenum		internal_format = InternalFormat();
547 		GLenum		format			= Format();
548 		const GLint csize			= 32;
549 		GLint		size			= csize;
550 
551 		glGenTextures(1, &tex);
552 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
553 		for (int i = 0; size > 0; ++i, size /= 2)
554 		{
555 			std::vector<Vec4> pixels(size * size * slices, Vec4(1.0));
556 			glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, size, size, slices, 0, format, GL_FLOAT, &pixels[0]);
557 		}
558 
559 		Vec4 data[4] = { Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
560 						 Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16) };
561 
562 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 22, 25, data_slice, 2, 2, 1, format, GL_FLOAT, data);
563 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 16, 10, data_slice, 1, 1, 1, format, GL_FLOAT, data + 0);
564 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 11, 2, data_slice, 1, 1, 1, format, GL_FLOAT, data + 1);
565 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 24, 13, data_slice, 1, 1, 1, format, GL_FLOAT, data + 2);
566 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 9, 14, data_slice, 1, 1, 1, format, GL_FLOAT, data + 3);
567 
568 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
569 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
570 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
571 
572 		if (IsFloatingPointTexture(internal_format))
573 		{
574 			glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
575 			glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
576 		}
577 	}
578 
CreateTextureCubeInt()579 	virtual GLvoid CreateTextureCubeInt()
580 	{
581 		GLenum		internal_format = InternalFormat();
582 		const GLint csize			= 32;
583 		GLint		size			= csize;
584 		GLenum		tex_type		= Type().find('u') != std::string::npos ? GL_UNSIGNED_INT : GL_INT;
585 
586 		const GLenum faces[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
587 								  GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
588 								  GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
589 
590 		glGenTextures(1, &tex);
591 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
592 		for (int i = 0; size > 0; ++i, size /= 2)
593 		{
594 			for (int j = 0; j < 6; ++j)
595 			{
596 				glTexImage2D(faces[j], i, internal_format, size, size, 0, GL_RGBA_INTEGER, tex_type, 0);
597 			}
598 		}
599 		std::vector<IVec4> pixels(csize * csize, IVec4(999));
600 		for (int j = 0; j < 6; ++j)
601 		{
602 			glTexSubImage2D(faces[j], 0, 0, 0, csize, csize, GL_RGBA_INTEGER, tex_type, &pixels[0]);
603 		}
604 
605 		IVec4 data[4] = { IVec4(12, 13, 14, 15), IVec4(8, 9, 10, 11), IVec4(0, 1, 2, 3), IVec4(4, 5, 6, 7) };
606 
607 		for (int j = 0; j < 6; ++j)
608 		{
609 			glTexSubImage2D(faces[j], 0, 22, 25, 2, 2, GL_RGBA_INTEGER, tex_type, data);
610 			glTexSubImage2D(faces[j], 0, 16, 10, 1, 1, GL_RGBA_INTEGER, tex_type, data + 0);
611 			glTexSubImage2D(faces[j], 0, 11, 2, 1, 1, GL_RGBA_INTEGER, tex_type, data + 1);
612 			glTexSubImage2D(faces[j], 0, 24, 13, 1, 1, GL_RGBA_INTEGER, tex_type, data + 2);
613 			glTexSubImage2D(faces[j], 0, 9, 14, 1, 1, GL_RGBA_INTEGER, tex_type, data + 3);
614 		}
615 
616 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
617 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
618 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
619 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
620 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
621 	}
622 
CreateTextureCube()623 	virtual GLvoid CreateTextureCube()
624 	{
625 		GLenum		internal_format = InternalFormat();
626 		GLenum		format			= Format();
627 		const GLint csize			= 32;
628 		GLint		size			= csize;
629 
630 		const GLenum faces[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
631 								  GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
632 								  GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
633 
634 		glGenTextures(1, &tex);
635 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
636 		for (int i = 0; size > 0; ++i, size /= 2)
637 		{
638 			std::vector<Vec4> pixels(size * size, Vec4(1.0));
639 			for (int j = 0; j < 6; ++j)
640 			{
641 				glTexImage2D(faces[j], i, internal_format, size, size, 0, format, GL_FLOAT, &pixels[0]);
642 			}
643 		}
644 
645 		Vec4 data[4] = { Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
646 						 Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16) };
647 
648 		Vec4  depthData(data[0][0], data[1][0], data[2][0], data[3][0]);
649 		Vec4* packedData = (format == GL_DEPTH_COMPONENT) ? &depthData : data;
650 
651 		for (int j = 0; j < 6; ++j)
652 		{
653 			glTexSubImage2D(faces[j], 0, 22, 25, 2, 2, format, GL_FLOAT, packedData);
654 			glTexSubImage2D(faces[j], 0, 16, 10, 1, 1, format, GL_FLOAT, data + 0);
655 			glTexSubImage2D(faces[j], 0, 11, 2, 1, 1, format, GL_FLOAT, data + 1);
656 			glTexSubImage2D(faces[j], 0, 24, 13, 1, 1, format, GL_FLOAT, data + 2);
657 			glTexSubImage2D(faces[j], 0, 9, 14, 1, 1, format, GL_FLOAT, data + 3);
658 		}
659 
660 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
661 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
662 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
663 
664 		if (IsFloatingPointTexture(internal_format))
665 		{
666 			glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
667 			glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
668 		}
669 	}
670 
CreateTextureSRGB()671 	virtual GLvoid CreateTextureSRGB()
672 	{
673 		GLenum		internal_format = InternalFormat();
674 		GLenum		format			= Format();
675 		const GLint csize			= 32;
676 		GLint		size			= csize;
677 		GLenum		target			= GL_TEXTURE_2D;
678 		GLenum		tex_type		= GL_UNSIGNED_BYTE;
679 
680 		glGenTextures(1, &tex);
681 		glBindTexture(target, tex);
682 		for (int i = 0; size > 0; ++i, size /= 2)
683 		{
684 			glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, 0);
685 		}
686 		std::vector<GLubyte> pixels(csize * csize * 4, 255);
687 		glTexSubImage2D(target, 0, 0, 0, csize, csize, format, tex_type, &pixels[0]);
688 
689 		if (format != GL_DEPTH_COMPONENT)
690 		{
691 			glGenerateMipmap(target);
692 		}
693 
694 		GLubyte data[16] = { 240, 13, 14, 15, 160, 9, 10, 11, 0, 1, 2, 3, 80, 5, 6, 7 };
695 
696 		glTexSubImage2D(target, 0, 22, 25, 2, 2, format, tex_type, data);
697 		glTexSubImage2D(target, 0, 16, 10, 1, 1, format, tex_type, data + 0);
698 		glTexSubImage2D(target, 0, 11, 2, 1, 1, format, tex_type, data + 4);
699 		glTexSubImage2D(target, 0, 24, 13, 1, 1, format, tex_type, data + 8);
700 		glTexSubImage2D(target, 0, 9, 14, 1, 1, format, tex_type, data + 12);
701 
702 		glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
703 		glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
704 		glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
705 	}
706 
CreateTexture2D(bool base_level=false)707 	virtual GLvoid CreateTexture2D(bool base_level = false)
708 	{
709 		GLenum		internal_format = InternalFormat();
710 		GLenum		format			= Format();
711 		const GLint csize			= base_level ? 64 : 32;
712 		GLint		size			= csize;
713 		GLenum		target			= GL_TEXTURE_2D;
714 		GLenum		tex_type		= InternalFormat() == GL_SRGB8_ALPHA8 ? GL_UNSIGNED_BYTE : GL_FLOAT;
715 
716 		glGenTextures(1, &tex);
717 		glBindTexture(target, tex);
718 		for (int i = 0; size > 0; ++i, size /= 2)
719 		{
720 			std::vector<Vec4> pixels(size * size, Vec4(1.0));
721 			glTexImage2D(target, i, internal_format, size, size, 0, format, tex_type, &pixels[0]);
722 		}
723 
724 		Vec4 data[4] = { Vec4(12. / 16, 13. / 16, 14. / 16, 15. / 16), Vec4(8. / 16, 9. / 16, 10. / 16, 11. / 16),
725 						 Vec4(0. / 16, 1. / 16, 2. / 16, 3. / 16), Vec4(4. / 16, 5. / 16, 6. / 16, 7. / 16) };
726 
727 		glTexSubImage2D(target, base_level, 22, 25, 2, 2, format, tex_type, data);
728 		glTexSubImage2D(target, base_level, 16, 10, 1, 1, format, tex_type, data + 0);
729 		glTexSubImage2D(target, base_level, 11, 2, 1, 1, format, tex_type, data + 1);
730 		glTexSubImage2D(target, base_level, 24, 13, 1, 1, format, tex_type, data + 2);
731 		glTexSubImage2D(target, base_level, 9, 14, 1, 1, format, tex_type, data + 3);
732 
733 		glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
734 		glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
735 		glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
736 
737 		if (IsFloatingPointTexture(internal_format))
738 		{
739 			glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
740 			glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
741 		}
742 
743 		if (base_level)
744 			glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 1);
745 	}
746 
FallthroughVertexShader()747 	virtual std::string FallthroughVertexShader()
748 	{
749 		return "#version 310 es                       \n"
750 			   "in vec4 v_in_0;                    \n"
751 			   "flat out vec4 v_out_0;             \n"
752 			   "void main() {                      \n"
753 			   "    gl_Position = vec4(0,0,0,1);   \n"
754 			   "#ifdef GL_ES                       \n"
755 			   "    gl_PointSize = 1.0f;           \n"
756 			   "#endif                             \n"
757 			   "    v_out_0 = v_in_0;              \n"
758 			   "}";
759 	}
760 
FallthroughFragmentShader()761 	virtual std::string FallthroughFragmentShader()
762 	{
763 		return "#version 310 es                          \n"
764 			   "precision highp float;                   \n"
765 			   "out mediump vec4 f_out_0;                \n"
766 			   "flat in  mediump vec4 v_out_0;           \n"
767 			   "void main() {                            \n"
768 			   "    f_out_0 = v_out_0;                   \n"
769 			   "}";
770 	}
771 
TestFunction()772 	virtual std::string TestFunction()
773 	{
774 		return Sampler() + TextBody();
775 	}
776 
Sampler()777 	virtual std::string Sampler()
778 	{
779 		return "uniform mediump sampler2D my_sampler;                  \n";
780 	}
781 
Type()782 	virtual std::string Type()
783 	{
784 		return "vec4";
785 	}
786 
TextBody()787 	virtual std::string TextBody()
788 	{
789 		std::string str_if = "    if (all(lessThanEqual(abs(tmp - " + Expected() + "), vec4(0.039)))) {           \n";
790 		if (Type().find('u') != std::string::npos || Type().find('i') != std::string::npos)
791 		{
792 			str_if = "    if (tmp == " + Expected() + ") {           \n";
793 		}
794 		return "vec4 test_function(vec4 p) {                                                                         "
795 			   "\n" +
796 			   Offset() + "    mediump " + Type() + " tmp = " + Gather() +
797 			   ";                                                   \n" + str_if +
798 			   "        return vec4(0.0, 1.0, 0.0, 1.0);                                                             \n"
799 			   "    } else {                                                                                         \n"
800 			   "        return vec4(float(tmp.x), float(tmp.y), float(tmp.z), float(tmp.w));                         \n"
801 			   "    }                                                                                                \n"
802 			   "}\n";
803 	}
804 
Gather()805 	virtual std::string Gather()
806 	{
807 		return "textureGather(my_sampler, vec2(p.x, p.y))";
808 	}
809 
Offset()810 	virtual std::string Offset()
811 	{
812 		return "";
813 	}
814 
VertexShader()815 	virtual std::string VertexShader()
816 	{
817 		return "#version 310 es                                       \n"
818 			   ""
819 			   "in mediump vec4 v_in_0;                            \n"
820 			   "flat out mediump vec4 v_out_0;                     \n" +
821 			   TestFunction() + "void main() {                                      \n"
822 								"    gl_Position = vec4(0, 0, 0, 1);                \n"
823 								"#ifdef GL_ES                                       \n"
824 								"    gl_PointSize = 1.0f;                           \n"
825 								"#endif                                             \n"
826 								"    v_out_0 = test_function(v_in_0);               \n"
827 								"}";
828 	}
829 
FragmentShader()830 	virtual std::string FragmentShader()
831 	{
832 		return "#version 310 es                                       \n"
833 			   ""
834 			   "precision highp float;                             \n"
835 			   "flat in mediump vec4 v_out_0;                      \n"
836 			   "out mediump vec4 f_out_0;                          \n" +
837 			   TestFunction() + "void main() {                                      \n"
838 								"    f_out_0 = test_function(v_out_0);              \n"
839 								"}";
840 	}
841 
ComputeShader()842 	virtual std::string ComputeShader()
843 	{
844 		return "#version 310 es                                       \n"
845 			   "layout(local_size_x = 1, local_size_y = 1) in;        \n"
846 			   "layout(std430) buffer Output {                        \n"
847 			   "  mediump vec4 data;                                  \n"
848 			   "} g_out;                                              \n"
849 			   "uniform mediump vec4 cs_in;                           \n" +
850 			   TestFunction() + "void main() {                                         \n"
851 								"  g_out.data = test_function(cs_in);                  \n"
852 								"}                                                     \n";
853 	}
854 
Init()855 	virtual void Init()
856 	{
857 		CreateTexture2D();
858 	}
859 
Verify()860 	virtual long Verify()
861 	{
862 		std::vector<GLubyte> data(4);
863 		glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
864 		if (data[0] != 0 || data[1] != 255 || data[2] != 0 || data[3] != 255)
865 		{
866 			m_context.getTestContext().getLog()
867 				<< tcu::TestLog::Message << "Expected Vec4(0, 255, 0, 255), got: " << data[0] << ", " << data[1] << ", "
868 				<< data[2] << ", " << data[3] << tcu::TestLog::EndMessage;
869 			return ERROR;
870 		}
871 		return NO_ERROR;
872 	}
873 
Expected()874 	virtual std::string Expected()
875 	{
876 		return "vec4(0./16., 4./16., 8./16., 12./16.)";
877 	}
878 
InternalFormat()879 	virtual GLenum InternalFormat()
880 	{
881 		return GL_RGBA32F;
882 	}
883 
Format()884 	virtual GLenum Format()
885 	{
886 		return GL_RGBA;
887 	}
888 
BufferData()889 	virtual Vec4 BufferData()
890 	{
891 		return Vec4(23. / 32, 26. / 32, 5, 3);
892 	}
893 
Supported()894 	virtual bool Supported()
895 	{
896 		return true;
897 	}
898 
Run()899 	virtual long Run()
900 	{
901 		if (!Supported())
902 			return NO_ERROR;
903 		Init();
904 
905 		glGenFramebuffers(1, &fbo);
906 		glGenRenderbuffers(1, &rbo);
907 		glBindRenderbuffer(GL_RENDERBUFFER, rbo);
908 		glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
909 		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
910 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
911 		GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
912 		glDrawBuffers(1, &drawBuffer);
913 		GLfloat colorf[4] = { 0, 0, 0, 0 };
914 		glClearBufferfv(GL_COLOR, 0, colorf);
915 		glViewport(0, 0, 1, 1);
916 
917 		glGenVertexArrays(1, &vao);
918 		glBindVertexArray(vao);
919 		glGenBuffers(1, &vbo);
920 		glBindBuffer(GL_ARRAY_BUFFER, vbo);
921 		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
922 		glEnableVertexAttribArray(0);
923 		Vec4 buffData = BufferData();
924 		glBufferData(GL_ARRAY_BUFFER, 16, &buffData, GL_STATIC_DRAW);
925 
926 		for (int i = 0; i < 2; ++i)
927 		{
928 			if (i == 0)
929 				program = CreateProgram(VertexShader().c_str(), FallthroughFragmentShader().c_str());
930 			else
931 				program = CreateProgram(FallthroughVertexShader().c_str(), FragmentShader().c_str());
932 			glBindAttribLocation(program, 0, "v_in_0");
933 			glLinkProgram(program);
934 			if (!CheckProgram(program))
935 				return ERROR;
936 			glUseProgram(program);
937 
938 			glDrawArrays(GL_POINTS, 0, 1);
939 			glReadBuffer(GL_COLOR_ATTACHMENT0);
940 
941 			glDeleteProgram(program);
942 
943 			if (Verify() == ERROR)
944 				return ERROR;
945 		}
946 
947 		return TestCompute();
948 	}
949 
TestCompute()950 	virtual long TestCompute()
951 	{
952 		GLuint m_buffer;
953 
954 		program = CreateComputeProgram(ComputeShader());
955 		glLinkProgram(program);
956 		if (!CheckProgram(program))
957 			return ERROR;
958 		glUseProgram(program);
959 
960 		glUniform4f(glGetUniformLocation(program, "cs_in"), BufferData().x(), BufferData().y(), BufferData().z(),
961 					BufferData().w());
962 
963 		glGenBuffers(1, &m_buffer);
964 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
965 		glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Vec4), NULL, GL_DYNAMIC_DRAW);
966 		glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
967 
968 		glDispatchCompute(1, 1, 1);
969 
970 		glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer);
971 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
972 		long error = VerifyCompute();
973 		glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
974 		glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
975 		glDeleteBuffers(1, &m_buffer);
976 
977 		return error;
978 	}
979 
VerifyCompute()980 	virtual long VerifyCompute()
981 	{
982 		Vec4* data;
983 		data = static_cast<Vec4*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(Vec4), GL_MAP_READ_BIT));
984 		if (data[0] != Vec4(0, 1, 0, 1))
985 		{
986 			m_context.getTestContext().getLog()
987 				<< tcu::TestLog::Message << "Expected Vec4(0, 1, 0, 1), got: " << data[0].x() << ", " << data[0].y()
988 				<< ", " << data[0].z() << ", " << data[0].w() << tcu::TestLog::EndMessage;
989 			return ERROR;
990 		}
991 		return NO_ERROR;
992 	}
993 
Cleanup()994 	virtual long Cleanup()
995 	{
996 		glViewport(0, 0, GetWindowWidth(), GetWindowHeight());
997 		glDisableVertexAttribArray(0);
998 		glDeleteTextures(1, &tex);
999 		glDeleteVertexArrays(1, &vao);
1000 		glDeleteBuffers(1, &vbo);
1001 		glDeleteRenderbuffers(1, &rbo);
1002 		glDeleteFramebuffers(1, &fbo);
1003 		glDeleteProgram(program);
1004 		return NO_ERROR;
1005 	}
1006 };
1007 
1008 class PlainGatherFloat2D : public GatherBase
1009 {
1010 };
1011 
1012 class PlainGatherInt2D : public GatherBase
1013 {
1014 public:
InternalFormat()1015 	virtual GLenum InternalFormat()
1016 	{
1017 		return GL_RGBA32I;
1018 	}
1019 
Init()1020 	virtual void Init()
1021 	{
1022 		CreateTexture2DInt();
1023 	}
1024 
Expected()1025 	virtual std::string Expected()
1026 	{
1027 		return "ivec4(0, 4, 8, 12)";
1028 	}
1029 
Sampler()1030 	virtual std::string Sampler()
1031 	{
1032 		return "uniform mediump isampler2D my_sampler;  \n";
1033 	}
1034 
Type()1035 	virtual std::string Type()
1036 	{
1037 		return "ivec4";
1038 	}
1039 };
1040 
1041 class PlainGatherUint2D : public GatherBase
1042 {
1043 public:
InternalFormat()1044 	virtual GLenum InternalFormat()
1045 	{
1046 		return GL_RGBA32UI;
1047 	}
1048 
Init()1049 	virtual void Init()
1050 	{
1051 		CreateTexture2DInt();
1052 	}
1053 
Expected()1054 	virtual std::string Expected()
1055 	{
1056 		return "uvec4(2u, 6u, 10u, 14u)";
1057 	}
1058 
Sampler()1059 	virtual std::string Sampler()
1060 	{
1061 		return "uniform  mediump usampler2D my_sampler;                     \n";
1062 	}
1063 
BufferData()1064 	virtual Vec4 BufferData()
1065 	{
1066 		return Vec4(22.9f / 32, 25.9f / 32, 2, 2);
1067 	}
1068 
Type()1069 	virtual std::string Type()
1070 	{
1071 		return "uvec4";
1072 	}
1073 
Gather()1074 	virtual std::string Gather()
1075 	{
1076 		return "textureGather(my_sampler, vec2(p.x, p.y), 2)";
1077 	}
1078 };
1079 
1080 class PlainGatherDepth2D : public GatherBase
1081 {
1082 public:
InternalFormat()1083 	virtual GLenum InternalFormat()
1084 	{
1085 		return GL_DEPTH_COMPONENT32F;
1086 	}
1087 
Format()1088 	virtual GLenum Format()
1089 	{
1090 		return GL_DEPTH_COMPONENT;
1091 	}
1092 
Init()1093 	virtual void Init()
1094 	{
1095 		CreateTexture2D();
1096 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1097 	}
1098 
Expected()1099 	virtual std::string Expected()
1100 	{
1101 		return "vec4(1.0, 1.0, 0.0, 0.0)";
1102 	}
1103 
BufferData()1104 	virtual Vec4 BufferData()
1105 	{
1106 		return Vec4(23. / 32, 26. / 32, 13.5 / 16, 3);
1107 	}
1108 
Sampler()1109 	virtual std::string Sampler()
1110 	{
1111 		return "uniform mediump sampler2DShadow my_sampler;                     \n";
1112 	}
1113 
Gather()1114 	virtual std::string Gather()
1115 	{
1116 		return "textureGather(my_sampler, vec2(p.x, p.y), p.z)";
1117 	}
1118 };
1119 
1120 class PlainGatherFloat2DArray : public GatherBase
1121 {
1122 public:
Init()1123 	virtual void Init()
1124 	{
1125 		CreateTexture2DArray(9, 5);
1126 	}
1127 
Sampler()1128 	virtual std::string Sampler()
1129 	{
1130 		return "uniform mediump sampler2DArray my_sampler;                     \n";
1131 	}
1132 
Gather()1133 	virtual std::string Gather()
1134 	{
1135 		return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1136 	}
1137 };
1138 
1139 class PlainGatherInt2DArray : public GatherBase
1140 {
1141 public:
Init()1142 	virtual void Init()
1143 	{
1144 		CreateTexture2DArrayInt(20, 11);
1145 	}
1146 
InternalFormat()1147 	virtual GLenum InternalFormat()
1148 	{
1149 		return GL_RGBA32I;
1150 	}
1151 
Expected()1152 	virtual std::string Expected()
1153 	{
1154 		return "ivec4(3, 7, 11, 15)";
1155 	}
1156 
Type()1157 	virtual std::string Type()
1158 	{
1159 		return "ivec4";
1160 	}
1161 
BufferData()1162 	virtual Vec4 BufferData()
1163 	{
1164 		return Vec4(23. / 32, 26. / 32, 11, 3);
1165 	}
1166 
Sampler()1167 	virtual std::string Sampler()
1168 	{
1169 		return "uniform mediump isampler2DArray my_sampler;                     \n";
1170 	}
1171 
Gather()1172 	virtual std::string Gather()
1173 	{
1174 		return "textureGather(my_sampler, vec3(p.x, p.y, p.z), 3)";
1175 	}
1176 };
1177 
1178 class PlainGatherUint2DArray : public GatherBase
1179 {
1180 public:
Init()1181 	virtual void Init()
1182 	{
1183 		CreateTexture2DArrayInt(3, 1);
1184 	}
1185 
InternalFormat()1186 	virtual GLenum InternalFormat()
1187 	{
1188 		return GL_RGBA32UI;
1189 	}
1190 
Expected()1191 	virtual std::string Expected()
1192 	{
1193 		return "uvec4(0u, 4u, 8u, 12u)";
1194 	}
1195 
Type()1196 	virtual std::string Type()
1197 	{
1198 		return "uvec4";
1199 	}
1200 
BufferData()1201 	virtual Vec4 BufferData()
1202 	{
1203 		return Vec4(23. / 32, 26. / 32, 1, 3);
1204 	}
1205 
Sampler()1206 	virtual std::string Sampler()
1207 	{
1208 		return "uniform  mediump usampler2DArray my_sampler;                     \n";
1209 	}
1210 
Gather()1211 	virtual std::string Gather()
1212 	{
1213 		return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1214 	}
1215 };
1216 
1217 class PlainGatherDepth2DArray : public GatherBase
1218 {
1219 public:
InternalFormat()1220 	virtual GLenum InternalFormat()
1221 	{
1222 		return GL_DEPTH_COMPONENT32F;
1223 	}
1224 
Format()1225 	virtual GLenum Format()
1226 	{
1227 		return GL_DEPTH_COMPONENT;
1228 	}
1229 
Init()1230 	virtual void Init()
1231 	{
1232 		CreateTexture2DArray(9, 5);
1233 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1234 	}
1235 
Expected()1236 	virtual std::string Expected()
1237 	{
1238 		return "vec4(1.0, 1.0, 0.0, 0.0)";
1239 	}
1240 
BufferData()1241 	virtual Vec4 BufferData()
1242 	{
1243 		return Vec4(23. / 32, 26. / 32, 5, 13.5 / 16);
1244 	}
1245 
Sampler()1246 	virtual std::string Sampler()
1247 	{
1248 		return "uniform mediump sampler2DArrayShadow my_sampler;                     \n";
1249 	}
1250 
Gather()1251 	virtual std::string Gather()
1252 	{
1253 		return "textureGather(my_sampler, vec3(p.x, p.y, p.z), p.w)";
1254 	}
1255 };
1256 
1257 class PlainGatherFloatCube : public GatherBase
1258 {
1259 public:
Init()1260 	virtual void Init()
1261 	{
1262 		CreateTextureCube();
1263 	}
1264 
BufferData()1265 	virtual Vec4 BufferData()
1266 	{
1267 		return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1268 	}
1269 
Sampler()1270 	virtual std::string Sampler()
1271 	{
1272 		return "uniform mediump samplerCube my_sampler;                     \n";
1273 	}
1274 
Gather()1275 	virtual std::string Gather()
1276 	{
1277 		return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1278 	}
1279 };
1280 
1281 class PlainGatherIntCube : public GatherBase
1282 {
1283 public:
Init()1284 	virtual void Init()
1285 	{
1286 		CreateTextureCubeInt();
1287 	}
1288 
BufferData()1289 	virtual Vec4 BufferData()
1290 	{
1291 		return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1292 	}
1293 
Sampler()1294 	virtual std::string Sampler()
1295 	{
1296 		return "uniform mediump isamplerCube my_sampler;                     \n";
1297 	}
1298 
Gather()1299 	virtual std::string Gather()
1300 	{
1301 		return "textureGather(my_sampler, vec3(p.x, p.y, p.z))";
1302 	}
1303 
InternalFormat()1304 	virtual GLenum InternalFormat()
1305 	{
1306 		return GL_RGBA32I;
1307 	}
1308 
Expected()1309 	virtual std::string Expected()
1310 	{
1311 		return "ivec4(0, 4, 8, 12)";
1312 	}
1313 
Type()1314 	virtual std::string Type()
1315 	{
1316 		return "ivec4";
1317 	}
1318 };
1319 
1320 class PlainGatherUintCube : public GatherBase
1321 {
1322 public:
Init()1323 	virtual void Init()
1324 	{
1325 		CreateTextureCubeInt();
1326 	}
1327 
BufferData()1328 	virtual Vec4 BufferData()
1329 	{
1330 		return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1331 	}
1332 
Sampler()1333 	virtual std::string Sampler()
1334 	{
1335 		return "uniform  mediump usamplerCube my_sampler;                     \n";
1336 	}
1337 
Gather()1338 	virtual std::string Gather()
1339 	{
1340 		return "textureGather(my_sampler, vec3(p.x, p.y, p.z), 0)";
1341 	}
1342 
InternalFormat()1343 	virtual GLenum InternalFormat()
1344 	{
1345 		return GL_RGBA32UI;
1346 	}
1347 
Expected()1348 	virtual std::string Expected()
1349 	{
1350 		return "uvec4(0u, 4u, 8u, 12u)";
1351 	}
1352 
Type()1353 	virtual std::string Type()
1354 	{
1355 		return "uvec4";
1356 	}
1357 };
1358 
1359 class PlainGatherDepthCube : public GatherBase
1360 {
1361 public:
Init()1362 	virtual void Init()
1363 	{
1364 		CreateTextureCube();
1365 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1366 	}
1367 
InternalFormat()1368 	virtual GLenum InternalFormat()
1369 	{
1370 		return GL_DEPTH_COMPONENT32F;
1371 	}
1372 
Format()1373 	virtual GLenum Format()
1374 	{
1375 		return GL_DEPTH_COMPONENT;
1376 	}
1377 
BufferData()1378 	virtual Vec4 BufferData()
1379 	{
1380 		return Vec4(7. / 16, -10. / 16, 1, 7.5 / 16);
1381 	}
1382 
Sampler()1383 	virtual std::string Sampler()
1384 	{
1385 		return "uniform mediump samplerCubeShadow my_sampler;                     \n";
1386 	}
1387 
Gather()1388 	virtual std::string Gather()
1389 	{
1390 		return "textureGather(my_sampler, vec3(p.x, p.y, p.z), p.w)";
1391 	}
1392 
Expected()1393 	virtual std::string Expected()
1394 	{
1395 		return "vec4(0.0, 0.0, 1.0, 1.0)";
1396 	}
1397 };
1398 
1399 class OffsetGatherFloat2D : public GatherBase
1400 {
BufferData()1401 	virtual Vec4 BufferData()
1402 	{
1403 		return Vec4(19. / 32, 22. / 32, 4, 4);
1404 	}
1405 
Offset()1406 	virtual std::string Offset()
1407 	{
1408 		return "const mediump ivec2 offset = ivec2(4);         \n";
1409 	}
1410 
Gather()1411 	virtual std::string Gather()
1412 	{
1413 		return "textureGatherOffset(my_sampler, vec2(p.x, p.y), offset)";
1414 	}
1415 };
1416 
1417 class OffsetGatherInt2D : public PlainGatherInt2D
1418 {
BufferData()1419 	virtual Vec4 BufferData()
1420 	{
1421 		return Vec4(18.9f / 32.f, 21.9f / 32.f, 4, 4);
1422 	}
1423 
Offset()1424 	virtual std::string Offset()
1425 	{
1426 		return "const mediump ivec2 offset = ivec2(4);         \n";
1427 	}
1428 
Gather()1429 	virtual std::string Gather()
1430 	{
1431 		return "textureGatherOffset(my_sampler, vec2(p.x, p.y), offset)";
1432 	}
1433 };
1434 
1435 class OffsetGatherUint2D : public PlainGatherUint2D
1436 {
BufferData()1437 	virtual Vec4 BufferData()
1438 	{
1439 		return Vec4(18.9f / 32.f, 21.9f / 32.f, 4, 2);
1440 	}
1441 
Offset()1442 	virtual std::string Offset()
1443 	{
1444 		return "const mediump ivec2 offset = ivec2(4);         \n";
1445 	}
1446 
Gather()1447 	virtual std::string Gather()
1448 	{
1449 		return "textureGatherOffset(my_sampler, vec2(p.x, p.y), offset, 2)";
1450 	}
1451 };
1452 
1453 class OffsetGatherDepth2D : public PlainGatherDepth2D
1454 {
BufferData()1455 	virtual Vec4 BufferData()
1456 	{
1457 		return Vec4(19. / 32, 22. / 32, 4, 13.5 / 16);
1458 	}
1459 
Offset()1460 	virtual std::string Offset()
1461 	{
1462 		return "const mediump ivec2 offset = ivec2(4);         \n";
1463 	}
1464 
Gather()1465 	virtual std::string Gather()
1466 	{
1467 		return "textureGatherOffset(my_sampler, vec2(p.x, p.y), p.w, offset)";
1468 	}
1469 };
1470 
1471 class OffsetGatherFloat2DArray : public PlainGatherFloat2DArray
1472 {
BufferData()1473 	virtual Vec4 BufferData()
1474 	{
1475 		return Vec4(19. / 32, 22. / 32, 5, 4);
1476 	}
1477 
Offset()1478 	virtual std::string Offset()
1479 	{
1480 		return "const mediump ivec2 offset = ivec2(4);         \n";
1481 	}
1482 
Gather()1483 	virtual std::string Gather()
1484 	{
1485 		return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), offset)";
1486 	}
1487 };
1488 
1489 class OffsetGatherInt2DArray : public PlainGatherInt2DArray
1490 {
BufferData()1491 	virtual Vec4 BufferData()
1492 	{
1493 		return Vec4(19. / 32, 22. / 32, 11, 4);
1494 	}
1495 
Offset()1496 	virtual std::string Offset()
1497 	{
1498 		return "const mediump ivec2 offset = ivec2(4);         \n";
1499 	}
1500 
Gather()1501 	virtual std::string Gather()
1502 	{
1503 		return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), offset, 3)";
1504 	}
1505 };
1506 
1507 class OffsetGatherUint2DArray : public PlainGatherUint2DArray
1508 {
BufferData()1509 	virtual Vec4 BufferData()
1510 	{
1511 		return Vec4(19. / 32, 22. / 32, 1, 4);
1512 	}
1513 
Offset()1514 	virtual std::string Offset()
1515 	{
1516 		return "const mediump ivec2 offset = ivec2(4);         \n";
1517 	}
1518 
Gather()1519 	virtual std::string Gather()
1520 	{
1521 		return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), offset, 0)";
1522 	}
1523 };
1524 
1525 class OffsetGatherDepth2DArray : public PlainGatherDepth2DArray
1526 {
Init()1527 	virtual void Init()
1528 	{
1529 		CreateTexture2DArray(7, 3);
1530 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1531 	}
1532 
BufferData()1533 	virtual Vec4 BufferData()
1534 	{
1535 		return Vec4(19. / 32, 22. / 32, 3, 4);
1536 	}
1537 
Offset()1538 	virtual std::string Offset()
1539 	{
1540 		return "const mediump ivec2 offset = ivec2(4);         \n";
1541 	}
1542 
Gather()1543 	virtual std::string Gather()
1544 	{
1545 		return "textureGatherOffset(my_sampler, vec3(p.x, p.y, p.z), p.y + (5.0/32.0), offset)";
1546 	}
1547 };
1548 
1549 class Swizzle : public PlainGatherFloat2D
1550 {
Gather()1551 	virtual std::string Gather()
1552 	{
1553 		return "textureGather(my_sampler, vec2(p.x, p.y), 1).yzww";
1554 	}
1555 
Expected()1556 	virtual std::string Expected()
1557 	{
1558 		return "vec4(5./16., 9./16., 13./16., 13./16.)";
1559 	}
1560 };
1561 
1562 class BaseLevel : public PlainGatherFloat2D
1563 {
Init()1564 	virtual void Init()
1565 	{
1566 		CreateTexture2D(true);
1567 	}
1568 };
1569 
1570 class IncompleteTexture : public PlainGatherFloat2D
1571 {
Init()1572 	virtual void Init()
1573 	{
1574 		CreateTexture2D();
1575 		glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, 0);
1576 	}
1577 
Expected()1578 	virtual std::string Expected()
1579 	{
1580 		return "vec4(0)";
1581 	}
1582 
Gather()1583 	virtual std::string Gather()
1584 	{
1585 		return "textureGatherOffset(my_sampler, vec2(p.x, p.y), ivec2(0), 1)";
1586 	}
1587 };
1588 
1589 class IncompleteTextureLastComp : public PlainGatherFloat2D
1590 {
Init()1591 	virtual void Init()
1592 	{
1593 		CreateTexture2D();
1594 		glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, 0);
1595 	}
1596 
Expected()1597 	virtual std::string Expected()
1598 	{
1599 		return "vec4(1.0)";
1600 	}
1601 
Gather()1602 	virtual std::string Gather()
1603 	{
1604 		return "textureGather(my_sampler, vec2(p.x, p.y), 3)";
1605 	}
1606 };
1607 
1608 class TriangleDraw : public GatherBase
1609 {
1610 	GLuint program, rbo, fbo, vao, vbo;
1611 
VertexShader()1612 	virtual std::string VertexShader()
1613 	{
1614 		return "#version 310 es                               \n"
1615 			   "flat out mediump vec2 texcoords;              \n"
1616 			   "in mediump vec4 Vertex;                       \n"
1617 			   "void main() {                                 \n"
1618 			   "   gl_Position = Vertex;                      \n"
1619 			   "   texcoords = (Vertex.xy + vec2(1.0)) / 2.0; \n"
1620 			   "}\n";
1621 	}
1622 
FragmentShader()1623 	virtual std::string FragmentShader()
1624 	{
1625 		return "#version 310 es                                   \n"
1626 			   "precision highp float;                            \n"
1627 			   "flat in mediump vec2 texcoords;                   \n"
1628 			   "out highp uvec4 FragColor;                        \n"
1629 			   "uniform mediump sampler2D tex;                    \n"
1630 			   "void main() {                                     \n"
1631 			   "   vec4 data = textureGather(tex, texcoords, 2);  \n"
1632 			   "   FragColor = floatBitsToUint(data);             \n"
1633 			   "}\n";
1634 	}
1635 
Run()1636 	virtual long Run()
1637 	{
1638 		glGenFramebuffers(1, &fbo);
1639 		glGenRenderbuffers(1, &rbo);
1640 		glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1641 		glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32UI, 100, 100);
1642 		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1643 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1644 		GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
1645 		glDrawBuffers(1, &drawBuffer);
1646 		GLfloat colorf[4] = { 0, 0, 0, 0 };
1647 		glClearBufferfv(GL_COLOR, 0, colorf);
1648 		glViewport(0, 0, 100, 100);
1649 
1650 		program = CreateProgram(VertexShader().c_str(), FragmentShader().c_str());
1651 		glBindAttribLocation(program, 0, "Vertex");
1652 		glLinkProgram(program);
1653 		if (!CheckProgram(program))
1654 			return ERROR;
1655 		glUseProgram(program);
1656 
1657 		glGenTextures(1, &tex);
1658 		glBindTexture(GL_TEXTURE_2D, tex);
1659 		std::vector<Vec4> data(100 * 100, Vec4(0.25, 0.5, 0.75, 1));
1660 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 100, 100, 0, GL_RGBA, GL_FLOAT, &data[0]);
1661 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1662 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1663 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
1664 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1665 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1666 
1667 		glGenVertexArrays(1, &vao);
1668 		glBindVertexArray(vao);
1669 		glGenBuffers(1, &vbo);
1670 		glBindBuffer(GL_ARRAY_BUFFER, vbo);
1671 		GLfloat buffData[16] = { -1, 1, 0, 1, -1, -1, 0, 1, 1, 1, 0, 1, 1, -1, 0, 1 };
1672 		glBufferData(GL_ARRAY_BUFFER, sizeof(buffData), buffData, GL_STATIC_DRAW);
1673 		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0);
1674 		glEnableVertexAttribArray(0);
1675 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1676 		glDisableVertexAttribArray(0);
1677 		glDeleteVertexArrays(1, &vao);
1678 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1679 
1680 		glReadBuffer(GL_COLOR_ATTACHMENT0);
1681 		std::vector<unsigned int> read(100 * 100 * 4, 0);
1682 		glReadPixels(0, 0, 100, 100, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &read[0]);
1683 		for (unsigned int i = 0; i < read.size() / 4; i += 4)
1684 		{
1685 			const GLfloat* rdata = (const GLfloat*)&read[i];
1686 			Vec4		   rvec(rdata[0], rdata[1], rdata[2], rdata[3]);
1687 			if (rvec != Vec4(0.75))
1688 			{
1689 				m_context.getTestContext().getLog()
1690 					<< tcu::TestLog::Message << "Got: " << rvec.x() << " " << rvec.y() << " " << rvec.z() << " "
1691 					<< rvec.w() << ", expected vec4(0.75)" << tcu::TestLog::EndMessage;
1692 				return ERROR;
1693 			}
1694 		}
1695 
1696 		return NO_ERROR;
1697 	}
1698 
Cleanup()1699 	virtual long Cleanup()
1700 	{
1701 		glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1702 		glDisableVertexAttribArray(0);
1703 		glViewport(0, 0, GetWindowWidth(), GetWindowHeight());
1704 		glDeleteTextures(1, &tex);
1705 		glDeleteFramebuffers(1, &fbo);
1706 		glDeleteRenderbuffers(1, &rbo);
1707 		glDeleteVertexArrays(1, &vao);
1708 		glDeleteBuffers(1, &vbo);
1709 		glDeleteProgram(program);
1710 		return NO_ERROR;
1711 	}
1712 };
1713 
1714 class PlainGatherFloat2DSrgb : public GatherBase
1715 {
1716 public:
Expected()1717 	virtual std::string Expected()
1718 	{
1719 		return "vec4(0, 20.0/255.0, 90.0/255.0, 222.0/255.0)";
1720 	}
1721 
InternalFormat()1722 	virtual GLenum InternalFormat()
1723 	{
1724 		return GL_SRGB8_ALPHA8;
1725 	}
1726 
Init()1727 	virtual void Init()
1728 	{
1729 		CreateTextureSRGB();
1730 	}
1731 };
1732 
1733 class PlainGatherFloat2DSrgbAlpha : public GatherBase
1734 {
1735 public:
Gather()1736 	virtual std::string Gather()
1737 	{
1738 		return "textureGather(my_sampler, vec2(p.x, p.y), 3)";
1739 	}
1740 
Expected()1741 	virtual std::string Expected()
1742 	{
1743 		return "vec4(3.0/255.0, 7.0/255.0, 11.0/255.0, 15.0/255.0)";
1744 	}
1745 
InternalFormat()1746 	virtual GLenum InternalFormat()
1747 	{
1748 		return GL_SRGB8_ALPHA8;
1749 	}
1750 
Init()1751 	virtual void Init()
1752 	{
1753 		CreateTextureSRGB();
1754 	}
1755 };
1756 
1757 class PlainGatherFloat2DRgb : public GatherBase
1758 {
1759 public:
Init()1760 	virtual void Init()
1761 	{
1762 		CreateTexture2DRgb();
1763 	}
1764 };
1765 
1766 class PlainGatherFloat2DRg : public GatherBase
1767 {
1768 public:
Init()1769 	virtual void Init()
1770 	{
1771 		CreateTexture2DRg();
1772 	}
1773 };
1774 
1775 class PlainGatherFloat2DR : public GatherBase
1776 {
1777 public:
Init()1778 	virtual void Init()
1779 	{
1780 		CreateTexture2DR();
1781 	}
1782 };
1783 
1784 class OffsetGatherFloat2DRgb : public OffsetGatherFloat2D
1785 {
1786 public:
Init()1787 	virtual void Init()
1788 	{
1789 		CreateTexture2DRgb();
1790 	}
1791 };
1792 
1793 class OffsetGatherFloat2DRg : public OffsetGatherFloat2D
1794 {
1795 public:
Init()1796 	virtual void Init()
1797 	{
1798 		CreateTexture2DRg();
1799 	}
1800 };
1801 
1802 class OffsetGatherFloat2DR : public OffsetGatherFloat2D
1803 {
1804 public:
Init()1805 	virtual void Init()
1806 	{
1807 		CreateTexture2DR();
1808 	}
1809 };
1810 
1811 } // anonymous namespace
1812 
TextureGatherTests(glcts::Context & context)1813 TextureGatherTests::TextureGatherTests(glcts::Context& context) : TestCaseGroup(context, "texture_gather", "")
1814 {
1815 }
1816 
~TextureGatherTests(void)1817 TextureGatherTests::~TextureGatherTests(void)
1818 {
1819 }
1820 
init()1821 void TextureGatherTests::init()
1822 {
1823 	using namespace glcts;
1824 	addChild(new TestSubcase(m_context, "api-enums", TestSubcase::Create<GatherEnumsTest>));
1825 	addChild(new TestSubcase(m_context, "gather-glsl-compile", TestSubcase::Create<GatherGLSLCompile>));
1826 	addChild(new TestSubcase(m_context, "plain-gather-float-2d", TestSubcase::Create<PlainGatherFloat2D>));
1827 	addChild(new TestSubcase(m_context, "plain-gather-int-2d", TestSubcase::Create<PlainGatherInt2D>));
1828 	addChild(new TestSubcase(m_context, "plain-gather-uint-2d", TestSubcase::Create<PlainGatherUint2D>));
1829 	addChild(new TestSubcase(m_context, "plain-gather-depth-2d", TestSubcase::Create<PlainGatherDepth2D>));
1830 	addChild(new TestSubcase(m_context, "plain-gather-float-2darray", TestSubcase::Create<PlainGatherFloat2DArray>));
1831 	addChild(new TestSubcase(m_context, "plain-gather-int-2darray", TestSubcase::Create<PlainGatherInt2DArray>));
1832 	addChild(new TestSubcase(m_context, "plain-gather-uint-2darray", TestSubcase::Create<PlainGatherUint2DArray>));
1833 	addChild(new TestSubcase(m_context, "plain-gather-depth-2darray", TestSubcase::Create<PlainGatherDepth2DArray>));
1834 	addChild(new TestSubcase(m_context, "plain-gather-float-cube-rgba", TestSubcase::Create<PlainGatherFloatCube>));
1835 	addChild(new TestSubcase(m_context, "plain-gather-int-cube-rgba", TestSubcase::Create<PlainGatherIntCube>));
1836 	addChild(new TestSubcase(m_context, "plain-gather-uint-cube", TestSubcase::Create<PlainGatherUintCube>));
1837 	addChild(new TestSubcase(m_context, "plain-gather-depth-cube", TestSubcase::Create<PlainGatherDepthCube>));
1838 	addChild(new TestSubcase(m_context, "offset-gather-float-2d", TestSubcase::Create<OffsetGatherFloat2D>));
1839 	addChild(new TestSubcase(m_context, "offset-gather-int-2d", TestSubcase::Create<OffsetGatherInt2D>));
1840 	addChild(new TestSubcase(m_context, "offset-gather-uint-2d", TestSubcase::Create<OffsetGatherUint2D>));
1841 	addChild(new TestSubcase(m_context, "offset-gather-depth-2d", TestSubcase::Create<OffsetGatherDepth2D>));
1842 	addChild(new TestSubcase(m_context, "offset-gather-float-2darray", TestSubcase::Create<OffsetGatherFloat2DArray>));
1843 	addChild(new TestSubcase(m_context, "offset-gather-int-2darray", TestSubcase::Create<OffsetGatherInt2DArray>));
1844 	addChild(new TestSubcase(m_context, "offset-gather-uint-2darray", TestSubcase::Create<OffsetGatherUint2DArray>));
1845 	addChild(new TestSubcase(m_context, "offset-gather-depth-2darray", TestSubcase::Create<OffsetGatherDepth2DArray>));
1846 	addChild(new TestSubcase(m_context, "swizzle", TestSubcase::Create<Swizzle>));
1847 	addChild(new TestSubcase(m_context, "base-level", TestSubcase::Create<BaseLevel>));
1848 	addChild(new TestSubcase(m_context, "incomplete-texture", TestSubcase::Create<IncompleteTexture>));
1849 	addChild(
1850 		new TestSubcase(m_context, "incomplete-texture-last-comp", TestSubcase::Create<IncompleteTextureLastComp>));
1851 	addChild(new TestSubcase(m_context, "triangle-draw", TestSubcase::Create<TriangleDraw>));
1852 	addChild(new TestSubcase(m_context, "plain-gather-float-2d-srgb", TestSubcase::Create<PlainGatherFloat2DSrgb>));
1853 	addChild(new TestSubcase(m_context, "plain-gather-float-2d-srgb-alpha",
1854 							 TestSubcase::Create<PlainGatherFloat2DSrgbAlpha>));
1855 	addChild(new TestSubcase(m_context, "plain-gather-float-2d-rgb", TestSubcase::Create<PlainGatherFloat2DRgb>));
1856 	addChild(new TestSubcase(m_context, "plain-gather-float-2d-rg", TestSubcase::Create<PlainGatherFloat2DRg>));
1857 	addChild(new TestSubcase(m_context, "plain-gather-float-2d-r", TestSubcase::Create<PlainGatherFloat2DR>));
1858 	addChild(new TestSubcase(m_context, "offset-gather-float-2d-rgb", TestSubcase::Create<OffsetGatherFloat2DRgb>));
1859 	addChild(new TestSubcase(m_context, "offset-gather-float-2d-rg", TestSubcase::Create<OffsetGatherFloat2DRg>));
1860 	addChild(new TestSubcase(m_context, "offset-gather-float-2d-r", TestSubcase::Create<OffsetGatherFloat2DR>));
1861 }
1862 } // glcts namespace
1863