• 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 "esextcGeometryShaderLayeredFramebuffer.hpp"
25 
26 #include "gluContextInfo.hpp"
27 #include "gluDefs.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "tcuTestLog.hpp"
31 #include <cstring>
32 
33 namespace glcts
34 {
35 /** Constructor
36  *
37  * @param context       Test context
38  * @param name          Test case's name
39  * @param description   Test case's desricption
40  **/
GeometryShaderLayeredFramebufferBlending(Context & context,const ExtParameters & extParams,const char * name,const char * description)41 GeometryShaderLayeredFramebufferBlending::GeometryShaderLayeredFramebufferBlending(Context&				context,
42 																				   const ExtParameters& extParams,
43 																				   const char*			name,
44 																				   const char*			description)
45 	: TestCaseBase(context, extParams, name, description)
46 	, m_fbo_id(0)
47 	, m_fs_id(0)
48 	, m_gs_id(0)
49 	, m_po_id(0)
50 	, m_read_fbo_id(0)
51 	, m_to_id(0)
52 	, m_vao_id(0)
53 	, m_vs_id(0)
54 {
55 	/* Left blank on purpose */
56 }
57 
58 /** Deinitializes GLES objects created during the test. */
deinit(void)59 void GeometryShaderLayeredFramebufferBlending::deinit(void)
60 {
61 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
62 
63 	/* Clean up */
64 	if (m_fbo_id != 0)
65 	{
66 		gl.deleteFramebuffers(1, &m_fbo_id);
67 	}
68 
69 	if (m_fs_id != 0)
70 	{
71 		gl.deleteShader(m_fs_id);
72 	}
73 
74 	if (m_gs_id != 0)
75 	{
76 		gl.deleteShader(m_gs_id);
77 	}
78 
79 	if (m_po_id != 0)
80 	{
81 		gl.deleteProgram(m_po_id);
82 	}
83 
84 	if (m_read_fbo_id != 0)
85 	{
86 		gl.deleteFramebuffers(1, &m_read_fbo_id);
87 	}
88 
89 	if (m_to_id != 0)
90 	{
91 		gl.deleteTextures(1, &m_to_id);
92 	}
93 
94 	if (m_vao_id != 0)
95 	{
96 		gl.deleteVertexArrays(1, &m_vao_id);
97 	}
98 
99 	if (m_vs_id != 0)
100 	{
101 		gl.deleteShader(m_vs_id);
102 	}
103 
104 	/* Release base class */
105 	TestCaseBase::deinit();
106 }
107 
108 /** Executes the test.
109  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
110  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
111  *  Note the function throws exception should an error occur!
112  **/
iterate(void)113 tcu::TestNode::IterateResult GeometryShaderLayeredFramebufferBlending::iterate(void)
114 {
115 /* Test-wide constants */
116 #define N_TEXTURE_COMPONENTS (4)
117 #define TEXTURE_DEPTH (4)
118 #define TEXTURE_HEIGHT (4)
119 #define TEXTURE_WIDTH (4)
120 
121 	/* Fragment shader code */
122 	const char* fs_code = "${VERSION}\n"
123 						  "\n"
124 						  "precision highp float;\n"
125 						  "\n"
126 						  "out vec4 result;\n"
127 						  "\n"
128 						  "void main()\n"
129 						  "{\n"
130 						  "    result = vec4(0.2);\n"
131 						  "}\n";
132 
133 	/* Geometry shader code */
134 	const char* gs_code = "${VERSION}\n"
135 						  "${GEOMETRY_SHADER_REQUIRE}\n"
136 						  "\n"
137 						  "layout(points)                          in;\n"
138 						  "layout(triangle_strip, max_vertices=64) out;\n"
139 						  "\n"
140 						  "void main()\n"
141 						  "{\n"
142 						  "    for (int n = 0; n < 4; ++n)\n"
143 						  "    {\n"
144 						  "        gl_Layer    = n;\n"
145 						  "        gl_Position = vec4(1, 1, 0, 1);\n"
146 						  "        EmitVertex();\n"
147 						  "\n"
148 						  "        gl_Layer    = n;\n"
149 						  "        gl_Position = vec4(1, -1, 0, 1);\n"
150 						  "        EmitVertex();\n"
151 						  "\n"
152 						  "        gl_Layer    = n;\n"
153 						  "        gl_Position = vec4(-1, 1, 0, 1);\n"
154 						  "        EmitVertex();\n"
155 						  "\n"
156 						  "        gl_Layer    = n;\n"
157 						  "        gl_Position = vec4(-1, -1, 0, 1);\n"
158 						  "        EmitVertex();\n"
159 						  "\n"
160 						  "        EndPrimitive();\n"
161 						  "    }\n"
162 						  "}\n";
163 
164 	/* General variables */
165 	const glw::Functions& gl		  = m_context.getRenderContext().getFunctions();
166 	unsigned int		  n			  = 0;
167 	unsigned int		  n_component = 0;
168 	unsigned int		  n_layer	 = 0;
169 	unsigned int		  n_slice	 = 0;
170 	unsigned int		  x			  = 0;
171 	unsigned int		  y			  = 0;
172 
173 	unsigned char buffer[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
174 	unsigned char buffer_slice1[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
175 	unsigned char buffer_slice2[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
176 	unsigned char buffer_slice3[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
177 	unsigned char buffer_slice4[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
178 	unsigned char ref_buffer_slice1[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
179 	unsigned char ref_buffer_slice2[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
180 	unsigned char ref_buffer_slice3[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
181 	unsigned char ref_buffer_slice4[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
182 
183 	if (!m_is_geometry_shader_extension_supported)
184 	{
185 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
186 	}
187 
188 	/* Set up shader objects */
189 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
190 	m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
191 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
192 
193 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate shader objects");
194 
195 	/* Set up program objects */
196 	m_po_id = gl.createProgram();
197 
198 	if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fs_code, m_gs_id, 1 /* part */, &gs_code, m_vs_id, 1 /* part */,
199 					  &m_boilerplate_vs_code))
200 	{
201 		TCU_FAIL("Could not build program object");
202 	}
203 
204 	/* Prepare texture data we will use for each slice */
205 	for (n = 0; n < TEXTURE_WIDTH * TEXTURE_HEIGHT; ++n)
206 	{
207 		unsigned char* slice_pixels_ptr[] = { buffer_slice1 + n * N_TEXTURE_COMPONENTS,
208 											  buffer_slice2 + n * N_TEXTURE_COMPONENTS,
209 											  buffer_slice3 + n * N_TEXTURE_COMPONENTS,
210 											  buffer_slice4 + n * N_TEXTURE_COMPONENTS };
211 
212 		for (n_slice = 0; n_slice < sizeof(slice_pixels_ptr) / sizeof(slice_pixels_ptr[0]); ++n_slice)
213 		{
214 			slice_pixels_ptr[n_slice][0] = 0;
215 			slice_pixels_ptr[n_slice][1] = (unsigned char)(n_slice * 255 / 4);
216 			slice_pixels_ptr[n_slice][2] = (unsigned char)(n_slice * 255 / 8);
217 			slice_pixels_ptr[n_slice][3] = (unsigned char)(n_slice * 255 / 12);
218 		} /* for (all slices) */
219 	}	 /* for (all pixels) */
220 
221 	/* Calculate reference texture data we will later use when verifying the rendered data */
222 	for (n = 0; n < TEXTURE_WIDTH * TEXTURE_HEIGHT; ++n)
223 	{
224 		unsigned char* ref_slice_pixels_ptr[] = { ref_buffer_slice1 + n * N_TEXTURE_COMPONENTS,
225 												  ref_buffer_slice2 + n * N_TEXTURE_COMPONENTS,
226 												  ref_buffer_slice3 + n * N_TEXTURE_COMPONENTS,
227 												  ref_buffer_slice4 + n * N_TEXTURE_COMPONENTS };
228 
229 		unsigned char* slice_pixels_ptr[] = { buffer_slice1 + n * N_TEXTURE_COMPONENTS,
230 											  buffer_slice2 + n * N_TEXTURE_COMPONENTS,
231 											  buffer_slice3 + n * N_TEXTURE_COMPONENTS,
232 											  buffer_slice4 + n * N_TEXTURE_COMPONENTS };
233 
234 		for (n_slice = 0; n_slice < sizeof(slice_pixels_ptr) / sizeof(slice_pixels_ptr[0]); ++n_slice)
235 		{
236 			unsigned char* ref_slice_ptr = ref_slice_pixels_ptr[n_slice];
237 			unsigned char* slice_ptr	 = slice_pixels_ptr[n_slice];
238 			float		   slice_rgba[]  = {
239 				float(slice_ptr[0]) / 255.0f, /* convert to FP representation */
240 				float(slice_ptr[1]) / 255.0f, /* convert to FP representation */
241 				float(slice_ptr[2]) / 255.0f, /* convert to FP representation */
242 				float(slice_ptr[3]) / 255.0f  /* convert to FP representation */
243 			};
244 
245 			for (n_component = 0; n_component < N_TEXTURE_COMPONENTS; ++n_component)
246 			{
247 				float temp_component = slice_rgba[n_component] /* dst_color */ * slice_rgba[n_component] /* dst_color */
248 									   + 0.8f /* 1-src_color */ * 0.2f /* src_color */;
249 
250 				/* Clamp if necessary */
251 				if (temp_component < 0)
252 				{
253 					temp_component = 0.0f;
254 				}
255 				else if (temp_component > 1)
256 				{
257 					temp_component = 1.0f;
258 				}
259 
260 				/* Convert back to GL_RGBA8 */
261 				ref_slice_ptr[n_component] = (unsigned char)(temp_component * 255.0f);
262 			} /* for (all components) */
263 		}	 /* for (all slices) */
264 	}		  /* for (all pixels) */
265 
266 	/* Set up texture object used for the test */
267 	gl.genTextures(1, &m_to_id);
268 	gl.bindTexture(GL_TEXTURE_3D, m_to_id);
269 	gl.texStorage3D(GL_TEXTURE_3D, 1 /* levels */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH);
270 	gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, TEXTURE_WIDTH,
271 					 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, buffer_slice1);
272 	gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */, TEXTURE_WIDTH,
273 					 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, buffer_slice2);
274 	gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */, TEXTURE_WIDTH,
275 					 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, buffer_slice3);
276 	gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */, TEXTURE_WIDTH,
277 					 TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, buffer_slice4);
278 
279 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture object");
280 
281 	/* Set up framebuffer object used for the test */
282 	gl.genFramebuffers(1, &m_fbo_id);
283 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
284 
285 	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, 0 /* level */);
286 
287 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up draw framebuffer");
288 
289 	/* Generate and bind a vertex array object */
290 	gl.genVertexArrays(1, &m_vao_id);
291 	gl.bindVertexArray(m_vao_id);
292 
293 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up vertex array object");
294 
295 	/* Set up blending */
296 	gl.blendFunc(GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR);
297 	gl.enable(GL_BLEND);
298 
299 	/* Render */
300 	gl.useProgram(m_po_id);
301 	gl.viewport(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT);
302 
303 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
304 
305 	GLU_EXPECT_NO_ERROR(gl.getError(), "Draw call failed");
306 
307 	/* Verify rendered data in the layers */
308 	gl.genFramebuffers(1, &m_read_fbo_id);
309 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
310 
311 	for (n_layer = 0; n_layer < TEXTURE_DEPTH; ++n_layer)
312 	{
313 		bool has_layer_failed = false;
314 
315 		const unsigned char* ref_buffer =
316 			(n_layer == 0) ?
317 				ref_buffer_slice1 :
318 				(n_layer == 1) ? ref_buffer_slice2 : (n_layer == 2) ? ref_buffer_slice3 : ref_buffer_slice4;
319 
320 		gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, 0 /* level */, n_layer);
321 		gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
322 
323 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixel data!");
324 
325 		for (y = 0; y < TEXTURE_HEIGHT; ++y)
326 		{
327 			const unsigned int   pixel_size = N_TEXTURE_COMPONENTS;
328 			const unsigned char* ref_row	= ref_buffer + y * pixel_size;
329 			const unsigned char* row		= buffer + y * pixel_size;
330 
331 			for (x = 0; x < TEXTURE_WIDTH; ++x)
332 			{
333 #define EPSILON (1)
334 
335 				const unsigned char* data	 = row + x * pixel_size;
336 				const unsigned char* ref_data = ref_row + x * pixel_size;
337 
338 				if (de::abs((int)data[0] - (int)ref_data[0]) > EPSILON ||
339 					de::abs((int)data[1] - (int)ref_data[1]) > EPSILON ||
340 					de::abs((int)data[2] - (int)ref_data[2]) > EPSILON ||
341 					de::abs((int)data[3] - (int)ref_data[3]) > EPSILON)
342 				{
343 					m_testCtx.getLog() << tcu::TestLog::Message << "(layer=" << n_layer << " x=" << x << " y=" << y
344 									   << ") "
345 									   << "Reference value is different than the rendered data (epsilon > " << EPSILON
346 									   << "): "
347 									   << "(" << (unsigned int)ref_data[0] << ", " << (unsigned int)ref_data[1] << ", "
348 									   << (unsigned int)ref_data[2] << ", " << (unsigned int)ref_data[3] << ") vs "
349 									   << "(" << (unsigned int)data[0] << ", " << (unsigned int)data[1] << ", "
350 									   << (unsigned int)data[2] << ", " << (unsigned int)data[3] << ")."
351 									   << tcu::TestLog::EndMessage;
352 
353 					has_layer_failed = true;
354 				} /* if (regions are different) */
355 
356 #undef EPSILON
357 			} /* for (all pixels in a row) */
358 		}	 /* for (all rows) */
359 
360 		if (has_layer_failed)
361 		{
362 			TCU_FAIL("Pixel data comparison failed");
363 		}
364 	} /* for (all layers) */
365 
366 	/* Done */
367 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
368 	return STOP;
369 
370 #undef N_TEXTURE_COMPONENTS
371 #undef TEXTURE_DEPTH
372 #undef TEXTURE_HEIGHT
373 #undef TEXTURE_WIDTH
374 }
375 
376 /** Constructor
377  *
378  * @param context       Test context
379  * @param name          Test case's name
380  * @param description   Test case's description
381  **/
GeometryShaderLayeredFramebufferClear(Context & context,const ExtParameters & extParams,const char * name,const char * description)382 GeometryShaderLayeredFramebufferClear::GeometryShaderLayeredFramebufferClear(Context&			  context,
383 																			 const ExtParameters& extParams,
384 																			 const char* name, const char* description)
385 	: TestCaseBase(context, extParams, name, description)
386 	, m_fbo_char_id(0)
387 	, m_fbo_int_id(0)
388 	, m_fbo_uint_id(0)
389 	, m_read_fbo_id(0)
390 	, m_to_rgba32i_id(0)
391 	, m_to_rgba32ui_id(0)
392 	, m_to_rgba8_id(0)
393 {
394 	/* Left blank on purpose */
395 }
396 
397 /** Executes the test.
398  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
399  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
400  *  Note the function throws exception should an error occur!
401  **/
iterate(void)402 tcu::TestNode::IterateResult GeometryShaderLayeredFramebufferClear::iterate(void)
403 {
404 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
405 
406 /* Test-wide definitions */
407 #define N_TEXTURE_COMPONENTS (4)
408 #define TEXTURE_DEPTH (4)
409 #define TEXTURE_HEIGHT (4)
410 #define TEXTURE_WIDTH (4)
411 
412 	/* Type definitions */
413 	typedef enum {
414 		/* Always first */
415 		CLEAR_FIRST = 0,
416 
417 		/* glClear() */
418 		CLEAR_PLAIN = CLEAR_FIRST,
419 		/* glClearBufferfv() */
420 		CLEAR_BUFFERFV,
421 		/* glClearBufferiv() */
422 		CLEAR_BUFFERIV,
423 		/* glClearBufferuiv() */
424 		CLEAR_BUFFERUIV,
425 
426 		/* Always last */
427 		CLEAR_COUNT
428 	} _clear_type;
429 
430 	/* General variables */
431 	const glw::GLenum fbo_draw_buffer = GL_COLOR_ATTACHMENT0;
432 
433 	int n		= 0;
434 	int n_layer = 0;
435 	int x		= 0;
436 	int y		= 0;
437 
438 	unsigned char buffer_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
439 	int			  buffer_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
440 	unsigned int  buffer_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
441 	unsigned char slice_1_data_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
442 	int			  slice_1_data_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
443 	unsigned int  slice_1_data_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
444 	unsigned char slice_2_data_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
445 	int			  slice_2_data_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
446 	unsigned int  slice_2_data_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
447 	unsigned char slice_3_data_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
448 	int			  slice_3_data_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
449 	unsigned int  slice_3_data_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
450 	unsigned char slice_4_data_char[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
451 	int			  slice_4_data_int[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
452 	unsigned int  slice_4_data_uint[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
453 
454 	/* Only carry on if geometry shaders are supported */
455 	if (!m_is_geometry_shader_extension_supported)
456 	{
457 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
458 	}
459 
460 	/* Set up slice data */
461 	memset(slice_1_data_char, 0, sizeof(slice_1_data_char));
462 	memset(slice_1_data_int, 0, sizeof(slice_1_data_int));
463 	memset(slice_1_data_uint, 0, sizeof(slice_1_data_uint));
464 	memset(slice_2_data_char, 0, sizeof(slice_2_data_char));
465 	memset(slice_2_data_int, 0, sizeof(slice_2_data_int));
466 	memset(slice_2_data_uint, 0, sizeof(slice_2_data_uint));
467 	memset(slice_3_data_char, 0, sizeof(slice_3_data_char));
468 	memset(slice_3_data_int, 0, sizeof(slice_3_data_int));
469 	memset(slice_3_data_uint, 0, sizeof(slice_3_data_uint));
470 	memset(slice_4_data_char, 0, sizeof(slice_4_data_char));
471 	memset(slice_4_data_int, 0, sizeof(slice_4_data_int));
472 	memset(slice_4_data_uint, 0, sizeof(slice_4_data_uint));
473 
474 	for (n = 0; n < 4 /* width */ * 4 /* height */; ++n)
475 	{
476 		slice_1_data_char[4 * n + 0] = 255;
477 		slice_1_data_int[4 * n + 0]  = 255;
478 		slice_1_data_uint[4 * n + 0] = 255;
479 
480 		slice_2_data_char[4 * n + 1] = 255;
481 		slice_2_data_int[4 * n + 1]  = 255;
482 		slice_2_data_uint[4 * n + 1] = 255;
483 
484 		slice_3_data_char[4 * n + 2] = 255;
485 		slice_3_data_int[4 * n + 2]  = 255;
486 		slice_3_data_uint[4 * n + 2] = 255;
487 
488 		slice_4_data_char[4 * n + 0] = 255;
489 		slice_4_data_char[4 * n + 1] = 255;
490 		slice_4_data_int[4 * n + 0]  = 255;
491 		slice_4_data_int[4 * n + 1]  = 255;
492 		slice_4_data_uint[4 * n + 0] = 255;
493 		slice_4_data_uint[4 * n + 1] = 255;
494 	} /* for (all pixels) */
495 
496 	/* Set up texture objects */
497 	gl.genTextures(1, &m_to_rgba8_id);
498 	gl.genTextures(1, &m_to_rgba32i_id);
499 	gl.genTextures(1, &m_to_rgba32ui_id);
500 
501 	for (n = 0; n < 3 /* textures */; ++n)
502 	{
503 		void* to_data_1 =
504 			(n == 0) ? (void*)slice_1_data_char : (n == 1) ? (void*)slice_1_data_int : (void*)slice_1_data_uint;
505 
506 		void* to_data_2 =
507 			(n == 0) ? (void*)slice_2_data_char : (n == 1) ? (void*)slice_2_data_int : (void*)slice_2_data_uint;
508 
509 		void* to_data_3 =
510 			(n == 0) ? (void*)slice_3_data_char : (n == 1) ? (void*)slice_3_data_int : (void*)slice_3_data_uint;
511 
512 		void* to_data_4 =
513 			(n == 0) ? (void*)slice_4_data_char : (n == 1) ? (void*)slice_4_data_int : (void*)slice_4_data_uint;
514 
515 		glw::GLenum to_format = (n == 0) ? GL_RGBA : (n == 1) ? GL_RGBA_INTEGER : GL_RGBA_INTEGER;
516 
517 		glw::GLenum to_internalformat = (n == 0) ? GL_RGBA8 : (n == 1) ? GL_RGBA32I : GL_RGBA32UI;
518 
519 		glw::GLuint to_id = (n == 0) ? m_to_rgba8_id : (n == 1) ? m_to_rgba32i_id : m_to_rgba32ui_id;
520 
521 		glw::GLenum to_type = (n == 0) ? GL_UNSIGNED_BYTE : (n == 1) ? GL_INT : GL_UNSIGNED_INT;
522 
523 		gl.bindTexture(GL_TEXTURE_3D, to_id);
524 
525 		gl.texStorage3D(GL_TEXTURE_3D, 1 /* levels */, to_internalformat, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH);
526 
527 		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, TEXTURE_WIDTH,
528 						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, to_data_1);
529 		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */, TEXTURE_WIDTH,
530 						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, to_data_2);
531 		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */, TEXTURE_WIDTH,
532 						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, to_data_3);
533 		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */, TEXTURE_WIDTH,
534 						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, to_data_4);
535 
536 		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
537 		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
538 		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
539 
540 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize texture object");
541 	} /* for (all texture objects) */
542 
543 	/* Set up framebuffer object */
544 	gl.genFramebuffers(1, &m_fbo_char_id);
545 	gl.genFramebuffers(1, &m_fbo_int_id);
546 	gl.genFramebuffers(1, &m_fbo_uint_id);
547 	gl.genFramebuffers(1, &m_read_fbo_id);
548 
549 	for (n = 0; n < 3 /* framebuffers */; ++n)
550 	{
551 		glw::GLuint fbo_id = (n == 0) ? m_fbo_char_id : (n == 1) ? m_fbo_int_id : m_fbo_uint_id;
552 
553 		glw::GLuint to_id = (n == 0) ? m_to_rgba8_id : (n == 1) ? m_to_rgba32i_id : m_to_rgba32ui_id;
554 
555 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
556 		gl.drawBuffers(1, &fbo_draw_buffer);
557 		gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id, 0 /* level */);
558 
559 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize framebuffer object");
560 	} /* for (all framebuffers) */
561 
562 	/* Try reading from the layered framebuffer. */
563 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_char_id);
564 	gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer_char);
565 
566 	/* Is the returned data an exact copy of what we've uploaded for layer zero? */
567 	if (memcmp(buffer_char, slice_1_data_char, sizeof(slice_1_data_char)) != 0)
568 	{
569 		TCU_FAIL("Retrieved data is different from data uploaded for layer 0 of a layered framebuffer.");
570 	}
571 
572 	/* Iterate through all clear calls supported */
573 
574 	for (int current_test = static_cast<int>(CLEAR_FIRST); current_test < static_cast<int>(CLEAR_COUNT); current_test++)
575 	{
576 		void*				buffer				= NULL;
577 		const float			clear_color_float[] = { 0.25f, 0.5f, 1.0f, 32.0f / 255.0f };
578 		const int			clear_color_int[]   = { 64, 128, 255, 32 };
579 		glw::GLuint			fbo_id				= 0;
580 		int					pixel_size			= 0;
581 		void*				slice_1_data		= NULL;
582 		void*				slice_2_data		= NULL;
583 		void*				slice_3_data		= NULL;
584 		void*				slice_4_data		= NULL;
585 		glw::GLenum			to_format			= GL_NONE;
586 		glw::GLuint			to_id				= 0;
587 		glw::GLenum			to_type				= GL_NONE;
588 
589 		switch (static_cast<_clear_type>(current_test))
590 		{
591 		case CLEAR_BUFFERFV:
592 		case CLEAR_PLAIN:
593 		{
594 			buffer		 = buffer_char;
595 			fbo_id		 = m_fbo_char_id;
596 			pixel_size   = N_TEXTURE_COMPONENTS;
597 			slice_1_data = slice_1_data_char;
598 			slice_2_data = slice_2_data_char;
599 			slice_3_data = slice_3_data_char;
600 			slice_4_data = slice_4_data_char;
601 			to_format	= GL_RGBA;
602 			to_id		 = m_to_rgba8_id;
603 			to_type		 = GL_UNSIGNED_BYTE;
604 
605 			break;
606 		}
607 
608 		case CLEAR_BUFFERIV:
609 		{
610 			buffer		 = (void*)buffer_int;
611 			fbo_id		 = m_fbo_int_id;
612 			pixel_size   = N_TEXTURE_COMPONENTS * sizeof(int);
613 			slice_1_data = slice_1_data_int;
614 			slice_2_data = slice_2_data_int;
615 			slice_3_data = slice_3_data_int;
616 			slice_4_data = slice_4_data_int;
617 			to_format	= GL_RGBA_INTEGER;
618 			to_id		 = m_to_rgba32i_id;
619 			to_type		 = GL_INT;
620 
621 			break;
622 		}
623 
624 		case CLEAR_BUFFERUIV:
625 		{
626 			buffer		 = (void*)buffer_uint;
627 			fbo_id		 = m_fbo_uint_id;
628 			pixel_size   = N_TEXTURE_COMPONENTS * sizeof(unsigned int);
629 			slice_1_data = slice_1_data_uint;
630 			slice_2_data = slice_2_data_uint;
631 			slice_3_data = slice_3_data_uint;
632 			slice_4_data = slice_4_data_uint;
633 			to_format	= GL_RGBA_INTEGER;
634 			to_id		 = m_to_rgba32ui_id;
635 			to_type		 = GL_UNSIGNED_INT;
636 
637 			break;
638 		}
639 
640 		default:
641 		{
642 			/* This location should never be reached */
643 			TCU_FAIL("Execution flow failure");
644 		}
645 		} /* switch (current_test)*/
646 
647 		/* Restore layer data just in case */
648 		gl.bindTexture(GL_TEXTURE_3D, to_id);
649 		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, TEXTURE_WIDTH,
650 						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, slice_1_data);
651 		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */, TEXTURE_WIDTH,
652 						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, slice_2_data);
653 		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */, TEXTURE_WIDTH,
654 						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, slice_3_data);
655 		gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */, TEXTURE_WIDTH,
656 						 TEXTURE_HEIGHT, 1 /* depth */, to_format, to_type, slice_4_data);
657 
658 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D() call failed.");
659 
660 		/* Issue requested clear call */
661 		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
662 
663 		switch (current_test)
664 		{
665 		case CLEAR_PLAIN:
666 		{
667 			gl.clearColor(clear_color_float[0], clear_color_float[1], clear_color_float[2], clear_color_float[3]);
668 			gl.clear(GL_COLOR_BUFFER_BIT);
669 
670 			break;
671 		}
672 
673 		case CLEAR_BUFFERIV:
674 		{
675 			gl.clearBufferiv(GL_COLOR, 0 /* draw buffer index */, clear_color_int);
676 
677 			break;
678 		}
679 
680 		case CLEAR_BUFFERUIV:
681 		{
682 			gl.clearBufferuiv(GL_COLOR, 0 /* draw buffer index */, (const glw::GLuint*)clear_color_int);
683 
684 			break;
685 		}
686 
687 		case CLEAR_BUFFERFV:
688 		{
689 			gl.clearBufferfv(GL_COLOR, 0 /* draw buffer index */, clear_color_float);
690 
691 			break;
692 		}
693 
694 		default:
695 		{
696 			/* This location should never be reached */
697 			TCU_FAIL("Execution flow failure");
698 		}
699 		} /* switch (current_test) */
700 
701 		/* Make sure no error was generated */
702 		GLU_EXPECT_NO_ERROR(gl.getError(), "Clear call failed.");
703 
704 		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
705 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create read framebuffer object!");
706 
707 		/* Check the layer data after a clear call */
708 		for (n_layer = 0; n_layer < TEXTURE_DEPTH; ++n_layer)
709 		{
710 			gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id, 0 /* level */, n_layer);
711 			gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, to_format, to_type, buffer);
712 
713 			GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
714 
715 			/* If we requested an integer clear, the pixels we obtained should be reset to specific values.
716 			 * If we asked for a FP-based clear, consider an epsilon. */
717 			for (y = 0; y < TEXTURE_HEIGHT; ++y)
718 			{
719 				const int	  row_size = TEXTURE_WIDTH * pixel_size;
720 				unsigned char* row		= (unsigned char*)buffer + y * row_size;
721 
722 				for (x = 0; x < TEXTURE_WIDTH; ++x)
723 				{
724 					if (current_test == CLEAR_BUFFERIV || current_test == CLEAR_BUFFERUIV)
725 					{
726 						unsigned int* pixel = (unsigned int*)(row + x * pixel_size);
727 						if (memcmp(pixel, clear_color_int, sizeof(clear_color_int)) != 0)
728 						{
729 							/* Test fails at this point */
730 							m_testCtx.getLog()
731 								<< tcu::TestLog::Message << "(x=" << x << " y=" << y << ") Reference pixel ["
732 								<< clear_color_int[0] << ", " << clear_color_int[1] << ", " << clear_color_int[2]
733 								<< ", " << clear_color_int[3] << "] is different from the one retrieved ["
734 								<< (int)pixel[0] << ", " << (int)pixel[1] << ", " << (int)pixel[2] << ", "
735 								<< (int)pixel[3] << "]" << tcu::TestLog::EndMessage;
736 
737 							TCU_FAIL("Data comparison failure");
738 						} /* if (memcmp(pixel, clear_color_int, sizeof(clear_color_int) ) != 0) */
739 					}	 /* if (current_test == CLEAR_BUFFERIV || current_test == CLEAR_BUFFERUIV) */
740 					else
741 					{
742 #define EPSILON (1)
743 
744 						unsigned char* pixel = (unsigned char*)(row + x * pixel_size);
745 
746 						if (de::abs((int)pixel[0] - clear_color_int[0]) > EPSILON ||
747 							de::abs((int)pixel[1] - clear_color_int[1]) > EPSILON ||
748 							de::abs((int)pixel[2] - clear_color_int[2]) > EPSILON ||
749 							de::abs((int)pixel[3] - clear_color_int[3]) > EPSILON)
750 						{
751 							/* Test fails at this point */
752 							m_testCtx.getLog()
753 								<< tcu::TestLog::Message << "(x=" << x << " y=" << y << ") Reference pixel ["
754 								<< clear_color_int[0] << ", " << clear_color_int[1] << ", " << clear_color_int[2]
755 								<< ", " << clear_color_int[3] << "] is different from the one retrieved ["
756 								<< (int)pixel[0] << ", " << (int)pixel[1] << ", " << (int)pixel[2] << ", "
757 								<< (int)pixel[3] << "]" << tcu::TestLog::EndMessage;
758 
759 							TCU_FAIL("Data comparison failure");
760 						} /* if (pixel component has exceeded an allowed epsilon) */
761 
762 #undef EPSILON
763 					}
764 				} /* for (all pixels) */
765 			}	 /* for (all rows) */
766 		}		  /* for (all layers) */
767 	}			  /* for (all clear call types) */
768 
769 	/* Done */
770 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
771 	return STOP;
772 
773 #undef TEXTURE_DEPTH
774 #undef TEXTURE_HEIGHT
775 #undef TEXTURE_WIDTH
776 }
777 
778 /** Deinitializes GLES objects created during the test. */
deinit(void)779 void GeometryShaderLayeredFramebufferClear::deinit(void)
780 {
781 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
782 
783 	if (m_fbo_char_id != 0)
784 	{
785 		gl.deleteFramebuffers(1, &m_fbo_char_id);
786 	}
787 
788 	if (m_fbo_int_id != 0)
789 	{
790 		gl.deleteFramebuffers(1, &m_fbo_int_id);
791 	}
792 
793 	if (m_fbo_uint_id != 0)
794 	{
795 		gl.deleteFramebuffers(1, &m_fbo_uint_id);
796 	}
797 
798 	if (m_to_rgba32i_id != 0)
799 	{
800 		gl.deleteTextures(1, &m_to_rgba32i_id);
801 	}
802 
803 	if (m_to_rgba32ui_id != 0)
804 	{
805 		gl.deleteTextures(1, &m_to_rgba32ui_id);
806 	}
807 
808 	if (m_to_rgba8_id != 0)
809 	{
810 		gl.deleteTextures(1, &m_to_rgba8_id);
811 	}
812 
813 	if (m_read_fbo_id != 0)
814 	{
815 		gl.deleteFramebuffers(1, &m_read_fbo_id);
816 	}
817 
818 	/* Release base class */
819 	TestCaseBase::deinit();
820 }
821 
822 /** Constructor
823  *
824  * @param context       Test context
825  * @param name          Test case's name
826  * @param description   Test case's desricption
827  **/
GeometryShaderLayeredFramebufferDepth(Context & context,const ExtParameters & extParams,const char * name,const char * description)828 GeometryShaderLayeredFramebufferDepth::GeometryShaderLayeredFramebufferDepth(Context&			  context,
829 																			 const ExtParameters& extParams,
830 																			 const char* name, const char* description)
831 	: TestCaseBase(context, extParams, name, description)
832 	, m_fbo_id(0)
833 	, m_fs_id(0)
834 	, m_gs_id(0)
835 	, m_po_id(0)
836 	, m_read_fbo_id(0)
837 	, m_to_a_id(0)
838 	, m_to_b_id(0)
839 	, m_vao_id(0)
840 	, m_vs_id(0)
841 {
842 	/* Left blank on purpose */
843 }
844 
845 /** Deinitializes GLES objects created during the test. */
deinit(void)846 void GeometryShaderLayeredFramebufferDepth::deinit(void)
847 {
848 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
849 
850 	/* Clean up */
851 	if (m_fbo_id != 0)
852 	{
853 		gl.deleteFramebuffers(1, &m_fbo_id);
854 	}
855 
856 	if (m_fs_id != 0)
857 	{
858 		gl.deleteShader(m_fs_id);
859 	}
860 
861 	if (m_gs_id != 0)
862 	{
863 		gl.deleteShader(m_gs_id);
864 	}
865 
866 	if (m_po_id != 0)
867 	{
868 		gl.deleteProgram(m_po_id);
869 	}
870 
871 	if (m_read_fbo_id != 0)
872 	{
873 		gl.deleteFramebuffers(1, &m_read_fbo_id);
874 	}
875 
876 	if (m_to_a_id != 0)
877 	{
878 		gl.deleteTextures(1, &m_to_a_id);
879 	}
880 
881 	if (m_to_b_id != 0)
882 	{
883 		gl.deleteTextures(1, &m_to_b_id);
884 	}
885 
886 	if (m_vao_id != 0)
887 	{
888 		gl.deleteVertexArrays(1, &m_vao_id);
889 	}
890 
891 	if (m_vs_id != 0)
892 	{
893 		gl.deleteShader(m_vs_id);
894 	}
895 
896 	/* Release base class */
897 	TestCaseBase::deinit();
898 }
899 
900 /** Executes the test.
901  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
902  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
903  *  Note the function throws exception should an error occur!
904  **/
iterate(void)905 tcu::TestNode::IterateResult GeometryShaderLayeredFramebufferDepth::iterate(void)
906 {
907 	/* General variables */
908 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
909 	unsigned int		  n  = 0;
910 	unsigned int		  x  = 0;
911 	unsigned int		  y  = 0;
912 
913 /* Test-wide definitions */
914 #define N_TEXTURE_COMPONENTS (4)
915 #define TEXTURE_DEPTH (4)
916 #define TEXTURE_HEIGHT (4)
917 #define TEXTURE_WIDTH (4)
918 
919 	/* Fragment shader code */
920 	const char* fs_code = "${VERSION}\n"
921 						  "\n"
922 						  "precision highp float;\n"
923 						  "\n"
924 						  "out vec4 result;\n"
925 						  "\n"
926 						  "void main()\n"
927 						  "{\n"
928 						  "    result = vec4(1.0);\n"
929 						  "}\n";
930 
931 	const char* gs_code = "${VERSION}\n"
932 						  "${GEOMETRY_SHADER_REQUIRE}\n"
933 						  "\n"
934 						  "layout(points)                          in;\n"
935 						  "layout(triangle_strip, max_vertices=64) out;\n"
936 						  "\n"
937 						  "void main()\n"
938 						  "{\n"
939 						  "    for (int n = 0; n < 4; ++n)\n"
940 						  "    {\n"
941 						  "        float depth = -1.0 + float(n) * 0.5;\n"
942 						  "\n"
943 						  "        gl_Layer    = n;\n"
944 						  "        gl_Position = vec4(1, 1, depth, 1);\n"
945 						  "        EmitVertex();\n"
946 						  "\n"
947 						  "        gl_Layer    = n;\n"
948 						  "        gl_Position = vec4(1, -1, depth, 1);\n"
949 						  "        EmitVertex();\n"
950 						  "\n"
951 						  "        gl_Layer    = n;\n"
952 						  "        gl_Position = vec4(-1, 1, depth, 1);\n"
953 						  "        EmitVertex();\n"
954 						  "\n"
955 						  "        gl_Layer    = n;\n"
956 						  "        gl_Position = vec4(-1, -1, depth, 1);\n"
957 						  "        EmitVertex();\n"
958 						  "\n"
959 						  "        EndPrimitive();\n"
960 						  "    }\n"
961 						  "}\n";
962 
963 	/* This test should only run if EXT_geometry_shader is supported */
964 	if (!m_is_geometry_shader_extension_supported)
965 	{
966 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
967 	}
968 
969 	/* Set up texture objects we will be using for the test */
970 	gl.genTextures(1, &m_to_a_id);
971 	gl.genTextures(1, &m_to_b_id);
972 
973 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_a_id);
974 	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* levels */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH);
975 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_b_id);
976 	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* levels */, GL_DEPTH_COMPONENT32F, TEXTURE_WIDTH, TEXTURE_HEIGHT,
977 					TEXTURE_DEPTH);
978 
979 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize texture objects");
980 
981 	/* Set up framebuffer object we will use for the test */
982 	gl.genFramebuffers(1, &m_fbo_id);
983 	gl.genFramebuffers(1, &m_read_fbo_id);
984 
985 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
986 
987 	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_a_id, 0 /* level */);
988 	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_to_b_id, 0 /* level */);
989 
990 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize framebuffer object");
991 
992 	if (gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
993 	{
994 		m_testCtx.getLog() << tcu::TestLog::Message
995 						   << "Draw framebuffer is incomplete: " << gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER)
996 						   << tcu::TestLog::EndMessage;
997 
998 		TCU_FAIL("Draw framebuffer is incomplete.");
999 	}
1000 
1001 	/* Set up shader objects */
1002 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1003 	m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
1004 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1005 
1006 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize shader objects");
1007 
1008 	/* Set up program object */
1009 	m_po_id = gl.createProgram();
1010 
1011 	if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fs_code, m_gs_id, 1 /* part */, &gs_code, m_vs_id, 1 /* part */,
1012 					  &m_boilerplate_vs_code))
1013 	{
1014 		TCU_FAIL("Could not build program object");
1015 	}
1016 
1017 	/* Set up vertex array object */
1018 	gl.genVertexArrays(1, &m_vao_id);
1019 	gl.bindVertexArray(m_vao_id);
1020 
1021 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind vertex array object");
1022 
1023 	/* Clear the depth attachment before we continue */
1024 	gl.clearColor(0.0f /* red */, 0.0f /* green */, 0.0f /* blue */, 0.0f /* alpha */);
1025 	gl.clearDepthf(0.5f);
1026 	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1027 
1028 	GLU_EXPECT_NO_ERROR(gl.getError(), "Depth buffer clear operation failed");
1029 
1030 	/* Render */
1031 	gl.useProgram(m_po_id);
1032 	gl.viewport(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT);
1033 
1034 	gl.enable(GL_DEPTH_TEST);
1035 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
1036 
1037 	GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed");
1038 
1039 	/* Verify the output */
1040 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
1041 
1042 	for (n = 0; n < TEXTURE_DEPTH; ++n)
1043 	{
1044 		unsigned char buffer[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS];
1045 		unsigned char ref_color[4];
1046 
1047 		/* Determine reference color */
1048 		if (n < 2)
1049 		{
1050 			memset(ref_color, 0xFF, sizeof(ref_color));
1051 		}
1052 		else
1053 		{
1054 			memset(ref_color, 0, sizeof(ref_color));
1055 		}
1056 
1057 		/* Read the rendered layer data */
1058 		gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_a_id, 0 /* level */, n);
1059 		gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
1060 
1061 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
1062 
1063 		/* Compare all pixels against the reference value */
1064 		for (y = 0; y < TEXTURE_HEIGHT; ++y)
1065 		{
1066 			const unsigned int   pixel_size = N_TEXTURE_COMPONENTS;
1067 			const unsigned int   row_width  = TEXTURE_WIDTH * pixel_size;
1068 			const unsigned char* row_data   = buffer + y * row_width;
1069 
1070 			for (x = 0; x < TEXTURE_WIDTH; ++x)
1071 			{
1072 				const unsigned char* result = row_data + x * pixel_size;
1073 
1074 				if (memcmp(result, ref_color, sizeof(ref_color)) != 0)
1075 				{
1076 					m_testCtx.getLog() << tcu::TestLog::Message << "(x=" << x << " y=" << y << ") "
1077 									   << "Reference value is different than the rendered data: "
1078 									   << "(" << (unsigned int)ref_color[0] << ", " << (unsigned int)ref_color[1]
1079 									   << ", " << (unsigned int)ref_color[2] << ", " << (unsigned int)ref_color[3]
1080 									   << ") vs "
1081 									   << "(" << (unsigned int)result[0] << ", " << (unsigned int)result[1] << ", "
1082 									   << (unsigned int)result[2] << ", " << (unsigned int)result[3] << ")."
1083 									   << tcu::TestLog::EndMessage;
1084 
1085 					TCU_FAIL("Rendered data mismatch");
1086 				} /* if (memcmp(row_data + x * pixel_size, ref_color, sizeof(ref_color) ) != 0)*/
1087 			}	 /* for (all pixels in a row) */
1088 		}		  /* for (all rows) */
1089 	}			  /* for (all layers) */
1090 
1091 	/* Done */
1092 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1093 	return STOP;
1094 
1095 #undef N_TEXTURE_COMPONENTS
1096 #undef TEXTURE_DEPTH
1097 #undef TEXTURE_HEIGHT
1098 #undef TEXTURE_WIDTH
1099 }
1100 
1101 /** Constructor
1102  *
1103  * @param context       Test context
1104  * @param name          Test case's name
1105  * @param description   Test case's desricption
1106  **/
GeometryShaderLayeredFramebufferStencil(Context & context,const ExtParameters & extParams,const char * name,const char * description)1107 GeometryShaderLayeredFramebufferStencil::GeometryShaderLayeredFramebufferStencil(Context&			  context,
1108 																				 const ExtParameters& extParams,
1109 																				 const char*		  name,
1110 																				 const char*		  description)
1111 	: TestCaseBase(context, extParams, name, description)
1112 	, m_fbo_id(0)
1113 	, m_fs_id(0)
1114 	, m_gs_id(0)
1115 	, m_po_id(0)
1116 	, m_to_a_id(0)
1117 	, m_to_b_id(0)
1118 	, m_vao_id(0)
1119 	, m_vs_id(0)
1120 {
1121 	/* Left blank on purpose */
1122 }
1123 
1124 /** Deinitializes GLES objects created during the test. */
deinit(void)1125 void GeometryShaderLayeredFramebufferStencil::deinit(void)
1126 {
1127 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1128 
1129 	/* Clean up */
1130 	if (m_fbo_id != 0)
1131 	{
1132 		gl.deleteFramebuffers(1, &m_fbo_id);
1133 	}
1134 
1135 	if (m_fs_id != 0)
1136 	{
1137 		gl.deleteShader(m_fs_id);
1138 	}
1139 
1140 	if (m_gs_id != 0)
1141 	{
1142 		gl.deleteShader(m_gs_id);
1143 	}
1144 
1145 	if (m_po_id != 0)
1146 	{
1147 		gl.deleteProgram(m_po_id);
1148 	}
1149 
1150 	if (m_to_a_id != 0)
1151 	{
1152 		gl.deleteTextures(1, &m_to_a_id);
1153 	}
1154 
1155 	if (m_to_b_id != 0)
1156 	{
1157 		gl.deleteTextures(1, &m_to_b_id);
1158 	}
1159 
1160 	if (m_vao_id != 0)
1161 	{
1162 		gl.deleteVertexArrays(1, &m_vao_id);
1163 	}
1164 
1165 	if (m_vs_id != 0)
1166 	{
1167 		gl.deleteShader(m_vs_id);
1168 	}
1169 
1170 	/* Release base class */
1171 	TestCaseBase::deinit();
1172 }
1173 
1174 /** Executes the test.
1175  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1176  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1177  *  Note the function throws exception should an error occur!
1178  **/
iterate(void)1179 tcu::TestNode::IterateResult GeometryShaderLayeredFramebufferStencil::iterate(void)
1180 {
1181 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1182 
1183 /* Test-wide definitions */
1184 #define N_TEXTURE_COMPONENTS (4)
1185 #define TEXTURE_DEPTH (4)
1186 #define TEXTURE_HEIGHT (4)
1187 #define TEXTURE_WIDTH (8)
1188 
1189 	/* Fragment shader code */
1190 	const char* fs_code = "${VERSION}\n"
1191 						  "\n"
1192 						  "precision highp float;\n"
1193 						  "\n"
1194 						  "out vec4 result;\n"
1195 						  "\n"
1196 						  "void main()\n"
1197 						  "{\n"
1198 						  "    result = vec4(1, 1, 1, 1);\n"
1199 						  "}\n";
1200 
1201 	/* Geometry shader code */
1202 	const char* gs_code = "${VERSION}\n"
1203 						  "${GEOMETRY_SHADER_REQUIRE}\n"
1204 						  "\n"
1205 						  "precision highp float;\n"
1206 						  "\n"
1207 						  "layout (points)                            in;\n"
1208 						  "layout (triangle_strip, max_vertices = 16) out;\n"
1209 						  "\n"
1210 						  "void main()\n"
1211 						  "{\n"
1212 						  "    for (int n = 0; n < 4; ++n)\n"
1213 						  "    {\n"
1214 						  "        gl_Position = vec4(1, -1, 0, 1);\n"
1215 						  "        gl_Layer    = n;\n"
1216 						  "        EmitVertex();\n"
1217 						  "\n"
1218 						  "        gl_Position = vec4(1,  1, 0, 1);\n"
1219 						  "        gl_Layer    = n;\n"
1220 						  "        EmitVertex();\n"
1221 						  "\n"
1222 						  "        gl_Position = vec4(-1, -1, 0, 1);\n"
1223 						  "        gl_Layer    = n;\n"
1224 						  "        EmitVertex();\n"
1225 						  "\n"
1226 						  "        gl_Position = vec4(-1,  1, 0, 1);\n"
1227 						  "        gl_Layer    = n;\n"
1228 						  "        EmitVertex();\n"
1229 						  "\n"
1230 						  "        EndPrimitive();\n"
1231 						  "    }\n"
1232 						  "\n"
1233 						  "}\n";
1234 
1235 	/* General variables */
1236 	int n = 0;
1237 
1238 	unsigned char slice_null_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 1 /* byte  per texel */] = { 0 };
1239 	unsigned char slice_1_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */]	= { 0 };
1240 	unsigned char slice_2_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */]	= { 0 };
1241 	unsigned char slice_3_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */]	= { 0 };
1242 	unsigned char slice_4_data[TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */]	= { 0 };
1243 
1244 	/* This test should only run if EXT_geometry_shader is supported */
1245 	if (!m_is_geometry_shader_extension_supported)
1246 	{
1247 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1248 	}
1249 
1250 	/* Create shader & program objects */
1251 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1252 	m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
1253 	m_po_id = gl.createProgram();
1254 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1255 
1256 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader or program objects");
1257 
1258 	/* Build test program object */
1259 	if (!buildProgram(m_po_id, m_fs_id, 1 /* parts */, &fs_code, m_gs_id, 1 /* parts */, &gs_code, m_vs_id,
1260 					  1 /* parts */, &m_boilerplate_vs_code))
1261 	{
1262 		TCU_FAIL("Could not build test program object");
1263 	}
1264 
1265 	/* Generate and bind a vertex array object */
1266 	gl.genVertexArrays(1, &m_vao_id);
1267 	gl.bindVertexArray(m_vao_id);
1268 
1269 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create & bind a vertex array object.");
1270 
1271 	/* Configure slice data */
1272 	for (n = 0; n < TEXTURE_DEPTH * TEXTURE_WIDTH * TEXTURE_HEIGHT * 8 /* bytes per texel */; ++n)
1273 	{
1274 		/* We are okay with depth data being filled with glitch, but need the stencil data to be
1275 		 * as per test spec. To keep code simple, we do not differentiate between floating-point and
1276 		 * stencil part.
1277 		 */
1278 		slice_1_data[n] = 2;
1279 		slice_2_data[n] = 1;
1280 
1281 		/* Slices 3 and 4 should be filled with 0s */
1282 		slice_3_data[n] = 0;
1283 		slice_4_data[n] = 0;
1284 	} /* for (all pixels making up slices) */
1285 
1286 	/* Set up texture objects */
1287 	gl.genTextures(1, &m_to_a_id);
1288 	gl.genTextures(1, &m_to_b_id);
1289 
1290 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_a_id);
1291 	gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH,
1292 				  0 /* border */, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1293 
1294 	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */,
1295 					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, slice_null_data);
1296 	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */,
1297 					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, slice_null_data);
1298 	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */,
1299 					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, slice_null_data);
1300 	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */,
1301 					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_RGBA, GL_UNSIGNED_BYTE, slice_null_data);
1302 
1303 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture object A.");
1304 
1305 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_b_id);
1306 	gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, GL_DEPTH32F_STENCIL8, TEXTURE_WIDTH, TEXTURE_HEIGHT,
1307 				  TEXTURE_DEPTH, 0 /* border */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL);
1308 
1309 	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */,
1310 					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1311 					 slice_1_data);
1312 	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 1 /* zoffset */,
1313 					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1314 					 slice_2_data);
1315 	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 2 /* zoffset */,
1316 					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1317 					 slice_3_data);
1318 	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 3 /* zoffset */,
1319 					 TEXTURE_WIDTH, TEXTURE_HEIGHT, 1 /* depth */, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1320 					 slice_4_data);
1321 
1322 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture object B.");
1323 
1324 	/* Set up depth tests */
1325 	gl.disable(GL_DEPTH_TEST);
1326 
1327 	/* Set up stencil tests */
1328 	gl.enable(GL_STENCIL_TEST);
1329 	gl.stencilFunc(GL_LESS, 0, /* reference value */ 0xFFFFFFFF /* mask */);
1330 
1331 	/* Set up framebuffer objects */
1332 	gl.genFramebuffers(1, &m_fbo_id);
1333 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
1334 
1335 	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_a_id, 0 /* level */);
1336 	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, m_to_b_id, 0 /* level */);
1337 
1338 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up draw framebuffer.");
1339 
1340 	/* Issue the draw call. */
1341 	gl.useProgram(m_po_id);
1342 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
1343 
1344 	GLU_EXPECT_NO_ERROR(gl.getError(), "Draw call failed.");
1345 
1346 	/* Check the results */
1347 	for (n = 0; n < 4 /* layers */; ++n)
1348 	{
1349 		glw::GLenum   fbo_completeness													 = GL_NONE;
1350 		int			  m																	 = 0;
1351 		unsigned char ref_data[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS]	= { 0 };
1352 		unsigned char result_data[TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS] = { 0 };
1353 		int			  x																	 = 0;
1354 		int			  y																	 = 0;
1355 
1356 		/* Configure the read framebuffer */
1357 		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id);
1358 
1359 		gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_a_id, 0 /* level */, n);
1360 		gl.framebufferTexture(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0 /* texture */, 0 /* level */);
1361 
1362 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up read framebuffer.");
1363 
1364 		/* Verify read framebuffer is considered complete */
1365 		fbo_completeness = gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER);
1366 
1367 		if (fbo_completeness != GL_FRAMEBUFFER_COMPLETE)
1368 		{
1369 			m_testCtx.getLog() << tcu::TestLog::Message << "Read FBO is incomplete: "
1370 							   << "[" << fbo_completeness << "]" << tcu::TestLog::EndMessage;
1371 
1372 			TCU_FAIL("Read FBO is incomplete.");
1373 		}
1374 
1375 		/* Build reference data */
1376 		for (m = 0; m < TEXTURE_WIDTH * TEXTURE_HEIGHT * N_TEXTURE_COMPONENTS; ++m)
1377 		{
1378 			if (n < 2)
1379 			{
1380 				ref_data[m] = 255;
1381 			}
1382 			else
1383 			{
1384 				ref_data[m] = 0;
1385 			}
1386 		} /* for (all reference pixels) */
1387 
1388 		/* Read the rendered data */
1389 		gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, result_data);
1390 
1391 		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed");
1392 
1393 		for (y = 0; y < TEXTURE_HEIGHT; ++y)
1394 		{
1395 			int			   pixel_size = N_TEXTURE_COMPONENTS;
1396 			int			   row_size   = pixel_size * TEXTURE_WIDTH;
1397 			unsigned char* ref_row	= ref_data + y * row_size;
1398 			unsigned char* result_row = result_data + y * row_size;
1399 
1400 			for (x = 0; x < TEXTURE_WIDTH; ++x)
1401 			{
1402 				if (memcmp(ref_row, result_row, pixel_size) != 0)
1403 				{
1404 					m_testCtx.getLog() << tcu::TestLog::Message << "(x=" << x << " y=" << y << "): Rendered data "
1405 									   << "(" << result_row[0] << ", " << result_row[1] << ", " << result_row[2] << ", "
1406 									   << result_row[3] << ")"
1407 									   << " is different from reference data "
1408 									   << "(" << ref_row[0] << ", " << ref_row[1] << ", " << ref_row[2] << ", "
1409 									   << ref_row[3] << ")" << tcu::TestLog::EndMessage;
1410 
1411 					TCU_FAIL("Data comparison failed");
1412 				} /* if (memcmp(ref_row, result_row, pixel_size) != 0) */
1413 
1414 				ref_row += pixel_size;
1415 				result_row += pixel_size;
1416 			} /* for (all pixels in a row) */
1417 		}	 /* for (all pixels) */
1418 	}		  /* for (all layers) */
1419 
1420 	/* Done */
1421 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1422 	return STOP;
1423 
1424 #undef N_TEXTURE_COMPONENTS
1425 #undef TEXTURE_DEPTH
1426 #undef TEXTURE_HEIGHT
1427 #undef TEXTURE_WIDTH
1428 }
1429 
1430 } // namespace glcts
1431