• 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 "esextcTextureCubeMapArrayColorDepthAttachments.hpp"
25 
26 #include "gluContextInfo.hpp"
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30 
31 namespace glcts
32 {
33 /* Shader parts */
34 const glw::GLchar* const TextureCubeMapArrayColorDepthAttachmentsTest::m_fragment_shader_code =
35 	"${VERSION}\n"
36 	"/* FS */\n"
37 	"\n"
38 	"precision highp float;\n"
39 	"\n"
40 	"in flat int fs_in_color;\n"
41 	"\n"
42 	"layout(location = 0) out int fs_out_color;\n"
43 	"\n"
44 	"void main()\n"
45 	"{\n"
46 	"    fs_out_color = fs_in_color;\n"
47 	"}\n"
48 	"\n";
49 
50 const glw::GLchar* const TextureCubeMapArrayColorDepthAttachmentsTest::m_geometry_shader_code_preamble =
51 	"${VERSION}\n"
52 	"/* Layered GS */\n"
53 	"\n"
54 	"${GEOMETRY_SHADER_REQUIRE}\n"
55 	"\n"
56 	"precision highp float;\n"
57 	"\n"
58 	"layout(points)                         in;\n"
59 	"layout(triangle_strip, max_vertices=4) out;\n"
60 	"\n";
61 
62 const glw::GLchar* const TextureCubeMapArrayColorDepthAttachmentsTest::m_geometry_shader_code_layered =
63 	"in  flat int vs_out_layer[];\n"
64 	"\n"
65 	"out flat int fs_in_color;\n"
66 	"\n"
67 	"void main()\n"
68 	"{\n"
69 	"    int   layer = vs_out_layer[0];\n";
70 
71 const glw::GLchar* const TextureCubeMapArrayColorDepthAttachmentsTest::m_geometry_shader_code_non_layered =
72 	"uniform  int uni_layer;\n"
73 	"\n"
74 	"out flat int fs_in_color;\n"
75 	"\n"
76 	"void main()\n"
77 	"{\n"
78 	"    int   layer = uni_layer;\n";
79 
80 const glw::GLchar* const TextureCubeMapArrayColorDepthAttachmentsTest::m_geometry_shader_code_body =
81 	";\n"
82 	"    \n"
83 	"    // Left-Bottom\n"
84 	"    gl_Position = vec4(-1.0, -1.0, depth, 1);\n"
85 	"    gl_Layer    = layer;\n"
86 	"    fs_in_color = layer;\n"
87 	"    EmitVertex();\n"
88 	"    \n"
89 	"    // Left-Top\n"
90 	"    gl_Position = vec4(-1.0,  1.0, depth, 1);\n"
91 	"    gl_Layer    = layer;\n"
92 	"    fs_in_color = layer;\n"
93 	"    EmitVertex();\n"
94 	"    \n"
95 	"    // Right-Bottom\n"
96 	"    gl_Position = vec4( 1.0, -1.0, depth, 1);\n"
97 	"    gl_Layer    = layer;\n"
98 	"    fs_in_color = layer;\n"
99 	"    EmitVertex();\n"
100 	"    \n"
101 	"    // Right-Top\n"
102 	"    gl_Position = vec4( 1.0,  1.0, depth, 1);\n"
103 	"    gl_Layer    = layer;\n"
104 	"    fs_in_color = layer;\n"
105 	"    EmitVertex();\n"
106 	"    EndPrimitive();\n"
107 	"}\n"
108 	"\n";
109 
110 const glw::GLchar* const TextureCubeMapArrayColorDepthAttachmentsTest::m_vertex_shader_code =
111 	"${VERSION}\n"
112 	"/* VS */\n"
113 	"\n"
114 	"precision highp float;\n"
115 	"\n"
116 	"flat out int vs_out_layer;\n"
117 	"\n"
118 	"void main()\n"
119 	"{\n"
120 	"    gl_PointSize = 1.0f;\n"
121 	"    vs_out_layer = gl_VertexID;\n"
122 	"}\n"
123 	"\n";
124 
125 /* Static constants */
126 const glw::GLenum TextureCubeMapArrayColorDepthAttachmentsTest::m_color_internal_format = GL_R32I;
127 const glw::GLenum TextureCubeMapArrayColorDepthAttachmentsTest::m_color_format			= GL_RED_INTEGER;
128 const glw::GLenum TextureCubeMapArrayColorDepthAttachmentsTest::m_color_type			= GL_INT;
129 const glw::GLenum TextureCubeMapArrayColorDepthAttachmentsTest::m_depth_format			= GL_DEPTH_COMPONENT;
130 
131 /** Verifies all texels in user-provided data buffer are equal to user-specified vector value.
132  *
133  * @tparam T            Type of image components
134  * @tparam N_Components Number of image components
135  *
136  * @param  image_width  Width of image
137  * @param  image_height Height of image
138  * @param  components   Amount of components per texel
139  * @param  image        Image data
140  *
141  * @return true if all texels are found valid, false otherwise.
142  **/
143 template <typename T, unsigned int N_Components>
verifyImage(glw::GLuint image_width,glw::GLuint image_height,const T * components,const T * image)144 bool verifyImage(glw::GLuint image_width, glw::GLuint image_height, const T* components, const T* image)
145 {
146 	const glw::GLuint line_size = image_width * N_Components;
147 
148 	for (glw::GLuint y = 0; y < image_height; ++y)
149 	{
150 		const glw::GLuint line_offset = y * line_size;
151 
152 		for (glw::GLuint x = 0; x < image_width; ++x)
153 		{
154 			const glw::GLuint pixel_offset = line_offset + x * N_Components;
155 
156 			for (glw::GLuint component = 0; component < N_Components; ++component)
157 			{
158 				if (image[pixel_offset + component] != components[component])
159 				{
160 					return false;
161 				}
162 			} /* for (all components) */
163 		}	 /* for (all columns) */
164 	}		  /* for (all rows) */
165 
166 	return true;
167 }
168 
169 /** Constructor
170  *
171  * @param size       Size of texture
172  * @param n_cubemaps Number of cube-maps in array
173  **/
_texture_size(glw::GLuint size,glw::GLuint n_cubemaps)174 TextureCubeMapArrayColorDepthAttachmentsTest::_texture_size::_texture_size(glw::GLuint size, glw::GLuint n_cubemaps)
175 	: m_size(size), m_n_cubemaps(n_cubemaps)
176 {
177 	/* Nothing to be done here */
178 }
179 
180 /** Constructor
181  *
182  * @param context       Test context
183  * @param name          Test case's name
184  * @param description   Test case's description
185  **/
TextureCubeMapArrayColorDepthAttachmentsTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)186 TextureCubeMapArrayColorDepthAttachmentsTest::TextureCubeMapArrayColorDepthAttachmentsTest(
187 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
188 	: TestCaseBase(context, extParams, name, description)
189 	, m_vao_id(0)
190 	, m_color_texture_id(0)
191 	, m_depth_texture_id(0)
192 	, m_fragment_shader_id(0)
193 	, m_framebuffer_object_id(0)
194 	, m_layered_geometry_shader_id(0)
195 	, m_layered_program_id(0)
196 	, m_non_layered_geometry_shader_id(0)
197 	, m_non_layered_program_id(0)
198 	, m_non_layered_program_id_uni_layer_uniform_location(0)
199 	, m_vertex_shader_id(0)
200 	, m_depth_internal_format(0)
201 	, m_depth_type(0)
202 	, m_n_invalid_color_checks(0)
203 	, m_n_invalid_depth_checks(0)
204 {
205 	/* Define tested resolutions */
206 	m_resolutions.push_back(_texture_size(8, 8));
207 	m_resolutions.push_back(_texture_size(64, 3));
208 	m_resolutions.push_back(_texture_size(117, 1));
209 	m_resolutions.push_back(_texture_size(256, 1));
210 	m_resolutions.push_back(_texture_size(173, 3));
211 }
212 
213 /** Attaches an user-specified texture object to zeroth color attachment OR depth attachment of
214  *  test-maintained FBO in a layered manner.
215  *
216  * @param texture_id                     Texture object's ID.
217  * @param should_use_as_color_attachment true to attach the texture object to GL_COLOR_ATTACHMENT0 of
218  *                                       the test-maintained FBO; false to use GL_DEPTH_ATTACHMENT
219  *                                       binding point.
220  **/
configureLayeredFramebufferAttachment(glw::GLuint texture_id,bool should_use_as_color_attachment)221 void TextureCubeMapArrayColorDepthAttachmentsTest::configureLayeredFramebufferAttachment(
222 	glw::GLuint texture_id, bool should_use_as_color_attachment)
223 {
224 	glw::GLenum			  attachment = GL_NONE;
225 	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
226 
227 	/* Determine which attachment should be used */
228 	if (true == should_use_as_color_attachment)
229 	{
230 		attachment = GL_COLOR_ATTACHMENT0;
231 	}
232 	else
233 	{
234 		attachment = GL_DEPTH_ATTACHMENT;
235 	}
236 
237 	/* Re-bind the draw framebuffer, just in case. */
238 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_object_id);
239 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
240 
241 	/* Update the FBO's attachment  */
242 	gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
243 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureEXT() call failed.");
244 }
245 
246 /** Attaches an user-specified texture object to zeroth color attachment OR depth attachment of
247  *  test-maintained FBO in a non-layered manner.
248  *
249  * @param texture_id                     Texture object's ID.
250  * @param n_layer                        Layer of the texture to attach.
251  * @param should_use_as_color_attachment true to attach the texture object to GL_COLOR_ATTACHMENT0 of
252  *                                       the test-maintained FBO; false to use GL_DEPTH_ATTACHMENT
253  *                                       binding point.
254  * @param should_update_draw_framebuffer true to bind the test-maintained FBO to GL_DRAW_FRAMEBUFFER
255  *                                       binding point first, false to use GL_READ_FRAMEBUFFER binding
256  *                                       point.
257  **/
configureNonLayeredFramebufferAttachment(glw::GLuint texture_id,glw::GLuint n_layer,bool should_use_as_color_attachment,bool should_update_draw_framebuffer)258 void TextureCubeMapArrayColorDepthAttachmentsTest::configureNonLayeredFramebufferAttachment(
259 	glw::GLuint texture_id, glw::GLuint n_layer, bool should_use_as_color_attachment,
260 	bool should_update_draw_framebuffer)
261 {
262 	glw::GLenum			  attachment_type	= GL_NONE;
263 	glw::GLenum			  framebuffer_target = GL_NONE;
264 	const glw::Functions& gl				 = m_context.getRenderContext().getFunctions();
265 
266 	/* Determine which attachment should be used */
267 	if (true == should_use_as_color_attachment)
268 	{
269 		attachment_type = GL_COLOR_ATTACHMENT0;
270 	}
271 	else
272 	{
273 		attachment_type = GL_DEPTH_ATTACHMENT;
274 	}
275 
276 	/* Determine which framebuffer target should be used */
277 	if (true == should_update_draw_framebuffer)
278 	{
279 		framebuffer_target = GL_DRAW_FRAMEBUFFER;
280 	}
281 	else
282 	{
283 		framebuffer_target = GL_READ_FRAMEBUFFER;
284 	}
285 
286 	/* Re-bind the framebuffer, just in case. */
287 	gl.bindFramebuffer(framebuffer_target, m_framebuffer_object_id);
288 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
289 
290 	/* Use the specified texture layer as attachment */
291 	gl.framebufferTextureLayer(framebuffer_target, attachment_type, texture_id, 0 /* level */, n_layer);
292 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
293 }
294 
295 /* Deinitializes GLES objects created during the test. */
deinit()296 void TextureCubeMapArrayColorDepthAttachmentsTest::deinit()
297 {
298 	/* Deinitialize base class */
299 	TestCaseBase::deinit();
300 
301 	if (true != m_is_texture_cube_map_array_supported)
302 	{
303 		return;
304 	}
305 	if (true != m_is_geometry_shader_extension_supported)
306 	{
307 		return;
308 	}
309 
310 	/* GL functions */
311 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
312 
313 	/* Release texture objects */
314 	releaseAndDetachTextureObject(m_color_texture_id, true /* is_color_attachment */);
315 	releaseAndDetachTextureObject(m_depth_texture_id, false /* is_color_attachment */);
316 
317 	/* Restore default state */
318 	gl.useProgram(0);
319 	gl.bindVertexArray(0);
320 
321 	/* Delete all remaining ES objects the test may have created. */
322 	if (0 != m_fragment_shader_id)
323 	{
324 		gl.deleteShader(m_fragment_shader_id);
325 
326 		m_fragment_shader_id = 0;
327 	}
328 
329 	if (0 != m_framebuffer_object_id)
330 	{
331 		gl.deleteFramebuffers(1, &m_framebuffer_object_id);
332 
333 		m_framebuffer_object_id = 0;
334 	}
335 
336 	if (0 != m_layered_geometry_shader_id)
337 	{
338 		gl.deleteShader(m_layered_geometry_shader_id);
339 
340 		m_layered_geometry_shader_id = 0;
341 	}
342 
343 	if (0 != m_layered_program_id)
344 	{
345 		gl.deleteProgram(m_layered_program_id);
346 
347 		m_layered_program_id = 0;
348 	}
349 
350 	if (0 != m_non_layered_geometry_shader_id)
351 	{
352 		gl.deleteShader(m_non_layered_geometry_shader_id);
353 
354 		m_non_layered_geometry_shader_id = 0;
355 	}
356 
357 	if (0 != m_non_layered_program_id)
358 	{
359 		gl.deleteProgram(m_non_layered_program_id);
360 
361 		m_non_layered_program_id = 0;
362 	}
363 
364 	if (0 != m_vertex_shader_id)
365 	{
366 		gl.deleteShader(m_vertex_shader_id);
367 
368 		m_vertex_shader_id = 0;
369 	}
370 
371 	if (m_vao_id != 0)
372 	{
373 		gl.deleteVertexArrays(1, &m_vao_id);
374 
375 		m_vao_id = 0;
376 	}
377 }
378 
379 /* Determines depth internalformat that can be used for a draw framebuffer.
380  * The result is stored in m_depth_internal_format and m_depth_type.
381  **/
determineSupportedDepthFormat()382 void TextureCubeMapArrayColorDepthAttachmentsTest::determineSupportedDepthFormat()
383 {
384 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
385 
386 	/* Start with 16-bit depth internalformat */
387 	m_depth_internal_format = GL_DEPTH_COMPONENT16;
388 	m_depth_type			= GL_UNSIGNED_SHORT;
389 
390 	while (true)
391 	{
392 		/* Create color and depth texture objectss */
393 		generateAndConfigureTextureObjects(8,	  /* texture_width */
394 										   1,	  /* n_cubemaps */
395 										   false); /* should_generate_mutable_textures */
396 
397 		/* Set framebuffer attachments up */
398 		configureNonLayeredFramebufferAttachment(m_color_texture_id, 0 /* layer */, true /* is_color_attachment */,
399 												 true /* should_update_draw_framebuffer */);
400 		configureNonLayeredFramebufferAttachment(m_depth_texture_id, 0 /* layer */, false /* is_color_attachment */,
401 												 true /* should_update_draw_framebuffer */);
402 
403 		/* Check framebuffer status */
404 		const glw::GLenum framebuffer_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
405 
406 		if (GL_FRAMEBUFFER_COMPLETE == framebuffer_status)
407 		{
408 			return;
409 		}
410 
411 		/* Current format does not work too well, try another one */
412 		switch (m_depth_internal_format)
413 		{
414 		case GL_DEPTH_COMPONENT16:
415 		{
416 			m_depth_internal_format = GL_DEPTH_COMPONENT24;
417 			m_depth_type			= GL_UNSIGNED_INT;
418 
419 			break;
420 		}
421 
422 		case GL_DEPTH_COMPONENT24:
423 		{
424 			m_depth_internal_format = GL_DEPTH_COMPONENT32F;
425 			m_depth_type			= GL_FLOAT;
426 
427 			break;
428 		}
429 
430 		case GL_DEPTH_COMPONENT32F:
431 		{
432 			throw tcu::NotSupportedError("Implementation does not support any known depth format");
433 		}
434 
435 		default:
436 		{
437 			TCU_FAIL("Unrecognized depth internalformat");
438 		}
439 		} /* switch (m_depth_internal_format) */
440 	}	 /* while (true) */
441 }
442 
443 /** Execute a draw call that renders (texture_size.m_n_cubemaps * 6) points.
444  *  First, the viewport is configured to match the texture resolution and
445  *  both color & depth buffers are cleared.
446  *
447  *  @param texture_size Render-target resolution.
448  *
449  **/
draw(const _texture_size & texture_size)450 void TextureCubeMapArrayColorDepthAttachmentsTest::draw(const _texture_size& texture_size)
451 {
452 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
453 
454 	/* Set up the viewport */
455 	gl.viewport(0, /* x */
456 				0, /* y */
457 				texture_size.m_size, texture_size.m_size);
458 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
459 
460 	/* Clear color & depth buffers */
461 	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
462 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
463 
464 	gl.drawArrays(GL_POINTS, 0 /* first */, texture_size.m_n_cubemaps * 6 /* layer-faces per cube-map */);
465 	GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
466 }
467 
468 /** Releases existing color & depth cube-map texture array objects, generates new
469  *  ones and configures them as per user-specified properties.
470  *
471  *  @param texture_width                    Size to use for each layer-face's width and height.
472  *  @param n_cubemaps                       Number of cube-maps to initialize for the cube-map texture arrays.
473  *  @param should_generate_mutable_textures true if the texture should be initialized as mutable, false otherwise.
474  **/
generateAndConfigureTextureObjects(glw::GLuint texture_width,glw::GLuint n_cubemaps,bool should_generate_mutable_textures)475 void TextureCubeMapArrayColorDepthAttachmentsTest::generateAndConfigureTextureObjects(
476 	glw::GLuint texture_width, glw::GLuint n_cubemaps, bool should_generate_mutable_textures)
477 {
478 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
479 
480 	/* Release any texture objects that may have already been initialized */
481 	releaseAndDetachTextureObject(m_color_texture_id, true /* is_color_attachment */);
482 	releaseAndDetachTextureObject(m_depth_texture_id, false /* is_color_attachment */);
483 
484 	/* Generate texture objects */
485 	gl.genTextures(1, &m_color_texture_id);
486 	gl.genTextures(1, &m_depth_texture_id);
487 
488 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
489 
490 	/* Configure new textures' storage */
491 	if (true == should_generate_mutable_textures)
492 	{
493 		prepareMutableTextureObject(m_color_texture_id, texture_width, n_cubemaps,
494 									true /* should_take_color_texture_properties */);
495 		prepareMutableTextureObject(m_depth_texture_id, texture_width, n_cubemaps,
496 									false /* should_take_color_texture_properties */);
497 	}
498 	else
499 	{
500 		prepareImmutableTextureObject(m_color_texture_id, texture_width, n_cubemaps,
501 									  true /* should_take_color_texture_properties */);
502 		prepareImmutableTextureObject(m_depth_texture_id, texture_width, n_cubemaps,
503 									  false /* should_take_color_texture_properties */);
504 	}
505 }
506 
507 /* Initializes all ES objects needed to run the test */
initTest()508 void TextureCubeMapArrayColorDepthAttachmentsTest::initTest()
509 {
510 	const glw::GLchar*	depth_calculation_code = DE_NULL;
511 	const glw::Functions& gl					 = m_context.getRenderContext().getFunctions();
512 
513 	/* Check if EXT_texture_cube_map_array extension is supported */
514 	if (true != m_is_texture_cube_map_array_supported)
515 	{
516 		throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED);
517 	}
518 
519 	/* This test should only run if EXT_geometry_shader is supported */
520 	if (true != m_is_geometry_shader_extension_supported)
521 	{
522 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED);
523 	}
524 
525 	/* Generate and bind VAO */
526 	gl.genVertexArrays(1, &m_vao_id);
527 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object");
528 
529 	gl.bindVertexArray(m_vao_id);
530 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!");
531 
532 	/* Create a framebuffer object */
533 	gl.genFramebuffers(1, &m_framebuffer_object_id);
534 	GLU_EXPECT_NO_ERROR(gl.getError(), "genFramebuffers");
535 
536 	/* Determine which depth format can be used as a depth attachment without
537 	 * making the FBO incomplete */
538 	determineSupportedDepthFormat();
539 
540 	/* Decide which code snippet to use for depth value calculation */
541 	switch (m_depth_internal_format)
542 	{
543 	case GL_DEPTH_COMPONENT16:
544 	{
545 		depth_calculation_code = "-1.0 + float(2 * layer) / float(0xffff)";
546 
547 		break;
548 	}
549 
550 	case GL_DEPTH_COMPONENT24:
551 	{
552 		depth_calculation_code = "-1.0 + float(2 * layer) / float(0xffffff)";
553 
554 		break;
555 	}
556 
557 	case GL_DEPTH_COMPONENT32F:
558 	{
559 		depth_calculation_code = "-1.0 + float(2 * layer) / 256.0";
560 
561 		break;
562 	}
563 
564 	default:
565 	{
566 		TCU_FAIL("Unrecognized depth internal format");
567 	}
568 	} /* switch (m_depth_internal_format) */
569 
570 	/* Create shader objects */
571 	m_fragment_shader_id			 = gl.createShader(GL_FRAGMENT_SHADER);
572 	m_layered_geometry_shader_id	 = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
573 	m_non_layered_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
574 	m_vertex_shader_id				 = gl.createShader(GL_VERTEX_SHADER);
575 
576 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
577 
578 	/* Create program objects */
579 	m_layered_program_id	 = gl.createProgram();
580 	m_non_layered_program_id = gl.createProgram();
581 
582 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed");
583 
584 	/* Build up an array of snippets making up bodies of two geometry shaders
585 	 * we'll be using for the test.
586 	 */
587 	const glw::GLchar* const layered_geometry_shader_parts[] = { m_geometry_shader_code_preamble,
588 																 m_geometry_shader_code_layered,
589 																 "    float depth = ", depth_calculation_code,
590 																 m_geometry_shader_code_body };
591 
592 	const glw::GLchar* const non_layered_geometry_shader_parts[] = { m_geometry_shader_code_preamble,
593 																	 m_geometry_shader_code_non_layered,
594 																	 "    float depth = ", depth_calculation_code,
595 																	 m_geometry_shader_code_body };
596 
597 	const glw::GLuint n_layered_geometry_shader_parts =
598 		sizeof(layered_geometry_shader_parts) / sizeof(layered_geometry_shader_parts[0]);
599 	const glw::GLuint n_non_layered_geometry_shader_parts =
600 		sizeof(non_layered_geometry_shader_parts) / sizeof(non_layered_geometry_shader_parts[0]);
601 
602 	/* Build both programs */
603 	if (!buildProgram(m_layered_program_id, m_fragment_shader_id, 1, &m_fragment_shader_code,
604 					  m_layered_geometry_shader_id, n_layered_geometry_shader_parts, layered_geometry_shader_parts,
605 					  m_vertex_shader_id, 1, &m_vertex_shader_code))
606 	{
607 		TCU_FAIL("Could not build layered-case program object");
608 	}
609 
610 	if (!buildProgram(m_non_layered_program_id, m_fragment_shader_id, 1, &m_fragment_shader_code,
611 					  m_non_layered_geometry_shader_id, n_non_layered_geometry_shader_parts,
612 					  non_layered_geometry_shader_parts, m_vertex_shader_id, 1, &m_vertex_shader_code))
613 	{
614 		TCU_FAIL("Could not build non-layered-case program object");
615 	}
616 
617 	/* Get location of "uni_layer" uniform */
618 	m_non_layered_program_id_uni_layer_uniform_location = gl.getUniformLocation(m_non_layered_program_id, "uni_layer");
619 
620 	if ((-1 == m_non_layered_program_id_uni_layer_uniform_location) || (GL_NO_ERROR != gl.getError()))
621 	{
622 		TCU_FAIL("Could not retrieve location of uni_layer uniform for non-layered program");
623 	}
624 }
625 
626 /** Executes the test.
627  *
628  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
629  *  Note the function throws exception should an error occur!
630  *
631  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
632  **/
iterate()633 tcu::TestCase::IterateResult TextureCubeMapArrayColorDepthAttachmentsTest::iterate()
634 {
635 	/* GL functions */
636 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
637 
638 	/* Initialize all ES objects needed to run the test */
639 	initTest();
640 
641 	/* Setup clear values */
642 	gl.clearColor(0.0f /* red */, 0.0f /* green */, 0.0f /* blue */, 0.0f /* alpha */);
643 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");
644 
645 	gl.clearDepthf(1.0f /* d */);
646 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearDepthf() call failed.");
647 
648 	/* Enable depth test */
649 	gl.enable(GL_DEPTH_TEST);
650 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed");
651 
652 	/* Execute tests for each resolution */
653 	for (_texture_size_vector::iterator texture_size_iterator = m_resolutions.begin(),
654 										end_iterator		  = m_resolutions.end();
655 		 end_iterator != texture_size_iterator; ++texture_size_iterator)
656 	{
657 		testNonLayeredRendering(*texture_size_iterator, false);
658 		testNonLayeredRendering(*texture_size_iterator, true);
659 		testLayeredRendering(*texture_size_iterator, false);
660 		testLayeredRendering(*texture_size_iterator, true);
661 	}
662 
663 	/* Test passes if there were no errors */
664 	if ((0 != m_n_invalid_color_checks) || (0 != m_n_invalid_depth_checks))
665 	{
666 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
667 	}
668 	else
669 	{
670 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
671 	}
672 
673 	/* Done */
674 	return STOP;
675 }
676 
677 /** Takes a texture ID, binds it to GL_TEXTURE_CUBE_MAP_ARRAY texture target and
678  *  initializes an immutable texture storage of @param texture_size x @param texture_size
679  *  x (@param n_elements * 6) resolution.
680  *
681  * @param texture_id                           ID to use for the initialization.
682  * @param texture_size                         Width & height to use for each layer-face.
683  * @param n_cubemaps                           Amount of cube-maps to initialize.
684  * @param should_take_color_texture_properties true if m_color_internal_format, m_color_format,
685  *                                             m_color_type should be used for texture storage
686  *                                             initialization, false to use relevant m_depth_*
687  *                                             fields.
688  **/
prepareImmutableTextureObject(glw::GLuint texture_id,glw::GLuint texture_size,glw::GLuint n_cubemaps,bool should_take_color_texture_properties)689 void TextureCubeMapArrayColorDepthAttachmentsTest::prepareImmutableTextureObject(
690 	glw::GLuint texture_id, glw::GLuint texture_size, glw::GLuint n_cubemaps, bool should_take_color_texture_properties)
691 {
692 	const glw::Functions& gl			  = m_context.getRenderContext().getFunctions();
693 	glw::GLenum			  internal_format = GL_NONE;
694 
695 	/* Set internal_format accordingly to requested texture type */
696 	if (true == should_take_color_texture_properties)
697 	{
698 		internal_format = m_color_internal_format;
699 	}
700 	else
701 	{
702 		internal_format = m_depth_internal_format;
703 	}
704 
705 	/* Bind the texture object to GL_TEXTURE_CUBE_MAP_ARRAY texture target. */
706 	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texture_id);
707 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
708 
709 	/* Initialize immutable texture storage as per description */
710 	gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, /* n_mipmap_levels */
711 					internal_format, texture_size, texture_size, n_cubemaps * 6 /* layer-faces per cube-map */);
712 
713 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
714 }
715 
716 /** Takes a texture ID, binds it to GL_TEXTURE_CUBE_MAP_ARRAY texture target and
717  *  initializes a mutable texture storage of @param texture_size x @param texture_size
718  *  x (@param n_elements * 6) resolution. Finally,the function sets GL_TEXTURE_MAX_LEVEL
719  *  of the texture object to 0.
720  *
721  * @param texture_id                           ID to use for the initialization.
722  * @param texture_size                         Width & height to use for each layer-face.
723  * @param n_cubemaps                           Amount of cube-maps to initialize.
724  * @param should_take_color_texture_properties true if m_color_internal_format, m_color_format,
725  *                                             m_color_type should be used for texture storage
726  *                                             initialization, false to use relevant m_depth_*
727  *                                             fields.
728  **/
prepareMutableTextureObject(glw::GLuint texture_id,glw::GLuint texture_size,glw::GLuint n_cubemaps,bool should_take_color_texture_properties)729 void TextureCubeMapArrayColorDepthAttachmentsTest::prepareMutableTextureObject(
730 	glw::GLuint texture_id, glw::GLuint texture_size, glw::GLuint n_cubemaps, bool should_take_color_texture_properties)
731 {
732 	const glw::Functions& gl			  = m_context.getRenderContext().getFunctions();
733 	glw::GLenum			  format		  = GL_NONE;
734 	glw::GLenum			  internal_format = GL_NONE;
735 	glw::GLenum			  type			  = GL_NONE;
736 
737 	/* Set internal_format, format and type accordingly to requested texture type */
738 	if (true == should_take_color_texture_properties)
739 	{
740 		internal_format = m_color_internal_format;
741 		format			= m_color_format;
742 		type			= m_color_type;
743 	}
744 	else
745 	{
746 		internal_format = m_depth_internal_format;
747 		format			= m_depth_format;
748 		type			= m_depth_type;
749 	}
750 
751 	/* Bind the texture object to GL_TEXTURE_CUBE_MAP_ARRAY texture target. */
752 	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texture_id);
753 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
754 
755 	/* Initialize mutable texture storage as per description */
756 	gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0 /* mipmap_level */, internal_format, texture_size, texture_size,
757 				  n_cubemaps * 6 /* layer-faces per cube-map */, 0 /* border */, format, type,
758 				  DE_NULL); /* initial data */
759 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D() call failed");
760 
761 	/* Update GL_TEXTURE_MAX_LEVEL so that the texture is considered complete */
762 	gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0 /* param */);
763 
764 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed");
765 }
766 
767 /** Releases a texture object and detaches it from test-maintained draw framebuffer.
768  *
769  * @param texture_id          Id of the texture object;
770  * @param is_color_attachment true if the texture object described by id @param texture_id
771  *                            is current draw framebuffer's color attachment, false if it's
772  *                            a depth attachment.
773  **/
releaseAndDetachTextureObject(glw::GLuint texture_id,bool is_color_attachment)774 void TextureCubeMapArrayColorDepthAttachmentsTest::releaseAndDetachTextureObject(glw::GLuint texture_id,
775 																				 bool		 is_color_attachment)
776 {
777 	glw::GLenum			  attachment = GL_NONE;
778 	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
779 
780 	if (true == is_color_attachment)
781 	{
782 		attachment = GL_COLOR_ATTACHMENT0;
783 	}
784 	else
785 	{
786 		attachment = GL_DEPTH_ATTACHMENT;
787 	}
788 
789 	/* Update draw framewbuffer binding just in case. */
790 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_object_id);
791 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
792 
793 	/* Clean framebuffer's attachment */
794 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, 0, /* texture */
795 							0);												   /* level */
796 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
797 
798 	/* Unbind the texture object from GL_TEXTURE_CUBE_MAP_ARRAY binding point */
799 	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
800 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
801 
802 	/* Finally delete the texture object */
803 	gl.deleteTextures(1, &texture_id);
804 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
805 }
806 
807 /** Verifies layered rendering works correctly.
808  *
809  * @param texture_size                Resolution of texture;
810  * @param should_use_mutable_textures true if mutable textures should be used for the test,
811  *                                    false to use immutable textures.
812  **/
testLayeredRendering(const _texture_size & texture_size,bool should_use_mutable_textures)813 void TextureCubeMapArrayColorDepthAttachmentsTest::testLayeredRendering(const _texture_size& texture_size,
814 																		bool should_use_mutable_textures)
815 {
816 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
817 
818 	/* Generate texture objects for the test */
819 	generateAndConfigureTextureObjects(texture_size.m_size, texture_size.m_n_cubemaps, should_use_mutable_textures);
820 
821 	/* Setup layered framebuffer */
822 	configureLayeredFramebufferAttachment(m_color_texture_id, true /* should_use_as_color_attachment */);
823 	configureLayeredFramebufferAttachment(m_depth_texture_id, false /* should_use_as_color_attachment */);
824 
825 	/* Activate the program object that performs layered rendering */
826 	gl.useProgram(m_layered_program_id);
827 
828 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
829 
830 	/* Issue the draw call. */
831 	draw(texture_size);
832 
833 	/* Restore default framebuffer attachments */
834 	configureLayeredFramebufferAttachment(0 /* texture_id */, true /* should_use_as_color_attachment */);
835 	configureLayeredFramebufferAttachment(0 /* texture_id */, false /* should_use_as_color_attachment */);
836 
837 	/* Restore draw framebuffer binding */
838 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
839 
840 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
841 
842 	/* Time to verify the results - update read framebuffer binding first. */
843 	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_framebuffer_object_id);
844 
845 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
846 
847 	/* Iterate through all layer-faces */
848 	for (glw::GLuint n_layer_face = 0; n_layer_face < texture_size.m_n_cubemaps * 6 /* layer-faces per cube-map */;
849 		 ++n_layer_face)
850 	{
851 		/* Configure read framebuffer attachments to point to the layer of our current interest */
852 		configureNonLayeredFramebufferAttachment(m_color_texture_id, n_layer_face,
853 												 true,   /* should_use_as_color_attachment */
854 												 false); /* should_update_draw_framebuffer */
855 		configureNonLayeredFramebufferAttachment(m_depth_texture_id, n_layer_face,
856 												 false,  /* should_use_as_color_attachment */
857 												 false); /* should_update_draw_framebuffer */
858 
859 		/* Verify contents of color and depth attachments */
860 		bool is_color_data_ok = verifyColorData(texture_size, n_layer_face);
861 		bool is_depth_data_ok = false;
862 
863 		if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
864 		{
865 			switch (m_depth_internal_format)
866 			{
867 			case GL_DEPTH_COMPONENT16:
868 			{
869 				is_depth_data_ok = verifyDepth16Data(texture_size, n_layer_face);
870 
871 				break;
872 			}
873 
874 			case GL_DEPTH_COMPONENT24:
875 			{
876 				is_depth_data_ok = verifyDepth24Data(texture_size, n_layer_face);
877 
878 				break;
879 			}
880 
881 			case GL_DEPTH_COMPONENT32F:
882 			{
883 				is_depth_data_ok = verifyDepth32FData(texture_size, n_layer_face);
884 
885 				break;
886 			}
887 
888 			default:
889 			{
890 				TCU_FAIL("Unrecognized depth internalformat");
891 			}
892 			} /* switch (m_depth_internal_format) */
893 		}
894 		else
895 		{
896 			is_depth_data_ok = true;
897 		}
898 
899 		/* Any errors? Increment relevant counters */
900 		if (false == is_color_data_ok)
901 		{
902 			m_n_invalid_color_checks++;
903 		}
904 
905 		if (false == is_depth_data_ok)
906 		{
907 			m_n_invalid_depth_checks++;
908 		}
909 	} /* for (all layer-faces) */
910 }
911 
912 /** Verifies layered rendering works correctly.
913  *
914  * @param texture_size               Resolution of texture
915  * @param should_use_mutable_texture true if an immutable texture should be used for
916  *                                   the invocation; false if mutable.
917  **/
testNonLayeredRendering(const _texture_size & texture_size,bool should_use_mutable_texture)918 void TextureCubeMapArrayColorDepthAttachmentsTest::testNonLayeredRendering(const _texture_size& texture_size,
919 																		   bool should_use_mutable_texture)
920 {
921 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
922 
923 	/* Activate a program object that renders in a non-layered fashion */
924 	gl.useProgram(m_non_layered_program_id);
925 
926 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
927 
928 	/* Create relevant textures */
929 	generateAndConfigureTextureObjects(texture_size.m_size, texture_size.m_n_cubemaps, should_use_mutable_texture);
930 
931 	/* Iterate over all layer-faces */
932 	for (glw::GLuint n_layer_face = 0; n_layer_face < texture_size.m_n_cubemaps * 6 /* layer-faces per cube-map */;
933 		 ++n_layer_face)
934 	{
935 		/* Set up non-layered framebuffer attachments */
936 		configureNonLayeredFramebufferAttachment(m_color_texture_id, n_layer_face, true /* is_color_attachment */);
937 		configureNonLayeredFramebufferAttachment(m_depth_texture_id, n_layer_face, false /* is_color_attachment */);
938 
939 		/* Update value assigned to "uni_layer" uniform */
940 		gl.uniform1i(m_non_layered_program_id_uni_layer_uniform_location, n_layer_face);
941 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
942 
943 		/* Execute a draw call */
944 		draw(texture_size);
945 
946 		/* Restore default framebuffer attachments */
947 		configureNonLayeredFramebufferAttachment(0 /* texture_id */, 0 /* n_layer */,
948 												 true /* should_use_as_color_attachment */);
949 		configureNonLayeredFramebufferAttachment(0 /* texture_id */, 0 /* n_layer */,
950 												 false /* should_use_as_color_attachment */);
951 
952 		/* Remove draw framebuffer binding */
953 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
954 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
955 
956 		/* Verify the results. First, make sure the read framebuffer binding is configured
957 		 * accordingly.
958 		 */
959 		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_framebuffer_object_id);
960 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
961 
962 		/* Configure read framebuffer attachments to point to the layer of our current interest */
963 		configureNonLayeredFramebufferAttachment(m_color_texture_id, n_layer_face,
964 												 true,   /* should_use_as_color_attachment */
965 												 false); /* should_update_draw_framebuffer */
966 		configureNonLayeredFramebufferAttachment(m_depth_texture_id, n_layer_face,
967 												 false,  /* should_use_as_color_attachment */
968 												 false); /* should_update_draw_framebuffer */
969 
970 		/* Verify contents of color and depth attachments */
971 		bool is_color_data_ok = verifyColorData(texture_size, n_layer_face);
972 		bool is_depth_data_ok = false;
973 
974 		if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
975 		{
976 			switch (m_depth_internal_format)
977 			{
978 			case GL_DEPTH_COMPONENT16:
979 			{
980 				is_depth_data_ok = verifyDepth16Data(texture_size, n_layer_face);
981 
982 				break;
983 			}
984 
985 			case GL_DEPTH_COMPONENT24:
986 			{
987 				is_depth_data_ok = verifyDepth24Data(texture_size, n_layer_face);
988 
989 				break;
990 			}
991 
992 			case GL_DEPTH_COMPONENT32F:
993 			{
994 				is_depth_data_ok = verifyDepth32FData(texture_size, n_layer_face);
995 
996 				break;
997 			}
998 
999 			default:
1000 			{
1001 				TCU_FAIL("Unrecognized depth internalformat");
1002 			}
1003 			} /* switch (m_depth_internal_format) */
1004 		}
1005 		else
1006 		{
1007 			is_depth_data_ok = true;
1008 		}
1009 
1010 		/* Any errors? Increment relevant counters */
1011 		if (false == is_color_data_ok)
1012 		{
1013 			m_n_invalid_color_checks++;
1014 		}
1015 
1016 		if (false == is_depth_data_ok)
1017 		{
1018 			m_n_invalid_depth_checks++;
1019 		}
1020 	} /* for (all layer-faces) */
1021 }
1022 
1023 /** Reads read buffer's color data and verifies its correctness.
1024  *
1025  *  @param texture_size Texture size
1026  *  @param n_layer      Index of the layer to verify.
1027  *
1028  *  @return true if the retrieved data was found correct, false otherwise.
1029  **/
verifyColorData(const _texture_size & texture_size,glw::GLuint n_layer)1030 bool TextureCubeMapArrayColorDepthAttachmentsTest::verifyColorData(const _texture_size& texture_size,
1031 																   glw::GLuint			n_layer)
1032 {
1033 	/* Allocate buffer for the data we will retrieve from the implementation */
1034 	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
1035 	bool				  result		   = false;
1036 	const glw::GLuint	 result_data_size = texture_size.m_size * texture_size.m_size * 4;
1037 	glw::GLuint*		  result_data	  = new glw::GLuint[result_data_size];
1038 
1039 	DE_ASSERT(result_data != NULL);
1040 
1041 	/* Read the data */
1042 	gl.readPixels(0, /* x */
1043 				  0, /* y */
1044 				  texture_size.m_size, texture_size.m_size, GL_RGBA_INTEGER, m_color_type, result_data);
1045 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
1046 
1047 	glw::GLuint expected[4] = { n_layer, 0, 0, 1 };
1048 
1049 	/* Verify image, expected value is layer index */
1050 	result = verifyImage<glw::GLuint, 4>(texture_size.m_size, texture_size.m_size, expected, result_data);
1051 
1052 	/* Release the buffer */
1053 	if (result_data != NULL)
1054 	{
1055 		delete[] result_data;
1056 
1057 		result_data = NULL;
1058 	}
1059 
1060 	return result;
1061 }
1062 
1063 /** Reads read buffer's depth data (assuming it's of 16-bit resolution)
1064  *  and verifies its correctness.
1065  *
1066  *  @param texture_size Texture size
1067  *  @param n_layer      Index of the layer to verify.
1068  *
1069  *  @return true if the retrieved data was found correct, false otherwise.
1070  **/
verifyDepth16Data(const _texture_size & texture_size,glw::GLuint n_layer)1071 bool TextureCubeMapArrayColorDepthAttachmentsTest::verifyDepth16Data(const _texture_size& texture_size,
1072 																	 glw::GLuint		  n_layer)
1073 {
1074 	/* Allocate buffer for the data we will retrieve from the implementation */
1075 	glw::GLushort		  expected_value   = (glw::GLushort)n_layer;
1076 	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
1077 	bool				  result		   = false;
1078 	const glw::GLuint	 result_data_size = texture_size.m_size * texture_size.m_size;
1079 	glw::GLushort*		  result_data	  = new glw::GLushort[result_data_size];
1080 
1081 	DE_ASSERT(result_data != NULL);
1082 
1083 	gl.pixelStorei(GL_PACK_ALIGNMENT, 2);
1084 
1085 	/* Read the data */
1086 	gl.readPixels(0, /* x */
1087 				  0, /* y */
1088 				  texture_size.m_size, texture_size.m_size, m_depth_format, m_depth_type, result_data);
1089 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
1090 
1091 	/* Verify image, expected value is layer index */
1092 	result = verifyImage<glw::GLushort, 1>(texture_size.m_size, texture_size.m_size, &expected_value, result_data);
1093 
1094 	/* Release the buffer */
1095 	if (result_data != NULL)
1096 	{
1097 		delete[] result_data;
1098 
1099 		result_data = NULL;
1100 	}
1101 
1102 	gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
1103 
1104 	return result;
1105 }
1106 
1107 /** Reads read buffer's depth data (assuming it's of 24-bit resolution)
1108  *  and verifies its correctness.
1109  *
1110  *  @param texture_size Texture size
1111  *  @param n_layer      Index of the layer to verify.
1112  *
1113  *  @return true if the retrieved data was found correct, false otherwise.
1114  **/
verifyDepth24Data(const _texture_size & texture_size,glw::GLuint n_layer)1115 bool TextureCubeMapArrayColorDepthAttachmentsTest::verifyDepth24Data(const _texture_size& texture_size,
1116 																	 glw::GLuint		  n_layer)
1117 {
1118 	/* Allocate buffer for the data we will retrieve from the implementation */
1119 	glw::GLuint			  expected_value   = n_layer << 8;
1120 	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
1121 	bool				  result		   = false;
1122 	const glw::GLuint	 result_data_size = texture_size.m_size * texture_size.m_size;
1123 	glw::GLuint*		  result_data	  = new glw::GLuint[result_data_size];
1124 
1125 	DE_ASSERT(result_data != NULL);
1126 
1127 	/* Read the data */
1128 	gl.readPixels(0, /* x */
1129 				  0, /* y */
1130 				  texture_size.m_size, texture_size.m_size, m_depth_format, m_depth_type, result_data);
1131 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
1132 
1133 	/* Verify image, expected value is layer index */
1134 	result = verifyImage<glw::GLuint, 1>(texture_size.m_size, texture_size.m_size, &expected_value, result_data);
1135 
1136 	/* Release the buffer */
1137 	if (result_data != NULL)
1138 	{
1139 		delete[] result_data;
1140 
1141 		result_data = NULL;
1142 	}
1143 
1144 	return result;
1145 }
1146 
1147 /** Reads read buffer's depth data (assuming it's of 32-bit FP resolution)
1148  *  and verifies its correctness.
1149  *
1150  *  @param texture_size Texture size
1151  *  @param n_layer      Index of the layer to verify.
1152  *
1153  *  @return true if the retrieved data was found correct, false otherwise.
1154  **/
verifyDepth32FData(const _texture_size & texture_size,glw::GLuint n_layer)1155 bool TextureCubeMapArrayColorDepthAttachmentsTest::verifyDepth32FData(const _texture_size& texture_size,
1156 																	  glw::GLuint		   n_layer)
1157 {
1158 	/* Allocate buffer for the data we will retrieve from the implementation */
1159 	glw::GLfloat		  expected_value   = (glw::GLfloat)n_layer / 256.0f;
1160 	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
1161 	bool				  result		   = false;
1162 	const glw::GLuint	 result_data_size = texture_size.m_size * texture_size.m_size;
1163 	glw::GLfloat*		  result_data	  = new glw::GLfloat[result_data_size];
1164 
1165 	DE_ASSERT(result_data != NULL);
1166 
1167 	/* Read the data */
1168 	gl.readPixels(0, /* x */
1169 				  0, /* y */
1170 				  texture_size.m_size, texture_size.m_size, m_depth_format, m_depth_type, result_data);
1171 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
1172 
1173 	/* Verify image, expected value is layer index */
1174 	result = verifyImage<glw::GLfloat, 1>(texture_size.m_size, texture_size.m_size, &expected_value, result_data);
1175 
1176 	/* Release the buffer */
1177 	if (result_data != NULL)
1178 	{
1179 		delete[] result_data;
1180 
1181 		result_data = NULL;
1182 	}
1183 
1184 	return result;
1185 }
1186 
1187 } /* glcts */
1188