Home | History | Annotate | Download | only in texture_cube_map_array
      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>
    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  **/
    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  **/
    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  **/
    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  **/
    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. */
    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  **/
    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  **/
    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  **/
    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 */
    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  **/
    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  **/
    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  **/
    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  **/
    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  **/
    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  **/
    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  **/
   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  **/
   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  **/
   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  **/
   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