/*-------------------------------------------------------------------------
 * 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  esextcTextureCubeMapArrayImageOperations.cpp
 * \brief texture_cube_map_array extension - Image Operations (Test 8)
 */ /*-------------------------------------------------------------------*/

#include "esextcTextureCubeMapArrayImageOperations.hpp"
#include "gluContextInfo.hpp"
#include "gluStrUtil.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuTestLog.hpp"
#include <cmath>
#include <cstring>
#include <vector>

namespace glcts
{

/* Set constant values for tests */
const glw::GLfloat TextureCubeMapArrayImageOpCompute::m_f_base  = 1.5f;
const glw::GLint   TextureCubeMapArrayImageOpCompute::m_i_base  = -1;
const glw::GLuint  TextureCubeMapArrayImageOpCompute::m_ui_base = 1;

const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_components	= 4;
const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_dimensions	= 3;
const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_image_formats = 3;
const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_resolutions   = 4;
const glw::GLuint TextureCubeMapArrayImageOpCompute::m_n_storage_type  = 2;

const char* TextureCubeMapArrayImageOpCompute::m_mutable_storage   = "MUTABLE";
const char* TextureCubeMapArrayImageOpCompute::m_immutable_storage = "IMMUTABLE";

/* Helper arrays for tests configuration */

/* Different texture resolutions */
const int m_resolutions[TextureCubeMapArrayImageOpCompute::m_n_resolutions]
					   [TextureCubeMapArrayImageOpCompute::m_n_dimensions] = {
						   /* Width , Height, Depth */
						   { 16, 16, 12 },
						   { 32, 32, 6 },
						   { 4, 4, 18 },
						   { 8, 8, 6 }
					   };

/** Check if buffers contains the same values
 * @param a      buffer with data to compare
 * @param b      buffer with data to compare
 * @param length buffers length
 * @return       true if both buffers are equal, otherwise false
 */
template <typename T>
glw::GLboolean areBuffersEqual(const T* a, const T* b, glw::GLuint length)
{
	return (memcmp(a, b, length * sizeof(T))) ? false : true;
}

/** Check if buffers contains the same values (float type)
 * @param a      buffer with data to compare
 * @param b      buffer with data to compare
 * @param length buffers length
 * @return       true if both buffers are equal, otherwise false
 */
template <>
glw::GLboolean areBuffersEqual(const glw::GLfloat* a, const glw::GLfloat* b, glw::GLuint length)
{
	for (glw::GLuint i = 0; i < length; ++i)
	{
		if (de::abs(a[i] - b[i]) > TestCaseBase::m_epsilon_float)
		{
			return false;
		}
	}
	return true;
}

/** Fill buffer with test data
 * @param data       buffer where values will be stored
 * @param width      buffer/texture width
 * @param height     buffer/texture height
 * @param depth      buffer/texture depth
 * @param components buffer/texture components number
 * @param base       base value used to fill array
 **/
template <typename T>
void fillData(T* data, glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLuint components, T base)
{
	for (glw::GLuint i = 0; i < depth; ++i)
	{
		for (glw::GLuint j = 0; j < width; ++j)
		{
			for (glw::GLuint k = 0; k < height; ++k)
			{
				for (glw::GLuint l = 0; l < components; ++l)
				{
					data[i * width * height * components + j * height * components + k * components + l] = base + (T)i;
				}
			}
		}
	}
}

/** Check if results are es expected and log error if not
 * @param context      application context
 * @param id           id of texture
 * @param width        texture width
 * @param height       texture height
 * @param depth        texture depth
 * @param components   number of components per texel
 * @param format       texture data format
 * @param type         texture data type
 * @param storType     storageType
 * @param expectedData buffer with expected data
 * @return             return true if data read from the texture is the same as expected
 */
template <typename T>
bool checkResults(Context& context, glw::GLuint copy_po_id, glw::GLuint id, glw::GLuint width, glw::GLuint height,
				  glw::GLuint depth, glw::GLuint components, glw::GLenum format, glw::GLenum type,
				  STORAGE_TYPE storType, T* expectedData)
{
	/* Get GL entry points */
	const glw::Functions& gl = context.getRenderContext().getFunctions();

	/* prepare buffers for result data */
	std::vector<T> resultData(width * height * components);

	glw::GLint  old_program = 0;
	glw::GLuint uint_tex_id = 0;

	/* Floating point textures are not renderable, so we will need to copy their bits to a temporary unsigned integer texture */
	if (type == GL_FLOAT)
	{
		/* Generate a new texture name */
		gl.genTextures(1, &uint_tex_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating temporary texture object!");

		/* Allocate unsigned integer storage */
		gl.bindTexture(GL_TEXTURE_2D, uint_tex_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding temporary texture object!");
		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, width, height);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating temporary texture object!");

		/* Set the filter mode */
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");

		/* Attach it to the framebuffer */
		gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, uint_tex_id, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer");

		/* And bind it to an image unit for writing */
		gl.bindImageTexture(1, uint_tex_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding integer texture for copy destination");

		/* Finally, bind the copy compute shader */
		gl.getIntegerv(GL_CURRENT_PROGRAM, &old_program);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error querying old program!");
		gl.useProgram(copy_po_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");

		gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");
	}
	else
	{
		gl.memoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");
	}

	bool result = true;

	for (glw::GLuint i = 0; i < depth; ++i)
	{
		/* Floating point textures are not renderable */
		if (type == GL_FLOAT)
		{
			/* Use a compute shader to store the float bits as unsigned integers */
			gl.bindImageTexture(0, id, 0, GL_FALSE, i, GL_READ_ONLY, GL_RGBA32F);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding floating point texture for copy source");
			gl.dispatchCompute(width, height, 1);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error dispatching float-to-integer compute shader");

			gl.memoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!");

			/* Read data as unsigned ints */
			gl.readPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &resultData[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixels from frame buffer!");
		}
		else
		{
			/* Attach proper 2D texture to frame buffer and read pixels */
			gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, id, 0, i);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer");

			/* Read data */
			gl.readPixels(0, 0, width, height, format, type, &resultData[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixels from frame buffer!");
		}

		/* Prepare correct pointer for expected data layer */
		T* pointer = &expectedData[0] + (i * width * height * components);

		/* If compared data are not equal log error and return false */
		if (!areBuffersEqual<T>(&resultData[0], pointer, width * height * components))
		{
			context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Wrong value in result texture for "
				<< ((type == GL_FLOAT) ? "imageCubeArray" : ((type == GL_INT) ? "iimageCubeArray" : "uimageCubeArray"))
				<< " for resolution[w,h,d] = [" << width << "," << height << "," << depth << "] for layer[" << i
				<< "] and " << ((storType == ST_MUTABLE) ? TextureCubeMapArrayImageOpCompute::m_mutable_storage :
														   TextureCubeMapArrayImageOpCompute::m_immutable_storage)
				<< " storage!" << tcu::TestLog::EndMessage;
			result = false;
			break;
		}
	}

	/* Clean up the floating point stuff */
	if (type == GL_FLOAT)
	{
		/* Restore the program */
		gl.useProgram(old_program);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");

		/* Delete the temporary texture */
		gl.deleteTextures(1, &uint_tex_id);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error deleting temporary texture!");
	}

	return result;
}

/** Configure texture object
 * @param context        application context
 * @param id             pointer where texture id will be stored
 * @param width          texture width
 * @param height         texture height
 * @param depth          texture depth
 * @param storType       storageType
 * @param internalFormat texture internal format
 * @param format         texture data format
 * @param type           texture data type
 * @param data           initialization data for texture
 */
template <typename T>
void configureTexture(glcts::Context& context, glw::GLuint* id, glw::GLuint width, glw::GLuint height,
					  glw::GLuint depth, STORAGE_TYPE storType, glw::GLenum internalFormat, glw::GLenum format,
					  glw::GLenum type, const T* data)
{
	/* Get GL entry points */
	const glw::Functions& gl = context.getRenderContext().getFunctions();

	/* Generate texture object */
	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active texture unit!");

	gl.genTextures(1, id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!");

	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, *id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!");

	gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");
	gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!");

	/* used glTexImage3D() method if texture should be MUTABLE */
	if (storType == ST_MUTABLE)
	{
		gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");
		gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter.");

		gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, internalFormat, width, height, depth, 0, format, type, data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");
	}
	/* used glTexStorage3D() method if texture should be IMMUTABLE */
	else
	{
		gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, internalFormat, width, height, depth);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating texture object's data store");

		gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, width, height, depth, format, type, data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data");
	}
}

/** Constructor
 *
 *  @param context       Test context
 *  @param name          Test case's name
 *  @param description   Test case's description
 **/
TextureCubeMapArrayImageOpCompute::TextureCubeMapArrayImageOpCompute(Context& context, const ExtParameters& extParams,
																	 const char* name, const char* description,
																	 SHADER_TO_CHECK shaderToCheck)
	: TestCaseBase(context, extParams, name, description)
	, m_shader_to_check(shaderToCheck)
	, m_cs_id(0)
	, m_fbo_id(0)
	, m_fs_id(0)
	, m_gs_id(0)
	, m_po_id(0)
	, m_tc_id(0)
	, m_te_id(0)
	, m_vao_id(0)
	, m_vs_id(0)
	, m_copy_po_id(0)
	, m_copy_cs_id(0)
	, m_iimage_read_to_id(0)
	, m_iimage_write_to_id(0)
	, m_image_read_to_id(0)
	, m_image_write_to_id(0)
	, m_uimage_read_to_id(0)
	, m_uimage_write_to_id(0)
{
	/* Nothing to be done here */
}

glw::GLenum getQueryPname(SHADER_TO_CHECK stage) {
	switch (stage) {
		case STC_COMPUTE_SHADER:					return GL_MAX_COMPUTE_IMAGE_UNIFORMS;
		case STC_VERTEX_SHADER:						return GL_MAX_VERTEX_IMAGE_UNIFORMS;
		case STC_FRAGMENT_SHADER:					return GL_MAX_FRAGMENT_IMAGE_UNIFORMS;
		case STC_GEOMETRY_SHADER:					return GL_MAX_GEOMETRY_IMAGE_UNIFORMS;
		case STC_TESSELLATION_CONTROL_SHADER:		return GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS;
		case STC_TESSELLATION_EVALUATION_SHADER:	return GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS;
	}
	DE_ASSERT(0);
	return GL_NONE;
}

/** Initialize test case */
void TextureCubeMapArrayImageOpCompute::initTest(void)
{
	/* Get GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check if texture_cube_map_array extension is supported */
	if (!m_is_texture_cube_map_array_supported)
	{
		throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}
	if (!m_is_geometry_shader_extension_supported && m_shader_to_check == STC_GEOMETRY_SHADER)
	{
		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}
	if (!m_is_tessellation_shader_supported && (m_shader_to_check == STC_TESSELLATION_CONTROL_SHADER ||
												m_shader_to_check == STC_TESSELLATION_EVALUATION_SHADER))
	{
		throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
	}

	int maxImages;
	glw::GLenum pname = getQueryPname(m_shader_to_check);
	gl.getIntegerv(pname, &maxImages);
	if (maxImages < 6)
		throw tcu::NotSupportedError( "Shader stage does not support at least 6 image uniforms", "", __FILE__, __LINE__);

	/* Generate and bind VAO */
	gl.genVertexArrays(1, &m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object");

	gl.bindVertexArray(m_vao_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!");

	/* Generate and bind framebuffer */
	gl.genFramebuffers(1, &m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating frame buffer object!");

	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding frame buffer object!");

	/* Create the floating point copy program */
	m_copy_po_id			   = gl.createProgram();
	m_copy_cs_id			   = gl.createShader(GL_COMPUTE_SHADER);
	const char* copy_cs_source = getFloatingPointCopyShaderSource();
	buildProgram(m_copy_po_id, m_copy_cs_id, 1, &copy_cs_source);

	/* Create program */
	m_po_id = gl.createProgram();
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating program object!");

	configureProgram();
}

/** Deinitialize test case */
void TextureCubeMapArrayImageOpCompute::deinit(void)
{
	/* Get GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Reset GLES configuration */
	gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
	gl.useProgram(0);
	gl.bindVertexArray(0);

	/* Delete GLES objects */
	if (m_po_id != 0)
	{
		gl.deleteProgram(m_po_id);
		m_po_id = 0;
	}
	if (m_cs_id != 0)
	{
		gl.deleteShader(m_cs_id);
		m_cs_id = 0;
	}
	if (m_fs_id != 0)
	{
		gl.deleteShader(m_fs_id);
		m_fs_id = 0;
	}
	if (m_gs_id != 0)
	{
		gl.deleteShader(m_gs_id);
		m_gs_id = 0;
	}
	if (m_tc_id != 0)
	{
		gl.deleteShader(m_tc_id);
		m_tc_id = 0;
	}
	if (m_te_id != 0)
	{
		gl.deleteShader(m_te_id);
		m_te_id = 0;
	}
	if (m_vs_id != 0)
	{
		gl.deleteShader(m_vs_id);
		m_vs_id = 0;
	}
	if (m_copy_cs_id != 0)
	{
		gl.deleteShader(m_copy_cs_id);
		m_copy_cs_id = 0;
	}
	if (m_copy_po_id != 0)
	{
		gl.deleteProgram(m_copy_po_id);
		m_copy_po_id = 0;
	}
	if (m_fbo_id != 0)
	{
		gl.deleteFramebuffers(1, &m_fbo_id);
		m_fbo_id = 0;
	}
	if (m_vao_id != 0)
	{
		gl.deleteVertexArrays(1, &m_vao_id);
		m_vao_id = 0;
	}

	removeTextures();

	/* Deinitialize base class */
	TestCaseBase::deinit();
}

/** Delete texture objects */
void TextureCubeMapArrayImageOpCompute::removeTextures()
{
	/* Get GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);

	/* Delete texture objects */
	if (m_iimage_read_to_id != 0)
	{
		gl.deleteTextures(1, &m_iimage_read_to_id);
		m_iimage_read_to_id = 0;
	}

	if (m_iimage_write_to_id != 0)
	{
		gl.deleteTextures(1, &m_iimage_write_to_id);
		m_iimage_write_to_id = 0;
	}

	if (m_image_read_to_id != 0)
	{
		gl.deleteTextures(1, &m_image_read_to_id);
		m_image_read_to_id = 0;
	}

	if (m_image_write_to_id != 0)
	{
		gl.deleteTextures(1, &m_image_write_to_id);
		m_image_write_to_id = 0;
	}

	if (m_uimage_read_to_id != 0)
	{
		gl.deleteTextures(1, &m_uimage_read_to_id);
		m_uimage_read_to_id = 0;
	}

	if (m_uimage_write_to_id != 0)
	{
		gl.deleteTextures(1, &m_uimage_write_to_id);
		m_uimage_write_to_id = 0;
	}
}

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

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

	gl.useProgram(m_po_id);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting active program object!");

	bool test_passed = true;

	std::vector<glw::GLfloat> floatData;
	std::vector<glw::GLfloat> floatClean;
	std::vector<glw::GLint>   intData;
	std::vector<glw::GLint>   intClean;
	std::vector<glw::GLuint>  uIntData;
	std::vector<glw::GLuint>  uIntClean;

	/* Execute test throught all resolutions, storage types, and image types */
	for (glw::GLuint res_index = 0; res_index < m_n_resolutions; ++res_index)
	{
		glw::GLuint width  = m_resolutions[res_index][DL_WIDTH];
		glw::GLuint height = m_resolutions[res_index][DL_HEIGHT];
		glw::GLuint depth  = m_resolutions[res_index][DL_DEPTH];

		/* Allocate memory buffers for data */
		floatData.resize(width * height * depth * m_n_components);
		floatClean.resize(width * height * depth * m_n_components);
		intData.resize(width * height * depth * m_n_components);
		intClean.resize(width * height * depth * m_n_components);
		uIntData.resize(width * height * depth * m_n_components);
		uIntClean.resize(width * height * depth * m_n_components);

		memset(&floatClean[0], 0, width * height * depth * m_n_components * sizeof(glw::GLfloat));
		memset(&intClean[0], 0, width * height * depth * m_n_components * sizeof(glw::GLint));
		memset(&uIntClean[0], 0, width * height * depth * m_n_components * sizeof(glw::GLuint));

		/* Fill buffers with expected data*/
		fillData<glw::GLfloat>(&floatData[0], width, height, depth, m_n_components, m_f_base);
		fillData<glw::GLint>(&intData[0], width, height, depth, m_n_components, m_i_base);
		fillData<glw::GLuint>(&uIntData[0], width, height, depth, m_n_components, m_ui_base);

		if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
		{

			/**
			 * Mutable textures cannot be bound as image textures on ES, but can be on
			 * desktop GL.
			 * */

			/* Work on mutable texture storage */

			/* Generate texture objects */
			configureTexture<glw::GLfloat>(m_context, &m_image_read_to_id, width, height, depth, ST_MUTABLE, GL_RGBA32F,
										   GL_RGBA, GL_FLOAT, &floatData[0]);
			configureTexture<glw::GLfloat>(m_context, &m_image_write_to_id, width, height, depth, ST_MUTABLE,
										   GL_RGBA32F, GL_RGBA, GL_FLOAT, &floatClean[0]);

			configureTexture<glw::GLint>(m_context, &m_iimage_read_to_id, width, height, depth, ST_MUTABLE, GL_RGBA32I,
										 GL_RGBA_INTEGER, GL_INT, &intData[0]);
			configureTexture<glw::GLint>(m_context, &m_iimage_write_to_id, width, height, depth, ST_MUTABLE, GL_RGBA32I,
										 GL_RGBA_INTEGER, GL_INT, &intClean[0]);

			configureTexture<glw::GLuint>(m_context, &m_uimage_read_to_id, width, height, depth, ST_MUTABLE,
										  GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &uIntData[0]);
			configureTexture<glw::GLuint>(m_context, &m_uimage_write_to_id, width, height, depth, ST_MUTABLE,
										  GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &uIntClean[0]);

			/* Bind texture objects to image units */
			gl.bindImageTexture(IF_IMAGE, m_image_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32F);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
			gl.bindImageTexture(IF_IIMAGE, m_iimage_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32I);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
			gl.bindImageTexture(IF_UIMAGE, m_uimage_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32UI);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
			gl.bindImageTexture(IF_IMAGE + m_n_image_formats, m_image_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
								GL_RGBA32F);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
			gl.bindImageTexture(IF_IIMAGE + m_n_image_formats, m_iimage_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
								GL_RGBA32I);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
			gl.bindImageTexture(IF_UIMAGE + m_n_image_formats, m_uimage_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
								GL_RGBA32UI);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");

			/* Call shaders */
			runShaders(width, height, depth);

			/* Check results */
			if (!checkResults<glw::GLfloat>(m_context, m_copy_po_id, m_image_write_to_id, width, height, depth,
											m_n_components, GL_RGBA, GL_FLOAT, ST_MUTABLE, &floatData[0]))
			{
				test_passed = false;
			}

			if (!checkResults<glw::GLint>(m_context, m_copy_po_id, m_iimage_write_to_id, width, height, depth,
										  m_n_components, GL_RGBA_INTEGER, GL_INT, ST_MUTABLE, &intData[0]))
			{
				test_passed = false;
			}

			if (!checkResults<glw::GLuint>(m_context, m_copy_po_id, m_uimage_write_to_id, width, height, depth,
										   m_n_components, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ST_MUTABLE, &uIntData[0]))
			{
				test_passed = false;
			}

			/* Delete textures */
			removeTextures();
		}

		/* Work on immutable texture storage */

		/* Generate texture objects */
		configureTexture<glw::GLfloat>(m_context, &m_image_read_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32F,
									   GL_RGBA, GL_FLOAT, &floatData[0]);
		configureTexture<glw::GLfloat>(m_context, &m_image_write_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32F,
									   GL_RGBA, GL_FLOAT, &floatClean[0]);

		configureTexture<glw::GLint>(m_context, &m_iimage_read_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32I,
									 GL_RGBA_INTEGER, GL_INT, &intData[0]);
		configureTexture<glw::GLint>(m_context, &m_iimage_write_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32I,
									 GL_RGBA_INTEGER, GL_INT, &intClean[0]);

		configureTexture<glw::GLuint>(m_context, &m_uimage_read_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32UI,
									  GL_RGBA_INTEGER, GL_UNSIGNED_INT, &uIntData[0]);
		configureTexture<glw::GLuint>(m_context, &m_uimage_write_to_id, width, height, depth, ST_IMMUTABLE, GL_RGBA32UI,
									  GL_RGBA_INTEGER, GL_UNSIGNED_INT, &uIntClean[0]);

		/* Bind texture objects to image units */
		gl.bindImageTexture(IF_IMAGE, m_image_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32F);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
		gl.bindImageTexture(IF_IIMAGE, m_iimage_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32I);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
		gl.bindImageTexture(IF_UIMAGE, m_uimage_read_to_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32UI);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
		gl.bindImageTexture(IF_IMAGE + m_n_image_formats, m_image_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
							GL_RGBA32F);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
		gl.bindImageTexture(IF_IIMAGE + m_n_image_formats, m_iimage_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
							GL_RGBA32I);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");
		gl.bindImageTexture(IF_UIMAGE + m_n_image_formats, m_uimage_write_to_id, 0, GL_TRUE, 0, GL_WRITE_ONLY,
							GL_RGBA32UI);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit!");

		/* Call shaders */
		runShaders(width, height, depth);

		/* Check results */
		if (!checkResults<glw::GLfloat>(m_context, m_copy_po_id, m_image_write_to_id, width, height, depth,
										m_n_components, GL_RGBA, GL_FLOAT, ST_IMMUTABLE, &floatData[0]))
		{
			test_passed = false;
		}

		if (!checkResults<glw::GLint>(m_context, m_copy_po_id, m_iimage_write_to_id, width, height, depth,
									  m_n_components, GL_RGBA_INTEGER, GL_INT, ST_IMMUTABLE, &intData[0]))
		{
			test_passed = false;
		}

		if (!checkResults<glw::GLuint>(m_context, m_copy_po_id, m_uimage_write_to_id, width, height, depth,
									   m_n_components, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ST_IMMUTABLE, &uIntData[0]))
		{
			test_passed = false;
		}

		/* Delete textures */
		removeTextures();
	}

	if (test_passed)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

	return STOP;
}

/** Run shaders - call glDispatchCompute for compuate shaders and glDrawArrays for other types of shaders */
void TextureCubeMapArrayImageOpCompute::runShaders(glw::GLuint width, glw::GLuint height, glw::GLuint depth)
{
	/* Get GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	switch (m_shader_to_check)
	{
	/* Call compute shader */
	case STC_COMPUTE_SHADER:
	{
		gl.dispatchCompute(width, height, depth);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error running compute shader!");

		break;
	}
	/* Run programs for VERTEX/FRAGMENT/GEOMETRY shader */
	case STC_VERTEX_SHADER:
	case STC_FRAGMENT_SHADER:
	case STC_GEOMETRY_SHADER:
	{
		glw::GLint dimensions_location = gl.getUniformLocation(m_po_id, "dimensions");
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting uniform location!");

		if (dimensions_location == -1)
		{
			TCU_FAIL("Invalid location returned for active uniform!");
		}

		gl.uniform3i(dimensions_location, width, height, depth);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for uniform variable!");

		gl.drawArrays(GL_POINTS, 0, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");

		break;
	}
	case STC_TESSELLATION_CONTROL_SHADER:
	case STC_TESSELLATION_EVALUATION_SHADER:
	{
		glw::GLint dimensions_location = gl.getUniformLocation(m_po_id, "dimensions");
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting uniform location!");

		if (dimensions_location == -1)
		{
			TCU_FAIL("Invalid location returned for active uniform!");
		}

		gl.uniform3i(dimensions_location, width, height, depth);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting value for uniform variable!");

		gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting patch parameter!");

		gl.drawArrays(m_glExtTokens.PATCHES, 0, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!");

		gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 3);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting patch parameter!");

		break;
	}
	}
}

/** Configure program object with proper shaders depending on m_shader_to_check value */
void TextureCubeMapArrayImageOpCompute::configureProgram(void)
{
	/* Get GL entry points */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	switch (m_shader_to_check)
	{
	case STC_COMPUTE_SHADER:
	{
		m_cs_id = gl.createShader(GL_COMPUTE_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");

		const char* csCode = getComputeShaderCode();

		if (!buildProgram(m_po_id, m_cs_id, 1 /* part */, &csCode))
		{
			TCU_FAIL("Could not create a program from valid compute shader code!");
		}
		break;
	}
	case STC_VERTEX_SHADER:
	case STC_FRAGMENT_SHADER:
	{
		m_vs_id = gl.createShader(GL_VERTEX_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
		m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");

		bool vs = (m_shader_to_check == STC_VERTEX_SHADER);
		const char* vsCode = vs	? getVertexShaderCode()
								: getVertexShaderCodeBoilerPlate();
		const char* fsCode = vs	? getFragmentShaderCodeBoilerPlate()
								: getFragmentShaderCode();

		if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_vs_id, 1 /* part */, &vsCode))
		{
			TCU_FAIL("Could not create shader program.");
		}
		break;
	}
	case STC_GEOMETRY_SHADER:
	{
		m_vs_id = gl.createShader(GL_VERTEX_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
		m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
		m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");

		const char* vsCode = getVertexShaderCodeBoilerPlate();
		const char* gsCode = getGeometryShaderCode();
		const char* fsCode = getFragmentShaderCodeBoilerPlate();

		if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_gs_id, 1 /* part */, &gsCode, m_vs_id,
						  1 /* part */, &vsCode))
		{
			TCU_FAIL("Could not create shader program.");
		}
		break;
	}
	case STC_TESSELLATION_CONTROL_SHADER:
	case STC_TESSELLATION_EVALUATION_SHADER:
	{
		m_vs_id = gl.createShader(GL_VERTEX_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
		m_tc_id = gl.createShader(m_glExtTokens.TESS_CONTROL_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
		m_te_id = gl.createShader(m_glExtTokens.TESS_EVALUATION_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");
		m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object!");

		bool tcs = (m_shader_to_check == STC_TESSELLATION_CONTROL_SHADER);
		const char* vsCode  = getVertexShaderCodeBoilerPlate();
		const char* tcsCode = tcs	? getTessControlShaderCode()
									: getTessControlShaderCodeBoilerPlate();
		const char* tesCode = tcs	? getTessEvaluationShaderCodeBoilerPlate()
									: getTessEvaluationShaderCode();
		const char* fsCode  = getFragmentShaderCodeBoilerPlate();

		if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_tc_id, 1 /* part */, &tcsCode, m_te_id,
						  1 /* part */, &tesCode, m_vs_id, 1 /* part */, &vsCode))
		{
			TCU_FAIL("Could not create shader program.");
		}
		break;
	}
	default:
		break;
	}
}

/** Returns code for Compute Shader
 *  @return pointer to literal with Compute Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getComputeShaderCode()
{
	static const char* computeShaderCode =
		"${VERSION}\n"
		"\n"
		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
		"\n"
		"precision highp float;\n"
		"\n"
		"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
		"\n"
		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
		"\n"
		"void main(void)\n"
		"{\n"
		"    ivec3 position = ivec3(gl_GlobalInvocationID.xyz);\n"
		"    imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
		"    imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
		"    imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
		"}\n";

	return computeShaderCode;
}

/** Returns code for Vertex Shader
 * @return pointer to literal with Vertex Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getVertexShaderCode(void)
{

	static const char* vertexShaderCode =
		"${VERSION}\n"
		"\n"
		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
		"\n"
		"precision highp float;\n"
		"\n"
		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
		"\n"
		"uniform ivec3 dimensions;\n"
		"\n"
		"void main()\n"
		"{\n"
		"\n"
		"    gl_PointSize = 1.0f;\n"
		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
		"    {\n"
		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
		"        {\n"
		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
		"            {\n"
		"                ivec3  position  = ivec3(w,h,d);\n"
		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
		"            }\n"
		"        }\n"
		"    }\n"
		"\n"
		"}\n";

	return vertexShaderCode;
}

/** Returns code for Boiler Plate Vertex Shader
 * @return pointer to literal with Boiler Plate Vertex Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getVertexShaderCodeBoilerPlate(void)
{
	static const char* vertexShaderBoilerPlateCode = "${VERSION}\n"
													 "\n"
													 "precision highp float;\n"
													 "\n"
													 "void main()\n"
													 "{\n"
													 "    gl_Position = vec4(0, 0, 0, 1.0f);\n"
													 "    gl_PointSize = 1.0f;\n"
													 "}\n";

	return vertexShaderBoilerPlateCode;
}

/** Returns code for Fragment Shader
 *  @return pointer to literal with Fragment Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getFragmentShaderCode(void)
{
	static const char* fragmentShaderCode =
		"${VERSION}\n"
		"\n"
		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
		"\n"
		"precision highp float;\n"
		"\n"
		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
		"\n"
		"uniform ivec3 dimensions;\n"
		"\n"
		"void main()\n"
		"{\n"
		"\n"
		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
		"    {\n"
		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
		"        {\n"
		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
		"            {\n"
		"                ivec3  position  = ivec3(w,h,d);\n"
		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
		"            }"
		"        }"
		"    }"
		"\n"
		"}\n";

	return fragmentShaderCode;
}

/** Returns code for Boiler Plate Fragment Shader
 *  @return pointer to literal with Boiler Plate Fragment Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getFragmentShaderCodeBoilerPlate(void)
{
	static const char* fragmentShaderBoilerPlateCode = "${VERSION}\n"
													   "\n"
													   "precision highp float;\n"
													   "\n"
													   "void main()\n"
													   "{\n"
													   "}\n";

	return fragmentShaderBoilerPlateCode;
}

/** Returns code for Geometry Shader
 * @return pointer to literal with Geometry Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getGeometryShaderCode(void)
{
	static const char* geometryShaderCode =
		"${VERSION}\n"
		"\n"
		"${GEOMETRY_SHADER_ENABLE}\n"
		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
		"\n"
		"precision highp float;\n"
		"\n"
		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
		"\n"
		"uniform ivec3 dimensions;\n"
		"\n"
		"layout(points) in;\n"
		"layout(points, max_vertices=1) out;\n"
		"\n"
		"void main()\n"
		"{\n"
		"\n"
		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
		"    {\n"
		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
		"        {\n"
		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
		"            {\n"
		"                ivec3  position  = ivec3(w,h,d);\n"
		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
		"            }\n"
		"        }\n"
		"    }\n"
		"\n"
		"}\n";

	return geometryShaderCode;
}

/** Returns code for Tessellation Control Shader
 *  @return pointer to literal with Tessellation Control Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getTessControlShaderCode(void)
{
	static const char* tessellationControlShaderCode =
		"${VERSION}\n"
		"\n"
		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
		"${TESSELLATION_SHADER_ENABLE}\n"
		"\n"
		"precision highp float;\n"
		"\n"
		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
		"\n"
		"uniform ivec3 dimensions;\n"
		"\n"
		"layout (vertices = 1) out;\n"
		"\n"
		"void main()\n"
		"{\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"
		"\n"
		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
		"    {\n"
		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
		"        {\n"
		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
		"            {\n"
		"                ivec3  position  = ivec3(w,h,d);\n"
		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position.xyz));\n"
		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position.xyz));\n"
		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position.xyz));\n"
		"            }\n"
		"        }\n"
		"    }\n"
		"\n"
		"}\n";

	return tessellationControlShaderCode;
}

/** Returns code for Boiler Plate Tessellation Control Shader
 *  @return pointer to literal with Boiler Plate Tessellation Control Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getTessControlShaderCodeBoilerPlate(void)
{
	static const char* tessControlShaderBoilerPlateCode = "${VERSION}\n"
														  "\n"
														  "${TESSELLATION_SHADER_ENABLE}\n"
														  "\n"
														  "precision highp float;\n"
														  "\n"
														  "layout (vertices = 1) out;\n"
														  "\n"
														  "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"
														  "}\n";

	return tessControlShaderBoilerPlateCode;
}

/** Returns code for Tessellation Evaluation Shader
 *  @return pointer to literal with Tessellation Evaluation Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getTessEvaluationShaderCode(void)
{
	static const char* tessellationEvaluationShaderCode =
		"${VERSION}\n"
		"\n"
		"${TESSELLATION_SHADER_ENABLE}\n"
		"${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
		"\n"
		"precision highp float;\n"
		"\n"
		"layout (rgba32f,  binding = 0) highp uniform readonly imageCubeArray  imageRead;\n"
		"layout (rgba32i,  binding = 1) highp uniform readonly iimageCubeArray iimageRead;\n"
		"layout (rgba32ui, binding = 2) highp uniform readonly uimageCubeArray uimageRead;\n"
		"layout (rgba32f,  binding = 3) highp uniform writeonly imageCubeArray  imageWrite;\n"
		"layout (rgba32i,  binding = 4) highp uniform writeonly iimageCubeArray iimageWrite;\n"
		"layout (rgba32ui, binding = 5) highp uniform writeonly uimageCubeArray uimageWrite;\n"
		"\n"
		"uniform ivec3 dimensions;\n"
		"\n"
		"layout(isolines, point_mode) in;"
		"\n"
		"void main()\n"
		"{\n"
		"\n"
		"    for(int w = 0; w < dimensions[0]; ++w)\n" /* width */
		"    {\n"
		"        for(int h = 0; h < dimensions[1]; ++h)\n" /* height */
		"        {\n"
		"            for(int d = 0; d < dimensions[2]; ++d)\n" /* depth */
		"            {\n"
		"                ivec3  position  = ivec3(w,h,d);\n"
		"                imageStore(imageWrite,  position, imageLoad(imageRead,  position));\n"
		"                imageStore(iimageWrite, position, imageLoad(iimageRead, position));\n"
		"                imageStore(uimageWrite, position, imageLoad(uimageRead, position));\n"
		"            }\n"
		"        }\n"
		"    }\n"
		"\n"
		"}\n";

	return tessellationEvaluationShaderCode;
}

/** Returns code for Boiler Plate Tessellation Evaluation Shader
 *  @return pointer to literal with Boiler Plate Tessellation Evaluation Shader code
 **/
const char* TextureCubeMapArrayImageOpCompute::getTessEvaluationShaderCodeBoilerPlate(void)
{
	static const char* tessellationEvaluationShaderBoilerPlateCode = "${VERSION}\n"
																	 "\n"
																	 "${TESSELLATION_SHADER_ENABLE}\n"
																	 "\n"
																	 "precision highp float;\n"
																	 "\n"
																	 "layout(isolines, point_mode) in;"
																	 "\n"
																	 "void main()\n"
																	 "{\n"
																	 "}\n";

	return tessellationEvaluationShaderBoilerPlateCode;
}

const char* TextureCubeMapArrayImageOpCompute::getFloatingPointCopyShaderSource(void)
{
	static const char* floatingPointCopyShaderCode =
		"${VERSION}\n"
		"\n"
		"layout (local_size_x=1) in;\n"
		"\n"
		"layout(binding=0, rgba32f) uniform highp readonly image2D src;\n"
		"layout(binding=1, rgba32ui) uniform highp writeonly uimage2D dst;\n"
		"\n"
		"void main()\n"
		"{\n"
		"ivec2 coord = ivec2(gl_WorkGroupID.xy);\n"
		"imageStore(dst, coord, floatBitsToUint(imageLoad(src, coord)));\n"
		"}\n";

	return floatingPointCopyShaderCode;
}

} /* glcts */
