/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2014-2016 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */ /*!
 * \file
 * \brief
 */ /*-------------------------------------------------------------------*/

/*!
 * \file  esextcTextureCubeMapArraySampling.cpp
 * \brief Texture Cube Map Array Sampling (Test 1)
 */ /*-------------------------------------------------------------------*/

/* Control logging of positive results. 0 disabled, 1 enabled */
#define TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_LOG 0

/* Control logging of program source for positive results. 0 disabled, 1 enabled */
#define TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_PROGRAM_LOG 1

/* Control logging of negative results. 0 disabled, 1 enabled */
#define TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG 1

/* Control logging of program source for negative results. 0 disabled, 1 enabled */
#define TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG 1

/* When enabled, textures will be stored as TGA files. Test will not be executed. 0 disabled, 1 enabled */
#define TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION 0

/* Output path for TGA files */
#define TEXTURECUBEMAPARRAYSAMPLINGTEST_PATH_FOR_COMPRESSION "c:\\textures\\"

#include "esextcTextureCubeMapArraySampling.hpp"
#include "esextcTextureCubeMapArraySamplingResources.hpp"

#include "gluContextInfo.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuTestLog.hpp"

#include <cmath>
#include <sstream>
#include <vector>

#if TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION
#include <fstream>
#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION */

namespace glcts
{
/** Structure used to write shaders' variables to stream
 *
 **/
struct var2str
{
public:
	/** Constructor. Stores strings used to create variable name
	 *  prefixName[index]
	 *
	 *  @param prefix Prefix part. Can be null.
	 *  @param name   Name part. Must not be null.
	 *  @param index  Index part. Can be null.
	 **/
	var2str(const glw::GLchar* prefix, const glw::GLchar* name, const glw::GLchar* index)
		: m_prefix(prefix), m_name(name), m_index(index)
	{
		/* Nothing to be done here */
	}

	const glw::GLchar* m_prefix;
	const glw::GLchar* m_name;
	const glw::GLchar* m_index;
};

/* Attribute names */
const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_grad_x			   = "grad_x";
const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_grad_y			   = "grad_y";
const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_lod				   = "lod";
const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_refZ			   = "refZ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_texture_coordinate = "texture_coordinates";

/* Compute shader parts */
const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_body =
	"void main()\n"
	"{\n"
	"    const int face_width         = 3;\n"
	"    const int face_height        = 3;\n"
	"    const int vertices_per_face  = face_width * face_height;\n"
	"    const int faces_per_layer    = 6;\n"
	"    const int layer_width        = faces_per_layer * face_width;\n"
	"    const int vertices_per_layer = vertices_per_face * faces_per_layer;\n"
	"\n"
	"    ivec2 image_coord            = ivec2(gl_WorkGroupID.xy);\n"
	"    ivec3 texture_size           = textureSize(sampler, 0);\n"
	"\n"
	"    int layer                    = image_coord.x / layer_width;\n"
	"    int layer_offset             = layer * layer_width;\n"
	"    int layer_index              = layer * vertices_per_layer;\n"
	"    int face                     = (image_coord.x - layer_offset) / face_width;\n"
	"    int face_offset              = face * face_width;\n"
	"    int face_index               = face * vertices_per_face;\n"
	"    int vertex                   = image_coord.x - layer_offset - face_offset;\n"
	"    int vertex_index             = layer_index + face_index + vertex + (face_height - image_coord.y - 1) * "
	"face_width;\n"
	"\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_layout_binding = "layout(std430, binding=";
const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_buffer			= ") buffer ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_color			= "color";
const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_image_store =
	"    imageStore(image, image_coord, ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_layout =
	"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_param = "cs_";

/* Fragment shader parts */
const glw::GLchar* const TextureCubeMapArraySamplingTest::fragment_shader_input  = "fs_in_color";
const glw::GLchar* const TextureCubeMapArraySamplingTest::fragment_shader_output = "fs_out_color";
const glw::GLchar* const TextureCubeMapArraySamplingTest::fragment_shader_pass_through_body_code =
	"void main()\n"
	"{\n"
	"    fs_out_color = fs_in_color;\n"
	"}\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::fragment_shader_sampling_body_code = "void main()\n"
																							   "{\n";

/* Geometry shader parts */
const glw::GLchar* const TextureCubeMapArraySamplingTest::geometry_shader_emit_vertex_code = "    EmitVertex();\n"
																							 "}\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::geometry_shader_extension = "${GEOMETRY_SHADER_REQUIRE}\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::geometry_shader_layout =
	"layout(points)                 in;\n"
	"layout(points, max_vertices=1) out;\n"
	"\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::geometry_shader_sampling_body_code =
	"void main()\n"
	"{\n"
	"    gl_Position = gl_in[0].gl_Position;\n";

/* Image types and name */
const glw::GLchar* const TextureCubeMapArraySamplingTest::image_float = "image2D ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::image_int   = "iimage2D ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::image_name  = "image";
const glw::GLchar* const TextureCubeMapArraySamplingTest::image_uint  = "uimage2D ";

/* Interpolation */
const glw::GLchar* const TextureCubeMapArraySamplingTest::interpolation_flat = "flat ";

/* Sampler types and name */
const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_depth = "samplerCubeArrayShadow ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_float = "samplerCubeArray ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_int   = "isamplerCubeArray ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_name  = "sampler";
const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_uint  = "usamplerCubeArray ";

/* Common shader parts for */
const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_code_preamble = "${VERSION}\n"
																				 "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
																				 "\n";

const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_precision = "precision highp float;\n";

const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_input	 = "in ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_layout	= "layout(location = 0) ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_output	= "out ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_uniform   = "uniform ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_writeonly = "writeonly ";

/* Tesselation control shader parts */
const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_control_shader_layout =
	"layout(vertices = 1) out;\n"
	"\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_control_shader_sampling_body_code =
	"void main()\n"
	"{\n"
	"    gl_TessLevelInner[0] = 1.0;\n"
	"    gl_TessLevelInner[1] = 1.0;\n"
	"    gl_TessLevelOuter[0] = 1.0;\n"
	"    gl_TessLevelOuter[1] = 1.0;\n"
	"    gl_TessLevelOuter[2] = 1.0;\n"
	"    gl_TessLevelOuter[3] = 1.0;\n"
	"    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_control_shader_output = "tcs_out_";

/* Tesselation evaluation shader parts */
const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_evaluation_shader_input = "tes_in_color";
const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_evaluation_shader_layout =
	"layout(isolines, point_mode) in;\n"
	"\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_evaluation_shader_pass_through_body_code =
	"void main()\n"
	"{\n"
	"    gl_Position = gl_in[0].gl_Position;\n"
	"    fs_in_color = tes_in_color[0];\n"
	"}\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_evaluation_shader_sampling_body_code =
	"void main()\n"
	"{\n"
	"    gl_Position = gl_in[0].gl_Position;\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_shader_extension =
	"${TESSELLATION_SHADER_REQUIRE}\n";

/* Texture sampling routines */
const glw::GLchar* const TextureCubeMapArraySamplingTest::texture_func		 = "texture";
const glw::GLchar* const TextureCubeMapArraySamplingTest::textureGather_func = "textureGather";
const glw::GLchar* const TextureCubeMapArraySamplingTest::textureGrad_func   = "textureGrad";
const glw::GLchar* const TextureCubeMapArraySamplingTest::textureLod_func	= "textureLod";

/* Data types */
const glw::GLchar* const TextureCubeMapArraySamplingTest::type_float = "float ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::type_ivec4 = "ivec4 ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::type_uint  = "uint ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::type_uvec4 = "uvec4 ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::type_vec3  = "vec3 ";
const glw::GLchar* const TextureCubeMapArraySamplingTest::type_vec4  = "vec4 ";

/* Vertex shader parts */
const glw::GLchar* const TextureCubeMapArraySamplingTest::vertex_shader_body_code =
	"void main()\n"
	"{\n"
	"    gl_PointSize = 1.0f;\n"
	"    gl_Position = vs_in_position;\n";
const glw::GLchar* const TextureCubeMapArraySamplingTest::vertex_shader_input	= "vs_in_";
const glw::GLchar* const TextureCubeMapArraySamplingTest::vertex_shader_output   = "vs_out_";
const glw::GLchar* const TextureCubeMapArraySamplingTest::vertex_shader_position = "position";

/* Static constants */
const glw::GLuint TextureCubeMapArraySamplingTest::m_get_type_api_status_program_resource						 = 0x02;
const glw::GLuint TextureCubeMapArraySamplingTest::m_get_type_api_status_uniform								 = 0x01;
const glw::GLuint TextureCubeMapArraySamplingTest::bufferDefinition::m_invalid_buffer_object_id					 = -1;
const glw::GLuint TextureCubeMapArraySamplingTest::programDefinition::m_invalid_program_object_id				 = 0;
const glw::GLuint TextureCubeMapArraySamplingTest::shaderDefinition::m_invalid_shader_object_id					 = 0;
const glw::GLuint TextureCubeMapArraySamplingTest::textureDefinition::m_invalid_texture_object_id				 = -1;
const glw::GLuint TextureCubeMapArraySamplingTest::textureDefinition::m_invalid_uniform_location				 = -1;
const glw::GLuint TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::m_invalid_attribute_location	 = -1;
const glw::GLuint TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::m_invalid_vertex_array_object_id = -1;

/* Functions */

/** Fill image with specified color
 *  @tparam T               Image component type
 *  @tparam N_Components    Number of image components
 *
 *  @param image_width      Width of image
 *  @param image_height     Height of image
 *  @param pixel_components Image will be filled with that color
 *  @param out_data         Image data, storage must be allocated
 **/
template <typename T, unsigned int N_Components>
void fillImage(glw::GLsizei image_width, glw::GLsizei image_height, const T* pixel_components, T* out_data)
{
	const glw::GLuint n_components_per_pixel = N_Components;
	const glw::GLuint n_components_per_line  = n_components_per_pixel * image_width;

	for (glw::GLsizei y = 0; y < image_height; ++y)
	{
		const glw::GLuint line_offset = y * n_components_per_line;

		for (glw::GLsizei x = 0; x < image_width; ++x)
		{
			for (glw::GLuint component = 0; component < n_components_per_pixel; ++component)
			{
				out_data[line_offset + x * n_components_per_pixel + component] = pixel_components[component];
			}
		}
	}
}

/* Out of alphabetical order due to use in other functions */
/** Normalize vector stored in array. Only first N_NormalizedComponents will be normalized.
 *
 *  @tparam N_NormalizedComponents Number of coordinates to normalize
 *  @tparam N_Components           Number of coordinates in vector
 *
 *  @param data                    Pointer to first coordinate of first vector in array
 *  @param index                   Index of vector to be normalized
 **/
template <unsigned int N_NormalizedComponents, unsigned int N_Components>
void vectorNormalize(glw::GLfloat* data, glw::GLuint index)
{
	glw::GLfloat* components = data + index * N_Components;

	glw::GLfloat sqr_length = 0.0f;

	for (glw::GLuint i = 0; i < N_NormalizedComponents; ++i)
	{
		const glw::GLfloat component = components[i];

		sqr_length += component * component;
	}

	const glw::GLfloat length = sqrtf(sqr_length);
	const glw::GLfloat factor = 1.0f / length;

	for (glw::GLuint i = 0; i < N_NormalizedComponents; ++i)
	{
		components[i] *= factor;
	}
}

/* Out of alphabetical order due to use in other functions */
/** Set coordinates of 4 element vector stored in array
 *
 *  @param data  Pointer to first coordinate of first vector in array
 *  @param index Index of vector to be normalized
 *  @param x     1st coordinate value
 *  @param y     2nd coordinate value
 *  @param z     3rd coordinate value
 *  @param w     4th coordinate value
 **/
void vectorSet4(glw::GLfloat* data, glw::GLuint index, glw::GLfloat x, glw::GLfloat y, glw::GLfloat z, glw::GLfloat w)
{
	const glw::GLuint n_components_per_vertex = 4;
	const glw::GLuint vector_offset			  = n_components_per_vertex * index;

	data[vector_offset + 0] = x;
	data[vector_offset + 1] = y;
	data[vector_offset + 2] = z;
	data[vector_offset + 3] = w;
}

/* Out of alphabetical order due to use in other functions */
/** Subtract vectors: a = b - a
 *
 *  @tparam N_Components Number of coordinates in vector
 *
 *  @param a             Pointer to vector a
 *  @param b             Pointer to vector b
 **/
template <unsigned int N_Components>
void vectorSubtractInPlace(glw::GLfloat* a, const glw::GLfloat* b)
{
	const glw::GLuint n_components = N_Components;

	for (glw::GLuint i = 0; i < n_components; ++i)
	{
		a[i] -= b[i];
	}
}

/** Prepare color for rgba float textures
 *
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param mipmap_level    Mipmap level
 *  @param n_elements      Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_data        Pointer to components storage
 **/
void getColorFloatComponents(glw::GLint cube_face, glw::GLint element_index, glw::GLint mipmap_level,
							 glw::GLint n_elements, glw::GLint n_mipmap_levels, glw::GLfloat* out_data)
{
	static const glw::GLfloat n_faces = 6.0f;

	out_data[0] = ((glw::GLfloat)(mipmap_level + 1)) / ((glw::GLfloat)n_mipmap_levels);
	out_data[1] = ((glw::GLfloat)(cube_face + 1)) / n_faces;
	out_data[2] = ((glw::GLfloat)(element_index + 1)) / ((glw::GLfloat)n_elements);
	out_data[3] = 1.0f / 4.0f;
}

/** Prepare color for rgba integer textures
 *
 *  @tparam T             Type of components
 *
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param mipmap_level    Mipmap level
 *  @param n_elements      Number of elements in array, ignored
 *  @param n_mipmap_levels Number of mipmap levels, ignored
 *  @param out_data        Pointer to components storage
 **/
template <typename T>
void getColorIntComponents(glw::GLint cube_face, glw::GLint element_index, glw::GLint		 mipmap_level,
						   glw::GLint /* n_elements */, glw::GLint /* n_mipmap_levels */, T* out_data)
{
	out_data[0] = static_cast<T>(mipmap_level + 1);
	out_data[1] = static_cast<T>(cube_face + 1);
	out_data[2] = static_cast<T>(element_index + 1);
	out_data[3] = 1;
}

/** Prepare color for rgba compressed textures
 *
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param mipmap_level    Mipmap level
 *  @param n_elements      Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_data        Pointer to components storage
 **/
void getCompressedColorUByteComponents(glw::GLint cube_face, glw::GLint element_index, glw::GLint mipmap_level,
									   glw::GLint n_elements, glw::GLint n_mipmap_levels, glw::GLubyte* out_data)
{
	(void)n_mipmap_levels;

	static const glw::GLuint n_faces = 6;

	const glw::GLuint  n_faces_per_level = n_elements * n_faces;
	const glw::GLubyte value =
		static_cast<glw::GLubyte>(mipmap_level * n_faces_per_level + element_index * n_faces + cube_face + 1);

	out_data[0] = value;
	out_data[1] = value;
	out_data[2] = value;
	out_data[3] = value;
}

/** Get compressed texture data and size from resources. Width, height, number of array elements and mipmap level are used to identify image.
 *  Width and height are dimmensions of base level image, same values are used to identify all mipmap levels.
 *
 *  @param width            Width of texture
 *  @param height           Height of texture
 *  @param n_array_elements Number of elemnts in array
 *  @param mipmap_level     Level
 *  @param out_image_data   Image data
 *  @param out_image_size   Image size
 **/
void getCompressedTexture(glw::GLuint width, glw::GLuint height, glw::GLuint n_array_elements, glw::GLuint mipmap_level,
						  const glw::GLubyte*& out_image_data, glw::GLuint& out_image_size)
{
	for (glw::GLuint i = 0; i < n_compressed_images; ++i)
	{
		const compressedImage& image = compressed_images[i];

		if ((image.width == width) && (image.height == height) && (image.length == n_array_elements) &&
			(image.level == mipmap_level))
		{
			out_image_data = image.image_data;
			out_image_size = image.image_size;

			return;
		}
	}

	out_image_data = 0;
	out_image_size = 0;
}

/** Prepare color for depth textures
 *
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param mipmap_level    Mipmap level
 *  @param n_elements      Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_depth       Depth value
 **/
void getDepthComponent(glw::GLint cube_face, glw::GLint element_index, glw::GLint mipmap_level, glw::GLint n_elements,
					   glw::GLint n_mipmap_levels, glw::GLfloat& out_depth)
{
	static const glw::GLuint n_faces = 6;

	out_depth = ((glw::GLfloat)(mipmap_level + 1 + cube_face + 1 + element_index + 1)) /
				((glw::GLfloat)(n_mipmap_levels + n_faces + n_elements));
}

/** Get expected color sampled by texture or textureGather from rgba float textures
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>. Ignored.
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param n_layers        Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_components  Pointer to components storage
 **/
void getExpectedColorFloatComponentsForTexture(glw::GLuint /* pixel_index */, glw::GLint cube_face,
											   glw::GLint element_index, glw::GLint n_layers,
											   glw::GLint n_mipmap_levels, glw::GLfloat* out_components)
{
	getColorFloatComponents(cube_face, element_index, 0 /* mipmap_level */, n_layers, n_mipmap_levels, out_components);
}

/** Get expected color sampled by textureLod or textureGrad from rgba float textures
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param n_layers        Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_components  Pointer to components storage
 **/
void getExpectedColorFloatComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint cube_face,
												  glw::GLint element_index, glw::GLint n_layers,
												  glw::GLint n_mipmap_levels, glw::GLfloat* out_components)
{
	glw::GLint mipmap_level = 0;

	if (1 == pixel_index % 2)
	{
		mipmap_level = n_mipmap_levels - 1;
	}

	getColorFloatComponents(cube_face, element_index, mipmap_level, n_layers, n_mipmap_levels, out_components);
}

/** Get expected color sampled by texture or textureGather from rgba integer textures
 *
 *  @tparam T              Type of image components
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>. Ignored.
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param n_layers        Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_components  Pointer to components storage
 **/
template <typename T>
void getExpectedColorIntComponentsForTexture(glw::GLuint /* pixel_index */, glw::GLint cube_face,
											 glw::GLint element_index, glw::GLint n_layers, glw::GLint n_mipmap_levels,
											 T* out_components)
{
	getColorIntComponents<T>(cube_face, element_index, 0 /* mipmap_level */, n_layers, n_mipmap_levels, out_components);
}

/** Get expected color sampled by textureLod or textureGrad from rgba integer textures
 *
 *  @tparam T              Type of image components
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param n_layers        Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_components  Pointer to components storage
 **/
template <typename T>
void getExpectedColorIntComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint cube_face, glw::GLint element_index,
												glw::GLint n_layers, glw::GLint n_mipmap_levels, T* out_components)
{
	glw::GLint mipmap_level = 0;

	if (1 == pixel_index % 2)
	{
		mipmap_level = n_mipmap_levels - 1;
	}

	getColorIntComponents<T>(cube_face, element_index, mipmap_level, n_layers, n_mipmap_levels, out_components);
}

/** Get expected color sampled by texture or textureGather from rgba compressed textures
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>. Ignored.
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param n_layers        Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_components  Pointer to components storage
 **/
void getExpectedCompressedComponentsForTexture(glw::GLuint /* pixel_index */, glw::GLint cube_face,
											   glw::GLint element_index, glw::GLint n_layers,
											   glw::GLint n_mipmap_levels, glw::GLubyte* out_components)
{
	getCompressedColorUByteComponents(cube_face, element_index, 0 /* mipmap_level */, n_layers, n_mipmap_levels,
									  out_components);
}

/** Get expected color sampled by textureLod or textureGrad from rgba compressed textures
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param n_layers        Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_components  Pointer to components storage
 **/
void getExpectedCompressedComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint cube_face,
												  glw::GLint element_index, glw::GLint n_layers,
												  glw::GLint n_mipmap_levels, glw::GLubyte* out_components)
{
	glw::GLint mipmap_level = 0;

	if (1 == pixel_index % 2)
	{
		mipmap_level = n_mipmap_levels - 1;
	}

	getCompressedColorUByteComponents(cube_face, element_index, mipmap_level, n_layers, n_mipmap_levels,
									  out_components);
}

/** Get expected color sampled by texture or textureGather from depth textures
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>
 *  @param cube_face       Index of cube's face. Ignored.
 *  @param element_index   Index of element in array. Ignored.
 *  @param n_layers        Number of elements in array. Ignored.
 *  @param n_mipmap_levels Number of mipmap levels. Ignored.
 *  @param out_components  Pointer to components storage
 **/
void getExpectedDepthComponentsForTexture(glw::GLuint pixel_index, glw::GLint /* cube_face */,
										  glw::GLint /* element_index */, glw::GLint /* n_layers */,
										  glw::GLint /* n_mipmap_levels */, glw::GLfloat* out_components)
{
	const glw::GLfloat results[9] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f };

	out_components[0] = results[pixel_index];
}

/** Get expected color sampled by textureLod or textureGrad from depth textures
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
 *  @param cube_face       Index of cube's face. Ignored.
 *  @param element_index   Index of element in array. Ignored.
 *  @param n_layers        Number of elements in array. Ignored.
 *  @param n_mipmap_levels Number of mipmap levels. Ignored.
 *  @param out_components  Pointer to components storage
 **/
void getExpectedDepthComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint /* cube_face */,
											 glw::GLint /* element_index */, glw::GLint /* n_layers */,
											 glw::GLint /* n_mipmap_levels */, glw::GLfloat* out_components)
{
	if (0 == pixel_index % 2)
	{
		out_components[0] = 0.0f;
	}
	else
	{
		out_components[0] = 1.0f;
	}
}

/* Out of alphabetical order due to use in other functions */
/** Prepare color for stencil textures
 *
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param mipmap_level    Mipmap level
 *  @param n_elements      Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_stencil     Stencil value
 **/
void getStencilComponent(glw::GLint cube_face, glw::GLint element_index, glw::GLint mipmap_level, glw::GLint n_elements,
						 glw::GLint n_mipmap_levels, glw::GLubyte& out_stencil)
{
	static const glw::GLint n_faces = 6;

	out_stencil = (glw::GLubyte)((mipmap_level + 1 + cube_face + 1 + element_index + 1) * 255 /
								 (n_mipmap_levels + n_faces + n_elements));
}

/** Get expected color sampled by texture or textureGather from stencil textures
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>. Ignored.
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param n_layers        Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_components  Pointer to components storage
 **/
void getExpectedStencilComponentsForTexture(glw::GLuint /* pixel_index */, glw::GLint cube_face,
											glw::GLint element_index, glw::GLint n_layers, glw::GLint n_mipmap_levels,
											glw::GLuint* out_components)
{
	glw::GLubyte value = 0;

	getStencilComponent(cube_face, element_index, 0 /* mipmap_level */, n_layers, n_mipmap_levels, value);

	out_components[0] = value;
}

/** Get expected color sampled by textureLod or textureGrad from stencil textures
 *
 *  @param pixel_index     Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
 *  @param cube_face       Index of cube's face
 *  @param element_index   Index of element in array
 *  @param n_layers        Number of elements in array
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param out_components  Pointer to components storage
 **/
void getExpectedStencilComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint cube_face, glw::GLint element_index,
											   glw::GLint n_layers, glw::GLint n_mipmap_levels,
											   glw::GLuint* out_components)
{
	glw::GLubyte value		  = 0;
	glw::GLint   mipmap_level = 0;

	if (1 == pixel_index % 2)
	{
		mipmap_level = n_mipmap_levels - 1;
	}

	getStencilComponent(cube_face, element_index, mipmap_level, n_layers, n_mipmap_levels, value);

	out_components[0] = value;
}

/** Returns number of mipmaps for given image dimmensions
 *
 *  @param texture_width  Width of image
 *  @param texture_height Height of image
 *
 *  @returns Number of mipmaps
 **/
glw::GLubyte getMipmapLevelCount(glw::GLsizei texture_width, glw::GLsizei texture_height)
{
	glw::GLsizei size  = de::max(texture_width, texture_height);
	glw::GLuint  count = 1;

	while (1 < size)
	{
		size /= 2;
		count += 1;
	}

	return (glw::GLubyte)count;
}

/** Calculate texture coordinates for "right neighbour" of given texture coordinates
 *
 *  @param texture_coordinates Texture coordinates of original point
 *  @param face                Cube map's face index
 *  @param offset              Offset of "neighbour" in "right" direction
 *  @param width               Image width
 *  @param out_neighbour       Texture coordinates of "neighbour" point
 **/
void getRightNeighbour(const glw::GLfloat* texture_coordinates, glw::GLuint face, glw::GLuint offset, glw::GLuint width,
					   glw::GLfloat* out_neighbour)
{
	const glw::GLfloat step = (float)offset / (float)width;

	glw::GLfloat& x = out_neighbour[0];
	glw::GLfloat& y = out_neighbour[1];
	glw::GLfloat& z = out_neighbour[2];

	const glw::GLfloat coord_x = texture_coordinates[0];
	const glw::GLfloat coord_y = texture_coordinates[1];
	const glw::GLfloat coord_z = texture_coordinates[2];

	switch (face)
	{
	case 0: // +X
		x = coord_x;
		y = coord_y - step;
		z = coord_z;
		break;
	case 1: // -X
		x = coord_x;
		y = coord_y + step;
		z = coord_z;
		break;
	case 2: // +Y
		x = coord_x + step;
		y = coord_y;
		z = coord_z;
		break;
	case 3: // -Y
		x = coord_x - step;
		y = coord_y;
		z = coord_z;
		break;
	case 4: // +Z
		x = coord_x + step;
		y = coord_y;
		z = coord_z;
		break;
	case 5: // -Z
		x = coord_x - step;
		y = coord_y;
		z = coord_z;
		break;
	}
}

/** Calculate texture coordinates for "top neighbour" of given texture coordinates
 *
 *  @param texture_coordinates Texture coordinates of original point
 *  @param face                Cube map's face index
 *  @param offset              Offset of "neighbour" in "top" direction
 *  @param width               Image width
 *  @param out_neighbour       Texture coordinates of "neighbour" point
 **/
void getTopNeighbour(const glw::GLfloat* texture_coordinates, glw::GLuint face, glw::GLuint offset, glw::GLuint width,
					 glw::GLfloat* out_neighbour)
{
	glw::GLfloat step = (float)offset / (float)width;

	glw::GLfloat& x = out_neighbour[0];
	glw::GLfloat& y = out_neighbour[1];
	glw::GLfloat& z = out_neighbour[2];

	const glw::GLfloat coord_x = texture_coordinates[0];
	const glw::GLfloat coord_y = texture_coordinates[1];
	const glw::GLfloat coord_z = texture_coordinates[2];

	switch (face)
	{
	case 0: // +X
		x = coord_x;
		y = coord_y;
		z = coord_z + step;
		break;
	case 1: // -X
		x = coord_x;
		y = coord_y;
		z = coord_z + step;
		break;
	case 2: // +Y
		x = coord_x;
		y = coord_y;
		z = coord_z + step;
		break;
	case 3: // -Y
		x = coord_x;
		y = coord_y;
		z = coord_z + step;
		break;
	case 4: // +Z
		x = coord_x;
		y = coord_y - step;
		z = coord_z;
		break;
	case 5: // -Z
		x = coord_x;
		y = coord_y + step;
		z = coord_z;
		break;
	}
}

/** Write var2str instance to output stream
 *
 *  @param stream Stream instance
 *  @param var    var2str instance
 *
 *  @returns Stream instance
 **/
std::ostream& operator<<(std::ostream& stream, const var2str& var)
{
	if (0 != var.m_prefix)
	{
		stream << var.m_prefix;
	}

	stream << var.m_name;

	if (0 != var.m_index)
	{
		stream << "[" << var.m_index << "]";
	}

	return stream;
}

/* Out of alphabetical order due to use in other functions */
/** Fill texture's face at given index and level with given color
 *
 *  @tparam T                 Type of image component
 *  @tparam N_Components      Number of components
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 *  @param components         Color used to fill texture
 **/
template <typename T, unsigned int N_Components>
void prepareDataForTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
						   glw::GLint mipmap_level, glw::GLenum texture_format, glw::GLenum texture_type,
						   glw::GLsizei texture_width, glw::GLsizei texture_height, const T* components)
{
	static const glw::GLuint n_components_per_pixel = N_Components;

	const glw::GLuint n_pixels			  = texture_width * texture_height;
	const glw::GLuint n_total_componenets = n_components_per_pixel * n_pixels;
	const glw::GLuint z_offset			  = element_index * 6 + cube_face;

	std::vector<T> texture_data;
	texture_data.resize(n_total_componenets);

	fillImage<T, N_Components>(texture_width, texture_height, components, &texture_data[0]);

	gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipmap_level, 0 /* x */, 0 /* y */, z_offset, texture_width,
					 texture_height, 1 /* depth */, texture_format, texture_type, &texture_data[0]);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update texture data");
}

/** Prepare texture's face at given index and level, for rgba float textures.
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param n_elements         Number of elements in array
 *  @param n_mipmap_levels    Number of mipmap levels
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 **/
void prepareDataForColorFloatTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
									 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
									 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
									 glw::GLsizei texture_height)
{
	glw::GLfloat components[4];

	getColorFloatComponents(cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, components);

	prepareDataForTexture<glw::GLfloat, 4>(gl, cube_face, element_index, mipmap_level, texture_format, texture_type,
										   texture_width, texture_height, components);
}

/** Prepare texture's face at given index and level, for rgba integer textures.
 *
 *  @tparam T                 Type of image component
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param n_elements         Number of elements in array
 *  @param n_mipmap_levels    Number of mipmap levels
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 **/
template <typename T>
void prepareDataForColorIntTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
								   glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
								   glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
								   glw::GLsizei texture_height)
{
	T components[4];

	getColorIntComponents<T>(cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, components);

	prepareDataForTexture<T, 4>(gl, cube_face, element_index, mipmap_level, texture_format, texture_type, texture_width,
								texture_height, components);
}

/** Prepare texture's face at given index and level, for depth textures.
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param n_elements         Number of elements in array
 *  @param n_mipmap_levels    Number of mipmap levels
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 **/
void prepareDataForDepthFloatTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
									 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
									 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
									 glw::GLsizei texture_height)
{
	glw::GLfloat component = 0;

	getDepthComponent(cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, component);

	prepareDataForTexture<glw::GLfloat, 1>(gl, cube_face, element_index, mipmap_level, texture_format, texture_type,
										   texture_width, texture_height, &component);
}

/** Prepare texture's face at given index and level, for stencil textures.
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param n_elements         Number of elements in array
 *  @param n_mipmap_levels    Number of mipmap levels
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 **/
void prepareDataForStencilUIntTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
									  glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
									  glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
									  glw::GLsizei texture_height)
{
	glw::GLubyte component = 0;

	getStencilComponent(cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, component);

	prepareDataForTexture<glw::GLubyte, 1>(gl, cube_face, element_index, mipmap_level, texture_format, texture_type,
										   texture_width, texture_height, &component);
}

/** Prepare texture's face at given index and level, for depth textures.
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param n_elements         Number of elements in array
 *  @param n_mipmap_levels    Number of mipmap levels
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 **/
void prepareDepthTextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
							 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
							 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
							 glw::GLsizei texture_height)
{
	switch (texture_type)
	{
	case GL_FLOAT:
		prepareDataForDepthFloatTexture(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
										texture_format, texture_type, texture_width, texture_height);
		break;

	default:
		TCU_FAIL("Not implemented case !");
	}
}

/** Prepare grad_x vector for given texture_coordinates
 *
 *  @param grad_x              Storage for grad_x
 *  @param face                Cube map's face index
 *  @param texture_coordinates Texture coordinate
 *  @param width               Image width
 **/
void prepareGradXForFace(glw::GLfloat* grad_x, glw::GLuint face, glw::GLfloat* texture_coordinates, glw::GLuint width)
{
	static const glw::GLuint n_points_per_face				  = 9;
	static const glw::GLuint n_texture_coordinates_components = 4;
	static const glw::GLuint n_grad_components				  = 4;

	for (glw::GLuint i = 0; i < n_points_per_face; i += 2)
	{
		const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
		const glw::GLuint grad_offset				 = i * n_grad_components;

		getRightNeighbour(texture_coordinates + texture_coordinates_offset, face, 1, width, grad_x + grad_offset);
	}

	for (glw::GLuint i = 1; i < n_points_per_face; i += 2)
	{
		const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
		const glw::GLuint grad_offset				 = i * n_grad_components;

		getRightNeighbour(texture_coordinates + texture_coordinates_offset, face, 4 * width, width,
						  grad_x + grad_offset);
	}

	for (glw::GLuint i = 0; i < n_points_per_face; ++i)
	{
		const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
		const glw::GLuint grad_offset				 = i * n_grad_components;

		vectorSubtractInPlace<3>(grad_x + grad_offset, texture_coordinates + texture_coordinates_offset);
	}
}

/** Prepare grad_y vector for given texture_coordinates
 *
 *  @param grad_y              Storage for grad_x
 *  @param face                Cube map's face index
 *  @param texture_coordinates Texture coordinate
 *  @param width               Image width
 **/
void prepareGradYForFace(glw::GLfloat* grad_y, glw::GLuint face, glw::GLfloat* texture_coordinates, glw::GLuint width)
{
	static const glw::GLuint n_points_per_face				  = 9;
	static const glw::GLuint n_texture_coordinates_components = 4;
	static const glw::GLuint n_grad_components				  = 4;

	for (glw::GLuint i = 0; i < n_points_per_face; i += 2)
	{
		const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
		const glw::GLuint grad_offset				 = i * n_grad_components;

		getTopNeighbour(texture_coordinates + texture_coordinates_offset, face, 1, width, grad_y + grad_offset);
	}

	for (glw::GLuint i = 1; i < n_points_per_face; i += 2)
	{
		const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
		const glw::GLuint grad_offset				 = i * n_grad_components;

		getTopNeighbour(texture_coordinates + texture_coordinates_offset, face, 4 * width, width, grad_y + grad_offset);
	}

	for (glw::GLuint i = 0; i < n_points_per_face; ++i)
	{
		const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
		const glw::GLuint grad_offset				 = i * n_grad_components;

		vectorSubtractInPlace<3>(grad_y + grad_offset, texture_coordinates + texture_coordinates_offset);
	}
}

/** Prepare "lods" for face.
 *  Pattern is: B T B
 *              T B T
 *              B T B
 *  B - base, T - top
 *
 *  @param lods            Storage for lods
 *  @param n_mipmap_levels Number of mipmap levels
 **/
void prepareLodForFace(glw::GLfloat* lods, glw::GLuint n_mipmap_levels)
{
	const glw::GLfloat base_level = 0.0f;
	const glw::GLfloat top_level  = (glw::GLfloat)(n_mipmap_levels - 1);

	lods[0] = base_level;
	lods[1] = top_level;
	lods[2] = base_level;
	lods[3] = top_level;
	lods[4] = base_level;
	lods[5] = top_level;
	lods[6] = base_level;
	lods[7] = top_level;
	lods[8] = base_level;
}

/** Prepare position for vertices. Each vertex is placed on a unique pixel of output image.
 *
 *  @param positions     Storage for positions
 *  @param cube_face     Texture coordinate
 *  @param element_index Index of element in array
 *  @param n_layers      Image width
 **/
void preparePositionForFace(glw::GLfloat* positions, glw::GLuint cube_face, glw::GLuint element_index,
							glw::GLuint n_layers)
{
	static const glw::GLuint x_offset_per_face = 3;
	static const glw::GLuint n_faces		   = 6;

	const glw::GLuint x_offset_for_face = (element_index * n_faces + cube_face) * x_offset_per_face;

	const glw::GLfloat x_step	 = 2.0f / ((glw::GLfloat)(n_layers * 3));
	const glw::GLfloat x_mid_step = x_step / 2.0f;
	const glw::GLfloat y_step	 = 2.0f / 3.0f;
	const glw::GLfloat y_mid_step = y_step / 2.0f;

	const glw::GLfloat x_left   = -1.0f + x_mid_step + ((glw::GLfloat)x_offset_for_face) * x_step;
	const glw::GLfloat x_middle = x_left + x_step;
	const glw::GLfloat x_right  = x_middle + x_step;

	const glw::GLfloat y_top	= 1.0f - y_mid_step;
	const glw::GLfloat y_middle = y_top - y_step;
	const glw::GLfloat y_bottom = y_middle - y_step;

	vectorSet4(positions, 0, x_left, y_top, 0.0f, 1.0f);
	vectorSet4(positions, 1, x_middle, y_top, 0.0f, 1.0f);
	vectorSet4(positions, 2, x_right, y_top, 0.0f, 1.0f);
	vectorSet4(positions, 3, x_left, y_middle, 0.0f, 1.0f);
	vectorSet4(positions, 4, x_middle, y_middle, 0.0f, 1.0f);
	vectorSet4(positions, 5, x_right, y_middle, 0.0f, 1.0f);
	vectorSet4(positions, 6, x_left, y_bottom, 0.0f, 1.0f);
	vectorSet4(positions, 7, x_middle, y_bottom, 0.0f, 1.0f);
	vectorSet4(positions, 8, x_right, y_bottom, 0.0f, 1.0f);
}

/** Prepare "refZ" for face.
 *  Pattern is: - = +
 *              - = +
 *              - = +
 *  '-' - lower than depth
 *   =  - eqaul to depth
 *   +  - higher thatn depth
 *
 *  @param refZs     Storage for refZs
 *  @param n_mipmaps Number of mipmap levels
 *  @param face      Cube map's face index
 *  @param layer     Index of element in array
 *  @param n_layers  Number of elements in array
 **/
void prepareRefZForFace(glw::GLfloat* refZs, glw::GLuint n_mipmaps, glw::GLuint face, glw::GLuint layer,
						glw::GLuint n_layers)
{
	glw::GLfloat expected_base_depth_value = 0;
	glw::GLfloat expected_top_depth_value  = 0;

	/* Get depth for top and base levles */
	getDepthComponent(face, layer, 0, n_layers, n_mipmaps, expected_base_depth_value);
	getDepthComponent(face, layer, n_mipmaps - 1, n_layers, n_mipmaps, expected_top_depth_value);

	/* Use step of 10% */
	const glw::GLfloat base_depth_step = expected_base_depth_value * 0.1f;
	const glw::GLfloat top_depth_step  = expected_top_depth_value * 0.1f;

	/* Top row */
	refZs[0] = expected_base_depth_value - base_depth_step;
	refZs[1] = expected_top_depth_value;
	refZs[2] = expected_base_depth_value + base_depth_step;

	/* Center row */
	refZs[3] = expected_top_depth_value - top_depth_step;
	refZs[4] = expected_base_depth_value;
	refZs[5] = expected_top_depth_value + top_depth_step;

	/* Bottom row */
	refZs[6] = expected_base_depth_value - base_depth_step;
	refZs[7] = expected_top_depth_value;
	refZs[8] = expected_base_depth_value + base_depth_step;
}

/** Prepare texture's face at given index and level, for rgba integer textures.
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param n_elements         Number of elements in array
 *  @param n_mipmap_levels    Number of mipmap levels
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 **/
void prepareRGBAIntegerTextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
								   glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
								   glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
								   glw::GLsizei texture_height)
{
	switch (texture_type)
	{
	case GL_UNSIGNED_INT:
		prepareDataForColorIntTexture<glw::GLuint>(gl, cube_face, element_index, mipmap_level, n_elements,
												   n_mipmap_levels, texture_format, texture_type, texture_width,
												   texture_height);
		break;

	case GL_INT:
		prepareDataForColorIntTexture<glw::GLint>(gl, cube_face, element_index, mipmap_level, n_elements,
												  n_mipmap_levels, texture_format, texture_type, texture_width,
												  texture_height);
		break;

	default:
		TCU_FAIL("Not implemented case !");
	}
}

/** Prepare texture's face at given index and level, for rgba textures.
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param n_elements         Number of elements in array
 *  @param n_mipmap_levels    Number of mipmap levels
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 **/
void prepareRGBATextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
							glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
							glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
							glw::GLsizei texture_height)
{
	switch (texture_type)
	{
	case GL_UNSIGNED_BYTE:
		prepareDataForColorIntTexture<glw::GLubyte>(gl, cube_face, element_index, mipmap_level, n_elements,
													n_mipmap_levels, texture_format, texture_type, texture_width,
													texture_height);
		break;

	case GL_FLOAT:
		prepareDataForColorFloatTexture(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
										texture_format, texture_type, texture_width, texture_height);
		break;

	default:
		TCU_FAIL("Not implemented case !");
	}
}

/** Prepare texture's face at given index and level, for stencil textures.
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param n_elements         Number of elements in array
 *  @param n_mipmap_levels    Number of mipmap levels
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 **/
void prepareStencilTextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
							   glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
							   glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
							   glw::GLsizei texture_height)
{
	switch (texture_type)
	{
	case GL_UNSIGNED_BYTE:
		prepareDataForStencilUIntTexture(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
										 texture_format, texture_type, texture_width, texture_height);
		break;

	default:
		TCU_FAIL("Not implemented case !");
	}
}

/** Prepare texture coordinates for vertices.
 *  Each vertex has unique value. 4 corners, centers of 4 edges and central points are selected.
 *
 *  @param positions     Storage for positions
 *  @param cube_face     Texture coordinate
 *  @param element_index Index of element in array
 *  @param n_layers      Image width
 **/
void prepareTextureCoordinatesForFace(glw::GLfloat* data, glw::GLuint width, glw::GLuint height, glw::GLfloat layer,
									  glw::GLuint face)
{
	const glw::GLfloat x_range = (glw::GLfloat)width;
	const glw::GLfloat y_range = (glw::GLfloat)height;

	const glw::GLfloat x_step = 2.0f / x_range;
	const glw::GLfloat y_step = 2.0f / y_range;

	const glw::GLfloat x_mid_step = x_step / 2.0f;
	const glw::GLfloat y_mid_step = y_step / 2.0f;

	const glw::GLfloat left		= -1.0f + x_mid_step;
	const glw::GLfloat right	= 1.0f - x_mid_step;
	const glw::GLfloat top		= 1.0f - y_mid_step;
	const glw::GLfloat bottom   = -1.0f + y_mid_step;
	const glw::GLfloat middle   = 0.0f;
	const glw::GLfloat negative = -1.0f;
	const glw::GLfloat positive = 1.0f;

	switch (face)
	{
	case 0:
		vectorSet4(data, 0, positive, left, top, layer);
		vectorSet4(data, 1, positive, middle, top, layer);
		vectorSet4(data, 2, positive, right, top, layer);
		vectorSet4(data, 3, positive, left, middle, layer);
		vectorSet4(data, 4, positive, middle, middle, layer);
		vectorSet4(data, 5, positive, right, middle, layer);
		vectorSet4(data, 6, positive, left, bottom, layer);
		vectorSet4(data, 7, positive, middle, bottom, layer);
		vectorSet4(data, 8, positive, right, bottom, layer);
		break;
	case 1:
		vectorSet4(data, 0, negative, left, top, layer);
		vectorSet4(data, 1, negative, middle, top, layer);
		vectorSet4(data, 2, negative, right, top, layer);
		vectorSet4(data, 3, negative, left, middle, layer);
		vectorSet4(data, 4, negative, middle, middle, layer);
		vectorSet4(data, 5, negative, right, middle, layer);
		vectorSet4(data, 6, negative, left, bottom, layer);
		vectorSet4(data, 7, negative, middle, bottom, layer);
		vectorSet4(data, 8, negative, right, bottom, layer);
		break;
	case 2:
		vectorSet4(data, 0, left, positive, top, layer);
		vectorSet4(data, 1, middle, positive, top, layer);
		vectorSet4(data, 2, right, positive, top, layer);
		vectorSet4(data, 3, left, positive, middle, layer);
		vectorSet4(data, 4, middle, positive, middle, layer);
		vectorSet4(data, 5, right, positive, middle, layer);
		vectorSet4(data, 6, left, positive, bottom, layer);
		vectorSet4(data, 7, middle, positive, bottom, layer);
		vectorSet4(data, 8, right, positive, bottom, layer);
		break;
	case 3:
		vectorSet4(data, 0, left, negative, top, layer);
		vectorSet4(data, 1, middle, negative, top, layer);
		vectorSet4(data, 2, right, negative, top, layer);
		vectorSet4(data, 3, left, negative, middle, layer);
		vectorSet4(data, 4, middle, negative, middle, layer);
		vectorSet4(data, 5, right, negative, middle, layer);
		vectorSet4(data, 6, left, negative, bottom, layer);
		vectorSet4(data, 7, middle, negative, bottom, layer);
		vectorSet4(data, 8, right, negative, bottom, layer);
		break;
	case 4:
		vectorSet4(data, 0, left, top, positive, layer);
		vectorSet4(data, 1, middle, top, positive, layer);
		vectorSet4(data, 2, right, top, positive, layer);
		vectorSet4(data, 3, left, middle, positive, layer);
		vectorSet4(data, 4, middle, middle, positive, layer);
		vectorSet4(data, 5, right, middle, positive, layer);
		vectorSet4(data, 6, left, bottom, positive, layer);
		vectorSet4(data, 7, middle, bottom, positive, layer);
		vectorSet4(data, 8, right, bottom, positive, layer);
		break;
	case 5:
		vectorSet4(data, 0, left, top, negative, layer);
		vectorSet4(data, 1, middle, top, negative, layer);
		vectorSet4(data, 2, right, top, negative, layer);
		vectorSet4(data, 3, left, middle, negative, layer);
		vectorSet4(data, 4, middle, middle, negative, layer);
		vectorSet4(data, 5, right, middle, negative, layer);
		vectorSet4(data, 6, left, bottom, negative, layer);
		vectorSet4(data, 7, middle, bottom, negative, layer);
		vectorSet4(data, 8, right, bottom, negative, layer);
		break;
	}

	vectorNormalize<3, 4>(data, 0);
	vectorNormalize<3, 4>(data, 1);
	vectorNormalize<3, 4>(data, 2);
	vectorNormalize<3, 4>(data, 3);
	vectorNormalize<3, 4>(data, 4);
	vectorNormalize<3, 4>(data, 5);
	vectorNormalize<3, 4>(data, 6);
	vectorNormalize<3, 4>(data, 7);
	vectorNormalize<3, 4>(data, 8);
}

/** Prepare texture coordinates for vertices. For sampling with textureGather routine.
 *  Each vertex has unique value. 4 corners, centers of 4 edges and central points are selected.
 *
 *  @param positions     Storage for positions
 *  @param cube_face     Texture coordinate
 *  @param element_index Index of element in array
 *  @param n_layers      Image width
 **/
void prepareTextureCoordinatesForGatherForFace(glw::GLfloat* data, glw::GLuint width, glw::GLuint height,
											   glw::GLfloat layer, glw::GLuint face)
{
	const glw::GLfloat x_range = (glw::GLfloat)width;
	const glw::GLfloat y_range = (glw::GLfloat)height;

	const glw::GLfloat x_step = 2.0f / x_range;
	const glw::GLfloat y_step = 2.0f / y_range;

	const glw::GLfloat x_mid_step = x_step / 2.0f;
	const glw::GLfloat y_mid_step = y_step / 2.0f;

	const glw::GLfloat left		= -1.0f + x_mid_step + x_step;
	const glw::GLfloat right	= 1.0f - x_mid_step - x_step;
	const glw::GLfloat top		= 1.0f - y_mid_step - y_step;
	const glw::GLfloat bottom   = -1.0f + y_mid_step + y_step;
	const glw::GLfloat middle   = 0.0f;
	const glw::GLfloat negative = -1.0f;
	const glw::GLfloat positive = 1.0f;

	switch (face)
	{
	case 0:
		vectorSet4(data, 0, positive, left, top, layer);
		vectorSet4(data, 1, positive, middle, top, layer);
		vectorSet4(data, 2, positive, right, top, layer);
		vectorSet4(data, 3, positive, left, middle, layer);
		vectorSet4(data, 4, positive, middle, middle, layer);
		vectorSet4(data, 5, positive, right, middle, layer);
		vectorSet4(data, 6, positive, left, bottom, layer);
		vectorSet4(data, 7, positive, middle, bottom, layer);
		vectorSet4(data, 8, positive, right, bottom, layer);
		break;
	case 1:
		vectorSet4(data, 0, negative, left, top, layer);
		vectorSet4(data, 1, negative, middle, top, layer);
		vectorSet4(data, 2, negative, right, top, layer);
		vectorSet4(data, 3, negative, left, middle, layer);
		vectorSet4(data, 4, negative, middle, middle, layer);
		vectorSet4(data, 5, negative, right, middle, layer);
		vectorSet4(data, 6, negative, left, bottom, layer);
		vectorSet4(data, 7, negative, middle, bottom, layer);
		vectorSet4(data, 8, negative, right, bottom, layer);
		break;
	case 2:
		vectorSet4(data, 0, left, positive, top, layer);
		vectorSet4(data, 1, middle, positive, top, layer);
		vectorSet4(data, 2, right, positive, top, layer);
		vectorSet4(data, 3, left, positive, middle, layer);
		vectorSet4(data, 4, middle, positive, middle, layer);
		vectorSet4(data, 5, right, positive, middle, layer);
		vectorSet4(data, 6, left, positive, bottom, layer);
		vectorSet4(data, 7, middle, positive, bottom, layer);
		vectorSet4(data, 8, right, positive, bottom, layer);
		break;
	case 3:
		vectorSet4(data, 0, left, negative, top, layer);
		vectorSet4(data, 1, middle, negative, top, layer);
		vectorSet4(data, 2, right, negative, top, layer);
		vectorSet4(data, 3, left, negative, middle, layer);
		vectorSet4(data, 4, middle, negative, middle, layer);
		vectorSet4(data, 5, right, negative, middle, layer);
		vectorSet4(data, 6, left, negative, bottom, layer);
		vectorSet4(data, 7, middle, negative, bottom, layer);
		vectorSet4(data, 8, right, negative, bottom, layer);
		break;
	case 4:
		vectorSet4(data, 0, left, top, positive, layer);
		vectorSet4(data, 1, middle, top, positive, layer);
		vectorSet4(data, 2, right, top, positive, layer);
		vectorSet4(data, 3, left, middle, positive, layer);
		vectorSet4(data, 4, middle, middle, positive, layer);
		vectorSet4(data, 5, right, middle, positive, layer);
		vectorSet4(data, 6, left, bottom, positive, layer);
		vectorSet4(data, 7, middle, bottom, positive, layer);
		vectorSet4(data, 8, right, bottom, positive, layer);
		break;
	case 5:
		vectorSet4(data, 0, left, top, negative, layer);
		vectorSet4(data, 1, middle, top, negative, layer);
		vectorSet4(data, 2, right, top, negative, layer);
		vectorSet4(data, 3, left, middle, negative, layer);
		vectorSet4(data, 4, middle, middle, negative, layer);
		vectorSet4(data, 5, right, middle, negative, layer);
		vectorSet4(data, 6, left, bottom, negative, layer);
		vectorSet4(data, 7, middle, bottom, negative, layer);
		vectorSet4(data, 8, right, bottom, negative, layer);
		break;
	}

	vectorNormalize<3, 4>(data, 0);
	vectorNormalize<3, 4>(data, 1);
	vectorNormalize<3, 4>(data, 2);
	vectorNormalize<3, 4>(data, 3);
	vectorNormalize<3, 4>(data, 4);
	vectorNormalize<3, 4>(data, 5);
	vectorNormalize<3, 4>(data, 6);
	vectorNormalize<3, 4>(data, 7);
	vectorNormalize<3, 4>(data, 8);
}

/** Prepare texture's face at given index and level.
 *
 *  @param gl                 GL functions
 *  @param cube_face          Index of cube map's face
 *  @param element_index      Index of element in array
 *  @param mipmap_level       Mipmap level
 *  @param n_elements         Number of elements in array
 *  @param n_mipmap_levels    Number of mipmap levels
 *  @param texture_format     Texture format
 *  @param texture_width      Texture width
 *  @param texture_height     Texture height
 **/
void prepareTextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
						glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
						glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
						glw::GLsizei texture_height)
{
	switch (texture_format)
	{
	case GL_RGBA:
		prepareRGBATextureFace(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, texture_format,
							   texture_type, texture_width, texture_height);
		break;

	case GL_RGBA_INTEGER:
		prepareRGBAIntegerTextureFace(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
									  texture_format, texture_type, texture_width, texture_height);
		break;

	case GL_DEPTH_COMPONENT:
		prepareDepthTextureFace(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, texture_format,
								texture_type, texture_width, texture_height);
		break;

	case GL_STENCIL_INDEX:
		prepareStencilTextureFace(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
								  texture_format, texture_type, texture_width, texture_height);
		break;

	default:
		TCU_FAIL("Not implemented case !");
	}
}

/** Verifies that all pixels rendered for specific face match expectations
 *
 *  @tparam T            Type of image component
 *  @tparam N_Components Number of image components
 *  @tparam Width        Width of single face
 *  @tparam Height       Height of single face
 *
 *  @param data            Rendered data
 *  @param cube_face       Index of face in array
 *  @param expected_values Expected values
 *  @param image_width     Widht of whole image
 **/
template <typename T, unsigned int N_Components, unsigned int Width, unsigned int Height>
bool verifyFace(const T* data, const glw::GLuint cube_face, const T* expected_values, const glw::GLuint image_width)
{
	static const glw::GLuint size_of_pixel = N_Components;

	const glw::GLuint data_face_offset  = N_Components * Width * cube_face;
	const glw::GLuint exp_face_offset   = N_Components * Width * Height * cube_face;
	const glw::GLuint data_size_of_line = image_width * size_of_pixel;
	const glw::GLuint exp_size_of_line  = Width * size_of_pixel;

	for (glw::GLuint y = 0; y < Height; ++y)
	{
		const glw::GLuint data_line_offset = y * data_size_of_line;
		const glw::GLuint exp_line_offset  = y * exp_size_of_line;

		for (glw::GLuint x = 0; x < Width; ++x)
		{
			const glw::GLuint data_pixel_offset = data_line_offset + data_face_offset + x * size_of_pixel;
			const glw::GLuint exp_pixel_offset  = exp_line_offset + exp_face_offset + x * size_of_pixel;

			for (glw::GLuint component = 0; component < N_Components; ++component)
			{
				if (data[data_pixel_offset + component] != expected_values[exp_pixel_offset + component])
				{
					return false;
				}
			}
		}
	}

	return true;
}

/** Verifies that all rendered pixels match expectation
 *
 *  @tparam T            Type of image component
 *  @tparam N_Components Number of image components
 *  @tparam Width        Width of single face
 *  @tparam Height       Height of single face
 *
 *  @param data            Rendered data
 *  @param expected_values Expected values
 *  @param n_layers        Number of elements in array
 **/
template <typename T, unsigned int N_Components, unsigned int Width, unsigned int Height>
bool verifyImage(const T* data, const T* expected_values, const glw::GLuint n_layers)
{
	static const glw::GLuint n_faces = 6;

	const glw::GLuint n_total_faces = n_layers * n_faces;

	for (glw::GLuint face = 0; face < n_total_faces; ++face)
	{
		if (false == verifyFace<T, N_Components, Width, Height>(data, face, expected_values, n_total_faces * Width))
		{
			return false;
		}
	}

	return true;
}

/** Verifies that all rendered pixels match expectation
 *
 *  @tparam T            Type of image component
 *  @tparam N_Components Number of image components
 *  @tparam Width        Width of single face
 *  @tparam Height       Height of single face
 *
 *  @param n_mipmap_levels Number of mipmap levels
 *  @param n_layers        Number of elements in array
 *  @param getComponents   Routine which is used to obtain components
 *  @param data            Rendered data
 **/
template <typename T, unsigned int N_Components, unsigned int Width, unsigned int Height>
bool verifyResultImage(glw::GLuint n_mipmap_levels, glw::GLuint n_layers,
					   void (*getComponents)(glw::GLuint pixel_index, glw::GLint cube_face, glw::GLint layer_index,
											 glw::GLint n_layers, glw::GLint n_mipmap_levels, T* out_components),
					   const glw::GLubyte* data)
{
	const glw::GLuint n_components			= N_Components;
	const glw::GLuint face_width			= Width;
	const glw::GLuint face_height			= Height;
	const glw::GLuint n_pixels_per_face		= face_width * face_height;
	const glw::GLuint n_components_per_face = n_pixels_per_face * n_components;
	const glw::GLuint n_faces				= 6;
	const glw::GLuint n_total_faces			= n_layers * n_faces;
	const glw::GLuint n_total_components	= n_total_faces * n_components_per_face;
	const T*		  result_image			= (const T*)data;

	std::vector<T> expected_values;
	expected_values.resize(n_total_components);

	for (glw::GLuint layer = 0; layer < n_layers; ++layer)
	{
		const glw::GLuint layer_offset = layer * n_faces * n_components_per_face;

		for (glw::GLuint face = 0; face < n_faces; ++face)
		{
			const glw::GLuint face_offset = face * n_components_per_face + layer_offset;

			for (glw::GLuint pixel = 0; pixel < n_pixels_per_face; ++pixel)
			{
				const glw::GLuint pixel_offset = pixel * n_components + face_offset;

				T components[n_components];

				getComponents(pixel, face, layer, n_layers, n_mipmap_levels, components);

				for (glw::GLuint component = 0; component < n_components; ++component)
				{
					const glw::GLuint component_offset = pixel_offset + component;

					expected_values[component_offset] = components[component];
				}
			}
		}
	}

	return verifyImage<T, N_Components, Width, Height>(result_image, &expected_values[0], n_layers);
}

/** Constructor
 *
 * @param context       Test context
 * @param name          Test case's name
 * @param description   Test case's desricption
 **/
TextureCubeMapArraySamplingTest::TextureCubeMapArraySamplingTest(Context& context, const ExtParameters& extParams,
																 const char* name, const char* description)
	: TestCaseBase(context, extParams, name, description)
	, m_framebuffer_object_id(0)
	, compiled_shaders(0)
	, invalid_shaders(0)
	, linked_programs(0)
	, invalid_programs(0)
	, tested_cases(0)
	, failed_cases(0)
	, invalid_type_cases(0)
{
	/* Prepare formats set */
	m_formats.push_back(formatDefinition(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false, Float, "GL_RGBA8"));
	m_formats.push_back(formatDefinition(GL_RGBA32I, GL_RGBA_INTEGER, GL_INT, false, Int, "GL_RGBA32I"));
	m_formats.push_back(formatDefinition(GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, false, UInt, "GL_RGBA32UI"));

	m_formats.push_back(formatDefinition(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false, GL_RGBA8, GL_RGBA,
										 GL_UNSIGNED_BYTE, Depth, "GL_DEPTH_COMPONENT32F"));
	m_formats.push_back(formatDefinition(GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, false, GL_R32UI,
										 GL_RGBA_INTEGER, GL_UNSIGNED_INT, Stencil, "GL_STENCIL_INDEX8"));

	/* Prepare sampling functions set */
	m_functions.push_back(samplingFunctionDefinition(Texture, "Texture"));
	m_functions.push_back(samplingFunctionDefinition(TextureLod, "TextureLod"));
	m_functions.push_back(samplingFunctionDefinition(TextureGrad, "TextureGrad"));
	m_functions.push_back(samplingFunctionDefinition(TextureGather, "TextureGather"));

	/* Prepare mutabilities set */
	m_mutabilities.push_back(true);
	m_mutabilities.push_back(false);

	/* Prepare resolutions set */
	m_resolutions.push_back(resolutionDefinition(64, 64, 18));
	m_resolutions.push_back(resolutionDefinition(117, 117, 6));
	m_resolutions.push_back(resolutionDefinition(256, 256, 6));
	m_resolutions.push_back(resolutionDefinition(173, 173, 12));

	/* Prepare resolutions set for compressed formats */
	m_compressed_resolutions.push_back(resolutionDefinition(8, 8, 12));
	m_compressed_resolutions.push_back(resolutionDefinition(13, 13, 12));
}

/** Check if getActiveUniform and glGetProgramResourceiv returns correct type for cube array samplers.
 *
 *  @param program_id   Program id
 *  @param sampler_name_p Name of sampler
 *  @param sampler_type Expected type of sampler
 *
 *  @return Status. 1st LSB - glGetActiveUniform, second LSB glGetProgramResourceiv, 0 valid, 1 invalid.
 **/
glw::GLuint TextureCubeMapArraySamplingTest::checkUniformAndResourceApi(glw::GLuint		   program_id,
																		const glw::GLchar* sampler_name_p,
																		samplerType		   sampler_type)
{
	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLenum  expected_type				= 0;
	glw::GLuint  index_getActiveUniform		= GL_INVALID_INDEX;
	glw::GLuint  index_getProgramResourceiv = GL_INVALID_INDEX;
	glw::GLenum  props						= GL_TYPE;
	glw::GLuint  result						= 0;
	glw::GLchar* name						= 0;
	glw::GLint   size						= 0;
	glw::GLenum  type_getActiveUniform		= 0;
	glw::GLint   type_getProgramResourceiv  = 0;

	// Get type by getActiveUniform
	gl.getUniformIndices(program_id, 1, &sampler_name_p, &index_getActiveUniform);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformIndices");

	if (GL_INVALID_INDEX == index_getActiveUniform)
	{
		throw tcu::InternalError("glGetUniformIndices: GL_INVALID_INDEX", "", __FILE__, __LINE__);
	}

	gl.getActiveUniform(program_id, index_getActiveUniform, 0, 0, &size, &type_getActiveUniform, name);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveUniform");

	// Get type by gl.getProgramResourceiv
	index_getProgramResourceiv = gl.getProgramResourceIndex(program_id, GL_UNIFORM, sampler_name_p);

	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceIndex");

	if (GL_INVALID_INDEX == index_getProgramResourceiv)
	{
		throw tcu::InternalError("glGetProgramResourceIndex: GL_INVALID_INDEX", "", __FILE__, __LINE__);
	}

	gl.getProgramResourceiv(program_id, GL_UNIFORM, index_getProgramResourceiv, 1, &props, 1, 0,
							&type_getProgramResourceiv);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv");

	// Verification
	switch (sampler_type)
	{
	case Float:
		expected_type = GL_SAMPLER_CUBE_MAP_ARRAY;
		break;
	case Int:
		expected_type = GL_INT_SAMPLER_CUBE_MAP_ARRAY;
		break;
	case UInt:
		expected_type = GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY;
		break;
	case Depth:
		expected_type = GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW;
		break;
	case Stencil:
		expected_type = GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY;
		break;
	}

	if (expected_type != type_getActiveUniform)
	{
		result |= m_get_type_api_status_uniform;
	}
	if (expected_type != (glw::GLuint)type_getProgramResourceiv)
	{
		result |= m_get_type_api_status_program_resource;
	}

	return result;
}

/** Compile shader
 *
 *  @param info Shader info
 **/
void TextureCubeMapArraySamplingTest::compile(shaderDefinition& info)
{
	compiled_shaders += 1;

	if (false == info.compile())
	{
		invalid_shaders += 1;

		logCompilationLog(info);
	}
}

/** Execute compute shader
 *
 *  @param program_id Program id
 *  @param width      Width of result image
 *  @param height     Height of result image
 **/
void TextureCubeMapArraySamplingTest::dispatch(glw::GLuint program_id, glw::GLuint width, glw::GLuint height)
{
	(void)program_id;

	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.dispatchCompute(width, height, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glDispatchCompute call.");
}

/** Execute render call
 *
 *  @param program_id     Program id
 *  @param primitive_type Type of primitive
 *  @param n_vertices     Number of vertices
 **/
void TextureCubeMapArraySamplingTest::draw(glw::GLuint program_id, glw::GLenum primitive_type, glw::GLuint n_vertices,
										   glw::GLenum format)
{
	(void)program_id;

	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	const glw::GLenum framebuffer_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
	if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status)
	{
		throw tcu::InternalError("Framebuffer is incomplete", "", __FILE__, __LINE__);
	}

	switch (format)
	{
	case GL_RGBA32I:
	{
		const glw::GLint clearValue[4] = { 255, 255, 255, 255 };
		gl.clearBufferiv(GL_COLOR, 0, clearValue);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearBufferiv call.");
	}
	break;
	case GL_RGBA32UI:
	case GL_R32UI:
	{
		const glw::GLuint clearValue[4] = { 255, 255, 255, 255 };
		gl.clearBufferuiv(GL_COLOR, 0, clearValue);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearBufferuiv call.");
	}
	break;
	case GL_DEPTH_COMPONENT32F:
		gl.clearDepthf(1.0f);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearDepthf call.");
		break;
	case GL_STENCIL_INDEX8:
		gl.clearStencil(1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearStencil call.");
		break;

	default:
		gl.clearColor(1.0f, 1.0f, 1.0f, 1.0f);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearColor call.");

		gl.clear(GL_COLOR_BUFFER_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClear call.");
	}

	gl.drawArrays(primitive_type, 0, n_vertices);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glDrawArrays call.");
}

/** Get attributes specific for type of sampler
 *
 *  @param sampler_type              Type of sampler
 *  @param out_attribute_definitions Array of attributes
 *  @param out_n_attributes          Number of attributes
 **/
void TextureCubeMapArraySamplingTest::getAttributes(samplerType					sampler_type,
													const attributeDefinition*& out_attribute_definitions,
													glw::GLuint&				out_n_attributes)
{
	static attributeDefinition depth_attributes[] = { { attribute_refZ, type_float, RefZ, 1 } };

	static const glw::GLuint n_depth_attributes = sizeof(depth_attributes) / sizeof(depth_attributes[0]);

	switch (sampler_type)
	{
	case Depth:
		out_attribute_definitions = depth_attributes;
		out_n_attributes		  = n_depth_attributes;
		break;
	default:
		out_attribute_definitions = 0;
		out_n_attributes		  = 0;
		break;
	}
}

/** Get attributes specific for sampling function
 *
 *  @param sampling_function         Sampling function
 *  @param out_attribute_definitions Array of attributes
 *  @param out_n_attributes          Number of attributes
 **/
void TextureCubeMapArraySamplingTest::getAttributes(samplingFunction			sampling_function,
													const attributeDefinition*& out_attribute_definitions,
													glw::GLuint&				out_n_attributes)
{
	static attributeDefinition texture_attributes[] = { { attribute_texture_coordinate, type_vec4, TextureCoordinates,
														  0 } };

	static attributeDefinition textureLod_attributes[] = {
		{ attribute_texture_coordinate, type_vec4, TextureCoordinates, 0 }, { attribute_lod, type_float, Lod, 1 }
	};

	static attributeDefinition textureGrad_attributes[] = { { attribute_texture_coordinate, type_vec4,
															  TextureCoordinates, 0 },
															{ attribute_grad_x, type_vec3, GradX, 1 },
															{ attribute_grad_y, type_vec3, GradY, 2 } };

	static attributeDefinition textureGather_attributes[] = { { attribute_texture_coordinate, type_vec4,
																TextureCoordinatesForGather, 0 } };

	static const glw::GLuint n_texture_attributes	= sizeof(texture_attributes) / sizeof(texture_attributes[0]);
	static const glw::GLuint n_textureLod_attributes = sizeof(textureLod_attributes) / sizeof(textureLod_attributes[0]);
	static const glw::GLuint n_textureGrad_attributes =
		sizeof(textureGrad_attributes) / sizeof(textureGrad_attributes[0]);
	static const glw::GLuint n_textureGather_attributes =
		sizeof(textureGather_attributes) / sizeof(textureGather_attributes[0]);

	switch (sampling_function)
	{
	case Texture:
		out_attribute_definitions = texture_attributes;
		out_n_attributes		  = n_texture_attributes;
		break;
	case TextureLod:
		out_attribute_definitions = textureLod_attributes;
		out_n_attributes		  = n_textureLod_attributes;
		break;
	case TextureGrad:
		out_attribute_definitions = textureGrad_attributes;
		out_n_attributes		  = n_textureGrad_attributes;
		break;
	case TextureGather:
		out_attribute_definitions = textureGather_attributes;
		out_n_attributes		  = n_textureGather_attributes;
		break;
	}
}

/** Get information about color type for type of sampler
 *
 *  @param sampler_type           Type of sampler
 *  @param out_color_type         Type used for color storage
 *  @param out_interpolation_type Type of interpolation
 *  @param out_sampler_type       Type of sampler
 *  @param out_n_components       Number of components in color
 *  @param out_is_shadow          If shadow sampler
 **/
void TextureCubeMapArraySamplingTest::getColorType(samplerType sampler_type, const glw::GLchar*& out_color_type,
												   const glw::GLchar*& out_interpolation_type,
												   const glw::GLchar*& out_sampler_type, glw::GLuint& out_n_components,
												   bool& out_is_shadow)
{
	switch (sampler_type)
	{
	case Float:
		out_color_type		   = type_vec4;
		out_interpolation_type = "";
		out_sampler_type	   = sampler_float;
		out_n_components	   = 4;
		out_is_shadow		   = false;
		break;
	case Int:
		out_color_type		   = type_ivec4;
		out_interpolation_type = interpolation_flat;
		out_sampler_type	   = sampler_int;
		out_n_components	   = 4;
		out_is_shadow		   = false;
		break;
	case UInt:
		out_color_type		   = type_uvec4;
		out_interpolation_type = interpolation_flat;
		out_sampler_type	   = sampler_uint;
		out_n_components	   = 4;
		out_is_shadow		   = false;
		break;
	case Depth:
		out_color_type		   = type_float;
		out_interpolation_type = "";
		out_sampler_type	   = sampler_depth;
		out_n_components	   = 1;
		out_is_shadow		   = true;
		break;
	case Stencil:
		out_color_type		   = type_uint;
		out_interpolation_type = interpolation_flat;
		out_sampler_type	   = sampler_uint;
		out_n_components	   = 1;
		out_is_shadow		   = false;
		break;
	}
}

/** Get information about color type for type of sampler
 *
 *  @param sampler_type           Type of sampler
 *  @param out_color_type         Type used for color storage
 *  @param out_interpolation_type Type of interpolation
 *  @param out_sampler_type       Type of sampler
 *  @param out_image_type         Type of image
 *  @param out_n_components       Number of components in color
 *  @param out_is_shadow          If shadow sampler
 **/
void TextureCubeMapArraySamplingTest::getColorType(samplerType sampler_type, const glw::GLchar*& out_color_type,
												   const glw::GLchar*& out_interpolation_type,
												   const glw::GLchar*& out_sampler_type,
												   const glw::GLchar*& out_image_type,
												   const glw::GLchar*& out_image_layout, glw::GLuint& out_n_components,
												   bool& out_is_shadow)
{
	getColorType(sampler_type, out_color_type, out_interpolation_type, out_sampler_type, out_n_components,
				 out_is_shadow);

	switch (sampler_type)
	{
	case Float:
		out_image_type   = image_float;
		out_image_layout = "rgba8";
		break;
	case Depth:
		out_image_type   = image_float;
		out_image_layout = "rgba8";
		break;
	case Int:
		out_image_type   = image_int;
		out_image_layout = "rgba32i";
		break;
	case UInt:
		out_image_type   = image_uint;
		out_image_layout = "rgba32ui";
		break;
	case Stencil:
		out_image_type   = image_uint;
		out_image_layout = "r32ui";
		break;
	}
}

/** Prepare code for passthrough fragment shader
 *
 *  @param sampler_type             Type of sampler
 *  @param out_fragment_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getPassThroughFragmentShaderCode(samplerType  sampler_type,
																	   std::string& out_fragment_shader_code)
{
	std::stringstream  stream;
	const glw::GLchar* color_type;
	const glw::GLchar* interpolation_type;
	const glw::GLchar* ignored_sampler_type;
	glw::GLuint		   ignored_n_components;
	bool			   ignored_is_shadow;

	/* Get type for color variables */
	getColorType(sampler_type, color_type, interpolation_type, ignored_sampler_type, ignored_n_components,
				 ignored_is_shadow);

	/* Preamble */
	stream << shader_code_preamble << shader_precision << "/* Pass through fragment shader */" << std::endl;

	/* in vec4 fs_in_color */
	stream << interpolation_type << shader_input << color_type << fragment_shader_input << ";" << std::endl;

	stream << std::endl;

	/* layout(location = 0) out vec4 fs_out_color */
	stream << shader_layout << shader_output << color_type << fragment_shader_output << ";" << std::endl;

	stream << std::endl;

	/* Body */
	stream << fragment_shader_pass_through_body_code << std::endl;

	/* Store result */
	out_fragment_shader_code = stream.str();
}

/** Prepare code for passthrough tesselation control shader
 *
 *  @param sampler_type                        Type of sampler
 *  @param out_tesselation_control_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getPassThroughTesselationControlShaderCode(
	const samplerType& sampler_type, const samplingFunction& sampling_function,
	std::string& out_tesselation_control_shader_code)
{
	std::stringstream		   stream;
	glw::GLuint				   n_routine_attributes			 = 0;
	glw::GLuint				   n_type_attributes			 = 0;
	const attributeDefinition* routine_attribute_definitions = 0;
	const attributeDefinition* type_attribute_definitions	= 0;

	getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
	getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);

	/* Preamble, extension : require  */
	stream << shader_code_preamble << tesselation_shader_extension << shader_precision << std::endl
		   << "/* Passthrough tesselation control shader */" << std::endl;

	/* layout(vertices = 1) out */
	stream << tesselation_control_shader_layout;

	/* in type attribute*/
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_output
			   << routine_attribute_definitions[i].name << "[];" << std::endl;
		stream << shader_output << routine_attribute_definitions[i].type << tesselation_control_shader_output
			   << routine_attribute_definitions[i].name << "[];" << std::endl;
	}
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << shader_input << type_attribute_definitions[i].type << vertex_shader_output
			   << type_attribute_definitions[i].name << "[];" << std::endl;
		stream << shader_output << type_attribute_definitions[i].type << tesselation_control_shader_output
			   << type_attribute_definitions[i].name << "[];" << std::endl;
	}

	/* Body */
	stream << tesselation_control_shader_sampling_body_code;

	/* tcs_out[gl_InvocationID] = vs_out[gl_InvocationID] */
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << "    " << tesselation_control_shader_output << routine_attribute_definitions[i].name
			   << "[gl_InvocationID] = " << vertex_shader_output << routine_attribute_definitions[i].name
			   << "[gl_InvocationID];" << std::endl;
	}

	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << "    " << tesselation_control_shader_output << type_attribute_definitions[i].name
			   << "[gl_InvocationID] = " << vertex_shader_output << type_attribute_definitions[i].name
			   << "[gl_InvocationID];" << std::endl;
	}

	stream << "}" << std::endl << std::endl;

	/* Store result */
	out_tesselation_control_shader_code = stream.str();
}

/** Prepare code for passthrough tesselation evaluation shader
 *
 *  @param sampler_type                           Type of sampler
 *  @param out_tesselation_evaluation_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getPassThroughTesselationEvaluationShaderCode(
	samplerType sampler_type, std::string& out_tesselation_evaluation_shader_code)
{
	const glw::GLchar* color_type			= 0;
	bool			   ignored_is_shadow	= false;
	glw::GLuint		   ignored_n_components = 0;
	const glw::GLchar* ignored_sampler_type = 0;
	const glw::GLchar* interpolation_type   = 0;
	std::stringstream  stream;

	/* Get type for color variables */
	getColorType(sampler_type, color_type, interpolation_type, ignored_sampler_type, ignored_n_components,
				 ignored_is_shadow);

	/* Preamble, extension : require */
	stream << shader_code_preamble << tesselation_shader_extension << shader_precision << std::endl
		   << "/* Pass through tesselation evaluation shader */" << std::endl;

	/* layout(point_mode) in; */
	stream << tesselation_evaluation_shader_layout;

	/* in vec4 tes_in_color[] */
	stream << interpolation_type << shader_input << color_type << tesselation_evaluation_shader_input << "[];"
		   << std::endl;

	stream << std::endl;

	/* out vec4 fs_in_color[] */
	stream << interpolation_type << shader_output << color_type << fragment_shader_input << ";" << std::endl;

	stream << std::endl;

	/* Body */
	stream << tesselation_evaluation_shader_pass_through_body_code << std::endl;

	/* Store result */
	out_tesselation_evaluation_shader_code = stream.str();
}

/** Prepare code for passthrough vertex shader
 *
 *  @param sampler_type           Type of sampler
 *  @param sampling_function      Type of sampling function
 *  @param out_vertex_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getPassThroughVertexShaderCode(const samplerType&		 sampler_type,
																	 const samplingFunction& sampling_function,
																	 std::string&			 out_vertex_shader_code)
{
	glw::GLuint				   n_routine_attributes			 = 0;
	glw::GLuint				   n_type_attributes			 = 0;
	const attributeDefinition* routine_attribute_definitions = 0;
	std::stringstream		   stream;
	const attributeDefinition* type_attribute_definitions = 0;

	/* Get attributes for sampling function */
	getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
	getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);

	/* Preamble */
	stream << shader_code_preamble << "/* Pass through vertex shader */" << std::endl << shader_precision;

	/* in vec4 vs_in_position */
	stream << shader_input << type_vec4 << vertex_shader_input << vertex_shader_position << ";" << std::endl;

	/* in type vs_in_attribute */
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_input
			   << routine_attribute_definitions[i].name << ";" << std::endl;
	}

	/* in float vs_in_refZ */
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << shader_input << type_attribute_definitions[i].type << vertex_shader_input
			   << type_attribute_definitions[i].name << ";" << std::endl;
	}

	stream << std::endl;

	/* out type vs_out_attribute */
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << shader_output << routine_attribute_definitions[i].type << vertex_shader_output
			   << routine_attribute_definitions[i].name << ";" << std::endl;
	}

	/* out float vs_out_refZ */
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << shader_output << type_attribute_definitions[i].type << vertex_shader_output
			   << type_attribute_definitions[i].name << ";" << std::endl;
	}

	stream << std::endl;

	/* Body */
	stream << vertex_shader_body_code;

	/* vs_out = vs_in */
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << "    " << vertex_shader_output << routine_attribute_definitions[i].name << " = "
			   << vertex_shader_input << routine_attribute_definitions[i].name << ";" << std::endl;
	}

	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << "    " << vertex_shader_output << type_attribute_definitions[i].name << " = " << vertex_shader_input
			   << type_attribute_definitions[i].name << ";" << std::endl;
	}

	stream << "}" << std::endl << std::endl;

	/* Store result */
	out_vertex_shader_code = stream.str();
}

/** Prepare code for sampling compute shader
 *
 *  @param sampler_type            Type of sampler
 *  @param sampling_function       Type of sampling function
 *  @param out_compute_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getSamplingComputeShaderCode(const samplerType&	  sampler_type,
																   const samplingFunction& sampling_function,
																   std::string&			   out_compute_shader_code)
{
	const glw::GLchar*		   color_type					 = 0;
	const glw::GLchar*		   image_type_str				 = 0;
	const glw::GLchar*		   image_layout_str				 = 0;
	const glw::GLchar*		   interpolation_type			 = 0;
	bool					   is_shadow_sampler			 = false;
	glw::GLuint				   n_components					 = 0;
	glw::GLuint				   n_routine_attributes			 = 0;
	glw::GLuint				   n_type_attributes			 = 0;
	const attributeDefinition* routine_attribute_definitions = 0;
	const attributeDefinition* type_attribute_definitions	= 0;
	const glw::GLchar*		   sampler_type_str				 = 0;
	std::string				   sampling_code;
	std::stringstream		   stream;

	/* Get attributes for sampling function */
	getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
	getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);

	/* Get type for color variables */
	getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, image_type_str, image_layout_str,
				 n_components, is_shadow_sampler);

	/* Get sampling code */
	if (false == is_shadow_sampler)
	{
		getSamplingFunctionCall(sampling_function, color_type, n_components, compute_shader_param, 0,
								compute_shader_color, 0, sampler_name, sampling_code);
	}
	else
	{
		getShadowSamplingFunctionCall(sampling_function, color_type, n_components, compute_shader_param, 0,
									  compute_shader_color, 0, sampler_name, sampling_code);
	}

	/* Preamble */
	stream << shader_code_preamble << shader_precision << "/* Sampling compute shader */" << std::endl;

	/* uniform samplerType sampler */
	stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;

	/* uniform writeonly image2D image*/
	stream << "layout(" << image_layout_str << ") " << shader_uniform << shader_writeonly << "highp " << image_type_str
		   << image_name << ";" << std::endl;

	/* layout(shared) buffer attribute { type attribute_data[]; }; */
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << compute_shader_layout_binding << routine_attribute_definitions[i].binding << compute_shader_buffer
			   << routine_attribute_definitions[i].name << std::endl;

		stream << "{\n";
		stream << "    " << routine_attribute_definitions[i].type << " " << routine_attribute_definitions[i].name
			   << "_data[];\n";
		stream << "};\n";
	}
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << compute_shader_layout_binding << type_attribute_definitions[i].binding << compute_shader_buffer
			   << type_attribute_definitions[i].name << std::endl;

		stream << "{\n";
		stream << "    " << type_attribute_definitions[i].type << " " << type_attribute_definitions[i].name
			   << "_data[];\n";
		stream << "};\n";
	}

	/* layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in; */
	stream << compute_shader_layout << std::endl;

	/* main + body */
	stream << compute_shader_body;

	/* type cs_attribute = attribute_data[vertex_index] */
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << "    " << routine_attribute_definitions[i].type << compute_shader_param
			   << routine_attribute_definitions[i].name << " = " << routine_attribute_definitions[i].name
			   << "_data[vertex_index];" << std::endl;
	}
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << "    " << type_attribute_definitions[i].type << compute_shader_param
			   << type_attribute_definitions[i].name << " = " << type_attribute_definitions[i].name
			   << "_data[vertex_index];" << std::endl;
	}

	/* type color */
	stream << std::endl << "    " << color_type << compute_shader_color << ";" << std::endl;

	/* color = texture*/
	stream << std::endl << sampling_code << std::endl;
	//stream << std::endl << compute_shader_color << " = vec4(cs_grad_x, 255.0);" << std::endl;

	/* imageStore */
	stream << compute_shader_image_store;
	switch (n_components)
	{
	case 1:
		/* imageStore(image, image_coord, color.r);*/
		if (sampler_type == Depth)
		{
			stream << "vec4(" << compute_shader_color << ")";
		}
		else if (sampler_type == Stencil)
		{
			stream << "uvec4(" << compute_shader_color << ")";
		}
		else
		{
			// unexpected case
			DE_ASSERT(false);
		}
		break;
	case 4:
		/* imageStore(image, image_coord, color);*/
		stream << compute_shader_color;
		break;
	}

	stream << ");\n";

	stream << "}\n" << std::endl;

	out_compute_shader_code = stream.str();
}

/** Prepare code for sampling fragment shader
 *
 *  @param sampler_type             Type of sampler
 *  @param sampling_function        Type of sampling function
 *  @param out_fragment_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getSamplingFragmentShaderCode(const samplerType&		sampler_type,
																	const samplingFunction& sampling_function,
																	std::string&			out_fragment_shader_code)
{
	const glw::GLchar*		   color_type					 = 0;
	const glw::GLchar*		   interpolation_type			 = 0;
	bool					   is_shadow_sampler			 = false;
	glw::GLuint				   n_components					 = 0;
	glw::GLuint				   n_routine_attributes			 = 0;
	glw::GLuint				   n_type_attributes			 = 0;
	const attributeDefinition* routine_attribute_definitions = 0;
	const attributeDefinition* type_attribute_definitions	= 0;
	const glw::GLchar*		   sampler_type_str				 = 0;
	std::string				   sampling_code;
	std::stringstream		   stream;

	/* Get attributes for sampling function */
	getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
	getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);

	/* Get type for color variables */
	getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);

	/* Get sampling code */
	if (false == is_shadow_sampler)
	{
		getSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, 0,
								fragment_shader_output, 0, sampler_name, sampling_code);
	}
	else
	{
		getShadowSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, 0,
									  fragment_shader_output, 0, sampler_name, sampling_code);
	}

	/* Preamble */
	stream << shader_code_preamble << shader_precision << "/* Sampling fragment shader */" << std::endl;

	/* uniform samplerType sampler */
	stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;

	stream << std::endl;

	/* in type attribute */
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_output
			   << routine_attribute_definitions[i].name << ";" << std::endl;
	}
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << shader_input << type_attribute_definitions[i].type << vertex_shader_output
			   << type_attribute_definitions[i].name << ";" << std::endl;
	}

	stream << std::endl;

	/* layout(location = 0) out vec4 fs_out_color */
	stream << shader_layout << shader_output << color_type << fragment_shader_output << ";" << std::endl;

	stream << std::endl;

	/* Body */
	stream << fragment_shader_sampling_body_code;

	/* Sampling code */
	stream << sampling_code;

	stream << "}" << std::endl << std::endl;

	/* Store result */
	out_fragment_shader_code = stream.str();
}

/** Prepare sampling code
 *
 *  @param sampling_function     Type of sampling function
 *  @param color_type            Type of color
 *  @param n_components          Number of components
 *  @param attribute_name_prefix Prefix for attributes
 *  @param attribute_index       Index for attributes
 *  @param color_variable_name   Name of color variable
 *  @param color_variable_index  Index for color variable
 *  @param sampler_name_p        Name of sampler
 *  @param out_code              Result code
 **/
void TextureCubeMapArraySamplingTest::getSamplingFunctionCall(samplingFunction   sampling_function,
															  const glw::GLchar* color_type, glw::GLuint n_components,
															  const glw::GLchar* attribute_name_prefix,
															  const glw::GLchar* attribute_index,
															  const glw::GLchar* color_variable_name,
															  const glw::GLchar* color_variable_index,
															  const glw::GLchar* sampler_name_p, std::string& out_code)
{
	std::stringstream stream;

	switch (sampling_function)
	{
	case Texture:
		/* fs_in_color = texture(sampler, vs_out_texture_coordinates); */
		stream << "    " << var2str(0, color_variable_name, color_variable_index);

		stream << " = " << texture_func << "(" << sampler_name_p;

		stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index);

		if (1 == n_components)
		{
			stream << ").x;" << std::endl;
		}
		else
		{
			stream << ");" << std::endl;
		}
		break;

	case TextureLod:
		/* fs_in_color = textureLod(sampler, vs_out_texture_coordinates, lod); */
		stream << "    " << var2str(0, color_variable_name, color_variable_index);
		stream << " = " << textureLod_func << "(" << sampler_name_p;

		stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
			   << var2str(attribute_name_prefix, attribute_lod, attribute_index);

		if (1 == n_components)
		{
			stream << ").x;" << std::endl;
		}
		else
		{
			stream << ");" << std::endl;
		}
		break;

	case TextureGrad:
		/* fs_in_color = textureGrad(sampler, vs_out_texture_coordinates, vs_out_grad_x, vs_out_grad_y); */
		stream << "    " << var2str(0, color_variable_name, color_variable_index);

		stream << " = " << textureGrad_func << "(" << sampler_name_p;

		stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
			   << var2str(attribute_name_prefix, attribute_grad_x, attribute_index) << ", "
			   << var2str(attribute_name_prefix, attribute_grad_y, attribute_index);

		if (1 == n_components)
		{
			stream << ").x;" << std::endl;
		}
		else
		{
			stream << ");" << std::endl;
		}
		break;

	case TextureGather:
		if (4 == n_components)
		{
			/**
			 *  color_type component_0 = textureGather(sampler, vs_out_texture_coordinates, 0);
			 *  color_type component_1 = textureGather(sampler, vs_out_texture_coordinates, 1);
			 *  color_type component_2 = textureGather(sampler, vs_out_texture_coordinates, 2);
			 *  color_type component_3 = textureGather(sampler, vs_out_texture_coordinates, 3);
			 *  fs_in_color = color_type(component_0.r, component_1.g, component_2.b, component_3.a);
			 **/
			for (glw::GLuint i = 0; i < 4; ++i)
			{
				stream << "    " << color_type << "component_" << i << " = " << textureGather_func << "("
					   << sampler_name_p;

				stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index);

				stream << ", " << i << ");" << std::endl;
			}

			stream << "    " << var2str(0, color_variable_name, color_variable_index);

			stream << " = " << color_type << "(component_0.r, "
				   << "component_1.g, "
				   << "component_2.b, "
				   << "component_3.a);" << std::endl;
		}
		else
		{
			stream << "    " << var2str(0, color_variable_name, color_variable_index);

			stream << " = " << textureGather_func << "(" << sampler_name_p;

			stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index);

			stream << ").x;" << std::endl;
		}
		break;
	}

	out_code = stream.str();
}

/** Prepare code for sampling geometry shader
 *
 *  @param sampler_type             Type of sampler
 *  @param sampling_function        Type of sampling function
 *  @param out_geometry_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getSamplingGeometryShaderCode(const samplerType&		sampler_type,
																	const samplingFunction& sampling_function,
																	std::string&			out_geometry_shader_code)
{
	const glw::GLchar*		   color_type					 = 0;
	const glw::GLchar*		   interpolation_type			 = 0;
	bool					   is_shadow_sampler			 = false;
	glw::GLuint				   n_components					 = 0;
	glw::GLuint				   n_routine_attributes			 = 0;
	glw::GLuint				   n_type_attributes			 = 0;
	const attributeDefinition* routine_attribute_definitions = 0;
	const attributeDefinition* type_attribute_definitions	= 0;
	const glw::GLchar*		   sampler_type_str				 = 0;
	std::string				   sampling_code;
	std::stringstream		   stream;

	/* Get attributes for sampling function */
	getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
	getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);

	/* Get type for color variables */
	getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);

	/* Get sampling code */
	if (false == is_shadow_sampler)
	{
		getSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, "0",
								fragment_shader_input, 0, sampler_name, sampling_code);
	}
	else
	{
		getShadowSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, "0",
									  fragment_shader_input, 0, sampler_name, sampling_code);
	}

	/* Preamble, extension : require  */
	stream << shader_code_preamble << geometry_shader_extension << shader_precision << std::endl
		   << "/* Sampling geometry shader */" << std::endl;

	/* In out layout */
	stream << geometry_shader_layout;

	/* uniform samplerType sampler */
	stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;

	stream << std::endl;

	/* in type attribute[]*/
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_output
			   << routine_attribute_definitions[i].name << "[];" << std::endl;
	}
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << shader_input << type_attribute_definitions[i].type << vertex_shader_output
			   << type_attribute_definitions[i].name << "[];" << std::endl;
	}

	stream << std::endl;

	/* out vec4 fs_in_color */
	stream << interpolation_type << shader_output << color_type << fragment_shader_input << ";" << std::endl;

	stream << std::endl;

	/* Body */
	stream << geometry_shader_sampling_body_code;

	/* Sampling code */
	stream << sampling_code;

	stream << geometry_shader_emit_vertex_code << std::endl;

	/* Store result */
	out_geometry_shader_code = stream.str();
}

/** Prepare code for sampling tesselation control shader
 *
 *  @param sampler_type                        Type of sampler
 *  @param sampling_function                   Type of sampling function
 *  @param out_tesselation_control_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getSamplingTesselationControlShaderCode(
	const samplerType& sampler_type, const samplingFunction& sampling_function,
	std::string& out_tesselation_control_shader_code)
{
	const glw::GLchar*		   color_type					 = 0;
	const glw::GLchar*		   interpolation_type			 = 0;
	bool					   is_shadow_sampler			 = false;
	glw::GLuint				   n_components					 = 0;
	glw::GLuint				   n_routine_attributes			 = 0;
	glw::GLuint				   n_type_attributes			 = 0;
	const attributeDefinition* routine_attribute_definitions = 0;
	const attributeDefinition* type_attribute_definitions	= 0;
	const glw::GLchar*		   sampler_type_str				 = 0;
	std::string				   sampling_code;
	std::stringstream		   stream;

	/* Get attributes for sampling function */
	getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
	getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);

	/* Get type for color variables */
	getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);

	/* Get sampling code */
	if (false == is_shadow_sampler)
	{
		getSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, "gl_InvocationID",
								tesselation_evaluation_shader_input, "gl_InvocationID", sampler_name, sampling_code);
	}
	else
	{
		getShadowSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output,
									  "gl_InvocationID", tesselation_evaluation_shader_input, "gl_InvocationID",
									  sampler_name, sampling_code);
	}

	/* Preamble, extension : require  */
	stream << shader_code_preamble << tesselation_shader_extension << shader_precision << std::endl
		   << "/* Sampling tesselation control shader */" << std::endl;

	/* layout(vertices = 1) out */
	stream << tesselation_control_shader_layout;

	/* uniform samplerType sampler */
	stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;

	stream << std::endl;

	/* in type attribute[]*/
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_output
			   << routine_attribute_definitions[i].name << "[];" << std::endl;
	}
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << shader_input << type_attribute_definitions[i].type << vertex_shader_output
			   << type_attribute_definitions[i].name << "[];" << std::endl;
	}

	stream << std::endl;

	/* out vec4 tes_in_color */
	stream << interpolation_type << shader_output << color_type << tesselation_evaluation_shader_input << "[];"
		   << std::endl;

	stream << std::endl;

	/* Body */
	stream << tesselation_control_shader_sampling_body_code;

	/* Sampling code */
	stream << sampling_code;

	stream << "}" << std::endl << std::endl;

	/* Store result */
	out_tesselation_control_shader_code = stream.str();
}

/** Prepare code for sampling tesselation evaluation shader
 *
 *  @param sampler_type                           Type of sampler
 *  @param sampling_function                      Type of sampling function
 *  @param out_tesselation_evaluation_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getSamplingTesselationEvaluationShaderCode(
	const samplerType& sampler_type, const samplingFunction& sampling_function,
	std::string& out_tesselation_evaluation_shader_code)
{
	const glw::GLchar*		   color_type					 = 0;
	const glw::GLchar*		   interpolation_type			 = 0;
	bool					   is_shadow_sampler			 = false;
	glw::GLuint				   n_components					 = 0;
	glw::GLuint				   n_routine_attributes			 = 0;
	glw::GLuint				   n_type_attributes			 = 0;
	const attributeDefinition* routine_attribute_definitions = 0;
	const attributeDefinition* type_attribute_definitions	= 0;
	const glw::GLchar*		   sampler_type_str				 = 0;
	std::string				   sampling_code;
	std::stringstream		   stream;
	const glw::GLchar*		   prev_stage_output = (glu::isContextTypeES(m_context.getRenderContext().getType())) ?
											   tesselation_control_shader_output :
											   vertex_shader_output;

	/* Get attributes for sampling function */
	getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
	getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);

	/* Get type for color variables */
	getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);

	/* Get sampling code */
	if (false == is_shadow_sampler)
	{
		getSamplingFunctionCall(sampling_function, color_type, n_components, prev_stage_output, "0",
								fragment_shader_input, 0, sampler_name, sampling_code);
	}
	else
	{
		getShadowSamplingFunctionCall(sampling_function, color_type, n_components, prev_stage_output, "0",
									  fragment_shader_input, 0, sampler_name, sampling_code);
	}

	/* Preamble, extension : require */
	stream << shader_code_preamble << tesselation_shader_extension << shader_precision << std::endl
		   << "/* Sampling tesselation evaluation shader */" << std::endl;

	/* layout(point_mode) in; */
	stream << tesselation_evaluation_shader_layout;

	/* uniform samplerType sampler */
	stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;

	stream << std::endl;

	/* in type attribute[]*/
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << shader_input << routine_attribute_definitions[i].type << prev_stage_output
			   << routine_attribute_definitions[i].name << "[];" << std::endl;
	}
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << shader_input << type_attribute_definitions[i].type << prev_stage_output
			   << type_attribute_definitions[i].name << "[];" << std::endl;
	}

	stream << std::endl;

	/* out vec4 tes_in_color */
	stream << interpolation_type << shader_output << color_type << fragment_shader_input << ";" << std::endl;

	stream << std::endl;

	/* Body */
	stream << tesselation_evaluation_shader_sampling_body_code;

	/* Sampling code */
	stream << sampling_code;

	stream << "}" << std::endl << std::endl;

	/* Store result */
	out_tesselation_evaluation_shader_code = stream.str();
}

/** Prepare code for sampling vertex shader
 *
 *  @param sampler_type           Type of sampler
 *  @param sampling_function      Type of sampling function
 *  @param out_vertex_shader_code Storage for code
 **/
void TextureCubeMapArraySamplingTest::getSamplingVertexShaderCode(const samplerType&	  sampler_type,
																  const samplingFunction& sampling_function,
																  std::string&			  out_vertex_shader_code)
{
	const glw::GLchar*		   color_type					 = 0;
	const glw::GLchar*		   interpolation_type			 = 0;
	bool					   is_shadow_sampler			 = false;
	glw::GLuint				   n_components					 = 0;
	glw::GLuint				   n_routine_attributes			 = 0;
	glw::GLuint				   n_type_attributes			 = 0;
	const attributeDefinition* routine_attribute_definitions = 0;
	const attributeDefinition* type_attribute_definitions	= 0;
	const glw::GLchar*		   sampler_type_str				 = 0;
	std::string				   sampling_code;
	std::stringstream		   stream;

	/* Get attributes for sampling function */
	getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
	getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);

	/* Get type for color variables */
	getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);

	/* Get sampling code */
	if (false == is_shadow_sampler)
	{
		getSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_input, 0,
								fragment_shader_input, 0, sampler_name, sampling_code);
	}
	else
	{
		getShadowSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_input, 0,
									  fragment_shader_input, 0, sampler_name, sampling_code);
	}

	/* Preamble */
	stream << shader_code_preamble << shader_precision << "/* Sampling vertex shader */" << std::endl;

	/* uniform samplerType sampler */
	stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;

	stream << std::endl;

	/* in vec4 vs_in_position */
	stream << shader_input << type_vec4 << vertex_shader_input << vertex_shader_position << ";" << std::endl;

	/* in type attribute */
	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_input
			   << routine_attribute_definitions[i].name << ";" << std::endl;
	}
	for (glw::GLuint i = 0; i < n_type_attributes; ++i)
	{
		stream << shader_input << type_attribute_definitions[i].type << vertex_shader_input
			   << type_attribute_definitions[i].name << ";" << std::endl;
	}

	stream << std::endl;

	/* out vec4 fs_in_color; */
	stream << interpolation_type << shader_output << color_type << fragment_shader_input << ";" << std::endl;

	stream << std::endl;

	/* Body */
	stream << vertex_shader_body_code;

	/* Sampling code */
	stream << sampling_code;

	stream << "}" << std::endl << std::endl;

	/* Store result */
	out_vertex_shader_code = stream.str();
}

/** Prepare shadow sampling code
 *
 *  @param sampling_function     Type of sampling function
 *  @param color_type            Type of color
 *  @param n_components          Number of components
 *  @param attribute_name_prefix Prefix for attributes
 *  @param attribute_index       Index for attributes
 *  @param color_variable_name   Name of color variable
 *  @param color_variable_index  Index for color variable
 *  @param sampler_name_p        Name of sampler
 *  @param out_code              Result code
 **/
void TextureCubeMapArraySamplingTest::getShadowSamplingFunctionCall(
	samplingFunction sampling_function, const glw::GLchar* color_type, glw::GLuint n_components,
	const glw::GLchar* attribute_name_prefix, const glw::GLchar* attribute_index,
	const glw::GLchar* color_variable_name, const glw::GLchar* color_variable_index, const glw::GLchar* sampler_name_p,
	std::string& out_code)
{
	std::stringstream stream;

	switch (sampling_function)
	{
	case Texture:
		/* fs_in_color = texture(sampler, vs_out_texture_coordinates); */
		stream << "    " << var2str(0, color_variable_name, color_variable_index);

		stream << " = " << texture_func << "(" << sampler_name_p;

		stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
			   << var2str(attribute_name_prefix, attribute_refZ, attribute_index);

		stream << ");" << std::endl;
		break;
	case TextureLod:
		/* fs_in_color = textureLod(sampler, vs_out_texture_coordinates, lod); */
		stream << "    " << var2str(0, color_variable_name, color_variable_index);

		stream << " = " << textureLod_func << "(" << sampler_name_p;

		stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
			   << var2str(attribute_name_prefix, attribute_lod, attribute_index) << ", "
			   << var2str(attribute_name_prefix, attribute_refZ, attribute_index);

		stream << ");" << std::endl;
		break;
	case TextureGrad:
		/* fs_in_color = textureGrad(sampler, vs_out_texture_coordinates, vs_out_grad_x, vs_out_grad_y); */
		throw tcu::NotSupportedError("textureGrad operation is not available for samplerCubeArrayShadow", "", __FILE__,
									 __LINE__);
	case TextureGather:
		if (4 == n_components)
		{
			/**
			 *  color_type component_0 = textureGather(sampler, vs_out_texture_coordinates, 0);
			 *  color_type component_1 = textureGather(sampler, vs_out_texture_coordinates, 1);
			 *  color_type component_2 = textureGather(sampler, vs_out_texture_coordinates, 2);
			 *  color_type component_3 = textureGather(sampler, vs_out_texture_coordinates, 3);
			 *  fs_in_color = color_type(component_0.r, component_1.g, component_2.b, component_3.a);
			 **/
			for (glw::GLuint i = 0; i < 4; ++i)
			{
				stream << "    " << color_type << "component_" << i;

				stream << " = " << textureGather_func << "(" << sampler_name_p;

				stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
					   << var2str(attribute_name_prefix, attribute_refZ, attribute_index);

				stream << ");" << std::endl;
			}

			stream << "    " << var2str(0, color_variable_name, color_variable_index);

			stream << " = " << color_type << "(component_0.r, "
				   << "component_1.g, "
				   << "component_2.b, "
				   << "component_3.a);" << std::endl;
		}
		else
		{
			stream << "    " << var2str(0, color_variable_name, color_variable_index);

			stream << " = " << textureGather_func << "(" << sampler_name_p;

			stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
				   << var2str(attribute_name_prefix, attribute_refZ, attribute_index);

			stream << ").x;" << std::endl;
		}
		break;
	}

	out_code = stream.str();
}

/** Check if combination of sampler type and sampling function is supported
 *
 *  @param sampler_type      Type of sampler
 *  @param sampling_function Type of sampling function
 *
 *  @return true  When supported
 *          false When not supported
 **/
bool TextureCubeMapArraySamplingTest::isSamplerSupportedByFunction(const samplerType	  sampler_type,
																   const samplingFunction sampling_function)
{
	if ((Depth == sampler_type) && ((TextureLod == sampling_function) || (TextureGrad == sampling_function)))
	{
		return false;
	}

	return true;
}

/** Executes the test.
 *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
 *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
 *  Note the function throws exception should an error occur!
 **/
tcu::TestNode::IterateResult TextureCubeMapArraySamplingTest::iterate()
{
#if TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION

	for (resolutionsVectorType::iterator resolution		= m_compressed_resolutions.begin(),
										 end_resolution = m_compressed_resolutions.end();
		 end_resolution != resolution; ++resolution)
	{
		prepareDumpForTextureCompression(*resolution);
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	return STOP;

#else  /* TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION */

	if (false == m_is_texture_cube_map_array_supported)
	{
		throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

	// These shader stages are always supported
	m_shaders.push_back(shaderConfiguration(Compute, GL_POINTS, "Compute"));
	m_shaders.push_back(shaderConfiguration(Fragment, GL_POINTS, "Fragment"));
	m_shaders.push_back(shaderConfiguration(Vertex, GL_POINTS, "Vertex"));

	// Check if geometry shader is supported
	if (true == m_is_geometry_shader_extension_supported)
	{
		m_shaders.push_back(shaderConfiguration(Geometry, GL_POINTS, "Geometry"));
	}

	// Check if tesselation shaders are supported
	if (true == m_is_tessellation_shader_supported)
	{
		m_shaders.push_back(shaderConfiguration(Tesselation_Control, m_glExtTokens.PATCHES, "Tesselation_Control"));
		m_shaders.push_back(
			shaderConfiguration(Tesselation_Evaluation, m_glExtTokens.PATCHES, "Tesselation_Evaluation"));
	}

	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genFramebuffers(1, &m_framebuffer_object_id);

	if (true == m_is_tessellation_shader_supported)
	{
		gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 1);
	}

	gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);

	testFormats(m_formats, m_resolutions);
	testFormats(m_compressed_formats, m_compressed_resolutions);

	if (true == m_is_tessellation_shader_supported)
	{
		gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 3);
	}

	gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4);

	gl.deleteFramebuffers(1, &m_framebuffer_object_id);
	m_framebuffer_object_id = 0;

	m_testCtx.getLog() << tcu::TestLog::Section("Summary", "");
	if ((0 != failed_cases) || (0 != invalid_type_cases))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! Number of found errors: " << failed_cases
						   << tcu::TestLog::EndMessage;

		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid shaders: " << invalid_shaders
						   << tcu::TestLog::EndMessage;

		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid programs: " << invalid_programs
						   << tcu::TestLog::EndMessage;

		m_testCtx.getLog() << tcu::TestLog::Message
						   << "glGetActiveUniform or glGetProgramResourceiv reported invalid type: "
						   << invalid_type_cases << tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
	}
	else
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}

	m_testCtx.getLog() << tcu::TestLog::Message << "Number of executed test cases: " << tested_cases
					   << tcu::TestLog::EndMessage;

	m_testCtx.getLog() << tcu::TestLog::Message << "Total shaders: " << compiled_shaders << tcu::TestLog::EndMessage;

	m_testCtx.getLog() << tcu::TestLog::Message << "Total programs: " << linked_programs << tcu::TestLog::EndMessage;

	m_testCtx.getLog() << tcu::TestLog::EndSection;

	return STOP;
#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION */
}

/** Link program
 *
 *  @param info Program information
 **/
void TextureCubeMapArraySamplingTest::link(programDefinition& info)
{
	linked_programs += 1;

	/* Not supported format */
	if (programDefinition::m_invalid_program_object_id == info.getProgramId())
	{
		return;
	}

	if (false == info.link())
	{
		invalid_programs += 1;

		logLinkingLog(info);
		logProgram(info);
	}
}

/** Logs compilation log
 *
 *  @param info Shader information
 **/
void TextureCubeMapArraySamplingTest::logCompilationLog(const shaderDefinition& info)
{
	std::string info_log = getCompilationInfoLog(info.getShaderId());
	m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failure:\n\n"
					   << info_log << tcu::TestLog::EndMessage;
	m_testCtx.getLog() << tcu::TestLog::Message << "Shader source:\n\n" << info.getSource() << tcu::TestLog::EndMessage;
}

/** Logs linkig log
 *
 *  @param info Program information
 **/
void TextureCubeMapArraySamplingTest::logLinkingLog(const programDefinition& info)
{
	glw::GLuint program_object_id = info.getProgramId();

	if (programDefinition::m_invalid_program_object_id == program_object_id)
	{
		return;
	}

	std::string info_log = getLinkingInfoLog(program_object_id);
	m_testCtx.getLog() << tcu::TestLog::Message << "Program linking failure:\n\n"
					   << info_log << tcu::TestLog::EndMessage;
}

/** Logs shaders used by program
 *
 *  @param info Program information
 **/
void TextureCubeMapArraySamplingTest::logProgram(const programDefinition& info)
{
	glw::GLuint program_object_id = info.getProgramId();

	if (programDefinition::m_invalid_program_object_id == program_object_id)
	{
		return;
	}

	tcu::MessageBuilder message = m_testCtx.getLog() << tcu::TestLog::Message;

	message << "Program id: " << program_object_id;

	const shaderDefinition* compute  = info.getShader(Compute);
	const shaderDefinition* fragment = info.getShader(Fragment);
	const shaderDefinition* geometry = info.getShader(Geometry);
	const shaderDefinition* tcs		 = info.getShader(Tesselation_Control);
	const shaderDefinition* tes		 = info.getShader(Tesselation_Evaluation);
	const shaderDefinition* vertex   = info.getShader(Vertex);

	if (0 != compute)
	{
		message << "\nCompute shader:\n" << compute->getSource();
	}

	if (0 != vertex)
	{
		message << "\nVertex shader:\n" << vertex->getSource();
	}

	if (0 != geometry)
	{
		message << "\nGeometry shader:\n" << geometry->getSource();
	}

	if (0 != tcs)
	{
		message << "\nTCS shader:\n" << tcs->getSource();
	}

	if (0 != tes)
	{
		message << "\nTES shader:\n" << tes->getSource();
	}

	if (0 != fragment)
	{
		message << "\nFragment shader:\n" << fragment->getSource();
	}

	message << tcu::TestLog::EndMessage;
}

/** Prepare compressed textures
 *
 *  @param texture    Texture information
 *  @param format     Texture format
 *  @param resolution Texture resolution
 *  @param mutability Texture mutability
 **/
void TextureCubeMapArraySamplingTest::prepareCompresedTexture(const textureDefinition&	texture,
															  const formatDefinition&	 format,
															  const resolutionDefinition& resolution, bool mutability)
{
	static const glw::GLint n_faces = 6;

	const glw::GLint array_length	= resolution.m_depth / n_faces;
	const glw::GLint n_mipmap_levels = getMipmapLevelCount(resolution.m_width, resolution.m_height);
	glw::GLsizei	 texture_width   = 0;
	glw::GLsizei	 texture_height  = 0;

	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	texture.bind(GL_TEXTURE_CUBE_MAP_ARRAY);

	if (false == mutability)
	{
		gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, n_mipmap_levels, format.m_source.m_internal_format,
						resolution.m_width, resolution.m_height, resolution.m_depth);

		GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage3D");

		texture_width  = resolution.m_width;
		texture_height = resolution.m_height;

		for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
		{
			const glw::GLubyte* image_data = 0;
			glw::GLuint			image_size = 0;

			getCompressedTexture(resolution.m_width, resolution.m_height, array_length, mipmap_level, image_data,
								 image_size);

			if (0 == image_data)
			{
				throw tcu::InternalError("Invalid compressed texture", "", __FILE__, __LINE__);
			}

			gl.compressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipmap_level, 0, /* x_offset */
									   0,										   /* y offset */
									   0,										   /* z offset */
									   texture_width, texture_height, resolution.m_depth,
									   format.m_source.m_internal_format, image_size, image_data);

			GLU_EXPECT_NO_ERROR(gl.getError(), "compressedTexSubImage3D");

			texture_width  = de::max(1, texture_width / 2);
			texture_height = de::max(1, texture_height / 2);
		}
	}
	else
	{
		texture_width  = resolution.m_width;
		texture_height = resolution.m_height;

		for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
		{
			const glw::GLubyte* image_data = 0;
			glw::GLuint			image_size = 0;

			getCompressedTexture(resolution.m_width, resolution.m_height, array_length, mipmap_level, image_data,
								 image_size);

			if (0 == image_data)
			{
				throw tcu::InternalError("Invalid compressed texture", "", __FILE__, __LINE__);
			}

			gl.compressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipmap_level, format.m_source.m_internal_format,
									texture_width, texture_height, resolution.m_depth, 0 /* border */, image_size,
									image_data);

			GLU_EXPECT_NO_ERROR(gl.getError(), "compressedTexImage3D");

			texture_width  = de::max(1, texture_width / 2);
			texture_height = de::max(1, texture_height / 2);
		}
	}
}

/** Prepare not comporessed textures
 *
 *  @param texture    Texture information
 *  @param format     Texture format
 *  @param resolution Texture resolution
 *  @param mutability Texture mutability
 **/
void TextureCubeMapArraySamplingTest::prepareTexture(const textureDefinition&	texture,
													 const formatDefinition&	 texture_format,
													 const resolutionDefinition& resolution, bool mutability)
{
	static const glw::GLint n_faces = 6;

	const glw::GLint n_elements		 = resolution.m_depth / n_faces;
	const glw::GLint n_mipmap_levels = getMipmapLevelCount(resolution.m_width, resolution.m_height);
	glw::GLsizei	 texture_width   = 0;
	glw::GLsizei	 texture_height  = 0;

	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	texture.bind(GL_TEXTURE_CUBE_MAP_ARRAY);

	if (false == mutability)
	{
		gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, n_mipmap_levels, texture_format.m_source.m_internal_format,
						resolution.m_width, resolution.m_height, resolution.m_depth);
	}
	else
	{
		texture_width  = resolution.m_width;
		texture_height = resolution.m_height;

		for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
		{
			gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipmap_level, texture_format.m_source.m_internal_format,
						  texture_width, texture_height, resolution.m_depth, 0 /* border */,
						  texture_format.m_source.m_format, texture_format.m_source.m_type, 0 /* data */);

			texture_width  = de::max(1, texture_width / 2);
			texture_height = de::max(1, texture_height / 2);
		}
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to allocate storage for texture");

	texture_width  = resolution.m_width;
	texture_height = resolution.m_height;

	for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
	{
		for (glw::GLint element_index = 0; element_index < n_elements; ++element_index)
		{
			for (glw::GLint face = 0; face < n_faces; ++face)
			{
				prepareTextureFace(gl, face, element_index, mipmap_level, n_elements, n_mipmap_levels,
								   texture_format.m_source.m_format, texture_format.m_source.m_type, texture_width,
								   texture_height);
			}
		}

		texture_width  = de::max(1, texture_width / 2);
		texture_height = de::max(1, texture_height / 2);
	}

	// not texture filterable formats
	if ((texture_format.m_source.m_internal_format == GL_RGBA32UI) ||
		(texture_format.m_source.m_internal_format == GL_RGBA32I) ||
		(texture_format.m_source.m_internal_format == GL_STENCIL_INDEX8) ||
		(texture_format.m_source.m_internal_format == GL_DEPTH_COMPONENT32F))
	{
		gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
	}
}

/** Setup shader storabe buffer for use with compute shader
 *
 *  @param attribute  Attribute information
 *  @param buffers    Collection of buffers
 *  @param program_id Program id
 **/
void TextureCubeMapArraySamplingTest::setupSharedStorageBuffer(const attributeDefinition& attribute,
															   const bufferCollection& buffers, glw::GLuint program_id)
{
	(void)program_id;

	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	std::string				attribute_name = attribute.name;
	const bufferDefinition* buffer		   = 0;

	switch (attribute.attribute_id)
	{
	case Position:
		buffer = &buffers.postion;
		break;
	case TextureCoordinates:
		buffer = &buffers.texture_coordinate;
		break;
	case TextureCoordinatesForGather:
		buffer = &buffers.texture_coordinate_for_gather;
		break;
	case Lod:
		buffer = &buffers.lod;
		break;
	case GradX:
		buffer = &buffers.grad_x;
		break;
	case GradY:
		buffer = &buffers.grad_y;
		break;
	case RefZ:
		buffer = &buffers.refZ;
		break;
	}

	buffer->bind(GL_SHADER_STORAGE_BUFFER, attribute.binding);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup shared storage block");
}

/** Setup shader storabe buffers for use with compute shader
 *
 *  @param format            Texture format
 *  @param sampling_function Sampling routine
 *  @param buffers           Collection of buffers
 *  @param program_id        Program id
 **/
void TextureCubeMapArraySamplingTest::setupSharedStorageBuffers(const formatDefinition& format,
																const samplingFunction& sampling_function,
																const bufferCollection& buffers, glw::GLuint program_id)
{
	const attributeDefinition* format_attributes	= 0;
	glw::GLuint				   n_format_attributes  = 0;
	glw::GLuint				   n_routine_attributes = 0;
	const attributeDefinition* routine_attributes   = 0;

	getAttributes(format.m_sampler_type, format_attributes, n_format_attributes);
	getAttributes(sampling_function, routine_attributes, n_routine_attributes);

	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		setupSharedStorageBuffer(routine_attributes[i], buffers, program_id);
	}

	for (glw::GLuint i = 0; i < n_format_attributes; ++i)
	{
		setupSharedStorageBuffer(format_attributes[i], buffers, program_id);
	}
}

/** Execute tests for set of formats and resolutions
 *
 *  @param formats     Set of texture formats
 *  @param resolutions Set of texture resolutions
 **/
void TextureCubeMapArraySamplingTest::testFormats(formatsVectorType& formats, resolutionsVectorType& resolutions)
{
	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	for (formatsVectorType::iterator format = formats.begin(), end_format = formats.end(); end_format != format;
		 ++format)
	{
		shaderCollectionForTextureFormat shader_collection;
		programCollectionForFormat		 program_collection;

		shader_collection.init(gl, *format, m_functions, *this);
		bool isContextES = (glu::isContextTypeES(m_context.getRenderContext().getType()));
		program_collection.init(gl, shader_collection, *this, isContextES);

		for (mutablitiesVectorType::iterator mutability = m_mutabilities.begin(), end_muatbility = m_mutabilities.end();
			 end_muatbility != mutability; ++mutability)
		{
			for (resolutionsVectorType::iterator resolution = resolutions.begin(), end_resolution = resolutions.end();
				 end_resolution != resolution; ++resolution)
			{
				textureDefinition texture;
				texture.init(gl);

				try
				{
					if (false == format->m_source.m_is_compressed)
					{
						prepareTexture(texture, *format, *resolution, *mutability);
					}
					else
					{
						prepareCompresedTexture(texture, *format, *resolution, *mutability);
					}
				}
#if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG
				catch (std::exception& exc)
				{
					m_testCtx.getLog() << tcu::TestLog::Section("Exception during texture creation", exc.what());

					m_testCtx.getLog() << tcu::TestLog::Message << "Format: " << format->m_name
									   << ", Mutability: " << *mutability << ", W: " << resolution->m_width
									   << ", H: " << resolution->m_height << tcu::TestLog::EndMessage;

					m_testCtx.getLog() << tcu::TestLog::EndSection;
#else  /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */
				catch (...)
				{
#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */
					continue;
				}

				testTexture(*format, *mutability, *resolution, texture, program_collection);
			}
		}
	}
}

/** Execute tests for given texture
 *
 *  @param format             Texture format
 *  @param mutability         Texture mutabilibty
 *  @param resolution         Texture resolution
 *  @param texture            Textue information
 *  @param shader_collection  Collection of shaders
 *  @param program_collection Collection of programs
 **/
void TextureCubeMapArraySamplingTest::testTexture(const formatDefinition& format, bool mutability,
												  const resolutionDefinition& resolution, textureDefinition& texture,
												  programCollectionForFormat& program_collection)
{
	std::vector<unsigned char> result_image;

	const glw::GLuint image_width  = 3 * resolution.m_depth;
	const glw::GLuint image_height = 3;
	const glw::GLuint estimated_image_size =
		static_cast<glw::GLuint>(image_width * image_height * 4 /* components */ * sizeof(glw::GLuint));

	result_image.resize(estimated_image_size);

	/* GL functions */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	bufferCollection buffers;
	buffers.init(gl, format, resolution);

	for (samplingFunctionsVectorType::iterator function = m_functions.begin(), end_function = m_functions.end();
		 end_function != function; ++function)
	{
		for (shadersVectorType::iterator shader = m_shaders.begin(), end_shader = m_shaders.end(); end_shader != shader;
			 ++shader)
		{
			const programCollectionForFunction* programs		  = 0;
			const programDefinition*			program			  = 0;
			glw::GLuint							program_object_id = programDefinition::m_invalid_program_object_id;
			textureDefinition					color_attachment;

			programs		  = program_collection.getPrograms(function->m_function);
			program			  = programs->getProgram(shader->m_type);
			program_object_id = program->getProgramId();

			if (programDefinition::m_invalid_program_object_id == program_object_id)
			{
				continue;
			}

			tested_cases += 1;

			color_attachment.init(gl);

			if (Compute != shader->m_type)
			{
				setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, color_attachment.getTextureId(),
														format.m_destination.m_internal_format, image_width,
														image_height);
			}
			else
			{
				color_attachment.bind(GL_TEXTURE_2D);
				gl.texStorage2D(GL_TEXTURE_2D, 1, format.m_destination.m_internal_format, image_width, image_height);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
				color_attachment.setupImage(0, format.m_destination.m_internal_format);
			}

			try
			{
				gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
				gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_object_id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");

				gl.useProgram(program_object_id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glUseProgram call.");

				texture.setupSampler(0, sampler_name, program_object_id, format.m_sampler_type == Depth);

				if (Compute != shader->m_type)
				{
					vertexArrayObjectDefinition vao;
					vao.init(gl, format, function->m_function, buffers, program_object_id);
					draw(program_object_id, shader->m_primitive_type, image_width * image_height,
						 format.m_destination.m_internal_format);
				}
				else
				{
					setupSharedStorageBuffers(format, function->m_function, buffers, program_object_id);
					dispatch(program_object_id, image_width, image_height);
				}

				gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
				gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_framebuffer_object_id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");

				color_attachment.bind(GL_TEXTURE_2D);
				gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
										color_attachment.getTextureId(), 0);
				GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");

				gl.viewport(0, 0, 3 * resolution.m_depth, 3);
				GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");

				gl.memoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
				gl.readPixels(0 /* x */, 0 /* y */, image_width, image_height, format.m_destination.m_format,
							  format.m_destination.m_type, &result_image[0]);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");

				/* GL_DEPTH_COMPONENT is nominally R32F, however R32F is not renderable, so we convert to
				 * RGBA8 instead.  Convert the red channel back to R32F for comparison.
				 */
				if (format.m_source.m_format == GL_DEPTH_COMPONENT)
				{
					unsigned char* p = (unsigned char*)&result_image[0];
					float*		   f = (float*)&result_image[0];

					for (unsigned int i = 0; i < image_width * image_height; i++)
					{
						*f = (float)p[0] / 255.0f;
						p += 4;
						f += 1;
					}
				}

				/* GL_STENCIL_INDEX is nominally one-channel format, however ReadPixels supports only RGBA formats.
				 * Convert the RGBA image to R for comparison.
				 */
				if (format.m_source.m_format == GL_STENCIL_INDEX && format.m_destination.m_format == GL_RGBA_INTEGER)
				{
					unsigned int* pRGBA = (unsigned int*)&result_image[0];
					unsigned int* pR	= (unsigned int*)&result_image[0];
					for (unsigned int i = 0; i < image_width * image_height; i++)
					{
						*pR = pRGBA[0];
						pR += 1;
						pRGBA += 4;
					}
				}

				glw::GLuint get_type_api_status =
					checkUniformAndResourceApi(program_object_id, sampler_name, format.m_sampler_type);
				bool verification_result = verifyResult(format, resolution, function->m_function, &result_image[0]);

				if ((true == verification_result) && (0 == get_type_api_status))
				{
#if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_LOG
					m_testCtx.getLog() << tcu::TestLog::Message << "Valid result. "
									   << " Format: " << format.m_name << ", Mutability: " << mutability
									   << ", Sampling shader: " << shader->m_name
									   << ", Sampling function: " << function->m_name << ", W: " << resolution.m_width
									   << ", H: " << resolution.m_height << tcu::TestLog::EndMessage;
#if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_PROGRAM_LOG
					logProgram(*program);
#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_PROGRAM_LOG */
#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_LOG */
				}
				else
				{
#if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG
					m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");

					if (true != verification_result)
					{
						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid image" << tcu::TestLog::EndMessage;
					}

					if (0 != get_type_api_status)
					{
						if (0 != (m_get_type_api_status_uniform & get_type_api_status))
						{
							m_testCtx.getLog() << tcu::TestLog::Message
											   << "glGetActiveUniform returns wrong type for sampler"
											   << tcu::TestLog::EndMessage;
						}

						if (0 != (m_get_type_api_status_program_resource & get_type_api_status))
						{
							m_testCtx.getLog() << tcu::TestLog::Message
											   << "glGetProgramResourceiv returns wrong type for sampler"
											   << tcu::TestLog::EndMessage;
						}
					}

					m_testCtx.getLog() << tcu::TestLog::Message << "Format: " << format.m_name
									   << ", Mutability: " << mutability << ", Sampling shader: " << shader->m_name
									   << ", Sampling function: " << function->m_name << ", W: " << resolution.m_width
									   << ", H: " << resolution.m_height << tcu::TestLog::EndMessage;

#if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG
					logProgram(*program);
#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG */

					m_testCtx.getLog() << tcu::TestLog::EndSection;
#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */

					if (false == verification_result)
					{
						failed_cases += 1;
					}

					if (0 != get_type_api_status)
					{
						invalid_type_cases += 1;
					}
				}
			}
#if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG
			catch (std::exception& exc)
			{
				m_testCtx.getLog() << tcu::TestLog::Section("Exception during test execution", exc.what());

				m_testCtx.getLog() << tcu::TestLog::Message << "Format: " << format.m_name
								   << ", Mutability: " << mutability << ", W: " << resolution.m_width
								   << ", H: " << resolution.m_height << tcu::TestLog::EndMessage;

#if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG
				logProgram(*program);
#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG */

				m_testCtx.getLog() << tcu::TestLog::EndSection;
#else  /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */
			catch (...)
			{
#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */

				failed_cases += 1;
			}
			//run()
		}
	}
}

/** Verify that rendered image match expectations
 *
 *  @param format            Texture format
 *  @param resolution        Texture resolution
 *  @param shader_type       Shader type
 *  @param sampling_function Type of sampling function
 *  @param data              Image data
 **/
bool TextureCubeMapArraySamplingTest::verifyResult(const formatDefinition&	 format,
												   const resolutionDefinition& resolution,
												   const samplingFunction sampling_function, unsigned char* data)
{
	componentProvider component_provider = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };

	switch (sampling_function)
	{
	case Texture:
	case TextureGather:
		component_provider.getColorFloatComponents = getExpectedColorFloatComponentsForTexture;
		component_provider.getColorUByteComponents = getExpectedColorIntComponentsForTexture<glw::GLubyte>;
		component_provider.getColorUintComponents  = getExpectedColorIntComponentsForTexture<glw::GLuint>;
		component_provider.getColorIntComponents   = getExpectedColorIntComponentsForTexture<glw::GLint>;
		component_provider.getDepthComponents	  = getExpectedDepthComponentsForTexture;
		component_provider.getStencilComponents	= getExpectedStencilComponentsForTexture;
		component_provider.getCompressedComponents = getExpectedCompressedComponentsForTexture;
		break;
	case TextureLod:
	case TextureGrad:
		component_provider.getColorFloatComponents = getExpectedColorFloatComponentsForTextureLod;
		component_provider.getColorUByteComponents = getExpectedColorIntComponentsForTextureLod<glw::GLubyte>;
		component_provider.getColorUintComponents  = getExpectedColorIntComponentsForTextureLod<glw::GLuint>;
		component_provider.getColorIntComponents   = getExpectedColorIntComponentsForTextureLod<glw::GLint>;
		component_provider.getDepthComponents	  = getExpectedDepthComponentsForTextureLod;
		component_provider.getStencilComponents	= getExpectedStencilComponentsForTextureLod;
		component_provider.getCompressedComponents = getExpectedCompressedComponentsForTextureLod;
		break;
	}

	return verifyResultHelper(format, resolution, component_provider, data);
}

/** Verify that rendered image match expectations
 *
 *  @param format            Texture format
 *  @param resolution        Texture resolution
 *  @param shader_type       Shader type
 *  @param sampling_function Type of sampling function
 *  @param data              Image data
 **/
bool TextureCubeMapArraySamplingTest::verifyResultHelper(const formatDefinition&	 format,
														 const resolutionDefinition& resolution,
														 const componentProvider&	component_provider,
														 unsigned char*				 data)
{
	const glw::GLuint n_mipmap_levels = getMipmapLevelCount(resolution.m_width, resolution.m_height);
	const glw::GLuint n_layers		  = resolution.m_depth / 6;

	bool result = false;

	if (GL_RGBA == format.m_source.m_format)
	{
		if (GL_UNSIGNED_BYTE == format.m_source.m_type)
		{
			result = verifyResultImage<glw::GLubyte, 4, 3, 3>(n_mipmap_levels, n_layers,
															  component_provider.getColorUByteComponents, data);
		}
		else if (GL_FLOAT == format.m_source.m_type)
		{
			result = verifyResultImage<glw::GLfloat, 4, 3, 3>(n_mipmap_levels, n_layers,
															  component_provider.getColorFloatComponents, data);
		}
		else if (GL_COMPRESSED_RGBA8_ETC2_EAC == format.m_source.m_type)
		{
			result = verifyResultImage<glw::GLubyte, 4, 3, 3>(n_mipmap_levels, n_layers,
															  component_provider.getCompressedComponents, data);
		}
	}
	else if (GL_RGBA_INTEGER == format.m_source.m_format)
	{
		if (GL_UNSIGNED_INT == format.m_source.m_type)
		{
			result = verifyResultImage<glw::GLuint, 4, 3, 3>(n_mipmap_levels, n_layers,
															 component_provider.getColorUintComponents, data);
		}
		else if (GL_INT == format.m_source.m_type)
		{
			result = verifyResultImage<glw::GLint, 4, 3, 3>(n_mipmap_levels, n_layers,
															component_provider.getColorIntComponents, data);
		}
	}
	if (GL_DEPTH_COMPONENT == format.m_source.m_format)
	{
		if (GL_FLOAT == format.m_source.m_type)
		{
			result = verifyResultImage<glw::GLfloat, 1, 3, 3>(n_mipmap_levels, n_layers,
															  component_provider.getDepthComponents, data);
		}
	}
	if (GL_STENCIL_INDEX == format.m_source.m_format)
	{
		if (GL_UNSIGNED_BYTE == format.m_source.m_type)
		{
			result = verifyResultImage<glw::GLuint, 1, 3, 3>(n_mipmap_levels, n_layers,
															 component_provider.getStencilComponents, data);
		}
	}

	return result;
}

/****************************************************************************/

/** Initialize buffer collection
 *
 *  @param gl         GL functions
 *  @param format     Texture format
 *  @param resolution Texture resolution
 **/
void TextureCubeMapArraySamplingTest::bufferCollection::init(const glw::Functions& gl, const formatDefinition& format,
															 const resolutionDefinition& resolution)
{
	(void)format;

	static const glw::GLuint n_faces						  = 6;
	static const glw::GLuint n_lods_components				  = 1;
	static const glw::GLuint n_grad_components				  = 4;
	static const glw::GLuint n_points_per_face				  = 9;
	static const glw::GLuint n_position_components			  = 4;
	static const glw::GLuint n_refZ_components				  = 1;
	static const glw::GLuint n_texture_coordinates_components = 4;

	const glw::GLuint n_layers = resolution.m_depth / n_faces;

	const glw::GLuint n_points_per_layer = n_points_per_face * n_faces;
	const glw::GLuint n_total_points	 = n_points_per_layer * n_layers;

	const glw::GLuint n_position_step_per_face			  = n_position_components * n_points_per_face;
	const glw::GLuint n_texture_coordinates_step_per_face = n_texture_coordinates_components * n_points_per_face;
	const glw::GLuint n_lods_step_per_face				  = n_lods_components * n_points_per_face;
	const glw::GLuint n_grad_step_per_face				  = n_grad_components * n_points_per_face;
	const glw::GLuint n_refZ_step_per_face				  = n_refZ_components * n_points_per_face;

	const glw::GLuint n_position_step_per_layer			   = n_faces * n_position_step_per_face;
	const glw::GLuint n_texture_coordinates_step_per_layer = n_faces * n_texture_coordinates_step_per_face;
	const glw::GLuint n_lods_step_per_layer				   = n_faces * n_lods_step_per_face;
	const glw::GLuint n_grad_step_per_layer				   = n_faces * n_grad_step_per_face;
	const glw::GLuint n_refZ_step_per_layer				   = n_faces * n_refZ_step_per_face;

	const glw::GLuint texture_width	= resolution.m_width;
	const glw::GLuint texture_height   = resolution.m_height;
	const glw::GLuint n_mip_map_levels = getMipmapLevelCount(texture_width, texture_height);

	std::vector<glw::GLfloat> position_buffer_data;
	std::vector<glw::GLfloat> texture_coordinate_buffer_data;
	std::vector<glw::GLfloat> texture_coordinate_for_gather_buffer_data;
	std::vector<glw::GLfloat> lod_buffer_data;
	std::vector<glw::GLfloat> grad_x_buffer_data;
	std::vector<glw::GLfloat> grad_y_buffer_data;
	std::vector<glw::GLfloat> refZ_buffer_data;

	position_buffer_data.resize(n_total_points * n_position_components);
	texture_coordinate_buffer_data.resize(n_total_points * n_texture_coordinates_components);
	texture_coordinate_for_gather_buffer_data.resize(n_total_points * n_texture_coordinates_components);
	lod_buffer_data.resize(n_total_points * n_lods_components);
	grad_x_buffer_data.resize(n_total_points * n_grad_components);
	grad_y_buffer_data.resize(n_total_points * n_grad_components);
	refZ_buffer_data.resize(n_total_points * n_refZ_components);

	/* Prepare data */
	for (glw::GLuint layer = 0; layer < n_layers; ++layer)
	{
		const glw::GLfloat layer_coordinate = (float)layer;

		for (glw::GLuint face = 0; face < n_faces; ++face)
		{
			/* Offsets */
			const glw::GLuint position_offset = layer * n_position_step_per_layer + face * n_position_step_per_face;
			const glw::GLuint texture_coordinates_offset =
				layer * n_texture_coordinates_step_per_layer + face * n_texture_coordinates_step_per_face;
			const glw::GLuint lods_offset = layer * n_lods_step_per_layer + face * n_lods_step_per_face;
			const glw::GLuint grad_offset = layer * n_grad_step_per_layer + face * n_grad_step_per_face;
			const glw::GLuint refZ_offset = layer * n_refZ_step_per_layer + face * n_refZ_step_per_face;

			/* Prepare data */
			preparePositionForFace(&position_buffer_data[0] + position_offset, face, layer, n_layers * n_faces);
			prepareTextureCoordinatesForFace(&texture_coordinate_buffer_data[0] + texture_coordinates_offset,
											 texture_width, texture_height, layer_coordinate, face);
			prepareTextureCoordinatesForGatherForFace(&texture_coordinate_for_gather_buffer_data[0] +
														  texture_coordinates_offset,
													  texture_width, texture_height, layer_coordinate, face);
			prepareLodForFace(&lod_buffer_data[0] + lods_offset, n_mip_map_levels);
			prepareGradXForFace(&grad_x_buffer_data[0] + grad_offset, face,
								&texture_coordinate_buffer_data[0] + texture_coordinates_offset, texture_width);
			prepareGradYForFace(&grad_y_buffer_data[0] + grad_offset, face,
								&texture_coordinate_buffer_data[0] + texture_coordinates_offset, texture_width);
			prepareRefZForFace(&refZ_buffer_data[0] + refZ_offset, n_mip_map_levels, face, layer, n_layers);
		}
	}

	/* Initialize buffers */
	postion.init(gl, (glw::GLsizeiptr)(position_buffer_data.size() * sizeof(glw::GLfloat)), &position_buffer_data[0]);
	texture_coordinate.init(gl, (glw::GLsizeiptr)(texture_coordinate_buffer_data.size() * sizeof(glw::GLfloat)),
							&texture_coordinate_buffer_data[0]);
	texture_coordinate_for_gather.init(
		gl, (glw::GLsizeiptr)(texture_coordinate_for_gather_buffer_data.size() * sizeof(glw::GLfloat)),
		&texture_coordinate_for_gather_buffer_data[0]);
	lod.init(gl, (glw::GLsizeiptr)(lod_buffer_data.size() * sizeof(glw::GLfloat)), &lod_buffer_data[0]);
	grad_x.init(gl, (glw::GLsizeiptr)(grad_x_buffer_data.size() * sizeof(glw::GLfloat)), &grad_x_buffer_data[0]);
	grad_y.init(gl, (glw::GLsizeiptr)(grad_y_buffer_data.size() * sizeof(glw::GLfloat)), &grad_y_buffer_data[0]);
	refZ.init(gl, (glw::GLsizeiptr)(refZ_buffer_data.size() * sizeof(glw::GLfloat)), &refZ_buffer_data[0]);
}

/** Constructor.
 *
 **/
TextureCubeMapArraySamplingTest::bufferDefinition::bufferDefinition()
	: m_gl(0), m_buffer_object_id(m_invalid_buffer_object_id)
{
}

/** Destructor
 *
 **/
TextureCubeMapArraySamplingTest::bufferDefinition::~bufferDefinition()
{
	if (m_invalid_buffer_object_id != m_buffer_object_id)
	{
		if (0 != m_gl)
		{
			m_gl->deleteBuffers(1, &m_buffer_object_id);

			m_gl = 0;
		}

		m_buffer_object_id = m_invalid_buffer_object_id;
	}
}

/** Bind buffer
 *
 *  @param target Target for bind
 **/
void TextureCubeMapArraySamplingTest::bufferDefinition::bind(glw::GLenum target) const
{
	if (m_invalid_buffer_object_id == m_buffer_object_id)
	{
		throw tcu::InternalError("Invalid buffer object id used", "", __FILE__, __LINE__);
	}

	m_gl->bindBuffer(target, m_buffer_object_id);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind buffer.");
}

/** Bind buffer
 *
 *  @param target Target for bind
 *  @param index  Index for target
 **/
void TextureCubeMapArraySamplingTest::bufferDefinition::bind(glw::GLenum target, glw::GLuint index) const
{
	if (m_invalid_buffer_object_id == m_buffer_object_id)
	{
		throw tcu::InternalError("Invalid buffer object id used", "", __FILE__, __LINE__);
	}

	m_gl->bindBufferBase(target, index, m_buffer_object_id);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind buffer.");
}

/** Initialize buffer definition
 *
 *  @param gl          GL functions
 *  @param buffer_size Size of buffer
 *  @param buffer_data Buffer data
 **/
void TextureCubeMapArraySamplingTest::bufferDefinition::init(const glw::Functions& gl, glw::GLsizeiptr buffer_size,
															 glw::GLvoid* buffer_data)
{
	m_gl = &gl;

	m_gl->genBuffers(1, &m_buffer_object_id);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to generate buffer.");

	m_gl->bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind buffer.");

	m_gl->bufferData(GL_ARRAY_BUFFER, buffer_size, buffer_data, GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to update buffer's data.");

	m_gl->bindBuffer(GL_ARRAY_BUFFER, 0);
	m_gl->getError();
}

/** Constructor
 *
 *  @param internal_format Internal format
 *  @param format          Format
 *  @param type            Type
 *  @param is_compressed   If format is compressed
 *  @param sampler_type    Type of sampler
 *  @param name            Name of format
 **/
TextureCubeMapArraySamplingTest::formatDefinition::formatDefinition(glw::GLenum internal_format, glw::GLenum format,
																	glw::GLenum type, bool is_compressed,
																	samplerType sampler_type, const glw::GLchar* name)
	: m_source(internal_format, format, type, is_compressed)
	, m_destination(internal_format, format, type, false /* is_compressed*/)
	, m_sampler_type(sampler_type)
	, m_name(name)
{
}

/** Constructor
 *
 *  @param src_internal_format Internal format of source image
 *  @param src_format          Format of source image
 *  @param src_type            Type of source image
 *  @param src_is_compressed   If format of source image is compressed
 *  @param dst_internal_format Internal format of destination image
 *  @param dst_format          Format of destination image
 *  @param dst_type            Type of destination image
 *  @param sampler_type        Type of sampler
 *  @param name                Name of format
 **/
TextureCubeMapArraySamplingTest::formatDefinition::formatDefinition(glw::GLenum src_internal_format,
																	glw::GLenum src_format, glw::GLenum src_type,
																	bool		src_is_compressed,
																	glw::GLenum dst_internal_format,
																	glw::GLenum dst_format, glw::GLenum dst_type,
																	samplerType sampler_type, const glw::GLchar* name)
	: m_source(src_internal_format, src_format, src_type, src_is_compressed)
	, m_destination(dst_internal_format, dst_format, dst_type, false /* is_compressed*/)
	, m_sampler_type(sampler_type)
	, m_name(name)
{
}

/** Constructor
 *
 *  @param internal_format Internal format
 *  @param format          Format
 *  @param type            Type
 *  @param is_compressed   If format is compressed
 **/
TextureCubeMapArraySamplingTest::formatInfo::formatInfo(glw::GLenum internal_format, glw::GLenum format,
														glw::GLenum type, bool is_compressed)
	: m_internal_format(internal_format), m_format(format), m_type(type), m_is_compressed(is_compressed)
{
}

/** Get collection of programs for sampling function
 *
 *  @param function Type of sampling function
 *
 *  @return Collection of programs for given sampling function
 **/
const TextureCubeMapArraySamplingTest::programCollectionForFunction* TextureCubeMapArraySamplingTest::
	programCollectionForFormat::getPrograms(samplingFunction function) const
{
	switch (function)
	{
	case Texture:
		return &m_programs_for_texture;
	case TextureLod:
		return &m_programs_for_textureLod;
	case TextureGrad:
		return &m_programs_for_textureGrad;
	case TextureGather:
		return &m_programs_for_textureGather;
	}

	return 0;
}

/** Initialize program collection for format
 *
 *  @param gl                GL functions
 *  @param shader_collection Collection of shaders
 *  @param test              Instance of test class
 **/
void TextureCubeMapArraySamplingTest::programCollectionForFormat::init(
	const glw::Functions& gl, const shaderCollectionForTextureFormat& shader_collection,
	TextureCubeMapArraySamplingTest& test, bool isContextES)
{
	shaderGroup shader_group;

	shader_collection.getShaderGroup(Texture, shader_group);
	m_programs_for_texture.init(gl, shader_group, test, isContextES);

	shader_collection.getShaderGroup(TextureLod, shader_group);
	m_programs_for_textureLod.init(gl, shader_group, test, isContextES);

	shader_collection.getShaderGroup(TextureGrad, shader_group);
	m_programs_for_textureGrad.init(gl, shader_group, test, isContextES);

	shader_collection.getShaderGroup(TextureGather, shader_group);
	m_programs_for_textureGather.init(gl, shader_group, test, isContextES);
}

/** Get program with specified sampling shader
 *
 *  @param shader_type Type of shader
 *
 *  @returns Program information
 **/
const TextureCubeMapArraySamplingTest::programDefinition* TextureCubeMapArraySamplingTest::
	programCollectionForFunction::getProgram(shaderType shader_type) const
{
	switch (shader_type)
	{
	case Compute:
		return &program_with_sampling_compute_shader;
	case Fragment:
		return &program_with_sampling_fragment_shader;
	case Geometry:
		return &program_with_sampling_geometry_shader;
	case Tesselation_Control:
		return &program_with_sampling_tesselation_control_shader;
	case Tesselation_Evaluation:
		return &program_with_sampling_tesselation_evaluation_shader;
	case Vertex:
		return &program_with_sampling_vertex_shader;
	}

	return 0;
}

/** Initialize program collection for sampling function
 *
 *  @param gl           GL functions
 *  @param shader_group Group of shader compatible with sampling function
 *  @param test         Instance of test class
 **/
void TextureCubeMapArraySamplingTest::programCollectionForFunction::init(const glw::Functions&			  gl,
																		 const shaderGroup&				  shader_group,
																		 TextureCubeMapArraySamplingTest& test,
																		 bool							  isContextES)
{
	program_with_sampling_compute_shader.init(gl, shader_group, Compute, isContextES);
	program_with_sampling_fragment_shader.init(gl, shader_group, Fragment, isContextES);
	program_with_sampling_vertex_shader.init(gl, shader_group, Vertex, isContextES);

	test.link(program_with_sampling_compute_shader);
	test.link(program_with_sampling_fragment_shader);
	test.link(program_with_sampling_vertex_shader);

	if (test.m_is_geometry_shader_extension_supported)
	{
		program_with_sampling_geometry_shader.init(gl, shader_group, Geometry, isContextES);
		test.link(program_with_sampling_geometry_shader);
	}

	if (test.m_is_tessellation_shader_supported)
	{
		program_with_sampling_tesselation_control_shader.init(gl, shader_group, Tesselation_Control, isContextES);
		program_with_sampling_tesselation_evaluation_shader.init(gl, shader_group, Tesselation_Evaluation, isContextES);
		test.link(program_with_sampling_tesselation_control_shader);
		test.link(program_with_sampling_tesselation_evaluation_shader);
	}
}

/** Constructor
 *
 **/
TextureCubeMapArraySamplingTest::programDefinition::programDefinition()
	: compute_shader(0)
	, geometry_shader(0)
	, fragment_shader(0)
	, tesselation_control_shader(0)
	, tesselation_evaluation_shader(0)
	, vertex_shader(0)
	, m_program_object_id(m_invalid_program_object_id)
	, m_gl(DE_NULL)
{
}

/** Destructor
 *
 **/
TextureCubeMapArraySamplingTest::programDefinition::~programDefinition()
{
	if (m_invalid_program_object_id != m_program_object_id)
	{
		if (0 != m_gl)
		{
			m_gl->deleteProgram(m_program_object_id);
			m_program_object_id = m_invalid_program_object_id;
			m_gl				= 0;
		}
	}
}

/** Get program id
 *
 *  @returns Program id
 **/
glw::GLuint TextureCubeMapArraySamplingTest::programDefinition::getProgramId() const
{
	return m_program_object_id;
}

/** Get shader
 *
 *  @param shader_type Requested shader type
 *
 *  @returns Pointer to shader information. Can be null.
 **/
const TextureCubeMapArraySamplingTest::shaderDefinition* TextureCubeMapArraySamplingTest::programDefinition::getShader(
	shaderType shader_type) const
{
	switch (shader_type)
	{
	case Compute:
		return compute_shader;
	case Fragment:
		return fragment_shader;
	case Geometry:
		return geometry_shader;
	case Tesselation_Control:
		return tesselation_control_shader;
	case Tesselation_Evaluation:
		return tesselation_evaluation_shader;
	case Vertex:
		return vertex_shader;
	}

	return 0;
}

/** Initialize program information
 *
 *  @param gl           GL functions
 *  @param shader_group Group of shaders compatible with samplinbg function and texture format
 *  @param shader_type  Stage that will execute sampling
 **/
void TextureCubeMapArraySamplingTest::programDefinition::init(const glw::Functions& gl, const shaderGroup& shader_group,
															  shaderType shader_type, bool isContextES)
{
	m_gl = &gl;

	bool is_program_defined = false;

	switch (shader_type)
	{
	case Compute:
		compute_shader	 = shader_group.sampling_compute_shader;
		is_program_defined = (0 != compute_shader);
		break;
	case Fragment:
		fragment_shader	= shader_group.sampling_fragment_shader;
		vertex_shader	  = shader_group.pass_through_vertex_shader;
		is_program_defined = ((0 != fragment_shader) && (0 != vertex_shader));
		break;
	case Geometry:
		fragment_shader	= shader_group.pass_through_fragment_shader;
		geometry_shader	= shader_group.sampling_geometry_shader;
		vertex_shader	  = shader_group.pass_through_vertex_shader;
		is_program_defined = ((0 != fragment_shader) && (0 != geometry_shader) && (0 != vertex_shader));
		break;
	case Tesselation_Control:
		fragment_shader				  = shader_group.pass_through_fragment_shader;
		tesselation_control_shader	= shader_group.sampling_tesselation_control_shader;
		tesselation_evaluation_shader = shader_group.pass_through_tesselation_evaluation_shader;
		vertex_shader				  = shader_group.pass_through_vertex_shader;
		is_program_defined			  = ((0 != fragment_shader) && (0 != tesselation_control_shader) &&
							  (0 != tesselation_evaluation_shader) && (0 != vertex_shader));
		break;
	case Tesselation_Evaluation:
		fragment_shader = shader_group.pass_through_fragment_shader;
		if (isContextES)
		{
			tesselation_control_shader = shader_group.pass_through_tesselation_control_shader;
		}
		tesselation_evaluation_shader = shader_group.sampling_tesselation_evaluation_shader;
		vertex_shader				  = shader_group.pass_through_vertex_shader;
		is_program_defined			  = ((0 != fragment_shader) && (0 != tesselation_control_shader) &&
							  (0 != tesselation_evaluation_shader) && (0 != vertex_shader));
		break;
	case Vertex:
		fragment_shader	= shader_group.pass_through_fragment_shader;
		vertex_shader	  = shader_group.sampling_vertex_shader;
		is_program_defined = ((0 != fragment_shader) && (0 != vertex_shader));
		break;
	}

	if (true == is_program_defined)
	{
		m_program_object_id = m_gl->createProgram();

		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");

		if (m_invalid_program_object_id == m_program_object_id)
		{
			throw tcu::InternalError("glCreateProgram return invalid id", "", __FILE__, __LINE__);
		}
	}
}

/** Link program
 *
 *  @return  true When linking was successful
 *          false When linking failed
 **/
bool TextureCubeMapArraySamplingTest::programDefinition::link()
{
	if (m_invalid_program_object_id == m_program_object_id)
	{
		return false;
	}

	if (0 != compute_shader)
	{
		compute_shader->attach(m_program_object_id);
	}

	if (0 != geometry_shader)
	{
		geometry_shader->attach(m_program_object_id);
	}

	if (0 != fragment_shader)
	{
		fragment_shader->attach(m_program_object_id);
	}

	if (0 != tesselation_control_shader)
	{
		tesselation_control_shader->attach(m_program_object_id);
	}

	if (0 != tesselation_evaluation_shader)
	{
		tesselation_evaluation_shader->attach(m_program_object_id);
	}

	if (0 != vertex_shader)
	{
		vertex_shader->attach(m_program_object_id);
	}

	/* Link Program */
	m_gl->linkProgram(m_program_object_id);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "glLinkProgram() call failed.");

	/* Check linking status */
	glw::GLint linkStatus = GL_FALSE;
	m_gl->getProgramiv(m_program_object_id, GL_LINK_STATUS, &linkStatus);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "glGetProgramiv() call failed.");

	if (linkStatus == GL_FALSE)
	{
		return false;
	}

	return true;
}

/** Constructor
 *
 *  @param width  Width
 *  @param height Height
 *  @param depth  Depth
 **/
TextureCubeMapArraySamplingTest::resolutionDefinition::resolutionDefinition(glw::GLuint width, glw::GLuint height,
																			glw::GLuint depth)
	: m_width(width), m_height(height), m_depth(depth)
{
}

/** Constructor
 *
 *  @param function Type of sampling function
 *  @param name     Name of sampling function
 **/
TextureCubeMapArraySamplingTest::samplingFunctionDefinition::samplingFunctionDefinition(samplingFunction   function,
																						const glw::GLchar* name)
	: m_function(function), m_name(name)
{
}

/** Initialize shader collection for sampling function
 *
 *  @param gl                GL functions
 *  @param format            Texture format
 *  @param sampling_function Sampling function
 *  @param test              Instance of test class
 **/
void TextureCubeMapArraySamplingTest::shaderCollectionForSamplingRoutine::init(
	const glw::Functions& gl, const formatDefinition& format, const samplingFunction& sampling_function,
	TextureCubeMapArraySamplingTest& test)
{
	m_sampling_function = sampling_function;

	std::string pass_through_vertex_shader_source;
	std::string pass_through_tesselation_control_shader_source;
	std::string sampling_compute_shader_source;
	std::string sampling_fragment_shader_source;
	std::string sampling_geometry_shader_source;
	std::string sampling_tesselation_control_shader_source;
	std::string sampling_tesselation_evaluation_shader_source;
	std::string sampling_vertex_shader_source;

	test.getPassThroughVertexShaderCode(format.m_sampler_type, m_sampling_function, pass_through_vertex_shader_source);

	test.getPassThroughTesselationControlShaderCode(format.m_sampler_type, m_sampling_function,
													pass_through_tesselation_control_shader_source);

	test.getSamplingComputeShaderCode(format.m_sampler_type, m_sampling_function, sampling_compute_shader_source);

	test.getSamplingFragmentShaderCode(format.m_sampler_type, m_sampling_function, sampling_fragment_shader_source);

	test.getSamplingGeometryShaderCode(format.m_sampler_type, m_sampling_function, sampling_geometry_shader_source);

	test.getSamplingTesselationControlShaderCode(format.m_sampler_type, m_sampling_function,
												 sampling_tesselation_control_shader_source);

	test.getSamplingTesselationEvaluationShaderCode(format.m_sampler_type, m_sampling_function,
													sampling_tesselation_evaluation_shader_source);

	test.getSamplingVertexShaderCode(format.m_sampler_type, m_sampling_function, sampling_vertex_shader_source);

	pass_through_vertex_shader.init(gl, GL_VERTEX_SHADER, pass_through_vertex_shader_source, &test);
	sampling_compute_shader.init(gl, GL_COMPUTE_SHADER, sampling_compute_shader_source, &test);
	sampling_fragment_shader.init(gl, GL_FRAGMENT_SHADER, sampling_fragment_shader_source, &test);
	sampling_vertex_shader.init(gl, GL_VERTEX_SHADER, sampling_vertex_shader_source, &test);

	test.compile(pass_through_vertex_shader);
	test.compile(sampling_compute_shader);
	test.compile(sampling_fragment_shader);
	test.compile(sampling_vertex_shader);

	if (test.m_is_tessellation_shader_supported)
	{
		pass_through_tesselation_control_shader.init(gl, test.m_glExtTokens.TESS_CONTROL_SHADER,
													 pass_through_tesselation_control_shader_source, &test);
		sampling_tesselation_control_shader.init(gl, test.m_glExtTokens.TESS_CONTROL_SHADER,
												 sampling_tesselation_control_shader_source, &test);
		sampling_tesselation_evaluation_shader.init(gl, test.m_glExtTokens.TESS_EVALUATION_SHADER,
													sampling_tesselation_evaluation_shader_source, &test);

		test.compile(pass_through_tesselation_control_shader);
		test.compile(sampling_tesselation_control_shader);
		test.compile(sampling_tesselation_evaluation_shader);
	}

	if (test.m_is_geometry_shader_extension_supported)
	{
		sampling_geometry_shader.init(gl, test.m_glExtTokens.GEOMETRY_SHADER, sampling_geometry_shader_source, &test);

		test.compile(sampling_geometry_shader);
	}
}

/** Get group of shader compatible with sampling function and texture format
 *
 *  @param function     Sampling function
 *  @param shader_group Group of shaders
 **/
void TextureCubeMapArraySamplingTest::shaderCollectionForTextureFormat::getShaderGroup(samplingFunction function,
																					   shaderGroup& shader_group) const
{
	shader_group.init();

	for (shaderCollectionForSamplingFunctionVectorType::const_iterator it  = per_sampling_routine.begin(),
																	   end = per_sampling_routine.end();
		 end != it; ++it)
	{
		if (it->m_sampling_function == function)
		{
			shader_group.pass_through_fragment_shader				= &pass_through_fragment_shader;
			shader_group.pass_through_tesselation_control_shader	= &it->pass_through_tesselation_control_shader;
			shader_group.pass_through_tesselation_evaluation_shader = &pass_through_tesselation_evaluation_shader;
			shader_group.pass_through_vertex_shader					= &it->pass_through_vertex_shader;

			shader_group.sampling_compute_shader				= &it->sampling_compute_shader;
			shader_group.sampling_fragment_shader				= &it->sampling_fragment_shader;
			shader_group.sampling_geometry_shader				= &it->sampling_geometry_shader;
			shader_group.sampling_tesselation_control_shader	= &it->sampling_tesselation_control_shader;
			shader_group.sampling_tesselation_evaluation_shader = &it->sampling_tesselation_evaluation_shader;
			shader_group.sampling_vertex_shader					= &it->sampling_vertex_shader;

			return;
		}
	}
}

/** Initialize shader collection for texture format
 *
 *  @param gl                GL functions
 *  @param format            Texture format
 *  @param sampling_routines Set of sampling functions
 *  @param test              Instance of test class
 **/
void TextureCubeMapArraySamplingTest::shaderCollectionForTextureFormat::init(
	const glw::Functions& gl, const formatDefinition& format, const samplingFunctionsVectorType& sampling_routines,
	TextureCubeMapArraySamplingTest& test)
{
	std::string pass_through_fragment_shader_source;
	std::string pass_through_tesselation_evaluation_shader_source;
	glw::GLuint n_routines_supporting_format = 0;

	test.getPassThroughFragmentShaderCode(format.m_sampler_type, pass_through_fragment_shader_source);
	test.getPassThroughTesselationEvaluationShaderCode(format.m_sampler_type,
													   pass_through_tesselation_evaluation_shader_source);

	pass_through_fragment_shader.init(gl, GL_FRAGMENT_SHADER, pass_through_fragment_shader_source, &test);

	if (test.m_is_tessellation_shader_supported)
	{
		pass_through_tesselation_evaluation_shader.init(gl, test.m_glExtTokens.TESS_EVALUATION_SHADER,
														pass_through_tesselation_evaluation_shader_source, &test);
	}

	test.compile(pass_through_fragment_shader);

	if (test.m_is_tessellation_shader_supported)
	{
		test.compile(pass_through_tesselation_evaluation_shader);
	}

	for (samplingFunctionsVectorType::const_iterator it = sampling_routines.begin(), end = sampling_routines.end();
		 end != it; ++it)
	{
		if (TextureCubeMapArraySamplingTest::isSamplerSupportedByFunction(format.m_sampler_type, it->m_function))
		{
			n_routines_supporting_format += 1;
		}
	}

	per_sampling_routine.resize(n_routines_supporting_format);
	shaderCollectionForSamplingFunctionVectorType::iterator jt = per_sampling_routine.begin();

	for (samplingFunctionsVectorType::const_iterator it = sampling_routines.begin(), end = sampling_routines.end();
		 end != it; ++it)
	{
		if (TextureCubeMapArraySamplingTest::isSamplerSupportedByFunction(format.m_sampler_type, it->m_function))
		{
			jt->init(gl, format, it->m_function, test);
			++jt;
		}
	}
}

/** Constructor
 *
 *  @param type           Type of shader
 *  @param is_supported   If configuration is supported
 *  @param primitive_type Type of primitive
 *  @param name           Name of sampling shader stage
 **/
TextureCubeMapArraySamplingTest::shaderConfiguration::shaderConfiguration(shaderType type, glw::GLenum primitive_type,
																		  const glw::GLchar* name)
	: m_type(type), m_primitive_type(primitive_type), m_name(name)
{
}

/** Constructor
 *
 **/
TextureCubeMapArraySamplingTest::shaderDefinition::shaderDefinition()
	: m_gl(0), m_shader_stage(0), m_shader_object_id(m_invalid_shader_object_id)
{
}

/** Destructor
 *
 **/
TextureCubeMapArraySamplingTest::shaderDefinition::~shaderDefinition()
{
	if (m_invalid_shader_object_id != m_shader_object_id)
	{
		if (0 != m_gl)
		{
			m_gl->deleteShader(m_shader_object_id);

			m_gl = 0;
		}

		m_shader_object_id = m_invalid_shader_object_id;
	}

	m_source.clear();
}

/** Attach shade to program
 *
 *  @parma program_object_id Progam id
 **/
void TextureCubeMapArraySamplingTest::shaderDefinition::attach(glw::GLuint program_object_id) const
{
	if (0 == m_gl)
	{
		throw tcu::InternalError("shaderDefinition not initialized", "", __FILE__, __LINE__);
	}

	m_gl->attachShader(program_object_id, m_shader_object_id);

	GLU_EXPECT_NO_ERROR(m_gl->getError(), "glAttachShader() call failed.");
}

/** Compile shader
 *
 *  @returns true  When successful
 *           false When compilation failed
 **/
bool TextureCubeMapArraySamplingTest::shaderDefinition::compile()
{
	glw::GLint		   compile_status = GL_FALSE;
	const glw::GLchar* source		  = m_source.c_str();

	/* Set shaders source */
	m_gl->shaderSource(m_shader_object_id, 1, &source, NULL);

	GLU_EXPECT_NO_ERROR(m_gl->getError(), "glShaderSource() call failed.");

	/* Try to compile the shader */
	m_gl->compileShader(m_shader_object_id);

	GLU_EXPECT_NO_ERROR(m_gl->getError(), "glCompileShader() call failed.");

	/* Check if all shaders compiled successfully */
	m_gl->getShaderiv(m_shader_object_id, GL_COMPILE_STATUS, &compile_status);

	GLU_EXPECT_NO_ERROR(m_gl->getError(), "glGetShaderiv() call failed.");

	if (compile_status == GL_FALSE)
	{
		return false;
	}

	return true;
}

/** Get shader id
 *
 *  @returns Shader id
 **/
glw::GLuint TextureCubeMapArraySamplingTest::shaderDefinition::getShaderId() const
{
	return m_shader_object_id;
}

/** Get source
 *
 *  @returns Code of shader
 **/
const std::string& TextureCubeMapArraySamplingTest::shaderDefinition::getSource() const
{
	return m_source;
}

/** Initialize shader informations
 *
 *  @param gl           GL functions
 *  @param shader_stage Stage of shader
 *  @param source       Source of shader
 **/
void TextureCubeMapArraySamplingTest::shaderDefinition::init(const glw::Functions& gl, glw::GLenum shader_stage,
															 const std::string&				  source,
															 TextureCubeMapArraySamplingTest* test)
{
	m_gl						   = &gl;
	m_shader_stage				   = shader_stage;
	const glw::GLchar* source_cstr = source.c_str();
	m_source					   = test->specializeShader(1, &source_cstr);

	if (m_invalid_shader_object_id == m_shader_object_id)
	{
		if (0 != m_gl)
		{
			m_shader_object_id = m_gl->createShader(m_shader_stage);

			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create shader");

			if (m_invalid_shader_object_id == m_shader_object_id)
			{
				throw tcu::InternalError("glCreateShader returned invalid id", "", __FILE__, __LINE__);
			}
		}
	}
}

/** Initialize shader group
 *
 **/
void TextureCubeMapArraySamplingTest::shaderGroup::init()
{
	pass_through_fragment_shader			   = 0;
	pass_through_tesselation_control_shader	= 0;
	pass_through_tesselation_evaluation_shader = 0;
	pass_through_vertex_shader				   = 0;
	sampling_compute_shader					   = 0;
	sampling_fragment_shader				   = 0;
	sampling_geometry_shader				   = 0;
	sampling_tesselation_control_shader		   = 0;
	sampling_tesselation_evaluation_shader	 = 0;
	sampling_vertex_shader					   = 0;
}

/** Constructor
 *
 **/
TextureCubeMapArraySamplingTest::textureDefinition::textureDefinition()
	: m_gl(0), m_texture_object_id(m_invalid_texture_object_id)
{
}

/** Destructor
 *
 **/
TextureCubeMapArraySamplingTest::textureDefinition::~textureDefinition()
{
	if (m_invalid_texture_object_id != m_texture_object_id)
	{
		if (0 != m_gl)
		{
			m_gl->deleteTextures(1, &m_texture_object_id);

			m_gl = 0;
		}

		m_texture_object_id = m_invalid_texture_object_id;
	}
}

/** Bind texture
 *
 *  @param binding_point Where texture will be bound
 **/
void TextureCubeMapArraySamplingTest::textureDefinition::bind(glw::GLenum binding_point) const
{
	if (0 == m_gl)
	{
		throw tcu::InternalError("TextureDefinition not initialized", "", __FILE__, __LINE__);
	}

	m_gl->bindTexture(binding_point, m_texture_object_id);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind texture");
}

/** Get texture id
 *
 *  @returns Texture id
 **/
glw::GLuint TextureCubeMapArraySamplingTest::textureDefinition::getTextureId() const
{
	return m_texture_object_id;
}

/** Initialize texture information
 *
 *  @param gl         GL functions
 *  @param bind_image Address of glBindImageTexture procedure
 **/
void TextureCubeMapArraySamplingTest::textureDefinition::init(const glw::Functions& gl)
{
	m_gl = &gl;

	gl.genTextures(1, &m_texture_object_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to generate texture");
}

/** Set texture as image
 *
 *  @param image_unit      Index of image unit
 *  @param internal_format Format for image unit
 **/
void TextureCubeMapArraySamplingTest::textureDefinition::setupImage(glw::GLuint image_unit, glw::GLenum internal_format)
{
	if ((0 == m_gl) || (m_invalid_texture_object_id == m_texture_object_id))
	{
		throw tcu::InternalError("Not initialized textureDefinition", "", __FILE__, __LINE__);
	}

	m_gl->bindImageTexture(image_unit, m_texture_object_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, internal_format);

	GLU_EXPECT_NO_ERROR(m_gl->getError(), "glBindImageTexture");
}

/** Setup texture unit with this
 *
 *  @param texture_unit Index of texture unit
 *  @param sampler_name_p Name of sampler uniform
 *  @param program_id   Program id
 *  @param is_shadow    If depth comparison should be enabled
 **/
void TextureCubeMapArraySamplingTest::textureDefinition::setupSampler(glw::GLuint		 texture_unit,
																	  const glw::GLchar* sampler_name_p,
																	  glw::GLuint program_id, bool is_shadow)
{
	if ((0 == m_gl) || (m_invalid_texture_object_id == m_texture_object_id))
	{
		throw tcu::InternalError("Not initialized textureDefinition", "", __FILE__, __LINE__);
	}

	glw::GLint sampler_location = m_gl->getUniformLocation(program_id, sampler_name_p);
	if ((m_invalid_uniform_location == (glw::GLuint)sampler_location) || (GL_NO_ERROR != m_gl->getError()))
	{
		//throw tcu::InternalError("Failed to get sampler location", sampler_name_p, __FILE__, __LINE__);
		return;
	}

	m_gl->activeTexture(GL_TEXTURE0 + texture_unit);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to activate texture unit");

	m_gl->bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_texture_object_id);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind texture to GL_TEXTURE_CUBE_MAP_ARRAY_EXT");

	if (true == is_shadow)
	{
		m_gl->texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
		m_gl->texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
	}

	m_gl->uniform1i(sampler_location, texture_unit);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to set sampler uniform");
}

/** Constructor
 *
 **/
TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::vertexArrayObjectDefinition()
	: m_gl(0), m_vertex_array_object_id(m_invalid_vertex_array_object_id)
{
}

/** Destructor
 *
 **/
TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::~vertexArrayObjectDefinition()
{
	if (m_invalid_vertex_array_object_id != m_vertex_array_object_id)
	{
		if (0 != m_gl)
		{
			m_gl->deleteVertexArrays(1, &m_vertex_array_object_id);

			m_gl = 0;
		}

		m_vertex_array_object_id = m_invalid_vertex_array_object_id;
	}
}

/** Initialize vertex array object
 *
 *  @param gl                GL functions
 *  @param format            Texture format
 *  @param sampling_function Type of sampling function
 *  @param buffers           Buffer collection
 *  @param program_id        Program id
 **/
void TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::init(const glw::Functions&   gl,
																		const formatDefinition& format,
																		const samplingFunction& sampling_function,
																		const bufferCollection& buffers,
																		glw::GLuint				program_id)
{
	m_gl = &gl;

	m_gl->genVertexArrays(1, &m_vertex_array_object_id);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to generate VAO.");

	m_gl->bindVertexArray(m_vertex_array_object_id);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind VAO.");

	attributeDefinition		   positionAttribute = { vertex_shader_position, type_vec4, Position, 0 };
	const attributeDefinition* format_attributes;
	glw::GLuint				   n_format_attributes;
	const attributeDefinition* routine_attributes   = 0;
	glw::GLuint				   n_routine_attributes = 0;

	getAttributes(format.m_sampler_type, format_attributes, n_format_attributes);
	getAttributes(sampling_function, routine_attributes, n_routine_attributes);

	setupAttribute(positionAttribute, buffers, program_id);

	for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
	{
		setupAttribute(routine_attributes[i], buffers, program_id);
	}

	for (glw::GLuint i = 0; i < n_format_attributes; ++i)
	{
		setupAttribute(format_attributes[i], buffers, program_id);
	}
}

/** Setup vertex array object
 *
 *  @param attribute  Attribute information
 *  @param buffers    Buffer collection
 *  @param program_id Program id
 **/
void TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::setupAttribute(const attributeDefinition& attribute,
																				  const bufferCollection&	buffers,
																				  glw::GLuint				 program_id)
{
	std::string				attribute_name = vertex_shader_input;
	const bufferDefinition* buffer		   = 0;
	glw::GLuint				n_components   = 0;
	glw::GLenum				type		   = GL_FLOAT;

	attribute_name.append(attribute.name);

	switch (attribute.attribute_id)
	{
	case Position:
		n_components = 4;
		buffer		 = &buffers.postion;
		break;
	case TextureCoordinates:
		n_components = 4;
		buffer		 = &buffers.texture_coordinate;
		break;
	case TextureCoordinatesForGather:
		n_components = 4;
		buffer		 = &buffers.texture_coordinate_for_gather;
		break;
	case Lod:
		n_components = 1;
		buffer		 = &buffers.lod;
		break;
	case GradX:
		n_components = 4;
		buffer		 = &buffers.grad_x;
		break;
	case GradY:
		n_components = 4;
		buffer		 = &buffers.grad_y;
		break;
	case RefZ:
		n_components = 1;
		buffer		 = &buffers.refZ;
		break;
	}

	/* Get attribute location */
	glw::GLint attribute_location = m_gl->getAttribLocation(program_id, attribute_name.c_str());

	if ((m_invalid_attribute_location == (glw::GLuint)attribute_location) || (GL_NO_ERROR != m_gl->getError()))
	{
		//throw tcu::InternalError("Failed to get location of attribute:", attribute_name.c_str(), __FILE__, __LINE__);
		return;
	}

	buffer->bind(GL_ARRAY_BUFFER);

	m_gl->enableVertexAttribArray(attribute_location);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to enable attribute");

	m_gl->vertexAttribPointer(attribute_location, n_components, type, GL_FALSE, 0 /* stride */, 0 /* offset */);

	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to setup vertex attribute arrays");
}

#if TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION
/** Get file name for given face
 * Such pattern is used: texture_cube_map_array_sampling_test_w_WIDTH_h_HEIGHT_l_LEVEL_i_INDEX_f_FACE
 *
 *  @param width  Width of texture
 *  @param height Height of texture
 *  @param level  Mipmap level
 *  @param index  Index of element in array
 *  @param face   Cube map's face index
 *  @param name   File name
 **/
void getTextureFileName(glw::GLuint width, glw::GLuint height, glw::GLuint level, glw::GLuint index, glw::GLuint face,
						std::string& name)
{
	std::stringstream file_name;

	file_name << TEXTURECUBEMAPARRAYSAMPLINGTEST_PATH_FOR_COMPRESSION;

	file_name << "texture_cube_map_array_sampling_test_"
			  << "w_" << width << "_h_" << height << "_l_" << level << "_i_" << index << "_f_" << face;

	name = file_name.str();
}

/** Store whole cube map as TGA files. Each face is stored as separate image.
 *
 *  @param resolution Resolution of base level
 **/
void prepareDumpForTextureCompression(const TextureCubeMapArraySamplingTest::resolutionDefinition& resolution)
{
	glw::GLsizei texture_width  = resolution.m_width;
	glw::GLsizei texture_height = resolution.m_height;

	const glw::GLuint n_components	 = 4;
	const glw::GLuint n_faces		   = 6;
	const glw::GLint  n_array_elements = resolution.m_depth / n_faces;
	const glw::GLint  n_mipmap_levels  = getMipmapLevelCount(resolution.m_width, resolution.m_height);

	const unsigned char  tga_id_length				  = 0; // no id
	const unsigned char  tga_color_map_type			  = 0; // no color map
	const unsigned char  tga_image_type				  = 2; // rgb no compression
	const unsigned short tga_color_map_offset		  = 0; // no color map
	const unsigned short tga_color_map_length		  = 0; // no color map
	const unsigned char  tga_color_map_bits_per_pixel = 0; // no color map
	const unsigned short tga_image_x				  = 0;
	const unsigned short tga_image_y				  = 0;
	const unsigned char  tga_image_bits_per_pixel	 = 32;
	const unsigned char  tga_image_descriptor		  = 0x8; // 8 per alpha

	for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
	{
		const unsigned short tga_image_width  = texture_width;
		const unsigned short tga_image_height = texture_height;

		for (glw::GLint array_index = 0; array_index < n_array_elements; ++array_index)
		{
			for (glw::GLint face = 0; face < n_faces; ++face)
			{
				std::fstream file;
				std::string  file_name;
				getTextureFileName(resolution.m_width, resolution.m_height, mipmap_level, array_index, face, file_name);
				file_name.append(".tga");

				file.open(file_name.c_str(), std::fstream::out | std::fstream::binary);

				file.write((const char*)&tga_id_length, sizeof(tga_id_length));
				file.write((const char*)&tga_color_map_type, sizeof(tga_color_map_type));
				file.write((const char*)&tga_image_type, sizeof(tga_image_type));
				file.write((const char*)&tga_color_map_offset, sizeof(tga_color_map_offset));
				file.write((const char*)&tga_color_map_length, sizeof(tga_color_map_length));
				file.write((const char*)&tga_color_map_bits_per_pixel, sizeof(tga_color_map_bits_per_pixel));
				file.write((const char*)&tga_image_x, sizeof(tga_image_x));
				file.write((const char*)&tga_image_y, sizeof(tga_image_y));
				file.write((const char*)&tga_image_width, sizeof(tga_image_width));
				file.write((const char*)&tga_image_height, sizeof(tga_image_height));
				file.write((const char*)&tga_image_bits_per_pixel, sizeof(tga_image_bits_per_pixel));
				file.write((const char*)&tga_image_descriptor, sizeof(tga_image_descriptor));

				glw::GLubyte components[n_components];

				getCompressedColorUByteComponents(face, array_index, mipmap_level, n_array_elements, n_mipmap_levels,
												  components);

				for (glw::GLuint y = 0; y < texture_height; ++y)
				{
					for (glw::GLuint x = 0; x < texture_width; ++x)
					{
						for (glw::GLuint i = 0; i < n_components; ++i)
						{
							file.write((const char*)&components[i], sizeof(glw::GLubyte));
						}
					}
				}
			}
		}

		texture_width  = de::max(1, texture_width / 2);
		texture_height = de::max(1, texture_height / 2);
	}
}

#endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION */

} /* glcts */
