/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2015-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  gl4cDirectStateAccessTexturesTests.cpp
 * \brief Conformance tests for the Direct State Access feature functionality (Texture access part).
 */ /*-----------------------------------------------------------------------------------------------------------*/

/* Uncomment this if SubImageErrorsTest crashes during negative test of TextureSubImage (negative value width/height/depth passed to the function). */
/* #define TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH */

/* Includes. */
#include "gl4cDirectStateAccessTests.hpp"

#include "deSharedPtr.hpp"

#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"

#include "tcuFuzzyImageCompare.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"

#include "glw.h"
#include "glwFunctions.hpp"

#include <algorithm>
#include <climits>
#include <set>
#include <sstream>
#include <stack>
#include <string>

namespace gl4cts
{
namespace DirectStateAccess
{
namespace Textures
{
/******************************** Creation Test Implementation   ********************************/

/** @brief Creation Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationTest::CreationTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_creation", "Texture Objects Creation Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CreationTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Textures' objects */
	static const glw::GLenum texture_targets[] = { GL_TEXTURE_1D,
												   GL_TEXTURE_2D,
												   GL_TEXTURE_3D,
												   GL_TEXTURE_1D_ARRAY,
												   GL_TEXTURE_2D_ARRAY,
												   GL_TEXTURE_RECTANGLE,
												   GL_TEXTURE_CUBE_MAP,
												   GL_TEXTURE_CUBE_MAP_ARRAY,
												   GL_TEXTURE_BUFFER,
												   GL_TEXTURE_2D_MULTISAMPLE,
												   GL_TEXTURE_2D_MULTISAMPLE_ARRAY };
	static const glw::GLuint texture_targets_count = sizeof(texture_targets) / sizeof(texture_targets[0]);
	static const glw::GLuint textures_count		   = 2;

	glw::GLuint textures_legacy[textures_count]						= {};
	glw::GLuint textures_dsa[texture_targets_count][textures_count] = {};

	try
	{
		/* Check legacy state creation. */
		gl.genTextures(textures_count, textures_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		for (glw::GLuint i = 0; i < textures_count; ++i)
		{
			if (gl.isTexture(textures_legacy[i]))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "GenTextures has created default objects, but it should create only a names."
					<< tcu::TestLog::EndMessage;
			}
		}

		/* Check direct state creation. */
		for (glw::GLuint j = 0; j < texture_targets_count; ++j)
		{
			gl.createTextures(texture_targets[j], textures_count, textures_dsa[j]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

			for (glw::GLuint i = 0; i < textures_count; ++i)
			{
				if (!gl.isTexture(textures_dsa[j][i]))
				{
					is_ok = false;

					/* Log. */
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "CreateTextures has not created default objects for target "
						<< glu::getTextureTargetStr(texture_targets[j]) << "." << tcu::TestLog::EndMessage;
				}
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	for (glw::GLuint i = 0; i < textures_count; ++i)
	{
		if (textures_legacy[i])
		{
			gl.deleteTextures(1, &textures_legacy[i]);

			textures_legacy[i] = 0;
		}

		for (glw::GLuint j = 0; j < texture_targets_count; ++j)
		{
			if (textures_dsa[j][i])
			{
				gl.deleteTextures(1, &textures_dsa[j][i]);

				textures_dsa[j][i] = 0;
			}
		}
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Reference Data Implementation   *****************************/

/** @brief Internal Format selector.
 *
 *  @tparam T      Type.
 *  @tparam S      Size (# of components).
 *  @tparam N      Is normalized.
 *
 *  @return Internal format.
 */
template <>
glw::GLenum Reference::InternalFormat<glw::GLbyte, 1, false>()
{
	return GL_R8I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLbyte, 2, false>()
{
	return GL_RG8I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLbyte, 3, false>()
{
	return GL_RGB8I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLbyte, 4, false>()
{
	return GL_RGBA8I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLubyte, 1, false>()
{
	return GL_R8UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLubyte, 2, false>()
{
	return GL_RG8UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLubyte, 3, false>()
{
	return GL_RGB8UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLubyte, 4, false>()
{
	return GL_RGBA8UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLshort, 1, false>()
{
	return GL_R16I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLshort, 2, false>()
{
	return GL_RG16I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLshort, 3, false>()
{
	return GL_RGB16I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLshort, 4, false>()
{
	return GL_RGBA16I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLushort, 1, false>()
{
	return GL_R16UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLushort, 2, false>()
{
	return GL_RG16UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLushort, 3, false>()
{
	return GL_RGB16UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLushort, 4, false>()
{
	return GL_RGBA16UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLint, 1, false>()
{
	return GL_R32I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLint, 2, false>()
{
	return GL_RG32I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLint, 3, false>()
{
	return GL_RGB32I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLint, 4, false>()
{
	return GL_RGBA32I;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLuint, 1, false>()
{
	return GL_R32UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLuint, 2, false>()
{
	return GL_RG32UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLuint, 3, false>()
{
	return GL_RGB32UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLuint, 4, false>()
{
	return GL_RGBA32UI;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLubyte, 1, true>()
{
	return GL_R8;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLubyte, 2, true>()
{
	return GL_RG8;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLubyte, 3, true>()
{
	return GL_RGB8;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLubyte, 4, true>()
{
	return GL_RGBA8;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLushort, 1, true>()
{
	return GL_R16;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLushort, 2, true>()
{
	return GL_RG16;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLushort, 3, true>()
{
	return GL_RGB16;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLushort, 4, true>()
{
	return GL_RGBA16;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLfloat, 1, true>()
{
	return GL_R32F;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLfloat, 2, true>()
{
	return GL_RG32F;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLfloat, 3, true>()
{
	return GL_RGB32F;
}

template <>
glw::GLenum Reference::InternalFormat<glw::GLfloat, 4, true>()
{
	return GL_RGBA32F;
}

/** @brief Format selector.
 *
 *  @tparam S      Size (# of components).
 *  @tparam N      Is normalized.
 *
 *  @return format.
 */
template <>
glw::GLenum Reference::Format<1, false>()
{
	return GL_RED_INTEGER;
}

template <>
glw::GLenum Reference::Format<2, false>()
{
	return GL_RG_INTEGER;
}

template <>
glw::GLenum Reference::Format<3, false>()
{
	return GL_RGB_INTEGER;
}

template <>
glw::GLenum Reference::Format<4, false>()
{
	return GL_RGBA_INTEGER;
}

template <>
glw::GLenum Reference::Format<1, true>()
{
	return GL_RED;
}

template <>
glw::GLenum Reference::Format<2, true>()
{
	return GL_RG;
}

template <>
glw::GLenum Reference::Format<3, true>()
{
	return GL_RGB;
}

template <>
glw::GLenum Reference::Format<4, true>()
{
	return GL_RGBA;
}

/** @brief Type selector.
 *
 *  @tparam T      Type.
 *
 *  @return Type.
 */
template <>
glw::GLenum Reference::Type<glw::GLbyte>()
{
	return GL_BYTE;
}

template <>
glw::GLenum Reference::Type<glw::GLubyte>()
{
	return GL_UNSIGNED_BYTE;
}

template <>
glw::GLenum Reference::Type<glw::GLshort>()
{
	return GL_SHORT;
}

template <>
glw::GLenum Reference::Type<glw::GLushort>()
{
	return GL_UNSIGNED_SHORT;
}

template <>
glw::GLenum Reference::Type<glw::GLint>()
{
	return GL_INT;
}

template <>
glw::GLenum Reference::Type<glw::GLuint>()
{
	return GL_UNSIGNED_INT;
}

template <>
glw::GLenum Reference::Type<glw::GLfloat>()
{
	return GL_FLOAT;
}

/** @brief Reference data selector.
 *
 *  @tparam T      Type.
 *  @tparam N      Is normalized.
 *
 *  @return Reference data.
 */

/* RGBA8I */
template <>
const glw::GLbyte* Reference::ReferenceData<glw::GLbyte, false>()
{
	static const glw::GLbyte reference[s_reference_count] = {
		0,  -1,  2,  -3,  4,  -5,  6,  -7,  8,  -9,  10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23,
		24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47,
		48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71,
		72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95
	};
	return reference;
}

/* RGBA8UI */
template <>
const glw::GLubyte* Reference::ReferenceData<glw::GLubyte, false>()
{
	static const glw::GLubyte reference[s_reference_count] = {
		0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
		24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
		48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
		72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
	};
	return reference;
}

/* RGBA16I */
template <>
const glw::GLshort* Reference::ReferenceData<glw::GLshort, false>()
{
	static const glw::GLshort reference[s_reference_count] = {
		0,  -1,  2,  -3,  4,  -5,  6,  -7,  8,  -9,  10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23,
		24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47,
		48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71,
		72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95
	};
	return reference;
}

/* RGBA16UI */
template <>
const glw::GLushort* Reference::ReferenceData<glw::GLushort, false>()
{
	static const glw::GLushort reference[s_reference_count] = {
		0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
		24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
		48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
		72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
	};
	return reference;
}

/* RGBA32I */
template <>
const glw::GLint* Reference::ReferenceData<glw::GLint, false>()
{
	static const glw::GLint reference[s_reference_count] = {
		0,  -1,  2,  -3,  4,  -5,  6,  -7,  8,  -9,  10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23,
		24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47,
		48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71,
		72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95
	};
	return reference;
}

/* RGBA32UI */
template <>
const glw::GLuint* Reference::ReferenceData<glw::GLuint, false>()
{
	static const glw::GLuint reference[s_reference_count] = {
		0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
		24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
		48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
		72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
	};
	return reference;
}

/* RGBA8 */
template <>
const glw::GLubyte* Reference::ReferenceData<glw::GLubyte, true>()
{
	static const glw::GLubyte reference[s_reference_count] = {
		0,   2,   5,   8,   10,  13,  16,  18,  21,  24,  26,  29,  32,  34,  37,  40,  42,  45,  48,  51,
		53,  56,  59,  61,  64,  67,  69,  72,  75,  77,  80,  83,  85,  88,  91,  93,  96,  99,  102, 104,
		107, 110, 112, 115, 118, 120, 123, 126, 128, 131, 134, 136, 139, 142, 144, 147, 150, 153, 155, 158,
		161, 163, 166, 169, 171, 174, 177, 179, 182, 185, 187, 190, 193, 195, 198, 201, 204, 206, 209, 212,
		214, 217, 220, 222, 225, 228, 230, 233, 236, 238, 241, 244, 246, 249, 252, 255
	};
	return reference;
}

/* RGBA16 */
template <>
const glw::GLushort* Reference::ReferenceData<glw::GLushort, true>()
{
	static const glw::GLushort reference[s_reference_count] = {
		0,	 689,   1379,  2069,  2759,  3449,  4139,  4828,  5518,  6208,  6898,  7588,  8278,  8967,  9657,  10347,
		11037, 11727, 12417, 13107, 13796, 14486, 15176, 15866, 16556, 17246, 17935, 18625, 19315, 20005, 20695, 21385,
		22074, 22764, 23454, 24144, 24834, 25524, 26214, 26903, 27593, 28283, 28973, 29663, 30353, 31042, 31732, 32422,
		33112, 33802, 34492, 35181, 35871, 36561, 37251, 37941, 38631, 39321, 40010, 40700, 41390, 42080, 42770, 43460,
		44149, 44839, 45529, 46219, 46909, 47599, 48288, 48978, 49668, 50358, 51048, 51738, 52428, 53117, 53807, 54497,
		55187, 55877, 56567, 57256, 57946, 58636, 59326, 60016, 60706, 61395, 62085, 62775, 63465, 64155, 64845, 65535
	};
	return reference;
}

/* RGBA32F */
template <>
const glw::GLfloat* Reference::ReferenceData<glw::GLfloat, true>()
{
	static const glw::GLfloat reference[s_reference_count] = {
		0.f,		   0.0105263158f, 0.0210526316f, 0.0315789474f, 0.0421052632f, 0.0526315789f,
		0.0631578947f, 0.0736842105f, 0.0842105263f, 0.0947368421f, 0.1052631579f, 0.1157894737f,
		0.1263157895f, 0.1368421053f, 0.1473684211f, 0.1578947368f, 0.1684210526f, 0.1789473684f,
		0.1894736842f, 0.2f,		  0.2105263158f, 0.2210526316f, 0.2315789474f, 0.2421052632f,
		0.2526315789f, 0.2631578947f, 0.2736842105f, 0.2842105263f, 0.2947368421f, 0.3052631579f,
		0.3157894737f, 0.3263157895f, 0.3368421053f, 0.3473684211f, 0.3578947368f, 0.3684210526f,
		0.3789473684f, 0.3894736842f, 0.4f,			 0.4105263158f, 0.4210526316f, 0.4315789474f,
		0.4421052632f, 0.4526315789f, 0.4631578947f, 0.4736842105f, 0.4842105263f, 0.4947368421f,
		0.5052631579f, 0.5157894737f, 0.5263157895f, 0.5368421053f, 0.5473684211f, 0.5578947368f,
		0.5684210526f, 0.5789473684f, 0.5894736842f, 0.6f,			0.6105263158f, 0.6210526316f,
		0.6315789474f, 0.6421052632f, 0.6526315789f, 0.6631578947f, 0.6736842105f, 0.6842105263f,
		0.6947368421f, 0.7052631579f, 0.7157894737f, 0.7263157895f, 0.7368421053f, 0.7473684211f,
		0.7578947368f, 0.7684210526f, 0.7789473684f, 0.7894736842f, 0.8f,		   0.8105263158f,
		0.8210526316f, 0.8315789474f, 0.8421052632f, 0.8526315789f, 0.8631578947f, 0.8736842105f,
		0.8842105263f, 0.8947368421f, 0.9052631579f, 0.9157894737f, 0.9263157895f, 0.9368421053f,
		0.9473684211f, 0.9578947368f, 0.9684210526f, 0.9789473684f, 0.9894736842f, 1.f
	};
	return reference;
}

/* Total number of reference components. */
glw::GLuint Reference::ReferenceDataCount()
{
	return s_reference_count;
}

/* Total number of reference size in basic machine units. */
template <typename T>
glw::GLuint Reference::ReferenceDataSize()
{
	return Reference::ReferenceDataCount() * sizeof(T);
}

/** @brief Comparison function (for floats).
 *
 *  @param [in] a      First element.
 *  @param [in] b      Second element.
 *
 *  @return Comparison result.
 */
template <>
bool Reference::Compare<glw::GLfloat>(const glw::GLfloat a, const glw::GLfloat b)
{
	if (de::abs(a - b) < 1.f / 256.f)
	{
		return true;
	}
	return false;
}

/** @brief Comparison function (integer).
 *
 *  @param [in] a      First element.
 *  @param [in] b      Second element.
 *
 *  @return Comparison result.
 */
template <typename T>
bool Reference::Compare(const T a, const T b)
{
	return a == b;
}

/******************************** Buffer Test Implementation   ********************************/

/** @brief Buffer Test constructor.
 *
 *  @tparam T      Type.
 *  @tparam S      Size.
 *  @tparam N      Is normalized.
 *
 *  @param [in] context     OpenGL context.
 *  @param [in] name     Name of the test.
 */
template <typename T, glw::GLint S, bool N>
BufferTest<T, S, N>::BufferTest(deqp::Context& context, const char* name)
	: deqp::TestCase(context, name, "Texture Buffer Objects Test")
	, m_fbo(0)
	, m_rbo(0)
	, m_po(0)
	, m_to(0)
	, m_bo(0)
	, m_vao(0)
{
	/* Intentionally left blank. */
}

/** @brief Count of reference data to be teted.
 *
 *  @return Count.
 */
template <typename T, glw::GLint S, bool N>
glw::GLuint BufferTest<T, S, N>::TestReferenceDataCount()
{
	return s_fbo_size_x * S;
}

/** @brief Size of reference data to be teted..
 *
 *  @return Size.
 */
template <typename T, glw::GLint S, bool N>
glw::GLuint BufferTest<T, S, N>::TestReferenceDataSize()
{
	return static_cast<glw::GLint>(TestReferenceDataCount() * sizeof(T));
}

/** @brief Create buffer textuew.
 *
 *  @param [in] use_range_version       Uses TextureBufferRange instead TextureBuffer.
 *
 *  @return True if succeded, false otherwise.
 */
template <typename T, glw::GLint S, bool N>
bool BufferTest<T, S, N>::CreateBufferTexture(bool use_range_version)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Objects creation. */
	gl.genTextures(1, &m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(GL_TEXTURE_BUFFER, m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.genBuffers(1, &m_bo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");

	gl.bindBuffer(GL_TEXTURE_BUFFER, m_bo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

	/* Data setup. */
	if (use_range_version)
	{
		glw::GLint alignment = 1;

		gl.getIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &alignment);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

		const glw::GLuint b_offset = alignment;
		const glw::GLuint b_size   = TestReferenceDataSize() + b_offset;

		gl.bufferData(GL_TEXTURE_BUFFER, b_size, NULL, GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData has failed");

		gl.bufferSubData(GL_TEXTURE_BUFFER, b_offset, TestReferenceDataSize(), ReferenceData<T, N>());
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubdata has failed");

		gl.textureBufferRange(m_to, InternalFormat<T, S, N>(), m_bo, b_offset, TestReferenceDataSize());
	}
	else
	{
		gl.bufferData(GL_TEXTURE_BUFFER, TestReferenceDataSize(), ReferenceData<T, N>(), GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");

		gl.textureBuffer(m_to, InternalFormat<T, S, N>(), m_bo);
	}

	/* Error checking. */
	glw::GLenum error;

	if (GL_NO_ERROR != (error = gl.getError()))
	{
		/* Log. */
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << (use_range_version ? ("glTextureBufferRange") : ("glTextureBuffer"))
			<< " unexpectedly generated error " << glu::getErrorStr(error) << " during test of internal format "
			<< glu::getTextureFormatStr(InternalFormat<T, S, N>()) << "." << tcu::TestLog::EndMessage;

		CleanBufferTexture();

		return false;
	}

	return true;
}

/** @brief Function prepares framebuffer with internal format color attachment.
 *         Viewport is set up. Content of the framebuffer is cleared.
 *
 *  @note The function may throw if unexpected error has occured.
 *
 *  @return if the framebuffer returned is supported
 */
template <typename T, glw::GLint S, bool N>
bool BufferTest<T, S, N>::PrepareFramebuffer(const glw::GLenum internal_format)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare framebuffer. */
	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.genRenderbuffers(1, &m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	gl.renderbufferStorage(GL_RENDERBUFFER, internal_format, s_fbo_size_x, s_fbo_size_y);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED)
			throw tcu::NotSupportedError("unsupported framebuffer configuration");
		else
			throw 0;
	}

	gl.viewport(0, 0, s_fbo_size_x, s_fbo_size_y);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");

	/* Clear framebuffer's content. */
	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

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

	return true;
}

/** @brief Create program.
 *
 *  @param [in] variable_declaration    Choose variable declaration of the fragment shader.
 */
template <typename T, glw::GLint S, bool N>
void BufferTest<T, S, N>::PrepareProgram(const glw::GLchar* variable_declaration)
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	struct Shader
	{
		glw::GLchar const* source[3];
		glw::GLsizei const count;
		glw::GLenum const  type;
		glw::GLuint		   id;
	} shader[] = {
		{ { s_vertex_shader, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 },
		{ { s_fragment_shader_head, variable_declaration, s_fragment_shader_tail }, 3, GL_FRAGMENT_SHADER, 0 }
	};

	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);

	try
	{
		/* Create program. */
		m_po = gl.createProgram();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

		/* Shader compilation. */

		for (glw::GLuint i = 0; i < shader_count; ++i)
		{
			{
				shader[i].id = gl.createShader(shader[i].type);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

				gl.attachShader(m_po, shader[i].id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

				gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

				gl.compileShader(shader[i].id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

				glw::GLint status = GL_FALSE;

				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

				if (GL_FALSE == status)
				{
					glw::GLint log_size = 0;
					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

					glw::GLchar* log_text = new glw::GLchar[log_size];

					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "Shader compilation has failed.\n"
						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
						<< "Shader compilation error log:\n"
						<< log_text << "\n"
						<< "Shader source code:\n"
						<< shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "")
						<< (shader[i].source[2] ? shader[i].source[2] : "") << "\n"
						<< tcu::TestLog::EndMessage;

					delete[] log_text;

					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

					throw 0;
				}
			}
		}

		/* Link. */
		gl.linkProgram(m_po);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

		glw::GLint status = GL_FALSE;

		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

		if (GL_TRUE == status)
		{
			for (glw::GLuint i = 0; i < shader_count; ++i)
			{
				if (shader[i].id)
				{
					gl.detachShader(m_po, shader[i].id);

					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
				}
			}
		}
		else
		{
			glw::GLint log_size = 0;

			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

			glw::GLchar* log_text = new glw::GLchar[log_size];

			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
												<< log_text << "\n"
												<< tcu::TestLog::EndMessage;

			delete[] log_text;

			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

			throw 0;
		}
	}
	catch (...)
	{
		if (m_po)
		{
			gl.deleteProgram(m_po);

			m_po = 0;
		}
	}

	for (glw::GLuint i = 0; i < shader_count; ++i)
	{
		if (0 != shader[i].id)
		{
			gl.deleteShader(shader[i].id);

			shader[i].id = 0;
		}
	}

	if (0 == m_po)
	{
		throw 0;
	}
}

/** @brief Create VAO.
 */
template <typename T, glw::GLint S, bool N>
void BufferTest<T, S, N>::PrepareVertexArray()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays has failed");

	gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray has failed");
}

/** @brief Test's draw function.
 */
template <typename T, glw::GLint S, bool N>
void BufferTest<T, S, N>::Draw()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(m_po);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed");

	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");

	gl.bindTextureUnit(0, m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
}

/** @brief Compre results with the reference.
 *
 *  @return True if equal, false otherwise.
 */
template <typename T, glw::GLint S, bool N>
bool BufferTest<T, S, N>::Check()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching data. */
	std::vector<T> result(TestReferenceDataCount());

	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(T));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(T));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	gl.readnPixels(0, 0, s_fbo_size_x, s_fbo_size_y, Format<S, N>(), Type<T>(), TestReferenceDataSize(),
				   (glw::GLvoid*)(&result[0]));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

	/* Comparison. */
	bool is_ok = true;

	for (glw::GLuint i = 0; i < TestReferenceDataCount(); ++i)
	{
		if (!Compare<T>(result[i], ReferenceData<T, N>()[i]))
		{
			is_ok = false;

			break;
		}
	}

	return is_ok;
}

/** @brief Test function.
 *
 *  @param [in] use_range_version   Uses TextureBufferRange instead TextureBuffer.
 *
 *  @return True if succeeded, false otherwise.
 */
template <typename T, glw::GLint S, bool N>
bool BufferTest<T, S, N>::Test(bool use_range_version)
{
	/* Setup. */
	if (!PrepareFramebuffer(InternalFormat<T, S, N>()))
	{
		/**
                 * If the framebuffer it not supported, means that the
                 * tested combination is unsupported for this driver,
                 * but allowed to be unsupported by OpenGL spec, so we
                 * just skip.
                 */
		CleanFramebuffer();
		CleanErrors();

		return true;
	}

	if (!CreateBufferTexture(use_range_version))
	{
		CleanFramebuffer();
		CleanErrors();

		return false;
	}

	/* Action. */
	Draw();

	/* Compare results with reference. */
	bool result = Check();

	/* Cleanup. */
	CleanFramebuffer();
	CleanBufferTexture();
	CleanErrors();

	/* Pass result. */
	return result;
}

/** @brief Clean GL objects
 */
template <typename T, glw::GLint S, bool N>
void BufferTest<T, S, N>::CleanBufferTexture()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Texture. */
	if (m_to)
	{
		gl.deleteTextures(1, &m_to);

		m_to = 0;
	}

	/* Texture buffer. */
	if (m_bo)
	{
		gl.deleteBuffers(1, &m_bo);

		m_bo = 0;
	}
}

/** @brief Clean GL objects
 */
template <typename T, glw::GLint S, bool N>
void BufferTest<T, S, N>::CleanFramebuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Framebuffer. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	/* Renderbuffer. */
	if (m_rbo)
	{
		gl.deleteRenderbuffers(1, &m_rbo);

		m_rbo = 0;
	}
}

/** @brief Clean GL objects
 */
template <typename T, glw::GLint S, bool N>
void BufferTest<T, S, N>::CleanProgram()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Program. */
	if (m_po)
	{
		gl.useProgram(0);

		gl.deleteProgram(m_po);

		m_po = 0;
	}
}

/** @brief Clean errors.
 */
template <typename T, glw::GLint S, bool N>
void BufferTest<T, S, N>::CleanErrors()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Query all errors until GL_NO_ERROR occure. */
	while (GL_NO_ERROR != gl.getError())
		;
}

/** @brief Clean GL objects
 */
template <typename T, glw::GLint S, bool N>
void BufferTest<T, S, N>::CleanVertexArray()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_vao)
	{
		gl.bindVertexArray(0);

		gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}
}

/** @brief Iterate Buffer Test cases.
 *
 *  @return Iteration result.
 */
template <typename T, glw::GLint S, bool N>
tcu::TestNode::IterateResult BufferTest<T, S, N>::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		PrepareVertexArray();

		PrepareProgram(FragmentShaderDeclaration());

		for (glw::GLuint i = 0; i < 2; ++i)
		{
			bool use_range = (i == 1);
			is_ok &= Test(use_range);
			CleanErrors();
		}

		CleanProgram();
	}
	catch (tcu::NotSupportedError& e)
	{
		throw e;
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	CleanBufferTexture();
	CleanFramebuffer();
	CleanProgram();
	CleanErrors();
	CleanVertexArray();

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/* Vertex shader source code. */
template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_vertex_shader = "#version 450\n"
														  "\n"
														  "void main()\n"
														  "{\n"
														  "    switch(gl_VertexID)\n"
														  "    {\n"
														  "        case 0:\n"
														  "            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
														  "            break;\n"
														  "        case 1:\n"
														  "            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
														  "            break;\n"
														  "        case 2:\n"
														  "            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
														  "            break;\n"
														  "        case 3:\n"
														  "            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
														  "            break;\n"
														  "    }\n"
														  "}\n";

/* Fragment shader source program. */
template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_head = "#version 450\n"
																 "\n"
																 "layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
																 "\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_fdecl_lowp = "uniform samplerBuffer texture_input;\n"
																	   "out     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_idecl_lowp = "uniform isamplerBuffer texture_input;\n"
																	   "out     ivec4          texture_output;\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_udecl_lowp = "uniform usamplerBuffer texture_input;\n"
																	   "out     uvec4          texture_output;\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_fdecl_mediump = "uniform samplerBuffer texture_input;\n"
																		  "out     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_idecl_mediump = "uniform isamplerBuffer texture_input;\n"
																		  "out     ivec4          texture_output;\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_udecl_mediump = "uniform usamplerBuffer texture_input;\n"
																		  "out     uvec4          texture_output;\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_fdecl_highp = "uniform samplerBuffer texture_input;\n"
																		"out     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_idecl_highp = "uniform isamplerBuffer texture_input;\n"
																		"out     ivec4          texture_output;\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_udecl_highp = "uniform usamplerBuffer texture_input;\n"
																		"out     uvec4          texture_output;\n";

template <typename T, glw::GLint S, bool N>
const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_tail =
	"\n"
	"void main()\n"
	"{\n"
	"    texture_output = texelFetch(texture_input, int(gl_FragCoord.x));\n"
	"}\n";

template class BufferTest<glw::GLbyte, 1, false>;
template class BufferTest<glw::GLbyte, 2, false>;
template class BufferTest<glw::GLbyte, 4, false>;

template class BufferTest<glw::GLubyte, 1, false>;
template class BufferTest<glw::GLubyte, 2, false>;
template class BufferTest<glw::GLubyte, 4, false>;
template class BufferTest<glw::GLubyte, 1, true>;
template class BufferTest<glw::GLubyte, 2, true>;
template class BufferTest<glw::GLubyte, 4, true>;

template class BufferTest<glw::GLshort, 1, false>;
template class BufferTest<glw::GLshort, 2, false>;
template class BufferTest<glw::GLshort, 4, false>;

template class BufferTest<glw::GLushort, 1, false>;
template class BufferTest<glw::GLushort, 2, false>;
template class BufferTest<glw::GLushort, 4, false>;
template class BufferTest<glw::GLushort, 1, true>;
template class BufferTest<glw::GLushort, 2, true>;
template class BufferTest<glw::GLushort, 4, true>;

template class BufferTest<glw::GLint, 1, false>;
template class BufferTest<glw::GLint, 2, false>;
template class BufferTest<glw::GLint, 3, false>;
template class BufferTest<glw::GLint, 4, false>;

template class BufferTest<glw::GLuint, 1, false>;
template class BufferTest<glw::GLuint, 2, false>;
template class BufferTest<glw::GLuint, 3, false>;
template class BufferTest<glw::GLuint, 4, false>;

template class BufferTest<glw::GLfloat, 1, true>;
template class BufferTest<glw::GLfloat, 2, true>;
template class BufferTest<glw::GLfloat, 3, true>;
template class BufferTest<glw::GLfloat, 4, true>;

/******************************** Storage and SubImage Test Implementation   ********************************/

/** @brief Storage Test constructor.
 *
 *  @tparam T      Type.
 *  @tparam S      Size.
 *  @tparam N      Is normalized.
 *  @tparam D      Texture dimension.
 *  @tparam I      Choose between SubImage and Storage tests.
 *
 *  @param [in] context     OpenGL context.
 *  @param [in] name        Name of the test.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
StorageAndSubImageTest<T, S, N, D, I>::StorageAndSubImageTest(deqp::Context& context, const char* name)
	: deqp::TestCase(context, name, "Texture Storage and SubImage Test")
	, m_fbo(0)
	, m_rbo(0)
	, m_po(0)
	, m_to(0)
	, m_vao(0)
{
	/* Intentionally left blank. */
}

/** @brief Count of reference data to be teted.
 *
 *  @return Count.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataCount()
{
	return 2 /* 1D */ * ((D > 1) ? 3 : 1) /* 2D */ * ((D > 2) ? 4 : 1) /* 3D */ * S /* components */;
}

/** @brief Size of reference data to be teted.
 *
 *  @tparam T      Type.
 *  @tparam S      Size (# of components).
 *  @tparam D      Texture dimenisons.
 *
 *  @return Size.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataSize()
{
	return static_cast<glw::GLint>(TestReferenceDataCount() * sizeof(T));
}

/** @brief Height, width or depth of reference data to be teted.
 *
 *  @return Height, width or depth.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataHeight()
{
	switch (D)
	{
	case 2:
	case 3:
		return 3;
	default:
		return 1;
	}
}

template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataDepth()
{
	switch (D)
	{
	case 3:
		return 4;
	default:
		return 1;
	}
}

template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataWidth()
{
	return 2;
}

/** @brief Fragment shader declaration selector.
 *
 *  @return Frgment shader source code part.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::FragmentShaderDeclaration()
{
	if (typeid(T) == typeid(glw::GLbyte))
	{
		switch (D)
		{
		case 1:
			return s_fragment_shader_1D_idecl_lowp;
		case 2:
			return s_fragment_shader_2D_idecl_lowp;
		case 3:
			return s_fragment_shader_3D_idecl_lowp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLubyte))
	{
		if (N)
		{
			switch (D)
			{
			case 1:
				return s_fragment_shader_1D_fdecl_lowp;
			case 2:
				return s_fragment_shader_2D_fdecl_lowp;
			case 3:
				return s_fragment_shader_3D_fdecl_lowp;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
		else
		{
			switch (D)
			{
			case 1:
				return s_fragment_shader_1D_udecl_lowp;
			case 2:
				return s_fragment_shader_2D_udecl_lowp;
			case 3:
				return s_fragment_shader_3D_udecl_lowp;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
	}

	if (typeid(T) == typeid(glw::GLshort))
	{
		switch (D)
		{
		case 1:
			return s_fragment_shader_1D_idecl_mediump;
		case 2:
			return s_fragment_shader_2D_idecl_mediump;
		case 3:
			return s_fragment_shader_3D_idecl_mediump;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLushort))
	{
		if (N)
		{
			switch (D)
			{
			case 1:
				return s_fragment_shader_1D_fdecl_mediump;
			case 2:
				return s_fragment_shader_2D_fdecl_mediump;
			case 3:
				return s_fragment_shader_3D_fdecl_mediump;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
		else
		{
			switch (D)
			{
			case 1:
				return s_fragment_shader_1D_udecl_mediump;
			case 2:
				return s_fragment_shader_2D_udecl_mediump;
			case 3:
				return s_fragment_shader_3D_udecl_mediump;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
	}

	if (typeid(T) == typeid(glw::GLint))
	{
		switch (D)
		{
		case 1:
			return s_fragment_shader_1D_idecl_highp;
		case 2:
			return s_fragment_shader_2D_idecl_highp;
		case 3:
			return s_fragment_shader_3D_idecl_highp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLuint))
	{
		switch (D)
		{
		case 1:
			return s_fragment_shader_1D_udecl_highp;
		case 2:
			return s_fragment_shader_2D_udecl_highp;
		case 3:
			return s_fragment_shader_3D_udecl_highp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	switch (D)
	{
	case 1:
		return s_fragment_shader_1D_fdecl_highp;
	case 2:
		return s_fragment_shader_2D_fdecl_highp;
	case 3:
		return s_fragment_shader_3D_fdecl_highp;
	default:
		DE_FATAL("invalid texture dimension");
		return DE_NULL;
	}
}

/** @brief Fragment shader tail selector.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @return Frgment shader source code part.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::FragmentShaderTail()
{
	switch (D)
	{
	case 1:
		return s_fragment_shader_1D_tail;
	case 2:
		return s_fragment_shader_2D_tail;
	case 3:
		return s_fragment_shader_3D_tail;
	default:
		DE_FATAL("invalid texture dimension");
		return DE_NULL;
	}
}

/** @brief Texture target selector.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @return Texture target.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
glw::GLenum StorageAndSubImageTest<T, S, N, D, I>::TextureTarget()
{
	switch (D)
	{
	case 1:
		return GL_TEXTURE_1D;
	case 2:
		return GL_TEXTURE_2D;
	case 3:
		return GL_TEXTURE_3D;
	default:
		DE_FATAL("invalid texture dimension");
		return DE_NULL;
	}
}

/** @brief TextureStorage* wrapper.
 *
 *  @return true if succeed (in legacy always or throw), false otherwise.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
bool StorageAndSubImageTest<T, S, N, D, I>::TextureStorage(glw::GLenum target, glw::GLuint texture, glw::GLsizei levels,
														   glw::GLenum internalformat, glw::GLsizei width,
														   glw::GLsizei height, glw::GLsizei depth)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (I)
	{
		switch (D)
		{
		case 1:
			gl.texStorage1D(target, levels, internalformat, width);
			break;
		case 2:
			gl.texStorage2D(target, levels, internalformat, width, height);
			break;
		case 3:
			gl.texStorage3D(target, levels, internalformat, width, height, depth);
			break;
		default:
			DE_FATAL("invalid texture dimension");
		}

		/* TextureSubImage* (not TextureStorage*) is tested */
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage*() has failed");
		return true;
	}
	else
	{
		switch (D)
		{
		case 1:
			gl.textureStorage1D(texture, levels, internalformat, width);
			break;
		case 2:
			gl.textureStorage2D(texture, levels, internalformat, width, height);
			break;
		case 3:
			gl.textureStorage3D(texture, levels, internalformat, width, height, depth);
			break;
		default:
			DE_FATAL("invalid texture dimension");
		}

		glw::GLenum error;
		if (GL_NO_ERROR != (error = gl.getError()))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glTextureStorage" << D << "D unexpectedly generated error " << glu::getErrorStr(error)
				<< " during test with levels " << levels << ", internal format " << internalformat
				<< " width=" << width << " height=" << height << " depth=" << depth
				<< "." << tcu::TestLog::EndMessage;

			CleanTexture();
			CleanErrors();

			return false;
		}

		return true;
	}
}

/** @brief TextureSubImage* wrapper.
 *
 *  @return true if suuceed (in legacy always or throw), false otherwise.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
bool StorageAndSubImageTest<T, S, N, D, I>::TextureSubImage(glw::GLenum target, glw::GLuint texture, glw::GLint level,
															glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth,
															glw::GLenum format, glw::GLenum type, const glw::GLvoid* data)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (I)
	{
		switch (D)
		{
		case 1:
			gl.textureSubImage1D(texture, level, 0, width, format, type, data);
			break;
		case 2:
			gl.textureSubImage2D(texture, level, 0, 0, width, height, format, type, data);
			break;
		case 3:
			gl.textureSubImage3D(texture, level, 0, 0, 0, width, height, depth, format, type, data);
			break;
		default:
			DE_FATAL("invalid texture dimension");
		}

		glw::GLenum error;
		if (GL_NO_ERROR != (error = gl.getError()))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glTextureSubImage" << D << "D unexpectedly generated error " << glu::getErrorStr(error)
				<< " during test with level " << level << ", width=" << width << ", height=" << height << ", depth=" << depth
				<< " format " << glu::getTextureFormatStr(format) << " and type " << glu::getTypeStr(type) << "."
				<< tcu::TestLog::EndMessage;

			CleanTexture();
			CleanErrors();

			return false;
		}

		return true;
	}
	else
	{
		switch (D)
		{
		case 1:
			gl.texSubImage1D(target, level, 0, width, format, type, data);
			break;
		case 2:
			gl.texSubImage2D(target, level, 0, 0, width, height, format, type, data);
			break;
		case 3:
			gl.texSubImage3D(target, level, 0, 0, 0, width, height, depth, format, type, data);
			break;
		default:
			DE_FATAL("invalid texture dimension");
		}

		/* TextureStorage* (not TextureSubImage) is tested */
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage*() has failed");
		return true;
	}
}

/** @brief Create texture.
 *
 *  @tparam T      Type.
 *  @tparam S      Size (# of components).
 *  @tparam N      Is normalized.
 *  @tparam D      Dimmensions.
 *  @tparam I      Test SubImage or Storage.
 *
 *  @return True if succeded, false otherwise.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
bool StorageAndSubImageTest<T, S, N, D, I>::CreateTexture()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Objects creation. */
	gl.genTextures(1, &m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(TextureTarget(), m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	/* Storage creation. */
	if (TextureStorage(TextureTarget(), m_to, 1, InternalFormat<T, S, N>(), TestReferenceDataWidth(),
					   TestReferenceDataHeight(), TestReferenceDataDepth()))
	{
		/* Data setup. */
		if (TextureSubImage(TextureTarget(), m_to, 0, TestReferenceDataWidth(), TestReferenceDataHeight(), TestReferenceDataDepth(),
							Format<S, N>(), Type<T>(), ReferenceData<T, N>()))
		{
			glTexParameteri(TextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri(TextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			return true;
		}
	}

	CleanTexture();

	return false;
}

/** @brief Compre results with the reference.
 *
 *  @return True if equal, false otherwise.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
bool StorageAndSubImageTest<T, S, N, D, I>::Check()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching data. */
	std::vector<T> result(TestReferenceDataCount());

	glw::GLuint fbo_size_x = 0;

	switch (D)
	{
	case 1:
		fbo_size_x = 2;
		break;
	case 2:
		fbo_size_x = 2 * 3;
		break;
	case 3:
		fbo_size_x = 2 * 3 * 4;
		break;
	default:
		throw 0;
	}

	gl.readnPixels(0, 0, fbo_size_x, 1, Format<S, N>(), Type<T>(), TestReferenceDataSize(),
				   (glw::GLvoid*)(&result[0]));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");

	/* Comparison. */
	for (glw::GLuint i = 0; i < TestReferenceDataCount(); ++i)
	{
		if (!Compare<T>(result[i], ReferenceData<T, N>()[i]))
		{
			return false;
		}
	}

	return true;
}

/** @brief Test case function.
 *
 *  @return True if test succeeded, false otherwise.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
bool StorageAndSubImageTest<T, S, N, D, I>::Test()
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(T));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(T));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	/* Setup. */
	PrepareFramebuffer(InternalFormat<T, S, N>());

	if (!CreateTexture())
	{
		return false;
	}

	/* Action. */
	Draw();

	/* Compare results with reference. */
	bool result = Check();

	/* Cleanup. */
	CleanTexture();
	CleanFramebuffer();
	CleanErrors();

	/* Pass result. */
	return result;
}

/** @brief Function prepares framebuffer with internal format color attachment.
 *         Viewport is set up. Content of the framebuffer is cleared.
 *
 *  @note The function may throw if unexpected error has occured.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
void StorageAndSubImageTest<T, S, N, D, I>::PrepareFramebuffer(const glw::GLenum internal_format)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare framebuffer. */
	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.genRenderbuffers(1, &m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	glw::GLuint fbo_size_x = 0;

	switch (D)
	{
	case 1:
		fbo_size_x = 2;
		break;
	case 2:
		fbo_size_x = 2 * 3;
		break;
	case 3:
		fbo_size_x = 2 * 3 * 4;
		break;
	default:
		throw 0;
	}

	gl.renderbufferStorage(GL_RENDERBUFFER, internal_format, fbo_size_x, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED)
			throw tcu::NotSupportedError("unsupported framebuffer configuration");
		else
			throw 0;
	}

	gl.viewport(0, 0, fbo_size_x, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");

	/* Clear framebuffer's content. */
	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

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

/** @brief Prepare program
 *
 *  @param [in] variable_declaration      Variables declaration part of fragment shader source code.
 *  @param [in] tail                      Tail part of fragment shader source code.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
void StorageAndSubImageTest<T, S, N, D, I>::PrepareProgram(const glw::GLchar* variable_declaration, const glw::GLchar* tail)
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	struct Shader
	{
		glw::GLchar const* source[3];
		glw::GLsizei const count;
		glw::GLenum const  type;
		glw::GLuint		   id;
	} shader[] = { { { s_vertex_shader, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 },
				   { { s_fragment_shader_head, variable_declaration, tail }, 3, GL_FRAGMENT_SHADER, 0 } };

	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);

	try
	{
		/* Create program. */
		m_po = gl.createProgram();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

		/* Shader compilation. */

		for (glw::GLuint i = 0; i < shader_count; ++i)
		{
			{
				shader[i].id = gl.createShader(shader[i].type);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

				gl.attachShader(m_po, shader[i].id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

				gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

				gl.compileShader(shader[i].id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

				glw::GLint status = GL_FALSE;

				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

				if (GL_FALSE == status)
				{
					glw::GLint log_size = 0;
					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

					glw::GLchar* log_text = new glw::GLchar[log_size];

					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "Shader compilation has failed.\n"
						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
						<< "Shader compilation error log:\n"
						<< log_text << "\n"
						<< "Shader source code:\n"
						<< shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "")
						<< (shader[i].source[2] ? shader[i].source[2] : "") << "\n"
						<< tcu::TestLog::EndMessage;

					delete[] log_text;

					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

					throw 0;
				}
			}
		}

		/* Link. */
		gl.linkProgram(m_po);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

		glw::GLint status = GL_FALSE;

		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

		if (GL_TRUE == status)
		{
			for (glw::GLuint i = 0; i < shader_count; ++i)
			{
				if (shader[i].id)
				{
					gl.detachShader(m_po, shader[i].id);

					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
				}
			}
		}
		else
		{
			glw::GLint log_size = 0;

			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

			glw::GLchar* log_text = new glw::GLchar[log_size];

			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
												<< log_text << "\n"
												<< tcu::TestLog::EndMessage;

			delete[] log_text;

			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

			throw 0;
		}
	}
	catch (...)
	{
		if (m_po)
		{
			gl.deleteProgram(m_po);

			m_po = 0;
		}
	}

	for (glw::GLuint i = 0; i < shader_count; ++i)
	{
		if (0 != shader[i].id)
		{
			gl.deleteShader(shader[i].id);

			shader[i].id = 0;
		}
	}

	if (0 == m_po)
	{
		throw 0;
	}
}

/** @brief Prepare VAO.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
void StorageAndSubImageTest<T, S, N, D, I>::PrepareVertexArray()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays has failed");

	gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray has failed");
}

/** @brief Test's draw call.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
void StorageAndSubImageTest<T, S, N, D, I>::Draw()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.useProgram(m_po);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed");

	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");

	gl.bindTextureUnit(0, m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");

	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
void StorageAndSubImageTest<T, S, N, D, I>::CleanTexture()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Texture. */
	if (m_to)
	{
		gl.deleteTextures(1, &m_to);

		m_to = 0;
	}
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
void StorageAndSubImageTest<T, S, N, D, I>::CleanFramebuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Framebuffer. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	/* Renderbuffer. */
	if (m_rbo)
	{
		gl.deleteRenderbuffers(1, &m_rbo);

		m_rbo = 0;
	}
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
void StorageAndSubImageTest<T, S, N, D, I>::CleanProgram()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Program. */
	if (m_po)
	{
		gl.useProgram(0);

		gl.deleteProgram(m_po);

		m_po = 0;
	}
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
void StorageAndSubImageTest<T, S, N, D, I>::CleanErrors()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Query all errors until GL_NO_ERROR occure. */
	while (GL_NO_ERROR != gl.getError())
		;
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
void StorageAndSubImageTest<T, S, N, D, I>::CleanVertexArray()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_vao)
	{
		gl.bindVertexArray(0);

		gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}
}

/** @brief Iterate Storage Test cases.
 *
 *  @return Iteration result.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
tcu::TestNode::IterateResult StorageAndSubImageTest<T, S, N, D, I>::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		PrepareVertexArray();
		PrepareProgram(FragmentShaderDeclaration(), FragmentShaderTail());
		is_ok = Test();
	}
	catch (tcu::NotSupportedError& e)
	{
		throw e;
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	CleanTexture();
	CleanFramebuffer();
	CleanProgram();
	CleanErrors();
	CleanVertexArray();

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/* Vertex shader source code. */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_vertex_shader =
	"#version 450\n"
	"\n"
	"void main()\n"
	"{\n"
	"    switch(gl_VertexID)\n"
	"    {\n"
	"        case 0:\n"
	"            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
	"            break;\n"
	"        case 1:\n"
	"            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
	"            break;\n"
	"        case 2:\n"
	"            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
	"            break;\n"
	"        case 3:\n"
	"            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
	"            break;\n"
	"    }\n"
	"}\n";

/* Fragment shader source program. */
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_head =
	"#version 450\n"
	"\n"
	"layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
	"\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_fdecl_lowp =
	"uniform  sampler1D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_idecl_lowp =
	"uniform isampler1D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_udecl_lowp =
	"uniform usampler1D texture_input;\nout     uvec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_fdecl_mediump =
	"uniform  sampler1D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_idecl_mediump =
	"uniform isampler1D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_udecl_mediump =
	"uniform usampler1D texture_input;\nout     uvec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_fdecl_highp =
	"uniform  sampler1D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_idecl_highp =
	"uniform isampler1D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_udecl_highp =
	"uniform usampler1D texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_fdecl_lowp =
	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_idecl_lowp =
	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_udecl_lowp =
	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_fdecl_mediump =
	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_idecl_mediump =
	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_udecl_mediump =
	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_fdecl_highp =
	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_idecl_highp =
	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_udecl_highp =
	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_fdecl_lowp =
	"uniform  sampler3D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_idecl_lowp =
	"uniform isampler3D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_udecl_lowp =
	"uniform usampler3D texture_input;\nout     uvec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_fdecl_mediump =
	"uniform  sampler3D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_idecl_mediump =
	"uniform isampler3D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_udecl_mediump =
	"uniform usampler3D texture_input;\nout     uvec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_fdecl_highp =
	"uniform  sampler3D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_idecl_highp =
	"uniform isampler3D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_udecl_highp =
	"uniform usampler3D texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_tail =
	"\n"
	"void main()\n"
	"{\n"
	"    texture_output = texelFetch(texture_input, int(gl_FragCoord.x), 0);\n"
	"}\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_tail =
	"\n"
	"void main()\n"
	"{\n"
	"    texture_output = texelFetch(texture_input, ivec2(int(gl_FragCoord.x) % 2, int(floor(gl_FragCoord.x / 2))), "
	"0);\n"
	"}\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I>
const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_tail =
	"\n"
	"void main()\n"
	"{\n"
	"    texture_output = texelFetch(texture_input, ivec3(int(gl_FragCoord.x) % 2, int(floor(gl_FragCoord.x / 2)) % 3, "
	"int(floor(gl_FragCoord.x / 2 / 3))), 0);\n"
	"}\n";

template class StorageAndSubImageTest<glw::GLbyte, 1, false, 1, false>;
template class StorageAndSubImageTest<glw::GLbyte, 2, false, 1, false>;
template class StorageAndSubImageTest<glw::GLbyte, 4, false, 1, false>;
template class StorageAndSubImageTest<glw::GLbyte, 1, false, 2, false>;
template class StorageAndSubImageTest<glw::GLbyte, 2, false, 2, false>;
template class StorageAndSubImageTest<glw::GLbyte, 4, false, 2, false>;
template class StorageAndSubImageTest<glw::GLbyte, 1, false, 3, false>;
template class StorageAndSubImageTest<glw::GLbyte, 2, false, 3, false>;
template class StorageAndSubImageTest<glw::GLbyte, 4, false, 3, false>;

template class StorageAndSubImageTest<glw::GLubyte, 1, false, 1, false>;
template class StorageAndSubImageTest<glw::GLubyte, 2, false, 1, false>;
template class StorageAndSubImageTest<glw::GLubyte, 4, false, 1, false>;
template class StorageAndSubImageTest<glw::GLubyte, 1, false, 2, false>;
template class StorageAndSubImageTest<glw::GLubyte, 2, false, 2, false>;
template class StorageAndSubImageTest<glw::GLubyte, 4, false, 2, false>;
template class StorageAndSubImageTest<glw::GLubyte, 1, false, 3, false>;
template class StorageAndSubImageTest<glw::GLubyte, 2, false, 3, false>;
template class StorageAndSubImageTest<glw::GLubyte, 4, false, 3, false>;

template class StorageAndSubImageTest<glw::GLubyte, 1, true, 1, false>;
template class StorageAndSubImageTest<glw::GLubyte, 2, true, 1, false>;
template class StorageAndSubImageTest<glw::GLubyte, 4, true, 1, false>;
template class StorageAndSubImageTest<glw::GLubyte, 1, true, 2, false>;
template class StorageAndSubImageTest<glw::GLubyte, 2, true, 2, false>;
template class StorageAndSubImageTest<glw::GLubyte, 4, true, 2, false>;
template class StorageAndSubImageTest<glw::GLubyte, 1, true, 3, false>;
template class StorageAndSubImageTest<glw::GLubyte, 2, true, 3, false>;
template class StorageAndSubImageTest<glw::GLubyte, 4, true, 3, false>;

template class StorageAndSubImageTest<glw::GLshort, 1, false, 1, false>;
template class StorageAndSubImageTest<glw::GLshort, 2, false, 1, false>;
template class StorageAndSubImageTest<glw::GLshort, 4, false, 1, false>;
template class StorageAndSubImageTest<glw::GLshort, 1, false, 2, false>;
template class StorageAndSubImageTest<glw::GLshort, 2, false, 2, false>;
template class StorageAndSubImageTest<glw::GLshort, 4, false, 2, false>;
template class StorageAndSubImageTest<glw::GLshort, 1, false, 3, false>;
template class StorageAndSubImageTest<glw::GLshort, 2, false, 3, false>;
template class StorageAndSubImageTest<glw::GLshort, 4, false, 3, false>;

template class StorageAndSubImageTest<glw::GLushort, 1, false, 1, false>;
template class StorageAndSubImageTest<glw::GLushort, 2, false, 1, false>;
template class StorageAndSubImageTest<glw::GLushort, 4, false, 1, false>;
template class StorageAndSubImageTest<glw::GLushort, 1, false, 2, false>;
template class StorageAndSubImageTest<glw::GLushort, 2, false, 2, false>;
template class StorageAndSubImageTest<glw::GLushort, 4, false, 2, false>;
template class StorageAndSubImageTest<glw::GLushort, 1, false, 3, false>;
template class StorageAndSubImageTest<glw::GLushort, 2, false, 3, false>;
template class StorageAndSubImageTest<glw::GLushort, 4, false, 3, false>;

template class StorageAndSubImageTest<glw::GLushort, 1, true, 1, false>;
template class StorageAndSubImageTest<glw::GLushort, 2, true, 1, false>;
template class StorageAndSubImageTest<glw::GLushort, 4, true, 1, false>;
template class StorageAndSubImageTest<glw::GLushort, 1, true, 2, false>;
template class StorageAndSubImageTest<glw::GLushort, 2, true, 2, false>;
template class StorageAndSubImageTest<glw::GLushort, 4, true, 2, false>;
template class StorageAndSubImageTest<glw::GLushort, 1, true, 3, false>;
template class StorageAndSubImageTest<glw::GLushort, 2, true, 3, false>;
template class StorageAndSubImageTest<glw::GLushort, 4, true, 3, false>;

template class StorageAndSubImageTest<glw::GLint, 1, false, 1, false>;
template class StorageAndSubImageTest<glw::GLint, 2, false, 1, false>;
template class StorageAndSubImageTest<glw::GLint, 3, false, 1, false>;
template class StorageAndSubImageTest<glw::GLint, 4, false, 1, false>;
template class StorageAndSubImageTest<glw::GLint, 1, false, 2, false>;
template class StorageAndSubImageTest<glw::GLint, 2, false, 2, false>;
template class StorageAndSubImageTest<glw::GLint, 3, false, 2, false>;
template class StorageAndSubImageTest<glw::GLint, 4, false, 2, false>;
template class StorageAndSubImageTest<glw::GLint, 1, false, 3, false>;
template class StorageAndSubImageTest<glw::GLint, 2, false, 3, false>;
template class StorageAndSubImageTest<glw::GLint, 3, false, 3, false>;
template class StorageAndSubImageTest<glw::GLint, 4, false, 3, false>;

template class StorageAndSubImageTest<glw::GLuint, 1, false, 1, false>;
template class StorageAndSubImageTest<glw::GLuint, 2, false, 1, false>;
template class StorageAndSubImageTest<glw::GLuint, 3, false, 1, false>;
template class StorageAndSubImageTest<glw::GLuint, 4, false, 1, false>;
template class StorageAndSubImageTest<glw::GLuint, 1, false, 2, false>;
template class StorageAndSubImageTest<glw::GLuint, 2, false, 2, false>;
template class StorageAndSubImageTest<glw::GLuint, 3, false, 2, false>;
template class StorageAndSubImageTest<glw::GLuint, 4, false, 2, false>;
template class StorageAndSubImageTest<glw::GLuint, 1, false, 3, false>;
template class StorageAndSubImageTest<glw::GLuint, 2, false, 3, false>;
template class StorageAndSubImageTest<glw::GLuint, 3, false, 3, false>;
template class StorageAndSubImageTest<glw::GLuint, 4, false, 3, false>;

template class StorageAndSubImageTest<glw::GLfloat, 1, true, 1, false>;
template class StorageAndSubImageTest<glw::GLfloat, 2, true, 1, false>;
template class StorageAndSubImageTest<glw::GLfloat, 3, true, 1, false>;
template class StorageAndSubImageTest<glw::GLfloat, 4, true, 1, false>;
template class StorageAndSubImageTest<glw::GLfloat, 1, true, 2, false>;
template class StorageAndSubImageTest<glw::GLfloat, 2, true, 2, false>;
template class StorageAndSubImageTest<glw::GLfloat, 3, true, 2, false>;
template class StorageAndSubImageTest<glw::GLfloat, 4, true, 2, false>;
template class StorageAndSubImageTest<glw::GLfloat, 1, true, 3, false>;
template class StorageAndSubImageTest<glw::GLfloat, 2, true, 3, false>;
template class StorageAndSubImageTest<glw::GLfloat, 3, true, 3, false>;
template class StorageAndSubImageTest<glw::GLfloat, 4, true, 3, false>;

template class StorageAndSubImageTest<glw::GLbyte, 1, false, 1, true>;
template class StorageAndSubImageTest<glw::GLbyte, 2, false, 1, true>;
template class StorageAndSubImageTest<glw::GLbyte, 4, false, 1, true>;
template class StorageAndSubImageTest<glw::GLbyte, 1, false, 2, true>;
template class StorageAndSubImageTest<glw::GLbyte, 2, false, 2, true>;
template class StorageAndSubImageTest<glw::GLbyte, 4, false, 2, true>;
template class StorageAndSubImageTest<glw::GLbyte, 1, false, 3, true>;
template class StorageAndSubImageTest<glw::GLbyte, 2, false, 3, true>;
template class StorageAndSubImageTest<glw::GLbyte, 4, false, 3, true>;

template class StorageAndSubImageTest<glw::GLubyte, 1, false, 1, true>;
template class StorageAndSubImageTest<glw::GLubyte, 2, false, 1, true>;
template class StorageAndSubImageTest<glw::GLubyte, 4, false, 1, true>;
template class StorageAndSubImageTest<glw::GLubyte, 1, false, 2, true>;
template class StorageAndSubImageTest<glw::GLubyte, 2, false, 2, true>;
template class StorageAndSubImageTest<glw::GLubyte, 4, false, 2, true>;
template class StorageAndSubImageTest<glw::GLubyte, 1, false, 3, true>;
template class StorageAndSubImageTest<glw::GLubyte, 2, false, 3, true>;
template class StorageAndSubImageTest<glw::GLubyte, 4, false, 3, true>;

template class StorageAndSubImageTest<glw::GLubyte, 1, true, 1, true>;
template class StorageAndSubImageTest<glw::GLubyte, 2, true, 1, true>;
template class StorageAndSubImageTest<glw::GLubyte, 4, true, 1, true>;
template class StorageAndSubImageTest<glw::GLubyte, 1, true, 2, true>;
template class StorageAndSubImageTest<glw::GLubyte, 2, true, 2, true>;
template class StorageAndSubImageTest<glw::GLubyte, 4, true, 2, true>;
template class StorageAndSubImageTest<glw::GLubyte, 1, true, 3, true>;
template class StorageAndSubImageTest<glw::GLubyte, 2, true, 3, true>;
template class StorageAndSubImageTest<glw::GLubyte, 4, true, 3, true>;

template class StorageAndSubImageTest<glw::GLshort, 1, false, 1, true>;
template class StorageAndSubImageTest<glw::GLshort, 2, false, 1, true>;
template class StorageAndSubImageTest<glw::GLshort, 4, false, 1, true>;
template class StorageAndSubImageTest<glw::GLshort, 1, false, 2, true>;
template class StorageAndSubImageTest<glw::GLshort, 2, false, 2, true>;
template class StorageAndSubImageTest<glw::GLshort, 4, false, 2, true>;
template class StorageAndSubImageTest<glw::GLshort, 1, false, 3, true>;
template class StorageAndSubImageTest<glw::GLshort, 2, false, 3, true>;
template class StorageAndSubImageTest<glw::GLshort, 4, false, 3, true>;

template class StorageAndSubImageTest<glw::GLushort, 1, false, 1, true>;
template class StorageAndSubImageTest<glw::GLushort, 2, false, 1, true>;
template class StorageAndSubImageTest<glw::GLushort, 4, false, 1, true>;
template class StorageAndSubImageTest<glw::GLushort, 1, false, 2, true>;
template class StorageAndSubImageTest<glw::GLushort, 2, false, 2, true>;
template class StorageAndSubImageTest<glw::GLushort, 4, false, 2, true>;
template class StorageAndSubImageTest<glw::GLushort, 1, false, 3, true>;
template class StorageAndSubImageTest<glw::GLushort, 2, false, 3, true>;
template class StorageAndSubImageTest<glw::GLushort, 4, false, 3, true>;

template class StorageAndSubImageTest<glw::GLushort, 1, true, 1, true>;
template class StorageAndSubImageTest<glw::GLushort, 2, true, 1, true>;
template class StorageAndSubImageTest<glw::GLushort, 4, true, 1, true>;
template class StorageAndSubImageTest<glw::GLushort, 1, true, 2, true>;
template class StorageAndSubImageTest<glw::GLushort, 2, true, 2, true>;
template class StorageAndSubImageTest<glw::GLushort, 4, true, 2, true>;
template class StorageAndSubImageTest<glw::GLushort, 1, true, 3, true>;
template class StorageAndSubImageTest<glw::GLushort, 2, true, 3, true>;
template class StorageAndSubImageTest<glw::GLushort, 4, true, 3, true>;

template class StorageAndSubImageTest<glw::GLint, 1, false, 1, true>;
template class StorageAndSubImageTest<glw::GLint, 2, false, 1, true>;
template class StorageAndSubImageTest<glw::GLint, 3, false, 1, true>;
template class StorageAndSubImageTest<glw::GLint, 4, false, 1, true>;
template class StorageAndSubImageTest<glw::GLint, 1, false, 2, true>;
template class StorageAndSubImageTest<glw::GLint, 2, false, 2, true>;
template class StorageAndSubImageTest<glw::GLint, 3, false, 2, true>;
template class StorageAndSubImageTest<glw::GLint, 4, false, 2, true>;
template class StorageAndSubImageTest<glw::GLint, 1, false, 3, true>;
template class StorageAndSubImageTest<glw::GLint, 2, false, 3, true>;
template class StorageAndSubImageTest<glw::GLint, 3, false, 3, true>;
template class StorageAndSubImageTest<glw::GLint, 4, false, 3, true>;

template class StorageAndSubImageTest<glw::GLuint, 1, false, 1, true>;
template class StorageAndSubImageTest<glw::GLuint, 2, false, 1, true>;
template class StorageAndSubImageTest<glw::GLuint, 3, false, 1, true>;
template class StorageAndSubImageTest<glw::GLuint, 4, false, 1, true>;
template class StorageAndSubImageTest<glw::GLuint, 1, false, 2, true>;
template class StorageAndSubImageTest<glw::GLuint, 2, false, 2, true>;
template class StorageAndSubImageTest<glw::GLuint, 3, false, 2, true>;
template class StorageAndSubImageTest<glw::GLuint, 4, false, 2, true>;
template class StorageAndSubImageTest<glw::GLuint, 1, false, 3, true>;
template class StorageAndSubImageTest<glw::GLuint, 2, false, 3, true>;
template class StorageAndSubImageTest<glw::GLuint, 3, false, 3, true>;
template class StorageAndSubImageTest<glw::GLuint, 4, false, 3, true>;

template class StorageAndSubImageTest<glw::GLfloat, 1, true, 1, true>;
template class StorageAndSubImageTest<glw::GLfloat, 2, true, 1, true>;
template class StorageAndSubImageTest<glw::GLfloat, 3, true, 1, true>;
template class StorageAndSubImageTest<glw::GLfloat, 4, true, 1, true>;
template class StorageAndSubImageTest<glw::GLfloat, 1, true, 2, true>;
template class StorageAndSubImageTest<glw::GLfloat, 2, true, 2, true>;
template class StorageAndSubImageTest<glw::GLfloat, 3, true, 2, true>;
template class StorageAndSubImageTest<glw::GLfloat, 4, true, 2, true>;
template class StorageAndSubImageTest<glw::GLfloat, 1, true, 3, true>;
template class StorageAndSubImageTest<glw::GLfloat, 2, true, 3, true>;
template class StorageAndSubImageTest<glw::GLfloat, 3, true, 3, true>;
template class StorageAndSubImageTest<glw::GLfloat, 4, true, 3, true>;

/******************************** Storage Multisample Test Implementation   ********************************/

/** @brief Storage Multisample Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
StorageMultisampleTest<T, S, N, D>::StorageMultisampleTest(deqp::Context& context, const char* name)
	: deqp::TestCase(context, name, "Texture Storage Multisample Test")
	, m_fbo_ms(0)
	, m_fbo_aux(0)
	, m_to_ms(0)
	, m_po_ms(0)
	, m_po_aux(0)
	, m_to(0)
	, m_to_aux(0)
	, m_vao(0)
{
	/* Intentionally left blank. */
}

/** @brief Count of reference data to be teted.
 *
 *  @return Count.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataCount()
{
	return 2 /* 1D */ * ((D > 1) ? 3 : 1) /* 2D */ * ((D > 2) ? 4 : 1) /* 3D */ * S /* components */;
}

/** @brief Size of reference data to be teted.
 *
 *  @return Size.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataSize()
{
	return TestReferenceDataCount() * sizeof(T);
}

/** @brief Height, width or depth of reference data to be teted.
 *
 *  @return Height, width or depth.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataHeight()
{
	switch(D)
	{
	case 3:
	case 2:
		return 3;
	default:
		return 1;
	}
}

template <typename T, glw::GLint S, bool N, glw::GLuint D>
glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataDepth()
{
	switch(D)
	{
	case 3:
		return 4;
	default:
		return 1;
	}
}

template <typename T, glw::GLint S, bool N, glw::GLuint D>
glw::GLuint	StorageMultisampleTest<T, S, N, D>::TestReferenceDataWidth()
{
	return 2;
}

/** @brief Fragment shader declaration selector.
 *
 *  @return Frgment shader source code part.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::FragmentShaderDeclarationMultisample()
{
	if (typeid(T) == typeid(glw::GLbyte))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_ms_2D_idecl_lowp;
		case 3:
			return s_fragment_shader_ms_3D_idecl_lowp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLubyte))
	{
		if (N)
		{
			switch (D)
			{
			case 2:
				return s_fragment_shader_ms_2D_fdecl_lowp;
			case 3:
				return s_fragment_shader_ms_3D_fdecl_lowp;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
		else
		{
			switch (D)
			{
			case 2:
				return s_fragment_shader_ms_2D_udecl_lowp;
			case 3:
				return s_fragment_shader_ms_3D_udecl_lowp;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
	}

	if (typeid(T) == typeid(glw::GLshort))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_ms_2D_idecl_mediump;
		case 3:
			return s_fragment_shader_ms_3D_idecl_mediump;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLushort))
	{
		if (N)
		{
			switch (D)
			{
			case 2:
				return s_fragment_shader_ms_2D_fdecl_mediump;
			case 3:
				return s_fragment_shader_ms_3D_fdecl_mediump;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
		else
		{
			switch (D)
			{
			case 2:
				return s_fragment_shader_ms_2D_udecl_mediump;
			case 3:
				return s_fragment_shader_ms_3D_udecl_mediump;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
	}

	if (typeid(T) == typeid(glw::GLint))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_ms_2D_idecl_highp;
		case 3:
			return s_fragment_shader_ms_3D_idecl_highp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLuint))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_ms_2D_udecl_highp;
		case 3:
			return s_fragment_shader_ms_3D_udecl_highp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLfloat))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_ms_2D_fdecl_highp;
		case 3:
			return s_fragment_shader_ms_3D_fdecl_highp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	DE_FATAL("invalid type");
	return DE_NULL;
}

/** @brief Fragment shader declaration selector.
 *
 *  @return Frgment shader source code part.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::FragmentShaderDeclarationAuxiliary()
{
	if (typeid(T) == typeid(glw::GLbyte))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_aux_2D_idecl_lowp;
		case 3:
			return s_fragment_shader_aux_3D_idecl_lowp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLubyte))
	{
		if (N)
		{
			switch (D)
			{
			case 2:
				return s_fragment_shader_aux_2D_fdecl_lowp;
			case 3:
				return s_fragment_shader_aux_3D_fdecl_lowp;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
		else
		{
			switch (D)
			{
			case 2:
				return s_fragment_shader_aux_2D_udecl_lowp;
			case 3:
				return s_fragment_shader_aux_3D_udecl_lowp;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
	}

	if (typeid(T) == typeid(glw::GLshort))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_aux_2D_idecl_mediump;
		case 3:
			return s_fragment_shader_aux_3D_idecl_mediump;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLushort))
	{
		if (N)
		{
			switch (D)
			{
			case 2:
				return s_fragment_shader_aux_2D_fdecl_mediump;
			case 3:
				return s_fragment_shader_aux_3D_fdecl_mediump;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
		else
		{
			switch (D)
			{
			case 2:
				return s_fragment_shader_aux_2D_udecl_mediump;
			case 3:
				return s_fragment_shader_aux_3D_udecl_mediump;
			default:
				DE_FATAL("invalid texture dimension");
				return DE_NULL;
			}
		}
	}

	if (typeid(T) == typeid(glw::GLint))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_aux_2D_idecl_highp;
		case 3:
			return s_fragment_shader_aux_3D_idecl_highp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLuint))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_aux_2D_udecl_highp;
		case 3:
			return s_fragment_shader_aux_3D_udecl_highp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	if (typeid(T) == typeid(glw::GLfloat))
	{
		switch (D)
		{
		case 2:
			return s_fragment_shader_aux_2D_fdecl_highp;
		case 3:
			return s_fragment_shader_aux_3D_fdecl_highp;
		default:
			DE_FATAL("invalid texture dimension");
			return DE_NULL;
		}
	}

	DE_FATAL("invalid type");
	return DE_NULL;
}

/** @brief Fragment shader tail selector.
 *
 *  @return Frgment shader source code part.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::FragmentShaderTail()
{
	switch (D)
	{
	case 2:
		return s_fragment_shader_tail_2D;
	case 3:
		return s_fragment_shader_tail_3D;
	default:
		DE_FATAL("invalid texture dimension");
		return DE_NULL;
	}
}

/** @brief Multisample texture target selector.
 *
 *  @return Texture target.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
glw::GLenum StorageMultisampleTest<T, S, N, D>::MultisampleTextureTarget()
{
	switch (D)
	{
	case 2:
		return GL_TEXTURE_2D_MULTISAMPLE;
	case 3:
		return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
	default:
		DE_FATAL("invalid texture dimension");
		return DE_NULL;
	}
}

/** @brief Input texture target selector.
 *
 *  @return Texture target.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
glw::GLenum StorageMultisampleTest<T, S, N, D>::InputTextureTarget()
{
	switch (D)
	{
	case 2:
		return GL_TEXTURE_2D;
	case 3:
		return GL_TEXTURE_2D_ARRAY;
	default:
		DE_FATAL("invalid texture dimension");
		return DE_NULL;
	}
}

/** @brief Prepare texture data for input texture.
 *
 *  @note parameters as passed to texImage*
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::InputTextureImage(const glw::GLenum internal_format, const glw::GLuint width,
														   const glw::GLuint height, const glw::GLuint depth,
														   const glw::GLenum format, const glw::GLenum type,
														   const glw::GLvoid* data)
{
	(void)depth;
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Data setup. */
	switch (D)
	{
	case 2:
		gl.texImage2D(InputTextureTarget(), 0, internal_format, width, height, 0, format, type, data);
		break;
	case 3:
		gl.texImage3D(InputTextureTarget(), 0, internal_format, width, height, depth, 0, format, type, data);
		break;
	default:
		DE_FATAL("invalid texture dimension");
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage has failed");
}

/** @brief Create texture.
 *
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::CreateInputTexture()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Objects creation. */
	gl.genTextures(1, &m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(InputTextureTarget(), m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	/* Data setup. */
	InputTextureImage(InternalFormat<T, S, N>(), TestReferenceDataWidth(), TestReferenceDataHeight(),
					  TestReferenceDataDepth(), Format<S, N>(), Type<T>(), ReferenceData<T, N>());

	/* Parameter setup. */
	gl.texParameteri(InputTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(InputTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
}

/** @brief Compre results with the reference.
 *
 *  @return True if equal, false otherwise.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
bool StorageMultisampleTest<T, S, N, D>::Check()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Fetching data fro auxiliary texture. */
	std::vector<T> result(TestReferenceDataCount());

	gl.bindTexture(InputTextureTarget() /* Auxiliary target is the same as input. */, m_to_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.getTexImage(InputTextureTarget() /* Auxiliary target is the same as input. */, 0, Format<S, N>(), Type<T>(),
				   (glw::GLvoid*)(&result[0]));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage has failed");

	/* Comparison. */
	for (glw::GLuint i = 0; i < TestReferenceDataCount(); ++i)
	{
		if (!Compare<T>(result[i], ReferenceData<T, N>()[i]))
		{
			return false;
		}
	}

	return true;
}

/** @brief Test case function.
 *
 *  @return True if test succeeded, false otherwise.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
bool StorageMultisampleTest<T, S, N, D>::Test()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Setup. */
	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(T));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(T));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	CreateInputTexture();

	if (!PrepareFramebufferMultisample(InternalFormat<T, S, N>()))
	{
		CleanInputTexture();

		return false;
	}

	PrepareFramebufferAuxiliary(InternalFormat<T, S, N>());

	/* Action. */
	Draw();

	/* Compare results with reference. */
	bool result = Check();

	/* Cleanup. */
	CleanAuxiliaryTexture();
	CleanFramebuffers();
	CleanInputTexture();
	CleanErrors();

	/* Pass result. */
	return result;
}

/** @brief Function prepares framebuffer with internal format color attachment.
 *         Viewport is set up. Content of the framebuffer is cleared.
 *
 *  @note The function may throw if unexpected error has occured.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
bool StorageMultisampleTest<T, S, N, D>::PrepareFramebufferMultisample(const glw::GLenum internal_format)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare framebuffer. */
	gl.genFramebuffers(1, &m_fbo_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.genTextures(1, &m_to_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.bindTexture(MultisampleTextureTarget(), m_to_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	switch (D)
	{
	case 2:
		gl.textureStorage2DMultisample(m_to_ms, 1, internal_format, TestReferenceDataWidth(),
									   TestReferenceDataHeight(), false);
		break;
	case 3:
		gl.textureStorage3DMultisample(m_to_ms, 1, internal_format, TestReferenceDataWidth(),
									   TestReferenceDataHeight(), TestReferenceDataDepth(), false);
		break;
	default:
		DE_FATAL("invalid texture dimension");
		return false;
	}

	glw::GLenum error;

	if (GL_NO_ERROR != (error = gl.getError()))
	{
		CleanFramebuffers();

		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glTextureStorageMultisample unexpectedly generated error "
			<< glu::getErrorStr(error) << " during the test of internal format "
			<< glu::getTextureFormatStr(internal_format) << ". Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	switch (D)
	{
	case 2:
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_to_ms, 0);
		break;
	case 3:
		for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i)
		{
			gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, m_to_ms, 0, i);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer call failed.");
		}
		break;
	default:
		DE_FATAL("invalid texture dimension");
		return false;
	}
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED)
			throw tcu::NotSupportedError("unsupported framebuffer configuration");
		else
			throw 0;
	}

	gl.viewport(0, 0, TestReferenceDataWidth(), TestReferenceDataHeight());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");

	/* Clear framebuffer's content. */
	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

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

	return true;
}

/** @brief Function prepares framebuffer with internal format color attachment.
 *         Viewport is set up. Content of the framebuffer is cleared.
 *
 *  @note The function may throw if unexpected error has occured.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::PrepareFramebufferAuxiliary(const glw::GLenum internal_format)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare framebuffer. */
	gl.genFramebuffers(1, &m_fbo_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.genTextures(1, &m_to_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.bindTexture(InputTextureTarget(), m_to_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	switch (D)
	{
	case 2:
		gl.textureStorage2D(m_to_aux, 1, internal_format, TestReferenceDataWidth(), TestReferenceDataHeight());
		break;
	case 3:
		gl.textureStorage3D(m_to_aux, 1, internal_format, TestReferenceDataWidth(), TestReferenceDataHeight(),
							TestReferenceDataDepth());
		break;
	default:
		DE_FATAL("invalid texture dimension");
	}
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D call failed.");

	/* Parameter setup. */
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");

	switch (D)
	{
	case 2:
		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_aux, 0);
		break;
	case 3:
		for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i)
		{
			gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, m_to_aux, 0, i);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer call failed.");
		}
		break;
	default:
		DE_FATAL("invalid texture dimension");
	}
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED)
			throw tcu::NotSupportedError("unsupported framebuffer configuration");
		else
			throw 0;
	}

	gl.viewport(0, 0, TestReferenceDataWidth(), TestReferenceDataHeight());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");

	/* Clear framebuffer's content. */
	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

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

/** @brief Prepare program
 *
 *  @param [in] variable_declaration      Variables declaration part of fragment shader source code.
 *  @param [in] tail                      Tail part of fragment shader source code.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
glw::GLuint StorageMultisampleTest<T, S, N, D>::PrepareProgram(const glw::GLchar* variable_declaration, const glw::GLchar* tail)
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	struct Shader
	{
		glw::GLchar const* source[3];
		glw::GLsizei const count;
		glw::GLenum const  type;
		glw::GLuint		   id;
	} shader[] = { { { s_vertex_shader, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 },
				   { { s_fragment_shader_head, variable_declaration, tail }, 3, GL_FRAGMENT_SHADER, 0 } };

	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);

	glw::GLuint po = 0;

	try
	{
		/* Create program. */
		po = gl.createProgram();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

		/* Shader compilation. */

		for (glw::GLuint i = 0; i < shader_count; ++i)
		{
			{
				shader[i].id = gl.createShader(shader[i].type);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

				gl.attachShader(po, shader[i].id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

				gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

				gl.compileShader(shader[i].id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

				glw::GLint status = GL_FALSE;

				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

				if (GL_FALSE == status)
				{
					glw::GLint log_size = 0;
					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

					glw::GLchar* log_text = new glw::GLchar[log_size];

					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "Shader compilation has failed.\n"
						<< "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n"
						<< "Shader compilation error log:\n"
						<< log_text << "\n"
						<< "Shader source code:\n"
						<< shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "")
						<< (shader[i].source[2] ? shader[i].source[2] : "") << "\n"
						<< tcu::TestLog::EndMessage;

					delete[] log_text;

					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

					throw 0;
				}
			}
		}

		/* Link. */
		gl.linkProgram(po);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

		glw::GLint status = GL_FALSE;

		gl.getProgramiv(po, GL_LINK_STATUS, &status);

		if (GL_TRUE == status)
		{
			for (glw::GLuint i = 0; i < shader_count; ++i)
			{
				if (shader[i].id)
				{
					gl.detachShader(po, shader[i].id);

					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
				}
			}
		}
		else
		{
			glw::GLint log_size = 0;

			gl.getProgramiv(po, GL_INFO_LOG_LENGTH, &log_size);

			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

			glw::GLchar* log_text = new glw::GLchar[log_size];

			gl.getProgramInfoLog(po, log_size, NULL, &log_text[0]);

			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
												<< log_text << "\n"
												<< tcu::TestLog::EndMessage;

			delete[] log_text;

			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

			throw 0;
		}
	}
	catch (...)
	{
		if (po)
		{
			gl.deleteProgram(po);

			po = 0;
		}
	}

	for (glw::GLuint i = 0; i < shader_count; ++i)
	{
		if (0 != shader[i].id)
		{
			gl.deleteShader(shader[i].id);

			shader[i].id = 0;
		}
	}

	if (0 == po)
	{
		throw 0;
	}

	return po;
}

/** @brief Prepare VAO.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::PrepareVertexArray()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays has failed");

	gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray has failed");
}

/** @brief Draw call
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::Draw()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare multisample texture using draw call. */

	/* Prepare framebuffer with multisample texture. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Use first program program. */
	gl.useProgram(m_po_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed");

	/* Prepare texture to be drawn with. */
	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");

	gl.bindTexture(InputTextureTarget(), m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");

	gl.uniform1i(gl.getUniformLocation(m_po_ms, "texture_input"), 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed");

	for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i)
	{
		/* Select layer. */
		gl.drawBuffer(GL_COLOR_ATTACHMENT0 + i);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");

		if (D == 3)
		{
			gl.uniform1i(gl.getUniformLocation(m_po_aux, "texture_layer"), i);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed");
		}

		/* Draw. */
		gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
	}

	/* Copy multisample texture to auxiliary texture using draw call. */

	/* Prepare framebuffer with auxiliary texture. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");

	/* Use first program program. */
	gl.useProgram(m_po_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed");

	/* Prepare texture to be drawn with. */
	gl.activeTexture(GL_TEXTURE0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");

	gl.bindTexture(MultisampleTextureTarget(), m_to_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed");

	gl.bindTextureUnit(0, m_to);

	gl.uniform1i(gl.getUniformLocation(m_po_aux, "texture_input"), 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed");

	/* For each texture layer. */
	for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i)
	{
		/* Select layer. */
		gl.drawBuffer(GL_COLOR_ATTACHMENT0 + i);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");

		if (D == 3)
		{
			gl.uniform1i(gl.getUniformLocation(m_po_aux, "texture_layer"), i);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed");
		}

		/* Draw. */
		gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed");
	}
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::CleanInputTexture()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Texture. */
	if (m_to)
	{
		gl.deleteTextures(1, &m_to);

		m_to = 0;
	}
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::CleanAuxiliaryTexture()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_to_aux)
	{
		gl.deleteTextures(1, &m_to_aux);

		m_to_aux = 0;
	}
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::CleanFramebuffers()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Mulitsample framebuffer. */
	if (m_fbo_ms)
	{
		gl.deleteFramebuffers(1, &m_fbo_ms);

		m_fbo_ms = 0;
	}

	/* Mulitsample texture. */
	if (m_to_ms)
	{
		gl.deleteTextures(1, &m_to_ms);

		m_to_ms = 0;
	}

	/* Auxiliary framebuffer. */
	if (m_fbo_aux)
	{
		gl.deleteFramebuffers(1, &m_fbo_aux);

		m_fbo_aux = 0;
	}

	/* Auxiliary texture. */
	if (m_to_aux)
	{
		gl.deleteTextures(1, &m_to_aux);

		m_to_aux = 0;
	}
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::CleanPrograms()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Binding point. */
	gl.useProgram(0);

	/* Multisample texture preparation program. */
	if (m_po_ms)
	{
		gl.deleteProgram(m_po_ms);

		m_po_ms = 0;
	}

	/* Auxiliary texture preparation program. */
	if (m_po_aux)
	{
		gl.deleteProgram(m_po_aux);

		m_po_aux = 0;
	}
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::CleanErrors()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Query all errors until GL_NO_ERROR occure. */
	while (GL_NO_ERROR != gl.getError())
		;
}

/** @brief Clean GL objects, test variables and GL errors.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
void StorageMultisampleTest<T, S, N, D>::CleanVertexArray()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_vao)
	{
		gl.bindVertexArray(0);

		gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}
}

/** @brief Iterate Storage Multisample Test cases.
 *
 *  @return Iteration result.
 */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
tcu::TestNode::IterateResult StorageMultisampleTest<T, S, N, D>::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		PrepareVertexArray();

		//  gl.enable(GL_MULTISAMPLE);

		m_po_ms  = PrepareProgram(FragmentShaderDeclarationMultisample(), FragmentShaderTail());
		m_po_aux = PrepareProgram(FragmentShaderDeclarationAuxiliary(), FragmentShaderTail());

		is_ok = Test();
	}
	catch (tcu::NotSupportedError& e)
	{
		throw e;
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	CleanInputTexture();
	CleanAuxiliaryTexture();
	CleanFramebuffers();
	CleanPrograms();
	CleanErrors();
	CleanVertexArray();
	gl.disable(GL_MULTISAMPLE);

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/* Vertex shader source code. */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_vertex_shader =
	"#version 450\n"
	"\n"
	"void main()\n"
	"{\n"
	"    switch(gl_VertexID)\n"
	"    {\n"
	"        case 0:\n"
	"            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
	"            break;\n"
	"        case 1:\n"
	"            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
	"            break;\n"
	"        case 2:\n"
	"            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
	"            break;\n"
	"        case 3:\n"
	"            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
	"            break;\n"
	"    }\n"
	"}\n";

/* Fragment shader source program. */
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_head =
	"#version 450\n"
	"\n"
	"layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
	"\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_fdecl_lowp =
	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_idecl_lowp =
	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_udecl_lowp =
	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_fdecl_mediump =
	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_idecl_mediump =
	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_udecl_mediump =
	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_fdecl_highp =
	"uniform  sampler2D texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_idecl_highp =
	"uniform isampler2D texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_udecl_highp =
	"uniform usampler2D texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_fdecl_lowp =
	"uniform  sampler2DArray texture_input;\nout     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_idecl_lowp =
	"uniform isampler2DArray texture_input;\nout     ivec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_udecl_lowp =
	"uniform usampler2DArray texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_fdecl_mediump =
	"uniform  sampler2DArray texture_input;\nout     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_idecl_mediump =
	"uniform isampler2DArray texture_input;\nout     ivec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_udecl_mediump =
	"uniform usampler2DArray texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_fdecl_highp =
	"uniform  sampler2DArray texture_input;\nout     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_idecl_highp =
	"uniform isampler2DArray texture_input;\nout     ivec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_udecl_highp =
	"uniform usampler2DArray texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_fdecl_lowp =
	"uniform  sampler2DMS texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_idecl_lowp =
	"uniform isampler2DMS texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_udecl_lowp =
	"uniform usampler2DMS texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_fdecl_mediump =
	"uniform  sampler2DMS texture_input;\nout     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_idecl_mediump =
	"uniform isampler2DMS texture_input;\nout     ivec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_udecl_mediump =
	"uniform usampler2DMS texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_fdecl_highp =
	"uniform  sampler2DMS texture_input;\nout     vec4          texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_idecl_highp =
	"uniform isampler2DMS texture_input;\nout     ivec4         texture_output;\n";
template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_udecl_highp =
	"uniform usampler2DMS texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_fdecl_lowp =
	"uniform  sampler2DMSArray texture_input;\nout     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_idecl_lowp =
	"uniform isampler2DMSArray texture_input;\nout     ivec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_udecl_lowp =
	"uniform usampler2DMSArray texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_fdecl_mediump =
	"uniform  sampler2DMSArray texture_input;\nout     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_idecl_mediump =
	"uniform isampler2DMSArray texture_input;\nout     ivec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_udecl_mediump =
	"uniform usampler2DMSArray texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_fdecl_highp =
	"uniform  sampler2DMSArray texture_input;\nout     vec4          texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_idecl_highp =
	"uniform isampler2DMSArray texture_input;\nout     ivec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_udecl_highp =
	"uniform usampler2DMSArray texture_input;\nout     uvec4         texture_output;\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_tail_2D =
	"\n"
	"void main()\n"
	"{\n"
	"    texture_output = texelFetch(texture_input, ivec2(gl_FragCoord.xy), 0);\n"
	"}\n";

template <typename T, glw::GLint S, bool N, glw::GLuint D>
const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_tail_3D =
	"\n"
	"uniform int texture_layer;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    texture_output = texelFetch(texture_input, ivec3(gl_FragCoord.xy, texture_layer), 0);\n"
	"}\n";

template class StorageMultisampleTest<glw::GLbyte, 1, false, 2>;
template class StorageMultisampleTest<glw::GLbyte, 2, false, 2>;
template class StorageMultisampleTest<glw::GLbyte, 4, false, 2>;
template class StorageMultisampleTest<glw::GLbyte, 1, false, 3>;
template class StorageMultisampleTest<glw::GLbyte, 2, false, 3>;
template class StorageMultisampleTest<glw::GLbyte, 4, false, 3>;

template class StorageMultisampleTest<glw::GLubyte, 1, false, 2>;
template class StorageMultisampleTest<glw::GLubyte, 2, false, 2>;
template class StorageMultisampleTest<glw::GLubyte, 4, false, 2>;
template class StorageMultisampleTest<glw::GLubyte, 1, false, 3>;
template class StorageMultisampleTest<glw::GLubyte, 2, false, 3>;
template class StorageMultisampleTest<glw::GLubyte, 4, false, 3>;

template class StorageMultisampleTest<glw::GLubyte, 1, true, 2>;
template class StorageMultisampleTest<glw::GLubyte, 2, true, 2>;
template class StorageMultisampleTest<glw::GLubyte, 4, true, 2>;
template class StorageMultisampleTest<glw::GLubyte, 1, true, 3>;
template class StorageMultisampleTest<glw::GLubyte, 2, true, 3>;
template class StorageMultisampleTest<glw::GLubyte, 4, true, 3>;

template class StorageMultisampleTest<glw::GLshort, 1, false, 2>;
template class StorageMultisampleTest<glw::GLshort, 2, false, 2>;
template class StorageMultisampleTest<glw::GLshort, 4, false, 2>;
template class StorageMultisampleTest<glw::GLshort, 1, false, 3>;
template class StorageMultisampleTest<glw::GLshort, 2, false, 3>;
template class StorageMultisampleTest<glw::GLshort, 4, false, 3>;

template class StorageMultisampleTest<glw::GLushort, 1, false, 2>;
template class StorageMultisampleTest<glw::GLushort, 2, false, 2>;
template class StorageMultisampleTest<glw::GLushort, 4, false, 2>;
template class StorageMultisampleTest<glw::GLushort, 1, false, 3>;
template class StorageMultisampleTest<glw::GLushort, 2, false, 3>;
template class StorageMultisampleTest<glw::GLushort, 4, false, 3>;

template class StorageMultisampleTest<glw::GLushort, 1, true, 2>;
template class StorageMultisampleTest<glw::GLushort, 2, true, 2>;
template class StorageMultisampleTest<glw::GLushort, 4, true, 2>;
template class StorageMultisampleTest<glw::GLushort, 1, true, 3>;
template class StorageMultisampleTest<glw::GLushort, 2, true, 3>;
template class StorageMultisampleTest<glw::GLushort, 4, true, 3>;

template class StorageMultisampleTest<glw::GLint, 1, false, 2>;
template class StorageMultisampleTest<glw::GLint, 2, false, 2>;
template class StorageMultisampleTest<glw::GLint, 3, false, 2>;
template class StorageMultisampleTest<glw::GLint, 4, false, 2>;
template class StorageMultisampleTest<glw::GLint, 1, false, 3>;
template class StorageMultisampleTest<glw::GLint, 2, false, 3>;
template class StorageMultisampleTest<glw::GLint, 3, false, 3>;
template class StorageMultisampleTest<glw::GLint, 4, false, 3>;

template class StorageMultisampleTest<glw::GLuint, 1, false, 2>;
template class StorageMultisampleTest<glw::GLuint, 2, false, 2>;
template class StorageMultisampleTest<glw::GLuint, 3, false, 2>;
template class StorageMultisampleTest<glw::GLuint, 4, false, 2>;
template class StorageMultisampleTest<glw::GLuint, 1, false, 3>;
template class StorageMultisampleTest<glw::GLuint, 2, false, 3>;
template class StorageMultisampleTest<glw::GLuint, 3, false, 3>;
template class StorageMultisampleTest<glw::GLuint, 4, false, 3>;

template class StorageMultisampleTest<glw::GLfloat, 1, true, 2>;
template class StorageMultisampleTest<glw::GLfloat, 2, true, 2>;
template class StorageMultisampleTest<glw::GLfloat, 3, true, 2>;
template class StorageMultisampleTest<glw::GLfloat, 4, true, 2>;
template class StorageMultisampleTest<glw::GLfloat, 1, true, 3>;
template class StorageMultisampleTest<glw::GLfloat, 2, true, 3>;
template class StorageMultisampleTest<glw::GLfloat, 3, true, 3>;
template class StorageMultisampleTest<glw::GLfloat, 4, true, 3>;

/******************************** Compressed SubImage Test Implementation   ********************************/

/* Compressed m_reference data for unsupported compression formats */

static const unsigned char data_0x8dbb_2D_8[] = {
	34, 237, 94, 207,
	252, 29, 75, 25
};

static const unsigned char data_0x8dbb_3D_32[] = {
	34, 237, 94, 207,
	252, 29, 75, 25,
	34, 237, 44, 173,
	101, 230, 139, 254,
	34, 237, 176, 88,
	174, 127, 248, 206,
	34, 237, 127, 209,
	211, 203, 100, 150
};

static const unsigned char data_0x8dbc_2D_8[] = {
	127, 0, 233, 64,
	0, 42, 71, 231
};

static const unsigned char data_0x8dbc_3D_32[] = {
	127, 0, 233, 64,
	0, 42, 71, 231,
	127, 0, 20, 227,
	162, 33, 246, 1,
	127, 0, 143, 57,
	86, 0, 136, 53,
	127, 0, 192, 62,
	48, 69, 29, 138
};

static const unsigned char data_0x8dbd_2D_16[] = {
	34, 237, 94, 207,
	252, 29, 75, 25,
	28, 242, 94, 111,
	44, 101, 35, 145
};

static const unsigned char data_0x8dbd_3D_64[] = {
	34, 237, 94, 207,
	252, 29, 75, 25,
	28, 242, 94, 111,
	44, 101, 35, 145,
	34, 237, 44, 173,
	101, 230, 139, 254,
	28, 242, 170, 45,
	98, 236, 202, 228,
	34, 237, 176, 88,
	174, 127, 248, 206,
	28, 242, 164, 148,
	178, 25, 252, 206,
	34, 237, 127, 209,
	211, 203, 100, 150,
	28, 242, 79, 216,
	149, 3, 101, 87
};

static const unsigned char data_0x8dbe_2D_16[] = {
	127, 0, 233, 64,
	0, 42, 71, 231,
	127, 0, 233, 144,
	23, 163, 100, 115
};

static const unsigned char data_0x8dbe_3D_64[] = {
	127, 0, 233, 64,
	0, 42, 71, 231,
	127, 0, 233, 144,
	23, 163, 100, 115,
	127, 0, 20, 227,
	162, 33, 246, 1,
	127, 0, 94, 98,
	190, 84, 55, 1,
	127, 0, 143, 57,
	86, 0, 136, 53,
	127, 0, 163, 45,
	113, 232, 131, 53,
	127, 0, 192, 62,
	48, 69, 29, 138,
	127, 0, 128, 182,
	138, 61, 157, 204
};

static const unsigned char data_0x8e8c_2D_16[] = {
	144, 43, 143, 15,
	254, 15, 152, 153,
	153, 153, 89, 143,
	140, 166, 183, 113
};

static const unsigned char data_0x8e8c_3D_64[] = {
	144, 43, 143, 15,
	254, 15, 152, 153,
	153, 153, 89, 143,
	140, 166, 183, 113,
	144, 43, 143, 15,
	254, 15, 152, 153,
	153, 153, 55, 48,
	102, 244, 186, 241,
	144, 43, 143, 15,
	254, 15, 152, 153,
	153, 153, 231, 54,
	211, 92, 240, 14,
	144, 121, 253, 241,
	193, 15, 152, 153,
	153, 153, 25, 41,
	102, 244, 248, 135
};

static const unsigned char data_0x8e8d_2D_16[] = {
	144, 43, 143, 15,
	254, 15, 152, 153,
	153, 153, 89, 143,
	140, 166, 183, 113
};

static const unsigned char data_0x8e8d_3D_64[] = {
	144, 43, 143, 15,
	254, 15, 152, 153,
	153, 153, 89, 143,
	140, 166, 183, 113,
	144, 43, 143, 15,
	254, 15, 152, 153,
	153, 153, 55, 48,
	102, 244, 186, 241,
	144, 43, 143, 15,
	254, 15, 152, 153,
	153, 153, 231, 54,
	211, 92, 240, 14,
	144, 121, 253, 241,
	193, 15, 152, 153,
	153, 153, 25, 41,
	102, 244, 248, 135
};

static const unsigned char data_0x8e8e_2D_16[] = {
	67, 155, 82, 120,
	142, 7, 31, 124,
	224, 255, 165, 221,
	239, 223, 122, 223
};

static const unsigned char data_0x8e8e_3D_64[] = {
	67, 155, 82, 120,
	142, 7, 31, 124,
	224, 255, 165, 221,
	239, 223, 122, 223,
	35, 30, 124, 240,
	209, 166, 20, 158,
	11, 250, 24, 21,
	0, 2, 34, 2,
	35, 30, 124, 240,
	209, 166, 20, 158,
	5, 88, 2, 1,
	34, 165, 0, 241,
	35, 30, 124, 240,
	209, 166, 20, 158,
	33, 34, 32, 0,
	81, 129, 175, 80
};

static const unsigned char data_0x8e8f_2D_16[] = {
	131, 54, 165, 148,
	26, 47, 62, 248,
	176, 254, 149, 203,
	222, 206, 187, 173
};

static const unsigned char data_0x8e8f_3D_64[] = {
	131, 54, 165, 148,
	26, 47, 62, 248,
	176, 254, 149, 203,
	222, 206, 187, 173,
	99, 188, 248, 224,
	163, 77, 41, 165,
	24, 250, 36, 70,
	18, 20, 53, 3,
	99, 188, 248, 224,
	163, 77, 41, 165,
	42, 68, 19, 18,
	67, 166, 16, 244,
	99, 188, 248, 224,
	163, 77, 41, 165,
	48, 83, 65, 33,
	100, 66, 175, 65
};

static const unsigned char data_GL_COMPRESSED_R11_EAC_2D_8[] = {
	146, 253, 99, 81,
	202, 222, 63, 243
};

static const unsigned char data_GL_COMPRESSED_R11_EAC_3D_32[] = {
	146, 253, 99, 81,
	202, 222, 63, 243,
	146, 253, 169, 188,
	102, 31, 246, 55,
	146, 253, 123, 247,
	62, 71, 139, 131,
	146, 253, 248, 63,
	248, 208, 230, 213
};

static const unsigned char data_GL_COMPRESSED_RG11_EAC_2D_16[] = {
	146, 253, 99, 81,
	202, 222, 63, 243,
	140, 254, 110, 0,
	160, 130, 207, 180
};

static const unsigned char data_GL_COMPRESSED_RG11_EAC_3D_64[] = {
	146, 253, 99, 81,
	202, 222, 63, 243,
	140, 254, 110, 0,
	160, 130, 207, 180,
	146, 253, 169, 188,
	102, 31, 246, 55,
	140, 254, 2, 73,
	46, 104, 102, 39,
	146, 253, 123, 247,
	62, 71, 139, 131,
	140, 254, 155, 121,
	68, 17, 1, 27,
	146, 253, 248, 63,
	248, 208, 230, 213,
	140, 254, 240, 60,
	19, 214, 73, 0
};

static const unsigned char data_GL_COMPRESSED_RGB8_ETC2_2D_8[] = {
	168, 122, 150, 252,
	234, 35, 0, 0
};

static const unsigned char data_GL_COMPRESSED_RGB8_ETC2_3D_32[] = {
	168, 122, 150, 252,
	234, 35, 0, 0,
	168, 122, 150, 253,
	31, 140, 0, 0,
	138, 167, 105, 252,
	196, 87, 0, 0,
	138, 167, 105, 253,
	49, 248, 0, 0
};

static const unsigned char data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8[] = {
	83, 83, 75, 252,
	240, 240, 15, 4
};

static const unsigned char data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32[] = {
	83, 83, 75, 252,
	240, 240, 15, 4,
	107, 99, 99, 253,
	240, 240, 14, 15,
	135, 135, 135, 252,
	240, 240, 15, 15,
	108, 108, 108, 253,
	240, 248, 11, 11
};

static const unsigned char data_GL_COMPRESSED_RGBA8_ETC2_EAC_2D_16[] = {
	127, 245, 255, 244,
	146, 255, 244, 146,
	168, 122, 150, 252,
	234, 35, 0, 0
};

static const unsigned char data_GL_COMPRESSED_RGBA8_ETC2_EAC_3D_64[] = {
	127, 245, 255, 244,
	146, 255, 244, 146,
	168, 122, 150, 252,
	234, 35, 0, 0,
	127, 245, 255, 244,
	146, 255, 244, 146,
	168, 122, 150, 253,
	31, 140, 0, 0,
	127, 245, 255, 244,
	146, 255, 244, 146,
	138, 167, 105, 252,
	196, 87, 0, 0,
	127, 245, 255, 244,
	146, 255, 244, 146,
	138, 167, 105, 253,
	49, 248, 0, 0
};

static const unsigned char data_GL_COMPRESSED_SIGNED_R11_EAC_2D_8[] = {
	73, 221, 99, 81,
	201, 222, 63, 241
};

static const unsigned char data_GL_COMPRESSED_SIGNED_R11_EAC_3D_32[] = {
	73, 221, 99, 81,
	201, 222, 63, 241,
	73, 221, 165, 156,
	102, 31, 246, 55,
	73, 221, 59, 247,
	62, 39, 139, 131,
	73, 221, 248, 63,
	248, 208, 226, 205
};

static const unsigned char data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16[] = {
	73, 221, 99, 81,
	201, 222, 63, 241,
	66, 191, 110, 0,
	96, 131, 77, 180
};

static const unsigned char data_GL_COMPRESSED_SIGNED_RG11_EAC_3D_64[] = {
	73, 221, 99, 81,
	201, 222, 63, 241,
	66, 191, 110, 0,
	96, 131, 77, 180,
	73, 221, 165, 156,
	102, 31, 246, 55,
	66, 191, 2, 73,
	54, 100, 102, 38,
	73, 221, 59, 247,
	62, 39, 139, 131,
	66, 191, 155, 105,
	132, 16, 129, 27,
	73, 221, 248, 63,
	248, 208, 226, 205,
	66, 191, 208, 60,
	11, 218, 73, 0
};

static const unsigned char data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_2D_16[] = {
	127, 245, 255, 244,
	146, 255, 244, 146,
	150, 122, 168, 252,
	234, 35, 0, 0
};

static const unsigned char data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_3D_64[] = {
	127, 245, 255, 244,
	146, 255, 244, 146,
	150, 122, 168, 252,
	234, 35, 0, 0,
	127, 245, 255, 244,
	146, 255, 244, 146,
	150, 122, 168, 253,
	31, 140, 0, 0,
	127, 245, 255, 244,
	146, 255, 244, 146,
	105, 167, 138, 252,
	196, 87, 0, 0,
	127, 245, 255, 244,
	146, 255, 244, 146,
	105, 167, 138, 253,
	49, 248, 0, 0
};

static const unsigned char data_GL_COMPRESSED_SRGB8_ETC2_2D_8[] = {
	168, 122, 150, 252,
	234, 35, 0, 0
};

static const unsigned char data_GL_COMPRESSED_SRGB8_ETC2_3D_32[] = {
	168, 122, 150, 252,
	234, 35, 0, 0,
	168, 122, 150, 253,
	31, 140, 0, 0,
	138, 167, 105, 252,
	196, 87, 0, 0,
	138, 167, 105, 253,
	49, 248, 0, 0
};

static const unsigned char data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8[] = {
	75, 83, 83, 252,
	240, 240, 15, 4
};

static const unsigned char data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32[] = {
	75, 83, 83, 252,
	240, 240, 15, 4,
	99, 99, 107, 253,
	240, 240, 14, 15,
	135, 135, 135, 252,
	240, 240, 15, 15,
	108, 108, 108, 253,
	240, 248, 11, 11
};

/** @brief Compressed SubImage Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CompressedSubImageTest::CompressedSubImageTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_compressed_subimage", "Texture Compressed SubImage Test")
	, m_to(0)
	, m_to_aux(0)
	, m_compressed_texture_data(DE_NULL)
	, m_reference(DE_NULL)
	, m_result(DE_NULL)
	, m_reference_size(0)
	, m_reference_internalformat(0)
{
	/* Intentionally left blank. */
}

/** @brief Create texture.
 *
 *  @param [in] target      Texture target.
 */
void CompressedSubImageTest::CreateTextures(glw::GLenum target)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Auxiliary texture (for content creation). */
	gl.genTextures(1, &m_to_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(target, m_to_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	/* Test texture (for data upload). */
	gl.genTextures(1, &m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	gl.bindTexture(target, m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
}

/** @brief Texture target selector.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @return Texture target.
 */
template <>
glw::GLenum CompressedSubImageTest::TextureTarget<1>()
{
	return GL_TEXTURE_1D;
}

template <>
glw::GLenum CompressedSubImageTest::TextureTarget<2>()
{
	return GL_TEXTURE_2D;
}

template <>
glw::GLenum CompressedSubImageTest::TextureTarget<3>()
{
	return GL_TEXTURE_2D_ARRAY;
}

/** @brief Prepare texture data for the auxiliary texture.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @note parameters as passed to texImage*
 *
 *  @return False if the internal format is unsupported for online compression, True otherwise
 */
template <>
bool CompressedSubImageTest::TextureImage<1>(glw::GLint internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.texImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);

	/* Online compression may be unsupported for some formats */
	GLenum error = gl.getError();
	if (error == GL_INVALID_OPERATION)
		return false;

	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	return true;
}

/** @brief Prepare texture data for the auxiliary texture.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @note parameters as passed to texImage*
 *
 *  @return False if the internal format is unsupported for online compression, True otherwise
 */
template <>
bool CompressedSubImageTest::TextureImage<2>(glw::GLint internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.texImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width, s_texture_height, 0, GL_RGBA,
				  GL_UNSIGNED_BYTE, s_texture_data);

	/* Online compression may be unsupported for some formats */
	GLenum error = gl.getError();
	if (error == GL_INVALID_OPERATION)
		return false;

	GLU_EXPECT_NO_ERROR(error, "glTexImage2D has failed");

	return true;
}

/** @brief Prepare texture data for the auxiliary texture.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @note parameters as passed to texImage*
 *
 *  @return False if the internal format is unsupported for online compression, True otherwise
 */
template <>
bool CompressedSubImageTest::TextureImage<3>(glw::GLint internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.texImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
				  GL_UNSIGNED_BYTE, s_texture_data);

	/* Online compression may be unsupported for some formats */
	GLenum error = gl.getError();
	if (error == GL_INVALID_OPERATION)
		return false;

	GLU_EXPECT_NO_ERROR(error, "glTexImage3D has failed");

	return true;
}

/** @brief Prepare texture data for the auxiliary texture.
 *
 *  @tparam D      Texture dimensions.
 *
 *  @note parameters as passed to compressedTexImage*
 */
template <>
void CompressedSubImageTest::CompressedTexImage<1>(glw::GLint internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.compressedTexImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width, 0, m_reference_size,
							m_compressed_texture_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage1D has failed");
}

/** @brief Prepare texture data for the auxiliary texture.
 *
 *  @tparam D      Texture dimensions.
 *
 *  @note parameters as passed to compressedTexImage*
 */
template <>
void CompressedSubImageTest::CompressedTexImage<2>(glw::GLint internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.compressedTexImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width, s_texture_height, 0,
							m_reference_size, m_compressed_texture_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed");
}

/** @brief Prepare texture data for the auxiliary texture.
 *
 *  @tparam D      Texture dimensions.
 *
 *  @note parameters as passed to compressedTexImage*
 */
template <>
void CompressedSubImageTest::CompressedTexImage<3>(glw::GLint internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.compressedTexImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width, s_texture_height, s_texture_depth,
							0, m_reference_size, m_compressed_texture_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D has failed");
}

/** @brief Prepare texture data for the compressed texture.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @return True if tested function succeeded, false otherwise.
 */
template <>
bool CompressedSubImageTest::CompressedTextureSubImage<1>(glw::GLint internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Load texture image with tested function. */
	if (m_reference_size)
	{
		for (glw::GLuint block = 0; block < s_block_count; ++block)
		{
			gl.compressedTextureSubImage1D(m_to, 0, s_texture_width * block, s_texture_width, internalformat,
										   m_reference_size, m_compressed_texture_data);
		}
	}
	else
	{
		/* For 1D version there is no specific compressed texture internal format spcified in OpenGL 4.5 core profile documentation.
		 Only implementation depended specific internalformats may provide this functionality. As a result there may be no reference data to be substituted.
		 Due to this reason there is no use of CompressedTextureSubImage1D and particulary it cannot be tested. */
		return true;
	}

	/* Check errors. */
	glw::GLenum error;

	if (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glCompressedTextureSubImage1D unexpectedly generated error "
			<< glu::getErrorStr(error) << " during the test with internal format "
			<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Prepare texture data for the compressed texture.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @param [in] internalformat      Texture internal format.
 *
 *  @return True if tested function succeeded, false otherwise.
 */
template <>
bool CompressedSubImageTest::CompressedTextureSubImage<2>(glw::GLint internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	for (glw::GLuint y = 0; y < s_block_2d_size_y; ++y)
	{
		for (glw::GLuint x = 0; x < s_block_2d_size_x; ++x)
		{
			/* Load texture image with tested function. */
			gl.compressedTextureSubImage2D(m_to, 0, s_texture_width * x, s_texture_height * y, s_texture_width,
										   s_texture_height, internalformat, m_reference_size,
										   m_compressed_texture_data);
		}
	}
	/* Check errors. */
	glw::GLenum error;

	if (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glCompressedTextureSubImage2D unexpectedly generated error "
			<< glu::getErrorStr(error) << " during the test with internal format "
			<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Prepare texture data for the compressed texture.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @param [in] internalformat      Texture internal format.
 *
 *  @return True if tested function succeeded, false otherwise.
 */
template <>
bool CompressedSubImageTest::CompressedTextureSubImage<3>(glw::GLint internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	for (glw::GLuint z = 0; z < s_block_3d_size; ++z)
	{
		for (glw::GLuint y = 0; y < s_block_3d_size; ++y)
		{
			for (glw::GLuint x = 0; x < s_block_3d_size; ++x)
			{
				/* Load texture image with tested function. */
				gl.compressedTextureSubImage3D(m_to, 0, s_texture_width * x, s_texture_height * y, s_texture_depth * z,
											   s_texture_width, s_texture_height, s_texture_depth, internalformat,
											   m_reference_size, m_compressed_texture_data);
			}
		}
	}

	/* Check errors. */
	glw::GLenum error;

	if (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glCompressedTextureSubImage2D unexpectedly generated error "
			<< glu::getErrorStr(error) << " during the test with internal format "
			<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;

		return false;
	}
	return true;
}

struct CompressedData
{
	glw::GLenum iformat;
	const unsigned char *data;
	int data_size;
	int dimensions;
};

static CompressedData compressed_images[] =
{
	/* 2D images */

	{GL_COMPRESSED_RED_RGTC1, data_0x8dbb_2D_8, sizeof data_0x8dbb_2D_8, 2},
	{GL_COMPRESSED_SIGNED_RED_RGTC1, data_0x8dbc_2D_8, sizeof data_0x8dbc_2D_8, 2},
	{GL_COMPRESSED_RG_RGTC2, data_0x8dbd_2D_16, sizeof data_0x8dbd_2D_16, 2},
	{GL_COMPRESSED_SIGNED_RG_RGTC2, data_0x8dbe_2D_16, sizeof data_0x8dbe_2D_16, 2},
	{GL_COMPRESSED_RGBA_BPTC_UNORM, data_0x8e8c_2D_16, sizeof data_0x8e8c_2D_16, 2},
	{GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, data_0x8e8d_2D_16, sizeof data_0x8e8d_2D_16, 2},
	{GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, data_0x8e8e_2D_16, sizeof data_0x8e8e_2D_16, 2},
	{GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, data_0x8e8f_2D_16, sizeof data_0x8e8f_2D_16, 2},
	{GL_COMPRESSED_RGB8_ETC2, data_GL_COMPRESSED_RGB8_ETC2_2D_8,
			sizeof data_GL_COMPRESSED_RGB8_ETC2_2D_8, 2},
	{GL_COMPRESSED_SRGB8_ETC2, data_GL_COMPRESSED_SRGB8_ETC2_2D_8,
			sizeof data_GL_COMPRESSED_SRGB8_ETC2_2D_8, 2},
	{GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
			data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8,
			sizeof data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8, 2},
	{GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
			data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8,
			sizeof data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8, 2},
	{GL_COMPRESSED_RGBA8_ETC2_EAC, data_GL_COMPRESSED_RGBA8_ETC2_EAC_2D_16,
			sizeof data_GL_COMPRESSED_RGBA8_ETC2_EAC_2D_16, 2},
	{GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_2D_16,
			sizeof data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_2D_16, 2},
	{GL_COMPRESSED_R11_EAC, data_GL_COMPRESSED_R11_EAC_2D_8,
			sizeof data_GL_COMPRESSED_R11_EAC_2D_8, 2},
	{GL_COMPRESSED_SIGNED_R11_EAC, data_GL_COMPRESSED_SIGNED_R11_EAC_2D_8,
			sizeof data_GL_COMPRESSED_SIGNED_R11_EAC_2D_8, 2},
	{GL_COMPRESSED_RG11_EAC, data_GL_COMPRESSED_RG11_EAC_2D_16,
			sizeof data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16, 2},
	{GL_COMPRESSED_SIGNED_RG11_EAC, data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16,
			sizeof data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16, 2},

	/* 3D images */

	{0x8dbb, data_0x8dbb_3D_32, sizeof data_0x8dbb_3D_32, 3},
	{0x8dbc, data_0x8dbc_3D_32, sizeof data_0x8dbc_3D_32, 3},
	{0x8dbd, data_0x8dbd_3D_64, sizeof data_0x8dbd_3D_64, 3},
	{0x8dbe, data_0x8dbe_3D_64, sizeof data_0x8dbe_3D_64, 3},
	{0x8e8c, data_0x8e8c_3D_64, sizeof data_0x8e8c_3D_64, 3},
	{0x8e8d, data_0x8e8d_3D_64, sizeof data_0x8e8d_3D_64, 3},
	{0x8e8e, data_0x8e8e_3D_64, sizeof data_0x8e8e_3D_64, 3},
	{0x8e8f, data_0x8e8f_3D_64, sizeof data_0x8e8f_3D_64, 3},
	{GL_COMPRESSED_RGB8_ETC2, data_GL_COMPRESSED_RGB8_ETC2_3D_32,
			sizeof data_GL_COMPRESSED_RGB8_ETC2_3D_32, 3},
	{GL_COMPRESSED_SRGB8_ETC2, data_GL_COMPRESSED_SRGB8_ETC2_3D_32,
			sizeof data_GL_COMPRESSED_SRGB8_ETC2_3D_32, 3},
	{GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
			data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32,
			sizeof data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32, 3},
	{GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
			data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32,
			sizeof data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32, 3},
	{GL_COMPRESSED_R11_EAC, data_GL_COMPRESSED_R11_EAC_3D_32,
			sizeof data_GL_COMPRESSED_R11_EAC_3D_32, 3},
	{GL_COMPRESSED_SIGNED_R11_EAC, data_GL_COMPRESSED_SIGNED_R11_EAC_3D_32,
			sizeof data_GL_COMPRESSED_SIGNED_R11_EAC_3D_32, 3},

	{GL_COMPRESSED_RGBA8_ETC2_EAC, data_GL_COMPRESSED_RGBA8_ETC2_EAC_3D_64,
			sizeof data_GL_COMPRESSED_RGBA8_ETC2_EAC_3D_64, 3},
	{GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_3D_64,
			sizeof data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_3D_64, 3},
	{GL_COMPRESSED_RG11_EAC, data_GL_COMPRESSED_RG11_EAC_3D_64,
			sizeof data_GL_COMPRESSED_RG11_EAC_3D_64, 3},
	{GL_COMPRESSED_SIGNED_RG11_EAC, data_GL_COMPRESSED_SIGNED_RG11_EAC_3D_64,
			sizeof data_GL_COMPRESSED_SIGNED_RG11_EAC_3D_64, 3}
};

/** @brief Prepare the reference data.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @return False if the internal format is unsupported for online compression, True otherwise
 */
template <glw::GLuint D>
bool CompressedSubImageTest::PrepareReferenceData(glw::GLenum internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Using OpenGL to compress raw data. */
	gl.bindTexture(TextureTarget<D>(), m_to_aux);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	glw::GLint is_compressed_texture = 0;
	glw::GLint compressed_texture_size = 0;

	/* Sanity checks. */
	if ((DE_NULL != m_reference) || (DE_NULL != m_compressed_texture_data))
	{
		throw 0;
	}

	/* "if" path is taken when there is no support for online compression for the format
	 * and we upload compressed data directly */
	if (!TextureImage<D>(internalformat))
	{
		for (unsigned int i=0; i<sizeof compressed_images / sizeof *compressed_images; i++)
		{
			if (internalformat == compressed_images[i].iformat
					&& D == compressed_images[i].dimensions)
			{
				is_compressed_texture = 1;
				compressed_texture_size = compressed_images[i].data_size;

				m_reference_size = compressed_texture_size;
				m_reference_internalformat = compressed_images[i].iformat;

				m_reference = new glw::GLubyte[compressed_texture_size];
				m_compressed_texture_data = new glw::GLubyte[compressed_texture_size];

				memcpy(m_reference, compressed_images[i].data, compressed_texture_size);
				memcpy(m_compressed_texture_data, compressed_images[i].data, compressed_texture_size);
			}
		}

		if (!is_compressed_texture)
			return false;

		PrepareCompressedStorage<D>(m_reference_internalformat);
	}
	else
	{
		/* Check that really compressed texture. */
		gl.getTexLevelParameteriv(TextureTarget<D>(), 0, GL_TEXTURE_COMPRESSED, &is_compressed_texture);

		if (is_compressed_texture)
		{
			/* Query texture size. */
			gl.getTexLevelParameteriv(TextureTarget<D>(), 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed_texture_size);

			/* If compressed then download. */
			if (compressed_texture_size)
			{
				/* Prepare storage. */
				m_compressed_texture_data = new glw::GLubyte[compressed_texture_size];

				if (DE_NULL != m_compressed_texture_data)
				{
					m_reference_size = compressed_texture_size;
				}
				else
				{
					throw 0;
				}

				/* Download the source compressed texture image. */
				gl.getCompressedTexImage(TextureTarget<D>(), 0, m_compressed_texture_data);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");

				// Upload the source compressed texture image to the texture object.
				// Some compressed texture format can be emulated by the driver (like the ETC2/EAC formats)
				// The compressed data sent by CompressedTexImage will be stored uncompressed by the driver
				// and will be re-compressed if the application call glGetCompressedTexImage.
				// The compression/decompression is not lossless, so when this happen it's possible for the source
				// and destination (from glGetCompressedTexImage) compressed data to be different.
				// To avoid that we will store both the source (in m_compressed_texture_data) and the destination
				// (in m_reference). The destination will be used later to make sure getCompressedTextureSubImage
				// return the expected value
				CompressedTexImage<D>(internalformat);

				m_reference = new glw::GLubyte[m_reference_size];

				if (DE_NULL == m_reference)
				{
					throw 0;
				}

				/* Download compressed texture image. */
				gl.getCompressedTexImage(TextureTarget<D>(), 0, m_reference);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
			}
		}

		PrepareStorage<D>(internalformat);
	}

	return true;
}

/** @brief Prepare texture storage.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @param [in] internalformat      Texture internal format.
 */
template <>
void CompressedSubImageTest::PrepareStorage<1>(glw::GLenum internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindTexture(TextureTarget<1>(), m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width * s_block_count, 0, GL_RGBA, GL_UNSIGNED_BYTE,
				  NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
}

/** @brief Prepare texture storage.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @param [in] internalformat      Texture internal format.
 */
template <>
void CompressedSubImageTest::PrepareStorage<2>(glw::GLenum internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindTexture(TextureTarget<2>(), m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width * s_block_2d_size_x,
				  s_texture_height * s_block_2d_size_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
}

/** @brief Prepare texture storage.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @param [in] internalformat      Texture internal format.
 */
template <>
void CompressedSubImageTest::PrepareStorage<3>(glw::GLenum internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.bindTexture(TextureTarget<3>(), m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width * s_block_3d_size,
				  s_texture_height * s_block_3d_size, s_texture_depth * s_block_3d_size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
				  NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");
}

/** @brief Prepare compressed texture storage.
 * @tparam D		Texture dimensions.
 *
 * @tparam [in] internalformat		Texture internal format.
 */
template <>
void CompressedSubImageTest::PrepareCompressedStorage<1>(glw::GLenum internalformat)
{
	/* Shortcut for GL functionality */
	const glw::Functions &gl = m_context.getRenderContext().getFunctions();

	gl.bindTexture(TextureTarget<1>(), m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.compressedTexImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width * s_block_count,
			0, s_texture_width * s_block_count, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage1D has failed");
}

/** @brief Prepare compressed texture storage.
 * @tparam D		Texture dimensions.
 *
 * @tparam [in] internalformat		Texture internal format.
 */
template <>
void CompressedSubImageTest::PrepareCompressedStorage<2>(glw::GLenum internalformat)
{
	/* Shortcut for GL functionality */
	const glw::Functions &gl = m_context.getRenderContext().getFunctions();

	gl.bindTexture(TextureTarget<2>(), m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	GLsizei size_x = s_texture_width * s_block_2d_size_x;
	GLsizei size_y = s_texture_height * s_block_2d_size_y;
	GLsizei size = m_reference_size * s_block_2d_size_x * s_block_2d_size_y;

	gl.compressedTexImage2D(TextureTarget<2>(), 0, internalformat, size_x, size_y,
			0, size, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed");
}

/** @brief Prepare compressed texture storage.
 * @tparam D		Texture dimensions.
 *
 * @tparam [in] internalformat		Texture internal format.
 */
template <>
void CompressedSubImageTest::PrepareCompressedStorage<3>(glw::GLenum internalformat)
{
	/* Shortcut for GL functionality */
	const glw::Functions &gl = m_context.getRenderContext().getFunctions();

	gl.bindTexture(TextureTarget<3>(), m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	GLsizei size_x = s_texture_width * s_block_3d_size;
	GLsizei size_y = s_texture_height * s_block_3d_size;
	GLsizei size_z = s_texture_depth * s_block_3d_size;
	GLsizei size = m_reference_size * s_block_3d_size * s_block_3d_size * s_block_3d_size;

	gl.compressedTexImage3D(TextureTarget<3>(), 0, internalformat, size_x, size_y, size_z, 0,
			size, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D has failed");
}

/** @brief Compare results with the reference.
 *
 *  @tparam T      Type.
 *  @tparam S      Size (# of components).
 *  @tparam N      Is normalized.
 *
 *  @param [in] internalformat      Texture internal format.
 *
 *  @return True if equal, false otherwise.
 */
template <glw::GLuint D>
bool CompressedSubImageTest::CheckData(glw::GLenum internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check texture content with reference. */
	m_result = new glw::GLubyte[m_reference_size * s_block_count];

	if (DE_NULL == m_result)
	{
		throw 0;
	}

	gl.getCompressedTexImage(TextureTarget<D>(), 0, m_result);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
	for (glw::GLuint block = 0; block < s_block_count; ++block)
	{
		for (glw::GLuint i = 0; i < m_reference_size; ++i)
		{
			if (m_reference[i] != m_result[block * m_reference_size + i])
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "glCompressedTextureSubImage*D created texture with data "
					<< DataToString(m_reference_size, m_reference) << " however texture contains data "
					<< DataToString(m_reference_size, &(m_result[block * m_reference_size])) << ". Texture target was "
					<< glu::getTextureTargetStr(TextureTarget<D>()) << " and internal format was "
					<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;

				return false;
			}
		}
	}

	return true;
}

/** @brief Compare results with the reference.
 *
 *  @tparam T      Type.
 *  @tparam S      Size (# of components).
 *  @tparam N      Is normalized.
 *
 *  @param [in] internalformat      Texture internal format.
 *
 *  @return True if equal, false otherwise.
 */
template <>
bool CompressedSubImageTest::CheckData<3>(glw::GLenum internalformat)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check texture content with reference. */
	m_result = new glw::GLubyte[m_reference_size * s_block_count];

	if (DE_NULL == m_result)
	{
		throw 0;
	}

	gl.getCompressedTexImage(TextureTarget<3>(), 0, m_result);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");

	glw::GLuint reference_layer_size = m_reference_size / s_texture_depth;

	for (glw::GLuint i = 0; i < m_reference_size * s_block_count; ++i)
	{
		// we will read the result one bytes at the time and compare with the reference
		// for each bytes of the result image we need to figure out which byte in the reference image it corresponds to
		glw::GLuint refIdx		= i % reference_layer_size;
		glw::GLuint refLayerIdx = (i / (reference_layer_size * s_block_3d_size * s_block_3d_size)) % s_texture_depth;
		if (m_reference[refLayerIdx * reference_layer_size + refIdx] != m_result[i])
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glCompressedTextureSubImage3D created texture with data "
				<< DataToString(reference_layer_size, &(m_reference[refLayerIdx * reference_layer_size]))
				<< " however texture contains data "
				<< DataToString(reference_layer_size, &(m_result[i % reference_layer_size])) << ". Texture target was "
				<< glu::getTextureTargetStr(TextureTarget<3>()) << " and internal format was "
				<< glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}
/** @brief Test case function.
 *
 *  @tparam D       Number of texture dimensions.
 *
 *  @param [in] internal format     Texture internal format.
 *
 *  @param [in] can be unsupported     If the format may not support online compression
 *
 *  @return True if test succeeded, false otherwise.
 */
template <glw::GLuint D>
bool CompressedSubImageTest::Test(glw::GLenum internalformat, bool can_be_unsupported)
{
	/* Create texture image. */
	CreateTextures(TextureTarget<D>());

	if (!PrepareReferenceData<D>(internalformat))
	{
		CleanAll();
		return can_be_unsupported;
	}

	/* Setup data with CompressedTextureSubImage<D>D function and check for errors. */
	if (!CompressedTextureSubImage<D>(internalformat))
	{
		CleanAll();

		return false;
	}

	/* If compressed reference data was generated than compare values. */
	if (m_reference)
	{
		if (!CheckData<D>(internalformat))
		{
			CleanAll();

			return false;
		}
	}

	CleanAll();

	return true;
}

/** @brief Clean GL objects, test variables and GL errors.
 */
void CompressedSubImageTest::CleanAll()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Textures. */
	if (m_to)
	{
		gl.deleteTextures(1, &m_to);

		m_to = 0;
	}

	if (m_to_aux)
	{
		gl.deleteTextures(1, &m_to_aux);

		m_to_aux = 0;
	}

	/* Reference data storage. */
	if (DE_NULL != m_reference)
	{
		delete[] m_reference;

		m_reference = DE_NULL;
	}

	if (DE_NULL != m_compressed_texture_data)
	{
		delete[] m_compressed_texture_data;

		m_compressed_texture_data = DE_NULL;
	}

	if (DE_NULL != m_result)
	{
		delete[] m_result;

		m_result = DE_NULL;
	}

	m_reference_size = 0;

	/* Errors. */
	while (GL_NO_ERROR != gl.getError())
		;
}

/** @brief Convert raw data into string for logging purposes.
 *
 *  @param [in] count      Count of the data.
 *  @param [in] data       Raw data.
 *
 *  @return String representation of data.
 */
std::string CompressedSubImageTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
{
	std::string data_str = "[";

	for (glw::GLuint i = 0; i < count; ++i)
	{
		std::stringstream int_sstream;

		int_sstream << unsigned(data[i]);

		data_str.append(int_sstream.str());

		if (i + 1 < count)
		{
			data_str.append(", ");
		}
		else
		{
			data_str.append("]");
		}
	}

	return data_str;
}

/** @brief Iterate Compressed SubImage Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CompressedSubImageTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		is_ok &= Test<1>(GL_COMPRESSED_RGB, false);

		is_ok &= Test<2>(GL_COMPRESSED_RED_RGTC1, false);
		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RED_RGTC1, false);
		is_ok &= Test<2>(GL_COMPRESSED_RG_RGTC2, false);
		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RG_RGTC2, false);
		is_ok &= Test<2>(GL_COMPRESSED_RGBA_BPTC_UNORM, false);
		is_ok &= Test<2>(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, false);
		is_ok &= Test<2>(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, false);
		is_ok &= Test<2>(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, false);
		is_ok &= Test<2>(GL_COMPRESSED_RGB8_ETC2, true);
		is_ok &= Test<2>(GL_COMPRESSED_SRGB8_ETC2, true);
		is_ok &= Test<2>(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, true);
		is_ok &= Test<2>(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, true);
		is_ok &= Test<2>(GL_COMPRESSED_RGBA8_ETC2_EAC, true);
		is_ok &= Test<2>(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, true);
		is_ok &= Test<2>(GL_COMPRESSED_R11_EAC, true);
		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_R11_EAC, true);
		is_ok &= Test<2>(GL_COMPRESSED_RG11_EAC, true);
		is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RG11_EAC, true);

		is_ok &= Test<3>(GL_COMPRESSED_RED_RGTC1, false);
		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RED_RGTC1, false);
		is_ok &= Test<3>(GL_COMPRESSED_RG_RGTC2, false);
		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RG_RGTC2, false);
		is_ok &= Test<3>(GL_COMPRESSED_RGBA_BPTC_UNORM, false);
		is_ok &= Test<3>(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, false);
		is_ok &= Test<3>(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, false);
		is_ok &= Test<3>(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, false);
		is_ok &= Test<3>(GL_COMPRESSED_RGB8_ETC2, true);
		is_ok &= Test<3>(GL_COMPRESSED_SRGB8_ETC2, true);
		is_ok &= Test<3>(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, true);
		is_ok &= Test<3>(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, true);
		is_ok &= Test<3>(GL_COMPRESSED_RGBA8_ETC2_EAC, true);
		is_ok &= Test<3>(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, true);
		is_ok &= Test<3>(GL_COMPRESSED_R11_EAC, true);
		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_R11_EAC, true);
		is_ok &= Test<3>(GL_COMPRESSED_RG11_EAC, true);
		is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RG11_EAC, true);
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	CleanAll();

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Reference data. */
const glw::GLubyte CompressedSubImageTest::s_texture_data[] = {
	0x00, 0x00, 0x00, 0xFF, 0x7f, 0x7f, 0x7f, 0x00, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x00,
	0x88, 0x00, 0x15, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x00, 0x00,
	0xc8, 0xbf, 0xe7, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0x00,
	0xa3, 0x49, 0xa4, 0xFF, 0x3f, 0x48, 0xcc, 0x00, 0x00, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0x00,

	0xa3, 0x49, 0xa4, 0xFF, 0xc8, 0xbf, 0xe7, 0x00, 0x88, 0x00, 0x15, 0xff, 0x00, 0x00, 0x00, 0x00,
	0x3f, 0x48, 0xcc, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x7f, 0x7f, 0x7f, 0x00,
	0x00, 0xa2, 0xe8, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xc3, 0xc3, 0xc3, 0x00,
	0x22, 0xb1, 0x4c, 0xFF, 0xb5, 0xe6, 0x1d, 0x00, 0xff, 0xf2, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,

	0x22, 0xb1, 0x4c, 0xFF, 0x00, 0xa2, 0xe8, 0x00, 0x3f, 0x48, 0xcc, 0xff, 0xa3, 0x49, 0xa4, 0x00,
	0xb5, 0xe6, 0x1d, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0x70, 0x92, 0xbe, 0xff, 0xc8, 0xbf, 0xe7, 0x00,
	0xff, 0xf2, 0x00, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x88, 0x00, 0x15, 0x00,
	0xff, 0xff, 0xff, 0xFF, 0xc3, 0xc3, 0xc3, 0x00, 0x7f, 0x7f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00,

	0xff, 0xff, 0xff, 0xFF, 0xff, 0xf2, 0x00, 0x00, 0xb5, 0xe6, 0x1d, 0xff, 0x22, 0xb1, 0x4c, 0x00,
	0xc3, 0xc3, 0xc3, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0x99, 0xd9, 0xea, 0xff, 0x00, 0xa2, 0xe8, 0x00,
	0x7f, 0x7f, 0x7f, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0x70, 0x92, 0xbe, 0xff, 0x3f, 0x48, 0xcc, 0x00,
	0x00, 0x00, 0x00, 0xFF, 0x88, 0x00, 0x15, 0x00, 0xc8, 0xbf, 0xe7, 0xff, 0xa3, 0x49, 0xa4, 0x00
};

/** Reference data parameters. */
const glw::GLuint CompressedSubImageTest::s_texture_width   = 4;
const glw::GLuint CompressedSubImageTest::s_texture_height  = 4;
const glw::GLuint CompressedSubImageTest::s_texture_depth   = 4;
const glw::GLuint CompressedSubImageTest::s_block_count		= 8;
const glw::GLuint CompressedSubImageTest::s_block_2d_size_x = 4;
const glw::GLuint CompressedSubImageTest::s_block_2d_size_y = 2;
const glw::GLuint CompressedSubImageTest::s_block_3d_size   = 2;

/******************************** Copy SubImage Test Implementation   ********************************/

/** @brief Compressed SubImage Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CopyTest::CopyTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_copy", "Texture Copy Test")
	, m_fbo(0)
	, m_to_src(0)
	, m_to_dst(0)
	, m_result(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Texture target selector.
 *
 *  @tparam D      Texture dimenisons.
 *
 *  @return Texture target.
 */
template <>
glw::GLenum CopyTest::TextureTarget<1>()
{
	return GL_TEXTURE_1D;
}
template <>
glw::GLenum CopyTest::TextureTarget<2>()
{
	return GL_TEXTURE_2D;
}
template <>
glw::GLenum CopyTest::TextureTarget<3>()
{
	return GL_TEXTURE_3D;
}

/** @brief Copy texture, check errors and log.
 *
 *  @note Parameters as passed to CopyTextureSubImage*D
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool CopyTest::CopyTextureSubImage1DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset,
												   glw::GLint x, glw::GLint y, glw::GLsizei width)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.readBuffer(GL_COLOR_ATTACHMENT0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");

	gl.copyTextureSubImage1D(texture, level, xoffset, x, y, width);

	/* Check errors. */
	glw::GLenum error;

	if (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glCopyTextureSubImage1D unexpectedly generated error "
											<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Copy texture, check errors and log.
 *
 *  @note Parameters as passed to CopyTextureSubImage*D
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool CopyTest::CopyTextureSubImage2DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset,
												   glw::GLint yoffset, glw::GLint x, glw::GLint y, glw::GLsizei width,
												   glw::GLsizei height)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.readBuffer(GL_COLOR_ATTACHMENT0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");

	gl.copyTextureSubImage2D(texture, level, xoffset, yoffset, x, y, width, height);

	/* Check errors. */
	glw::GLenum error;

	if (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glCopyTextureSubImage2D unexpectedly generated error "
											<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Copy texture, check errors and log.
 *
 *  @note Parameters as passed to CopyTextureSubImage*D
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool CopyTest::CopyTextureSubImage3DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset,
												   glw::GLint yoffset, glw::GLint zoffset, glw::GLint x, glw::GLint y,
												   glw::GLsizei width, glw::GLsizei height)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.readBuffer(GL_COLOR_ATTACHMENT0 + zoffset);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");

	gl.copyTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, x, y, width, height);

	/* Check errors. */
	glw::GLenum error;

	if (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message
											<< "glCopyTextureSubImage3D unexpectedly generated error "
											<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Create texture.
 *
 *  @tparam D      Dimmensions.
 */
template <>
void CopyTest::CreateSourceTexture<1>()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genTextures(1, &m_to_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindTexture(TextureTarget<1>(), m_to_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	gl.texImage1D(TextureTarget<1>(), 0, GL_RGBA8, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
}

/** @brief Create texture.
 *
 *  @tparam D      Dimmensions.
 */
template <>
void CopyTest::CreateSourceTexture<2>()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genTextures(1, &m_to_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindTexture(TextureTarget<2>(), m_to_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	gl.texImage2D(TextureTarget<2>(), 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
				  s_texture_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
}

/** @brief Create texture.
 *
 *  @tparam D      Dimmensions.
 */
template <>
void CopyTest::CreateSourceTexture<3>()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genTextures(1, &m_to_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindTexture(TextureTarget<3>(), m_to_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	gl.texImage3D(TextureTarget<3>(), 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
				  GL_UNSIGNED_BYTE, s_texture_data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
}

/** @brief Create texture.
 *
 *  @tparam D      Dimmensions.
 */
template <>
void CopyTest::CreateDestinationTexture<1>()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genTextures(1, &m_to_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindTexture(TextureTarget<1>(), m_to_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	gl.texImage1D(TextureTarget<1>(), 0, GL_RGBA8, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
}

/** @brief Create texture.
 *
 *  @tparam D      Dimmensions.
 */
template <>
void CopyTest::CreateDestinationTexture<2>()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genTextures(1, &m_to_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindTexture(TextureTarget<2>(), m_to_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	gl.texImage2D(TextureTarget<2>(), 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
				  DE_NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
}

/** @brief Create texture.
 *
 *  @tparam D      Dimmensions.
 */
template <>
void CopyTest::CreateDestinationTexture<3>()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genTextures(1, &m_to_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindTexture(TextureTarget<3>(), m_to_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	gl.texImage3D(TextureTarget<3>(), 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
				  GL_UNSIGNED_BYTE, DE_NULL);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed.");
}

/** @brief Create framebuffer.
 *
 *  @tparam D      Dimmensions.
 */
template <>
void CopyTest::CreateSourceFramebuffer<1>()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare framebuffer. */
	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.framebufferTexture1D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TextureTarget<1>(), m_to_src, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		throw 0;
	}

	gl.viewport(0, 0, s_texture_width, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
}

/** @brief Create framebuffer.
 *
 *  @tparam D      Dimmensions.
 */
template <>
void CopyTest::CreateSourceFramebuffer<2>()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare framebuffer. */
	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TextureTarget<2>(), m_to_src, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		throw 0;
	}

	gl.viewport(0, 0, s_texture_width, s_texture_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
}

/** @brief Create framebuffer.
 *
 *  @tparam D      Dimmensions.
 */
template <>
void CopyTest::CreateSourceFramebuffer<3>()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare framebuffer. */
	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	for (glw::GLuint i = 0; i < s_texture_depth; ++i)
	{
		gl.framebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, TextureTarget<3>(), m_to_src, 0, i);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");
	}

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		throw 0;
	}

	gl.viewport(0, 0, s_texture_width, s_texture_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
}

/** @brief Dispatch function to create test objects */
template <glw::GLuint D>
void				  CopyTest::CreateAll()
{
	CreateSourceTexture<D>();
	CreateSourceFramebuffer<D>();
	CreateDestinationTexture<D>();
}

/** @brief Test function */
template <>
bool CopyTest::Test<1>()
{
	CreateAll<1>();

	bool result = true;

	result &= CopyTextureSubImage1DAndCheckErrors(m_to_dst, 0, 0, 0, 0, s_texture_width / 2);
	result &= CopyTextureSubImage1DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_width / 2, 0,
												  s_texture_width / 2);

	result &= CheckData(TextureTarget<1>(), 4 /* RGBA */ * s_texture_width);

	CleanAll();

	return result;
}

/** @brief Test function */
template <>
bool CopyTest::Test<2>()
{
	CreateAll<2>();

	bool result = true;

	result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, 0, 0, 0, 0, s_texture_width / 2, s_texture_height / 2);
	result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, 0, s_texture_width / 2, 0,
												  s_texture_width / 2, s_texture_height / 2);
	result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, 0, s_texture_height / 2, 0, s_texture_height / 2,
												  s_texture_width / 2, s_texture_height / 2);
	result &=
		CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_height / 2, s_texture_width / 2,
											s_texture_height / 2, s_texture_width / 2, s_texture_height / 2);

	result &= CheckData(TextureTarget<2>(), 4 /* RGBA */ * s_texture_width * s_texture_height);

	CleanAll();

	return result;
}

/** @brief Test function */
template <>
bool CopyTest::Test<3>()
{
	CreateAll<3>();

	bool result = true;

	for (glw::GLuint i = 0; i < s_texture_depth; ++i)
	{
		result &=
			CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, 0, 0, i, 0, 0, s_texture_width / 2, s_texture_height / 2);
		result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, 0, i, s_texture_width / 2, 0,
													  s_texture_width / 2, s_texture_height / 2);
		result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, 0, s_texture_height / 2, i, 0, s_texture_height / 2,
													  s_texture_width / 2, s_texture_height / 2);
		result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_height / 2, i,
													  s_texture_width / 2, s_texture_height / 2, s_texture_width / 2,
													  s_texture_height / 2);
	}

	result &= CheckData(TextureTarget<3>(), 4 /* RGBA */ * s_texture_width * s_texture_height * s_texture_depth);

	CleanAll();

	return result;
}

/** @brief Compre results with the reference.
 *
 *  @param [in] target      Texture target.
 *  @param [in] size        Size of the buffer.
 *
 *  @return True if equal, false otherwise.
 */
bool CopyTest::CheckData(glw::GLenum target, glw::GLuint size)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check texture content with reference. */
	m_result = new glw::GLubyte[size];

	if (DE_NULL == m_result)
	{
		throw 0;
	}

	gl.getTexImage(target, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_result);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");

	for (glw::GLuint i = 0; i < size; ++i)
	{
		if (s_texture_data[i] != m_result[i])
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glCopyTextureSubImage*D created texture with data "
				<< DataToString(size, s_texture_data) << " however texture contains data "
				<< DataToString(size, m_result) << ". Texture target was " << glu::getTextureTargetStr(target)
				<< ". Test fails." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}

/** @brief Convert raw data into string for logging purposes.
 *
 *  @param [in] count      Count of the data.
 *  @param [in] data       Raw data.
 *
 *  @return String representation of data.
 */
std::string CopyTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
{
	std::string data_str = "[";

	for (glw::GLuint i = 0; i < count; ++i)
	{
		std::stringstream int_sstream;

		int_sstream << unsigned(data[i]);

		data_str.append(int_sstream.str());

		if (i + 1 < count)
		{
			data_str.append(", ");
		}
		else
		{
			data_str.append("]");
		}
	}

	return data_str;
}

/** @brief Clean GL objects, test variables and GL errors.
 */
void CopyTest::CleanAll()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (m_to_src)
	{
		gl.deleteTextures(1, &m_to_src);

		m_to_src = 0;
	}

	if (m_to_dst)
	{
		gl.deleteTextures(1, &m_to_dst);

		m_to_dst = 0;
	}

	if (DE_NULL == m_result)
	{
		delete[] m_result;

		m_result = DE_NULL;
	}

	while (GL_NO_ERROR != gl.getError())
		;
}

/** @brief Iterate Copy Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CopyTest::iterate()
{
	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		is_ok &= Test<1>();
		is_ok &= Test<2>();
		is_ok &= Test<3>();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	CleanAll();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Reference data. */
const glw::GLubyte CopyTest::s_texture_data[] = {
	0x00, 0x00, 0x00, 0xFF, 0x7f, 0x7f, 0x7f, 0x00, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x00,
	0x88, 0x00, 0x15, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x00, 0x00,
	0xc8, 0xbf, 0xe7, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0x00,
	0xa3, 0x49, 0xa4, 0xFF, 0x3f, 0x48, 0xcc, 0x00, 0x00, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0x00,

	0xa3, 0x49, 0xa4, 0xFF, 0xc8, 0xbf, 0xe7, 0x00, 0x88, 0x00, 0x15, 0xff, 0x00, 0x00, 0x00, 0x00,
	0x3f, 0x48, 0xcc, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x7f, 0x7f, 0x7f, 0x00,
	0x00, 0xa2, 0xe8, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xc3, 0xc3, 0xc3, 0x00,
	0x22, 0xb1, 0x4c, 0xFF, 0xb5, 0xe6, 0x1d, 0x00, 0xff, 0xf2, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,

	0x22, 0xb1, 0x4c, 0xFF, 0x00, 0xa2, 0xe8, 0x00, 0x3f, 0x48, 0xcc, 0xff, 0xa3, 0x49, 0xa4, 0x00,
	0xb5, 0xe6, 0x1d, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0x70, 0x92, 0xbe, 0xff, 0xc8, 0xbf, 0xe7, 0x00,
	0xff, 0xf2, 0x00, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x88, 0x00, 0x15, 0x00,
	0xff, 0xff, 0xff, 0xFF, 0xc3, 0xc3, 0xc3, 0x00, 0x7f, 0x7f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00,

	0xff, 0xff, 0xff, 0xFF, 0xff, 0xf2, 0x00, 0x00, 0xb5, 0xe6, 0x1d, 0xff, 0x22, 0xb1, 0x4c, 0x00,
	0xc3, 0xc3, 0xc3, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0x99, 0xd9, 0xea, 0xff, 0x00, 0xa2, 0xe8, 0x00,
	0x7f, 0x7f, 0x7f, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0x70, 0x92, 0xbe, 0xff, 0x3f, 0x48, 0xcc, 0x00,
	0x00, 0x00, 0x00, 0xFF, 0x88, 0x00, 0x15, 0x00, 0xc8, 0xbf, 0xe7, 0xff, 0xa3, 0x49, 0xa4, 0x00
};

/** Reference data parameters. */
const glw::GLuint CopyTest::s_texture_width  = 4;
const glw::GLuint CopyTest::s_texture_height = 4;
const glw::GLuint CopyTest::s_texture_depth  = 4;

/******************************** Get Set Parameter Test Implementation   ********************************/

/** @brief Get Set Parameter Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetSetParameterTest::GetSetParameterTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_get_set_parameter", "Texture Get Set Parameter Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Get Set Parameter Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetSetParameterTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Texture. */
	glw::GLuint texture = 0;

	try
	{
		gl.genTextures(1, &texture);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_3D, texture);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		{
			glw::GLenum name	  = GL_DEPTH_STENCIL_TEXTURE_MODE;
			glw::GLint  value_src = GL_DEPTH_COMPONENT;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_BASE_LEVEL;
			glw::GLint  value_src = 2;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum  name		  = GL_TEXTURE_BORDER_COLOR;
			glw::GLfloat value_src[4] = { 0.25, 0.5, 0.75, 1.0 };
			glw::GLfloat value_dst[4] = {};

			gl.textureParameterfv(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameterfv", name);

			gl.getTextureParameterfv(texture, name, value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameterfv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name		 = GL_TEXTURE_BORDER_COLOR;
			glw::GLint  value_src[4] = { 0, 64, -64, -32 };
			glw::GLint  value_dst[4] = {};

			gl.textureParameterIiv(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameterIiv", name);

			gl.getTextureParameterIiv(texture, name, value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameterIiv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name		 = GL_TEXTURE_BORDER_COLOR;
			glw::GLuint value_src[4] = { 0, 64, 128, 192 };
			glw::GLuint value_dst[4] = {};

			gl.textureParameterIuiv(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameterIuiv", name);

			gl.getTextureParameterIuiv(texture, name, value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameterIuiv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_COMPARE_FUNC;
			glw::GLint  value_src = GL_LEQUAL;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_COMPARE_MODE;
			glw::GLint  value_src = GL_COMPARE_REF_TO_TEXTURE;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum  name	  = GL_TEXTURE_LOD_BIAS;
			glw::GLfloat value_src = -2.f;
			glw::GLfloat value_dst = 0.f;

			gl.textureParameterf(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameterf", name);

			gl.getTextureParameterfv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameterfv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MIN_FILTER;
			glw::GLint  value_src = GL_LINEAR_MIPMAP_NEAREST;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MAG_FILTER;
			glw::GLint  value_src = GL_NEAREST;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MIN_LOD;
			glw::GLint  value_src = -100;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MAX_LOD;
			glw::GLint  value_src = 100;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MAX_LEVEL;
			glw::GLint  value_src = 100;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_R;
			glw::GLint  value_src = GL_BLUE;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_G;
			glw::GLint  value_src = GL_ALPHA;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_B;
			glw::GLint  value_src = GL_RED;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_A;
			glw::GLint  value_src = GL_GREEN;
			glw::GLint  value_dst = 0;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name		 = GL_TEXTURE_SWIZZLE_RGBA;
			glw::GLint  value_src[4] = { GL_ZERO, GL_ONE, GL_ZERO, GL_ONE };
			glw::GLint  value_dst[4] = {};

			gl.textureParameteriv(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_WRAP_S;
			glw::GLint  value_src = GL_MIRROR_CLAMP_TO_EDGE;
			glw::GLint  value_dst = 11;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_WRAP_T;
			glw::GLint  value_src = GL_CLAMP_TO_EDGE;
			glw::GLint  value_dst = 11;

			gl.textureParameteri(texture, name, value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_WRAP_R;
			glw::GLint  value_src = GL_CLAMP_TO_EDGE;
			glw::GLint  value_dst = 11;

			gl.textureParameteriv(texture, name, &value_src);
			is_ok &= CheckErrorAndLog("glTextureParameteri", name);

			gl.getTextureParameteriv(texture, name, &value_dst);
			is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name);

			is_ok &= CompareAndLog(value_src, value_dst, name);
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture)
	{
		gl.deleteTextures(1, &texture);
	}

	while (GL_NO_ERROR != gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Check for errors and log.
 *
 *  @param [in] fname     Name of the function (to be logged).
 *  @param [in] pname     Parameter name with which function was called.
 *
 *  @return True if no error, false otherwise.
 */
bool GetSetParameterTest::CheckErrorAndLog(const glw::GLchar* fname, glw::GLenum pname)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Check errors. */
	glw::GLenum error;

	if (GL_NO_ERROR != (error = gl.getError()))
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << fname << " unexpectedly generated error "
											<< glu::getErrorStr(error) << " during test of pname "
											<< glu::getTextureParameterStr(pname) << ". Test fails."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool GetSetParameterTest::CompareAndLog(glw::GLint value_src, glw::GLint value_dst, glw::GLenum pname)
{
	if (value_src != value_dst)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
											<< ", however " << value_src << " was expected. Test fails."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool GetSetParameterTest::CompareAndLog(glw::GLuint value_src, glw::GLuint value_dst, glw::GLenum pname)
{
	if (value_src != value_dst)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
											<< ", however " << value_src << " was expected. Test fails."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool GetSetParameterTest::CompareAndLog(glw::GLfloat value_src, glw::GLfloat value_dst, glw::GLenum pname)
{
	if (de::abs(value_src - value_dst) > 0.0125 /* Precision */)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
											<< ", however " << value_src << " was expected. Test fails."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool GetSetParameterTest::CompareAndLog(glw::GLint value_src[4], glw::GLint value_dst[4], glw::GLenum pname)
{
	if ((value_src[0] != value_dst[0]) || (value_src[1] != value_dst[1]) || (value_src[2] != value_dst[2]) ||
		(value_src[3] != value_dst[3]))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
			<< "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3]
			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool GetSetParameterTest::CompareAndLog(glw::GLuint value_src[4], glw::GLuint value_dst[4], glw::GLenum pname)
{
	if ((value_src[0] != value_dst[0]) || (value_src[1] != value_dst[1]) || (value_src[2] != value_dst[2]) ||
		(value_src[3] != value_dst[3]))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
			<< "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3]
			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool GetSetParameterTest::CompareAndLog(glw::GLfloat value_src[4], glw::GLfloat value_dst[4], glw::GLenum pname)
{
	if ((de::abs(value_src[0] - value_dst[0]) > 0.0125 /* Precision */) ||
		(de::abs(value_src[1] - value_dst[1]) > 0.0125 /* Precision */) ||
		(de::abs(value_src[2] - value_dst[2]) > 0.0125 /* Precision */) ||
		(de::abs(value_src[3] - value_dst[3]) > 0.0125 /* Precision */))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
			<< "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3]
			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/******************************** Defaults Test Implementation   ********************************/

/** @brief Defaults Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
DefaultsTest::DefaultsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_defaults", "Texture Defaults Test")
{
	/* Intentionally left blank. */
}

/** @brief Defaults Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult DefaultsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Texture. */
	glw::GLuint texture = 0;

	try
	{
		gl.createTextures(GL_TEXTURE_3D, 1, &texture);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		{
			glw::GLenum name	  = GL_DEPTH_STENCIL_TEXTURE_MODE;
			glw::GLint  value_ref = GL_DEPTH_COMPONENT;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_BASE_LEVEL;
			glw::GLint  value_ref = 0;
			glw::GLint  value_dst = 1;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum  name		  = GL_TEXTURE_BORDER_COLOR;
			glw::GLfloat value_ref[4] = { 0.f, 0.f, 0.f, 0.f };
			glw::GLfloat value_dst[4] = {};

			gl.getTextureParameterfv(texture, name, value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_COMPARE_FUNC;
			glw::GLint  value_ref = GL_LEQUAL;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_COMPARE_MODE;
			glw::GLint  value_ref = GL_NONE;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum  name	  = GL_TEXTURE_LOD_BIAS;
			glw::GLfloat value_ref = 0.f;
			glw::GLfloat value_dst = 0.f;

			gl.getTextureParameterfv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MIN_FILTER;
			glw::GLint  value_ref = GL_NEAREST_MIPMAP_LINEAR;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MAG_FILTER;
			glw::GLint  value_ref = GL_LINEAR;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MIN_LOD;
			glw::GLint  value_ref = -1000;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MAX_LOD;
			glw::GLint  value_ref = 1000;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_MAX_LEVEL;
			glw::GLint  value_ref = 1000;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_R;
			glw::GLint  value_ref = GL_RED;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_G;
			glw::GLint  value_ref = GL_GREEN;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_B;
			glw::GLint  value_ref = GL_BLUE;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_SWIZZLE_A;
			glw::GLint  value_ref = GL_ALPHA;
			glw::GLint  value_dst = 0;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_WRAP_S;
			glw::GLint  value_ref = GL_REPEAT;
			glw::GLint  value_dst = 11;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_WRAP_T;
			glw::GLint  value_ref = GL_REPEAT;
			glw::GLint  value_dst = 11;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}

		{
			glw::GLenum name	  = GL_TEXTURE_WRAP_R;
			glw::GLint  value_ref = GL_REPEAT;
			glw::GLint  value_dst = 11;

			gl.getTextureParameteriv(texture, name, &value_dst);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed");

			is_ok &= CompareAndLog(value_ref, value_dst, name);
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture)
	{
		gl.deleteTextures(1, &texture);
	}

	while (GL_NO_ERROR != gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool DefaultsTest::CompareAndLog(glw::GLint value_ref, glw::GLint value_dst, glw::GLenum pname)
{
	if (value_ref != value_dst)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
											<< ", however " << value_ref << " was expected. Test fails."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool DefaultsTest::CompareAndLog(glw::GLuint value_ref, glw::GLuint value_dst, glw::GLenum pname)
{
	if (value_ref != value_dst)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
											<< ", however " << value_ref << " was expected. Test fails."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool DefaultsTest::CompareAndLog(glw::GLfloat value_ref, glw::GLfloat value_dst, glw::GLenum pname)
{
	if (de::abs(value_ref - value_dst) > 0.0125 /* Precision */)
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname "
											<< glu::getTextureParameterStr(pname) << " is equal to " << value_dst
											<< ", however " << value_ref << " was expected. Test fails."
											<< tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool DefaultsTest::CompareAndLog(glw::GLint value_ref[4], glw::GLint value_dst[4], glw::GLenum pname)
{
	if ((value_ref[0] != value_dst[0]) || (value_ref[1] != value_dst[1]) || (value_ref[2] != value_dst[2]) ||
		(value_ref[3] != value_dst[3]))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
			<< "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3]
			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool DefaultsTest::CompareAndLog(glw::GLuint value_ref[4], glw::GLuint value_dst[4], glw::GLenum pname)
{
	if ((value_ref[0] != value_dst[0]) || (value_ref[1] != value_dst[1]) || (value_ref[2] != value_dst[2]) ||
		(value_ref[3] != value_dst[3]))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
			<< "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3]
			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/** @brief Compare queried value of parameter with the expected vale.
 *
 *  @param [in] value_src           First value.
 *  @param [in] value_dst           Second value.
 *  @param [in] pname               Parameter name.
 *
 *  @return True if no error was generated by CopyTextureSubImage*D, false otherwise
 */
bool DefaultsTest::CompareAndLog(glw::GLfloat value_ref[4], glw::GLfloat value_dst[4], glw::GLenum pname)
{
	if ((de::abs(value_ref[0] - value_dst[0]) > 0.0125 /* Precision */) ||
		(de::abs(value_ref[1] - value_dst[1]) > 0.0125 /* Precision */) ||
		(de::abs(value_ref[2] - value_dst[2]) > 0.0125 /* Precision */) ||
		(de::abs(value_ref[3] - value_dst[3]) > 0.0125 /* Precision */))
	{
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname)
			<< " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3]
			<< "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3]
			<< "] was expected. Test fails." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/******************************** Generate Mipmap Test Implementation   ********************************/

/** @brief Generate Mipmap Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GenerateMipmapTest::GenerateMipmapTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_generate_mipmaps", "Textures Generate Mipmap Test")
{
	/* Intentionally left blank. */
}

/** @brief Generate Mipmap Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GenerateMipmapTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Texture and cpu results storage. */
	glw::GLuint   texture = 0;
	glw::GLubyte* result  = DE_NULL;

	try
	{
		/* Prepare texture. */
		gl.genTextures(1, &texture);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_1D, texture);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texImage1D(GL_TEXTURE_1D, 0, GL_R8, s_texture_width, 0, GL_RED, GL_UNSIGNED_BYTE, s_texture_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

		/* Generate mipmaps with tested function. */
		gl.generateTextureMipmap(texture);

		glw::GLenum error = GL_NO_ERROR;

		if (GL_NO_ERROR != (error = gl.getError()))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "GenerateTextureMipmap unexpectedly generated error "
				<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;

			is_ok = false;
		}

		/* Continue only if mipmaps has been generated. */
		if (is_ok)
		{
			result = new glw::GLubyte[s_texture_width];

			if (DE_NULL == result)
			{
				throw 0;
			}

			/* For each mipmap. */
			for (glw::GLuint i = 0, j = s_texture_width;
				 i < s_texture_width_log - 1 /* Do not test single pixel mipmap. */; ++i, j /= 2)
			{
				/* Check mipmap size. */
				glw::GLint mipmap_size = 0;

				gl.getTexLevelParameteriv(GL_TEXTURE_1D, i, GL_TEXTURE_WIDTH, &mipmap_size);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

				if (mipmap_size != (glw::GLint)j)
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message
						<< "GenerateTextureMipmap unexpectedly generated mipmap with improper size. Mipmap size is "
						<< mipmap_size << ", but " << j << " was expected. Test fails." << tcu::TestLog::EndMessage;

					is_ok = false;

					break;
				}

				/* Fetch data. */
				gl.getTexImage(GL_TEXTURE_1D, i, GL_RED, GL_UNSIGNED_BYTE, result);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage has failed");

				/* Make comparison. */
				for (glw::GLuint k = 0; k < j - 1; ++k)
				{
					if (((glw::GLint)result[k + 1]) - ((glw::GLint)result[k]) < 0)
					{
						m_context.getTestContext().getLog() << tcu::TestLog::Message
															<< "GenerateTextureMipmap unexpectedly generated improper "
															   "mipmap (not descending). Test fails."
															<< tcu::TestLog::EndMessage;

						is_ok = false;

						break;
					}
				}
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture)
	{
		gl.deleteTextures(1, &texture);
	}

	if (DE_NULL != result)
	{
		delete[] result;
	}

	while (GL_NO_ERROR != gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Reference data. */
const glw::GLubyte GenerateMipmapTest::s_texture_data[] = {
	0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,
	22,  23,  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,
	44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,
	66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,
	88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99,  100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
	110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
	132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
	154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
	176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
	198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
	220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
	242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
};

/** Reference data parameters. */
const glw::GLuint GenerateMipmapTest::s_texture_width	 = 256;
const glw::GLuint GenerateMipmapTest::s_texture_width_log = 8;

/******************************** Bind Unit Test Implementation   ********************************/

/** @brief Bind Unit Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
BindUnitTest::BindUnitTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_bind_unit", "Textures Bind Unit Test")
	, m_po(0)
	, m_fbo(0)
	, m_rbo(0)
	, m_vao(0)
	, m_result(DE_NULL)
{
	m_to[0] = 0;
	m_to[1] = 0;
	m_to[2] = 0;
	m_to[3] = 0;
}

/** @brief Bind Unit Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult BindUnitTest::iterate()
{
	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		CreateProgram();
		CreateTextures();
		CreateFrambuffer();
		CreateVertexArray();
		is_ok &= Draw();
		is_ok &= Check();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	CleanAll();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Create test program.
 */
void BindUnitTest::CreateProgram()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	struct Shader
	{
		glw::GLchar const* source;
		glw::GLenum const  type;
		glw::GLuint		   id;
	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };

	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);

	try
	{
		/* Create program. */
		m_po = gl.createProgram();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");

		/* Shader compilation. */

		for (glw::GLuint i = 0; i < shader_count; ++i)
		{
			if (DE_NULL != shader[i].source)
			{
				shader[i].id = gl.createShader(shader[i].type);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");

				gl.attachShader(m_po, shader[i].id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");

				gl.shaderSource(shader[i].id, 1, &shader[i].source, NULL);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");

				gl.compileShader(shader[i].id);

				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");

				glw::GLint status = GL_FALSE;

				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

				if (GL_FALSE == status)
				{
					glw::GLint log_size = 0;
					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");

					glw::GLchar* log_text = new glw::GLchar[log_size];

					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);

					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
														<< "\n"
														<< "Shader compilation error log:\n"
														<< log_text << "\n"
														<< "Shader source code:\n"
														<< shader[i].source << "\n"
														<< tcu::TestLog::EndMessage;

					delete[] log_text;

					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");

					throw 0;
				}
			}
		}

		/* Link. */
		gl.linkProgram(m_po);

		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

		glw::GLint status = GL_FALSE;

		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);

		if (GL_TRUE == status)
		{
			for (glw::GLuint i = 0; i < shader_count; ++i)
			{
				if (shader[i].id)
				{
					gl.detachShader(m_po, shader[i].id);

					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
				}
			}
		}
		else
		{
			glw::GLint log_size = 0;

			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);

			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");

			glw::GLchar* log_text = new glw::GLchar[log_size];

			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);

			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
												<< log_text << "\n"
												<< tcu::TestLog::EndMessage;

			delete[] log_text;

			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");

			throw 0;
		}
	}
	catch (...)
	{
		if (m_po)
		{
			gl.deleteProgram(m_po);

			m_po = 0;
		}
	}

	for (glw::GLuint i = 0; i < shader_count; ++i)
	{
		if (0 != shader[i].id)
		{
			gl.deleteShader(shader[i].id);

			shader[i].id = 0;
		}
	}

	if (0 == m_po)
	{
		throw 0;
	}
}

/** @brief Create texture.
 */
void BindUnitTest::CreateTextures()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare texture. */
	gl.genTextures(4, m_to);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

	/* Setup pixel sotre modes.*/
	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(glw::GLubyte));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(glw::GLubyte));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	/* Red texture. */
	gl.bindTexture(GL_TEXTURE_2D, m_to[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
				  s_texture_data_r);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");

	/* Green texture. */
	gl.bindTexture(GL_TEXTURE_2D, m_to[1]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
				  s_texture_data_g);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");

	/* Blue texture. */
	gl.bindTexture(GL_TEXTURE_2D, m_to[2]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
				  s_texture_data_b);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");

	/* Alpha texture. */
	gl.bindTexture(GL_TEXTURE_2D, m_to[3]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE,
				  s_texture_data_a);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed.");
}

/** @brief Create framebuffer.
 */
void BindUnitTest::CreateFrambuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Prepare framebuffer. */
	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.genRenderbuffers(1, &m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed.");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, s_texture_width, s_texture_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed.");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		throw 0;
	}

	gl.viewport(0, 0, s_texture_width, s_texture_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");

	/* Clear framebuffer's content. */
	gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed.");

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

/** @brief Create vertex array object.
 */
void BindUnitTest::CreateVertexArray()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.genVertexArrays(1, &m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call has failed.");

	gl.bindVertexArray(m_vao);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call has failed.");
}

bool BindUnitTest::Draw()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Setup program. */
	gl.useProgram(m_po);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call has failed.");

	/* Bind textures to proper units and setup program's samplers. */
	for (glw::GLuint i = 0; i < 4; ++i)
	{
		/* Tested binding funcion. */
		gl.bindTextureUnit(i, m_to[i]);

		/* Check for errors. */
		glw::GLenum error = GL_NO_ERROR;

		if (GL_NO_ERROR != (error = gl.getError()))
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "BindTextureUnit unexpectedly generated error " << glu::getErrorStr(error)
				<< " when binding texture " << m_to[i] << " to texture unit " << i << ". Test fails."
				<< tcu::TestLog::EndMessage;

			return false;
		}

		/* Sampler setup. */
		gl.uniform1i(gl.getUniformLocation(m_po, s_fragment_shader_samplers[i]), i);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation or glUniform1i call has failed.");
	}

	/* Draw call. */
	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call has failed.");

	return true;
}

/** @brief Compare results with reference.
 *
 *  @return True if equal, false otherwise.
 */
bool BindUnitTest::Check()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Setup storage for results. */
	m_result = new glw::GLubyte[s_texture_count_rgba];

	/* Setup pixel sotre modes.*/
	gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(glw::GLubyte));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(glw::GLubyte));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed");

	/* Query framebuffer's image. */
	gl.readPixels(0, 0, s_texture_width, s_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, m_result);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call has failed.");

	/* Compare values with reference. */
	for (glw::GLuint i = 0; i < s_texture_count_rgba; ++i)
	{
		if (s_texture_data_rgba[i] != m_result[i])
		{
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "Framebuffer data " << DataToString(s_texture_count_rgba, m_result)
				<< " does not match the reference values " << DataToString(s_texture_count_rgba, s_texture_data_rgba)
				<< "." << tcu::TestLog::EndMessage;

			return false;
		}
	}

	return true;
}

/** @brief Clean GL objects, test variables and GL errors.
 */
void BindUnitTest::CleanAll()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Release GL objects. */
	if (m_po)
	{
		gl.useProgram(0);

		gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_to[0] || m_to[1] || m_to[2] || m_to[3])
	{
		gl.deleteTextures(4, m_to);

		m_to[0] = 0;
		m_to[1] = 0;
		m_to[2] = 0;
		m_to[3] = 0;
	}

	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (m_rbo)
	{
		gl.deleteRenderbuffers(1, &m_rbo);

		m_rbo = 0;
	}

	/* Release heap. */
	if (DE_NULL != m_result)
	{
		delete[] m_result;
	}

	/* Erros clean-up. */
	while (GL_NO_ERROR != gl.getError())
		;
}

/** @brief Convert raw data into string for logging purposes.
 *
 *  @param [in] count      Count of the data.
 *  @param [in] data       Raw data.
 *
 *  @return String representation of data.
 */
std::string BindUnitTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
{
	std::string data_str = "[";

	for (glw::GLuint i = 0; i < count; ++i)
	{
		std::stringstream int_sstream;

		int_sstream << unsigned(data[i]);

		data_str.append(int_sstream.str());

		if (i + 1 < count)
		{
			data_str.append(", ");
		}
		else
		{
			data_str.append("]");
		}
	}

	return data_str;
}

/** Reference data and parameters. */
const glw::GLubyte BindUnitTest::s_texture_data_r[]	= { 0, 4, 8, 12, 16, 20 };
const glw::GLubyte BindUnitTest::s_texture_data_g[]	= { 1, 5, 9, 13, 17, 21 };
const glw::GLubyte BindUnitTest::s_texture_data_b[]	= { 2, 6, 10, 14, 18, 22 };
const glw::GLubyte BindUnitTest::s_texture_data_a[]	= { 3, 7, 11, 15, 19, 23 };
const glw::GLubyte BindUnitTest::s_texture_data_rgba[] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11,
														   12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
const glw::GLuint BindUnitTest::s_texture_width		 = 2;
const glw::GLuint BindUnitTest::s_texture_height	 = 3;
const glw::GLuint BindUnitTest::s_texture_count_rgba = sizeof(s_texture_data_rgba) / sizeof(s_texture_data_rgba[0]);

/* Vertex shader source code. */
const glw::GLchar* BindUnitTest::s_vertex_shader = "#version 450\n"
												   "\n"
												   "void main()\n"
												   "{\n"
												   "    switch(gl_VertexID)\n"
												   "    {\n"
												   "        case 0:\n"
												   "            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
												   "            break;\n"
												   "        case 1:\n"
												   "            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
												   "            break;\n"
												   "        case 2:\n"
												   "            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
												   "            break;\n"
												   "        case 3:\n"
												   "            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
												   "            break;\n"
												   "    }\n"
												   "}\n";

/* Fragment shader source program. */
const glw::GLchar* BindUnitTest::s_fragment_shader =
	"#version 450\n"
	"\n"
	"layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
	"\n"
	"uniform sampler2D texture_input_r;\n"
	"uniform sampler2D texture_input_g;\n"
	"uniform sampler2D texture_input_b;\n"
	"uniform sampler2D texture_input_a;\n"
	"\n"
	"out     vec4      color_output;\n"
	"\n"
	"void main()\n"
	"{\n"
	"    color_output = vec4(texelFetch(texture_input_r, ivec2(gl_FragCoord.xy), 0).r,\n"
	"                        texelFetch(texture_input_g, ivec2(gl_FragCoord.xy), 0).r,\n"
	"                        texelFetch(texture_input_b, ivec2(gl_FragCoord.xy), 0).r,\n"
	"                        texelFetch(texture_input_a, ivec2(gl_FragCoord.xy), 0).r);\n"
	"}\n";

const glw::GLchar* BindUnitTest::s_fragment_shader_samplers[4] = { "texture_input_r", "texture_input_g",
																   "texture_input_b", "texture_input_a" };

/******************************** Get Image Test Implementation   ********************************/

/** @brief Get Image Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetImageTest::GetImageTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_get_image", "Textures Get Image Test")
{
	/* Intentionally left blank */
}

/** Reference data. */
const glw::GLubyte GetImageTest::s_texture_data[] = { 0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3,
													  0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0x0,  0x15, 0xff, 0xed, 0x1c,
													  0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff, 0xc8,
													  0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff,
													  0xb5, 0xe6, 0x1d, 0xff, 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc,
													  0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff };

/** Reference data (compressed). */
const glw::GLubyte GetImageTest::s_texture_data_compressed[] = { 0x90, 0x2b, 0x8f, 0x0f, 0xfe, 0x0f, 0x98, 0x99,
																 0x99, 0x99, 0x59, 0x8f, 0x8c, 0xa6, 0xb7, 0x71 };

/** Reference data parameters. */
const glw::GLuint GetImageTest::s_texture_width			  = 4;
const glw::GLuint GetImageTest::s_texture_height		  = 4;
const glw::GLuint GetImageTest::s_texture_size			  = sizeof(s_texture_data);
const glw::GLuint GetImageTest::s_texture_size_compressed = sizeof(s_texture_data_compressed);
const glw::GLuint GetImageTest::s_texture_count			  = s_texture_size / sizeof(s_texture_data[0]);
const glw::GLuint GetImageTest::s_texture_count_compressed =
	s_texture_size_compressed / sizeof(s_texture_data_compressed[0]);

/** @brief Get Image Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetImageTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Objects. */
	glw::GLuint  texture									   = 0;
	glw::GLubyte result[s_texture_count]					   = {};
	glw::GLubyte result_compressed[s_texture_count_compressed] = {};

	try
	{
		/* Uncompressed case. */
		{
			/* Texture initiation. */
			gl.genTextures(1, &texture);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

			gl.bindTexture(GL_TEXTURE_2D, texture);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
						  s_texture_data);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

			/* Quering image with tested function. */
			gl.getTextureImage(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, sizeof(result), result);

			/* Check for errors. */
			glw::GLenum error = GL_NO_ERROR;

			if (GL_NO_ERROR != (error = gl.getError()))
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "GetTextureImage unexpectedly generated error "
					<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;

				is_ok = false;
			}
			else
			{
				/* No error, so compare images. */
				for (glw::GLuint i = 0; i < s_texture_count; ++i)
				{
					if (s_texture_data[i] != result[i])
					{
						m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetTextureImage returned "
															<< DataToString(s_texture_count, result) << ", but "
															<< DataToString(s_texture_count, s_texture_data)
															<< " was expected. Test fails." << tcu::TestLog::EndMessage;

						is_ok = false;

						break;
					}
				}
			}
		}

		/* Clean up texture .*/
		gl.deleteTextures(1, &texture);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		texture = 0;

		/* Compressed case. */
		{
			/* Texture initiation. */
			gl.genTextures(1, &texture);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

			gl.bindTexture(GL_TEXTURE_2D, texture);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

			gl.compressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM, s_texture_width, s_texture_height,
									0, s_texture_size_compressed, s_texture_data_compressed);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed");

			/* Quering image with tested function. */
			gl.getCompressedTextureImage(texture, 0, s_texture_count_compressed * sizeof(result_compressed[0]),
										 result_compressed);

			/* Check for errors. */
			glw::GLenum error = GL_NO_ERROR;

			if (GL_NO_ERROR != (error = gl.getError()))
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "GetCompressedTextureImage unexpectedly generated error "
					<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;

				is_ok = false;
			}
			else
			{
				/* No error, so compare images. */
				for (glw::GLuint i = 0; i < s_texture_count_compressed; ++i)
				{
					if (s_texture_data_compressed[i] != result_compressed[i])
					{
						m_context.getTestContext().getLog()
							<< tcu::TestLog::Message << "GetCompressedTextureImage returned "
							<< DataToString(s_texture_count_compressed, result_compressed) << ", but "
							<< DataToString(s_texture_count_compressed, s_texture_data_compressed)
							<< " was expected. Test fails." << tcu::TestLog::EndMessage;

						is_ok = false;

						break;
					}
				}
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture)
	{
		gl.deleteTextures(1, &texture);
	}

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Convert raw data into string for logging purposes.
 *
 *  @param [in] count      Count of the data.
 *  @param [in] data       Raw data.
 *
 *  @return String representation of data.
 */
std::string GetImageTest::DataToString(glw::GLuint count, const glw::GLubyte data[])
{
	std::string data_str = "[";

	for (glw::GLuint i = 0; i < count; ++i)
	{
		std::stringstream int_sstream;

		int_sstream << unsigned(data[i]);

		data_str.append(int_sstream.str());

		if (i + 1 < count)
		{
			data_str.append(", ");
		}
		else
		{
			data_str.append("]");
		}
	}

	return data_str;
}

/******************************** Get Level Parameter Test Implementation   ********************************/

/** @brief Get Level Parameter Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GetLevelParameterTest::GetLevelParameterTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_get_level_parameter", "Textures Get Level Parameter Test")
{
	/* Intentionally left blank */
}

/** Reference data. */
const glw::GLubyte GetLevelParameterTest::s_texture_data[] = {
	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,

	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,

	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,

	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff
};

/** Reference data parameters. */
const glw::GLuint GetLevelParameterTest::s_texture_width  = 4;
const glw::GLuint GetLevelParameterTest::s_texture_height = 4;
const glw::GLuint GetLevelParameterTest::s_texture_depth  = 4;

/** @brief Get Level Parameter Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GetLevelParameterTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Objects. */
	glw::GLuint texture = 0;

	try
	{
		/* Texture initiation. */
		gl.genTextures(1, &texture);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_3D, texture);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA,
					  GL_UNSIGNED_BYTE, s_texture_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

		gl.texImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, s_texture_width / 2, s_texture_height / 2, s_texture_depth / 2, 0,
					  GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

		static const glw::GLenum pnames[] = {
			GL_TEXTURE_WIDTH,	  GL_TEXTURE_HEIGHT,	 GL_TEXTURE_DEPTH,		 GL_TEXTURE_INTERNAL_FORMAT,
			GL_TEXTURE_RED_TYPE,   GL_TEXTURE_GREEN_TYPE, GL_TEXTURE_BLUE_TYPE,  GL_TEXTURE_ALPHA_TYPE,
			GL_TEXTURE_DEPTH_TYPE, GL_TEXTURE_RED_SIZE,   GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE,
			GL_TEXTURE_ALPHA_SIZE, GL_TEXTURE_DEPTH_SIZE, GL_TEXTURE_COMPRESSED
		};
		static const glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]);

		/* Test GetTextureLevelParameteriv. */
		for (glw::GLuint i = 0; i < 2 /* levels */; ++i)
		{
			for (glw::GLuint j = 0; j < pnames_count; ++j)
			{
				glw::GLint result_legacy = 0;
				glw::GLint result_dsa	= 0;

				/* Quering reference value. */
				gl.getTexLevelParameteriv(GL_TEXTURE_3D, i, pnames[j], &result_legacy);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

				/* Quering using DSA function. */
				gl.getTextureLevelParameteriv(texture, i, pnames[j], &result_dsa);

				/* Check for errors. */
				glw::GLenum error = GL_NO_ERROR;

				if (GL_NO_ERROR != (error = gl.getError()))
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetTextureLevelParameteriv unexpectedly generated error "
						<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;

					is_ok = false;
				}
				else
				{
					/* Compare values. */
					if (result_legacy != result_dsa)
					{
						m_context.getTestContext().getLog()
							<< tcu::TestLog::Message << "For parameter name "
							<< glu::getTextureLevelParameterStr(pnames[j]) << " GetTextureLevelParameteriv returned "
							<< result_dsa << ", but reference value (queried using GetTexLevelParameteriv) was "
							<< result_legacy << ". Test fails." << tcu::TestLog::EndMessage;

						is_ok = false;
					}
				}
			}
		}

		/* Test GetTextureLevelParameterfv. */
		for (glw::GLuint i = 0; i < 2 /* levels */; ++i)
		{
			for (glw::GLuint j = 0; j < pnames_count; ++j)
			{
				glw::GLfloat result_legacy = 0.f;
				glw::GLfloat result_dsa	= 0.f;

				/* Quering reference value. */
				gl.getTexLevelParameterfv(GL_TEXTURE_3D, i, pnames[j], &result_legacy);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameterfv has failed");

				/* Quering using DSA function. */
				gl.getTextureLevelParameterfv(texture, i, pnames[j], &result_dsa);

				/* Check for errors. */
				glw::GLenum error = GL_NO_ERROR;

				if (GL_NO_ERROR != (error = gl.getError()))
				{
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message << "GetTextureLevelParameterfv unexpectedly generated error "
						<< glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage;

					is_ok = false;
				}
				else
				{
					/* Compare values. */
					if (de::abs(result_legacy - result_dsa) > 0.125 /* Precision. */)
					{
						m_context.getTestContext().getLog()
							<< tcu::TestLog::Message << "For parameter name "
							<< glu::getTextureLevelParameterStr(pnames[j]) << " GetTextureLevelParameterfv returned "
							<< result_dsa << ", but reference value (queried using GetTexLevelParameterfv) was "
							<< result_legacy << ". Test fails." << tcu::TestLog::EndMessage;

						is_ok = false;
					}
				}
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture)
	{
		gl.deleteTextures(1, &texture);
	}

	while (GL_NO_ERROR != gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/*********************************** Errors Utility Class *****************************************************/

/** @brief Check for errors and log.
 *
 *  @param [in] context             Test's context.
 *  @param [in] expected_error      Expected error value.
 *  @param [in] function_name       Name of the function (to be logged).
 *  @param [in] log                 Log message.
 *
 *  @return True if error is equal to expected, false otherwise.
 */
bool ErrorsUtilities::CheckErrorAndLog(deqp::Context& context, glw::GLuint expected_error,
									   const glw::GLchar* function_name, const glw::GLchar* log)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = context.getRenderContext().getFunctions();

	/* Check error. */
	glw::GLenum error = GL_NO_ERROR;

	if (expected_error != (error = gl.getError()))
	{
		context.getTestContext().getLog() << tcu::TestLog::Message << function_name << " generated error "
										  << glu::getErrorStr(error) << " but, " << glu::getErrorStr(expected_error)
										  << " was expected if " << log << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/******************************** Creation Errors Test Implementation   ********************************/

/** @brief Creation Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationErrorsTest::CreationErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_creation_errors", "Texture Objects Creation Errors Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Creation Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CreationErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Textures' objects */
	glw::GLuint texture = 0;

	try
	{
		/* Not a target test. */
		gl.createTextures(NotATarget(), 1, &texture);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCreateTextures",
								  "target is not one of the allowable values.");

		if (texture)
		{
			gl.deleteTextures(1, &texture);

			texture = 0;
		}

		/* Negative number of textures. */
		gl.createTextures(GL_TEXTURE_2D, -1, &texture);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCreateTextures", "n is negative.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture)
	{
		gl.deleteTextures(1, &texture);
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Function retruns enum which is not a texture target.
 */
glw::GLenum CreationErrorsTest::NotATarget()
{
	static const glw::GLenum texture_targets[] = { GL_TEXTURE_1D,
												   GL_TEXTURE_2D,
												   GL_TEXTURE_3D,
												   GL_TEXTURE_1D_ARRAY,
												   GL_TEXTURE_2D_ARRAY,
												   GL_TEXTURE_RECTANGLE,
												   GL_TEXTURE_CUBE_MAP,
												   GL_TEXTURE_CUBE_MAP_ARRAY,
												   GL_TEXTURE_BUFFER,
												   GL_TEXTURE_2D_MULTISAMPLE,
												   GL_TEXTURE_2D_MULTISAMPLE_ARRAY };

	glw::GLenum not_a_target = 0;
	bool		is_target	= true;

	while (is_target)
	{
		not_a_target++;

		is_target = false;

		for (glw::GLuint i = 0; i < sizeof(texture_targets) / sizeof(texture_targets[0]); ++i)
		{
			if (texture_targets[i] == not_a_target)
			{
				is_target = true;
				break;
			}
		}
	}

	return not_a_target;
}

/******************************** Texture Buffer Errors Test Implementation   ********************************/

/** @brief Texture Buffer Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
BufferErrorsTest::BufferErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_buffer_errors", "Texture Buffer Errors Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Texture Buffer Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult BufferErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Textures' objects */
	glw::GLuint texture_buffer = 0;
	glw::GLuint texture_1D	 = 0;
	glw::GLuint buffer		   = 0;

	static const glw::GLubyte data[4]   = { 1, 2, 3, 4 };
	static const glw::GLuint  data_size = sizeof(data);

	try
	{
		/* Auxiliary objects setup. */
		gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

		gl.createTextures(GL_TEXTURE_1D, 1, &texture_1D);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");

		gl.namedBufferData(buffer, data_size, data, GL_STATIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");

		/*  Check that INVALID_OPERATION is generated by glTextureBuffer if texture
		 is not the name of an existing texture object. */
		{
			glw::GLuint not_a_texture = 0;

			while (gl.isTexture(++not_a_texture))
				;
			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");

			gl.textureBuffer(not_a_texture, GL_RGBA8, buffer);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBuffer",
									  "texture is not the name of an existing texture object.");
		}

		/*  Check that INVALID_ENUM is generated by glTextureBuffer if the effective
		 target of texture is not TEXTURE_BUFFER. */
		{
			gl.textureBuffer(texture_1D, GL_RGBA8, buffer);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBuffer",
									  "the effective target of texture is not TEXTURE_BUFFER.");
		}

		/*  Check that INVALID_ENUM is generated if internalformat is not one of the
		 sized internal formats described above. */
		{
			gl.textureBuffer(texture_buffer, GL_COMPRESSED_SIGNED_RED_RGTC1, buffer);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBuffer",
									  "internalformat is not one of the sized internal formats described above..");
		}

		/*  Check that INVALID_OPERATION is generated if buffer is not zero and is
		 not the name of an existing buffer object. */
		{
			glw::GLuint not_a_buffer = 0;

			while (gl.isBuffer(++not_a_buffer))
				;
			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsBuffer has failed");

			gl.textureBuffer(texture_buffer, GL_RGBA8, not_a_buffer);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBuffer",
									  "buffer is not zero and is not the name of an existing buffer object.");
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture_1D)
	{
		gl.deleteTextures(1, &texture_1D);
	}

	if (texture_buffer)
	{
		gl.deleteTextures(1, &texture_buffer);
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Texture Buffer Range Errors Test Implementation   ********************************/

/** @brief Texture Buffer Range Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
BufferRangeErrorsTest::BufferRangeErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_buffer_range_errors", "Texture Buffer Range Errors Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Texture Buffer Range Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult BufferRangeErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Textures' objects */
	glw::GLuint texture_buffer = 0;
	glw::GLuint texture_1D	 = 0;
	glw::GLuint buffer		   = 0;

	static const glw::GLubyte data[4]   = { 1, 2, 3, 4 };
	static const glw::GLuint  data_size = sizeof(data);

	try
	{
		/* Auxiliary objects setup. */
		gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

		gl.createTextures(GL_TEXTURE_1D, 1, &texture_1D);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");

		gl.namedBufferData(buffer, data_size, data, GL_STATIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");

		/*  Check that INVALID_OPERATION is generated by TextureBufferRange if
		 texture is not the name of an existing texture object.*/
		{
			glw::GLuint not_a_texture = 0;

			while (gl.isTexture(++not_a_texture))
				;
			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");

			gl.textureBufferRange(not_a_texture, GL_RGBA8, buffer, 0, data_size);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBufferRange",
									  "texture is not the name of an existing texture object.");
		}

		/*  Check that INVALID_ENUM is generated by TextureBufferRange if the
		 effective target of texture is not TEXTURE_BUFFER. */
		{
			gl.textureBufferRange(texture_1D, GL_RGBA8, buffer, 0, data_size);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBufferRange",
									  "the effective target of texture is not TEXTURE_BUFFER.");
		}

		/*  Check that INVALID_ENUM is generated by TextureBufferRange if
		 internalformat is not one of the sized internal formats described above. */
		{
			gl.textureBufferRange(texture_buffer, GL_COMPRESSED_SIGNED_RED_RGTC1, buffer, 0, data_size);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBufferRange",
									  "internalformat is not one of the supported sized internal formats.");
		}

		/*  Check that INVALID_OPERATION is generated by TextureBufferRange if
		 buffer is not zero and is not the name of an existing buffer object. */
		{
			glw::GLuint not_a_buffer = 0;

			while (gl.isBuffer(++not_a_buffer))
				;
			GLU_EXPECT_NO_ERROR(gl.getError(), "glIsBuffer has failed");

			gl.textureBufferRange(texture_buffer, GL_RGBA8, not_a_buffer, 0, data_size);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBufferRange",
									  "buffer is not zero and is not the name of an existing buffer object.");
		}

		/* Check that INVALID_VALUE is generated by TextureBufferRange if offset
		 is negative, if size is less than or equal to zero, or if offset + size
		 is greater than the value of BUFFER_SIZE for buffer. */
		{
			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, -1, data_size);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "offset is negative.");

			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, 0);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "size is zero.");

			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, -1);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "size is negative.");

			gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, data_size * 16);

			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange",
									  "size is greater than the value of BUFFER_SIZE for buffer.");
		}

		/* Check that INVALID_VALUE is generated by TextureBufferRange if offset is
		 not an integer multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT. */
		{
			glw::GLint gl_texture_buffer_offset_alignment = 0;

			gl.getIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_texture_buffer_offset_alignment);

			/* If alignmet is 1 we cannot do anything. Error situtation is impossible then. */
			if (gl_texture_buffer_offset_alignment > 1)
			{
				gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 1, data_size - 1);

				is_ok &= CheckErrorAndLog(
					m_context, GL_INVALID_VALUE, "glTextureBufferRange",
					"offset is not an integer multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT.");
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture_1D)
	{
		gl.deleteTextures(1, &texture_1D);
	}

	if (texture_buffer)
	{
		gl.deleteTextures(1, &texture_buffer);
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);
	}

	/* Errors clean up. */
	while (gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Texture Storage Errors Test Implementation   ********************************/

/** @brief Texture Storage Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
StorageErrorsTest::StorageErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_storage_errors", "Texture Storage Errors Test")
	, m_to_1D(0)
	, m_to_1D_array(0)
	, m_to_2D(0)
	, m_to_2D_array(0)
	, m_to_3D(0)
	, m_to_2D_ms(0)
	, m_to_2D_ms_immutable(0)
	, m_to_3D_ms(0)
	, m_to_3D_ms_immutable(0)
	, m_to_invalid(0)
	, m_internalformat_invalid(0)
	, m_max_texture_size(1)
	, m_max_samples(1)
	, m_max_array_texture_layers(1)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Texture Storage Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult StorageErrorsTest::iterate()
{
	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		Prepare();

		is_ok &= Test1D();
		is_ok &= Test2D();
		is_ok &= Test3D();
		is_ok &= Test2DMultisample();
		is_ok &= Test3DMultisample();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Prepare test objects.
 */
void StorageErrorsTest::Prepare()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Auxiliary objects setup. */

	/* 1D */
	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 1D ARRAY */
	gl.createTextures(GL_TEXTURE_1D_ARRAY, 1, &m_to_1D_array);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 2D */
	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 2D ARRAY */
	gl.createTextures(GL_TEXTURE_2D_ARRAY, 1, &m_to_2D_array);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 3D */
	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 2D Multisample */
	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 2D Multisample with storage */
	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms_immutable);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.textureStorage2DMultisample(m_to_2D_ms_immutable, 1, GL_R8, 16, 16, false);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");

	/* 3D Multisample */
	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &m_to_3D_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 3D Multisample with storage */
	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &m_to_3D_ms_immutable);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.textureStorage3DMultisample(m_to_3D_ms_immutable, 1, GL_R8, 16, 16, 16, false);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");

	/* Invalid values */

	/* invalid texture object */
	while (gl.isTexture(++m_to_invalid))
		;
	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");

	/* invalid internal format */
	static const glw::GLenum all_internal_formats[] = { GL_R8,
														GL_R8_SNORM,
														GL_R16,
														GL_R16_SNORM,
														GL_RG8,
														GL_RG8_SNORM,
														GL_RG16,
														GL_RG16_SNORM,
														GL_R3_G3_B2,
														GL_RGB4,
														GL_RGB5,
														GL_RGB565,
														GL_RGB8,
														GL_RGB8_SNORM,
														GL_RGB10,
														GL_RGB12,
														GL_RGB16,
														GL_RGB16_SNORM,
														GL_RGBA2,
														GL_RGBA4,
														GL_RGB5_A1,
														GL_RGBA8,
														GL_RGBA8_SNORM,
														GL_RGB10_A2,
														GL_RGB10_A2UI,
														GL_RGBA12,
														GL_RGBA16,
														GL_RGBA16_SNORM,
														GL_SRGB8,
														GL_SRGB8_ALPHA8,
														GL_R16F,
														GL_RG16F,
														GL_RGB16F,
														GL_RGBA16F,
														GL_R32F,
														GL_RG32F,
														GL_RGB32F,
														GL_RGBA32F,
														GL_R11F_G11F_B10F,
														GL_RGB9_E5,
														GL_R8I,
														GL_R8UI,
														GL_R16I,
														GL_R16UI,
														GL_R32I,
														GL_R32UI,
														GL_RG8I,
														GL_RG8UI,
														GL_RG16I,
														GL_RG16UI,
														GL_RG32I,
														GL_RG32UI,
														GL_RGB8I,
														GL_RGB8UI,
														GL_RGB16I,
														GL_RGB16UI,
														GL_RGB32I,
														GL_RGB32UI,
														GL_RGBA8I,
														GL_RGBA8UI,
														GL_RGBA16I,
														GL_RGBA16UI,
														GL_RGBA32I,
														GL_RGBA32UI,
														GL_COMPRESSED_RED,
														GL_COMPRESSED_RG,
														GL_COMPRESSED_RGB,
														GL_COMPRESSED_RGBA,
														GL_COMPRESSED_SRGB,
														GL_COMPRESSED_SRGB_ALPHA,
														GL_COMPRESSED_RED_RGTC1,
														GL_COMPRESSED_SIGNED_RED_RGTC1,
														GL_COMPRESSED_RG_RGTC2,
														GL_COMPRESSED_SIGNED_RG_RGTC2,
														GL_COMPRESSED_RGBA_BPTC_UNORM,
														GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
														GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT,
														GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
														GL_COMPRESSED_RGB8_ETC2,
														GL_COMPRESSED_SRGB8_ETC2,
														GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
														GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
														GL_COMPRESSED_RGBA8_ETC2_EAC,
														GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
														GL_COMPRESSED_R11_EAC,
														GL_COMPRESSED_SIGNED_R11_EAC,
														GL_COMPRESSED_RG11_EAC,
														GL_COMPRESSED_SIGNED_RG11_EAC,
														GL_DEPTH_COMPONENT16,
														GL_DEPTH_COMPONENT24,
														GL_DEPTH_COMPONENT32,
														GL_DEPTH_COMPONENT32F,
														GL_DEPTH24_STENCIL8,
														GL_DEPTH32F_STENCIL8,
														GL_STENCIL_INDEX1,
														GL_STENCIL_INDEX4,
														GL_STENCIL_INDEX8,
														GL_STENCIL_INDEX16 };

	static const glw::GLuint all_internal_formats_count =
		sizeof(all_internal_formats) / sizeof(all_internal_formats[0]);

	bool is_valid			 = true;
	m_internalformat_invalid = 0;

	while (is_valid)
	{
		is_valid = false;
		m_internalformat_invalid++;
		for (glw::GLuint i = 0; i < all_internal_formats_count; ++i)
		{
			if (all_internal_formats[i] == m_internalformat_invalid)
			{
				is_valid = true;
				break;
			}
		}
	}

	/* Maximum texture size.*/
	gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	/* Maximum number of samples. */
	gl.getInternalformativ(GL_RENDERBUFFER, GL_R8, GL_SAMPLES, 1, &m_max_samples);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ has failed");

	/* Maximum number of array texture layers. */
	gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &m_max_array_texture_layers);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
}

/** @brief Test TextureStorage1D
 *
 *  @return Test result.
 */
bool StorageErrorsTest::Test1D()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/*  Check that INVALID_OPERATION is generated by TextureStorage1D if texture
	 is not the name of an existing texture object. */
	{
		gl.textureStorage1D(m_to_invalid, 1, GL_R8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D",
								  "texture is not the name of an existing texture object.");
	}

	/*  Check that INVALID_ENUM is generated by TextureStorage1D if
	 internalformat is not a valid sized internal format. */
	{
		gl.textureStorage1D(m_to_1D, 1, m_internalformat_invalid, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage1D",
								  "internalformat is not a valid sized internal format.");
	}

	/*  Check that INVALID_ENUM is generated by TextureStorage1D if target or
	 the effective target of texture is not one of the accepted targets
	 described above. */
	{
		gl.textureStorage1D(m_to_2D, 1, GL_R8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D",
								  "the effective target of texture is not one of the accepted targets.");
	}

	/*  Check that INVALID_VALUE is generated by TextureStorage1D if width or
	 levels are less than 1. */
	{
		gl.textureStorage1D(m_to_1D, 0, GL_R8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage1D", "levels is less than 1.");

		gl.textureStorage1D(m_to_1D, 1, GL_R8, 0);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage1D", "width is less than 1.");
	}

	/*  Check that INVALID_OPERATION is generated by TextureStorage1D if levels
	 is greater than log2(width)+1. */
	{
		gl.textureStorage1D(m_to_1D, 8, GL_R8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D",
								  "levels is greater than log2(width)+1.");
	}

	return is_ok;
}

/** @brief Test TextureStorage2D
 *
 *  @return Test result.
 */
bool StorageErrorsTest::Test2D()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/*  Check that INVALID_OPERATION is generated by TextureStorage2D if
	 texture is not the name of an existing texture object. */
	{
		gl.textureStorage2D(m_to_invalid, 1, GL_R8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
								  "texture is not the name of an existing texture object.");
	}

	/*  Check that INVALID_ENUM is generated by TextureStorage2D if
	 internalformat is not a valid sized internal format. */
	{
		gl.textureStorage2D(m_to_2D, 1, m_internalformat_invalid, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage2D",
								  "internalformat is not a valid sized internal format.");
	}

	/*  Check that INVALID_ENUM is generated by TextureStorage2D if target or
	 the effective target of texture is not one of the accepted targets
	 described above. */
	{
		gl.textureStorage2D(m_to_1D, 1, GL_R8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
								  "the effective target of texture is not one of the accepted targets.");
	}

	/*  Check that INVALID_VALUE is generated by TextureStorage2D if width,
	 height or levels are less than 1. */
	{
		gl.textureStorage2D(m_to_2D, 0, GL_R8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "levels is less than 1.");

		gl.textureStorage2D(m_to_2D, 1, GL_R8, 0, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "width is less than 1.");

		gl.textureStorage2D(m_to_2D, 1, GL_R8, 8, 0);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "height is less than 1.");
	}

	/* Check that INVALID_OPERATION is generated by TextureStorage2D if target
	 is TEXTURE_1D_ARRAY or PROXY_TEXTURE_1D_ARRAY and levels is greater than
	 log2(width)+1. */
	{
		gl.textureStorage2D(m_to_1D_array, 8, GL_R8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
								  "target is TEXTURE_1D_ARRAY and levels is greater than log2(width)+1.");
	}

	/*  Check that INVALID_OPERATION is generated by TextureStorage2D if target
	 is not TEXTURE_1D_ARRAY or PROXY_TEXTURE_1D_ARRAY and levels is greater
	 than log2(max(width, height))+1.  */
	{
		gl.textureStorage2D(m_to_2D, 8, GL_R8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D",
								  "target is TEXTURE_2D and levels is greater than log2(max(width, height))+1.");
	}

	return is_ok;
}

/** @brief Test TextureStorage3D
 *
 *  @return Test result.
 */
bool StorageErrorsTest::Test3D()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/*  Check that INVALID_OPERATION is generated by TextureStorage3D if texture
	 is not the name of an existing texture object. */
	{
		gl.textureStorage3D(m_to_invalid, 1, GL_R8, 8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
								  "texture is not the name of an existing texture object.");
	}

	/*  Check that INVALID_ENUM is generated by TextureStorage3D if
	 internalformat is not a valid sized internal format. */
	{
		gl.textureStorage3D(m_to_3D, 1, m_internalformat_invalid, 8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage3D",
								  "internalformat is not a valid sized internal format.");
	}

	/*  Check that INVALID_ENUM is generated by TextureStorage3D if target or
	 the effective target of texture is not one of the accepted targets
	 described above. */
	{
		gl.textureStorage3D(m_to_1D, 1, GL_R8, 8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
								  "the effective target of texture is not one of the accepted targets.");
	}

	/*  Check that INVALID_VALUE is generated by TextureStorage3D if width,
	 height, depth or levels are less than 1. */
	{
		gl.textureStorage3D(m_to_3D, 0, GL_R8, 8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "levels is less than 1.");

		gl.textureStorage3D(m_to_3D, 1, GL_R8, 0, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "width is less than 1.");

		gl.textureStorage3D(m_to_3D, 1, GL_R8, 8, 0, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "height is less than 1.");

		gl.textureStorage3D(m_to_3D, 1, GL_R8, 8, 8, 0);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "depth is less than 1.");
	}

	/* Check that INVALID_OPERATION is generated by TextureStorage3D if target
	 is TEXTURE_3D or PROXY_TEXTURE_3D and levels is greater than
	 log2(max(width, height, depth))+1. */
	{
		gl.textureStorage3D(m_to_3D, 8, GL_R8, 8, 8, 8);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
								  "target is TEXTURE_3D and levels is greater than log2(max(width, height, depth))+1.");
	}

	/*  Check that INVALID_OPERATION is generated by TextureStorage3D if target
	 is TEXTURE_2D_ARRAY, PROXY_TEXTURE_2D_ARRAY, TEXURE_CUBE_ARRAY,
	 or PROXY_TEXTURE_CUBE_MAP_ARRAY and levels is greater than
	 log2(max(width, height))+1.  */
	{
		gl.textureStorage3D(m_to_2D_array, 6, GL_R8, 8, 8, 256);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D",
								  "target is TEXTURE_2D_ARRAY and levels is greater than log2(max(width, height))+1.");
	}

	return is_ok;
}

/** @brief Test TextureStorage2DMultisample
 *
 *  @return Test result.
 */
bool StorageErrorsTest::Test2DMultisample()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/*  Check that INVALID_OPERATION is generated by TextureStorage2DMultisample
	 if texture is not the name of an existing texture object. */
	{
		gl.textureStorage2DMultisample(m_to_invalid, 1, GL_R8, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
								  "texture is not the name of an existing texture object.");
	}

	/*  Check that INVALID_ENUM is generated by TextureStorage2DMultisample if
	 internalformat is not a valid color-renderable, depth-renderable or
	 stencil-renderable format. */
	{
		gl.textureStorage2DMultisample(m_to_2D_ms, 1, m_internalformat_invalid, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage2DMultisample",
								  "internalformat is not a valid sized internal format.");
	}

	/*  Check that INVALID_OPERATION is generated by TextureStorage2DMultisample if
	 target or the effective target of texture is not one of the accepted
	 targets described above. */
	{
		gl.textureStorage2DMultisample(m_to_1D, 1, GL_R8, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
								  "the effective target of texture is not one of the accepted targets.");
	}

	/* Check that INVALID_VALUE is generated by TextureStorage2DMultisample if
	 width or height are less than 1 or greater than the value of
	 MAX_TEXTURE_SIZE. */
	{
		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 0, 8, false);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", "width is less than 1.");

		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 8, 0, false);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", "height is less than 1.");

		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, m_max_texture_size * 2, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample",
								  "width is greater than the value of MAX_TEXTURE_SIZE.");

		gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 8, m_max_texture_size * 2, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample",
								  "height is greater than the value of MAX_TEXTURE_SIZE.");
	}

	/* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample if
	 samples is greater than the value of MAX_SAMPLES. */
	{
		gl.textureStorage2DMultisample(m_to_2D_ms, m_max_samples * 2, GL_R8, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
								  "samples is greater than the value of MAX_SAMPLES.");
	}

	/* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample
	 if the value of TEXTURE_IMMUTABLE_FORMAT for the texture bound to target
	 is not FALSE. */
	{
		gl.textureStorage2DMultisample(m_to_2D_ms_immutable, 1, GL_R8, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample",
								  "samples is greater than the value of MAX_SAMPLES.");
	}

	return is_ok;
}

/** @brief Test TextureStorage3DMultisample
 *
 *  @return Test result.
 */
bool StorageErrorsTest::Test3DMultisample()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/*  Check that INVALID_OPERATION is generated by TextureStorage3DMultisample
	 if texture is not the name of an existing texture object. */
	{
		gl.textureStorage3DMultisample(m_to_invalid, 1, GL_R8, 8, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
								  "texture is not the name of an existing texture object.");
	}

	/*  Check that INVALID_ENUM is generated by TextureStorage3DMultisample if
	 internalformat is not a valid color-renderable, depth-renderable or
	 stencil-renderable format. */
	{
		gl.textureStorage3DMultisample(m_to_3D_ms, 1, m_internalformat_invalid, 8, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage3DMultisample",
								  "internalformat is not a valid sized internal format.");
	}

	/*  Check that INVALID_OPERATION is generated by TextureStorage3DMultisample if
	 target or the effective target of texture is not one of the accepted
	 targets described above. */
	{
		gl.textureStorage3DMultisample(m_to_1D, 1, GL_R8, 8, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
								  "the effective target of texture is not one of the accepted targets.");
	}

	/* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if
	 width or height are less than 1 or greater than the value of
	 MAX_TEXTURE_SIZE. */
	{
		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 0, 8, 8, false);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "width is less than 1.");

		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 0, 8, false);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "height is less than 1.");

		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, m_max_texture_size * 2, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample",
								  "width is greater than the value of MAX_TEXTURE_SIZE.");

		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, m_max_texture_size * 2, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample",
								  "height is greater than the value of MAX_TEXTURE_SIZE.");
	}

	/* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if
	 depth is less than 1 or greater than the value of
	 MAX_ARRAY_TEXTURE_LAYERS. */
	{
		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 8, 0, false);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "depth is less than 1.");

		gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 8, m_max_array_texture_layers * 2, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample",
								  "depth is greater than the value of MAX_ARRAY_TEXTURE_LAYERS.");
	}

	/* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if
	 samples is greater than the maximum number of samples reported for GL_R8 */
	{
		gl.textureStorage3DMultisample(m_to_3D_ms, m_max_samples * 2, GL_R8, 8, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
								  "samples is greater than the value of MAX_SAMPLES.");
	}

	/* Check that INVALID_OPERATION is generated by TextureStorage3DMultisample
	 if the value of TEXTURE_IMMUTABLE_FORMAT for the texture bound to target
	 is not FALSE. */
	{
		gl.textureStorage3DMultisample(m_to_3D_ms_immutable, 1, GL_R8, 8, 8, 8, false);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample",
								  "samples is greater than the value of MAX_SAMPLES.");
	}

	return is_ok;
}

/** @brief Clean GL objects, test variables and GL errors.
 */
void StorageErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Cleanup. */
	if (m_to_1D)
	{
		gl.deleteTextures(1, &m_to_1D);

		m_to_1D = 0;
	}

	if (m_to_1D_array)
	{
		gl.deleteTextures(1, &m_to_1D_array);

		m_to_1D_array = 0;
	}

	if (m_to_2D)
	{
		gl.deleteTextures(1, &m_to_2D);

		m_to_2D = 0;
	}

	if (m_to_2D_array)
	{
		gl.deleteTextures(1, &m_to_2D_array);

		m_to_2D_array = 0;
	}

	if (m_to_3D)
	{
		gl.deleteTextures(1, &m_to_3D);

		m_to_3D = 0;
	}

	if (m_to_2D_ms)
	{
		gl.deleteTextures(1, &m_to_2D_ms);

		m_to_2D_ms = 0;
	}

	if (m_to_2D_ms_immutable)
	{
		gl.deleteTextures(1, &m_to_2D_ms_immutable);

		m_to_2D_ms_immutable = 0;
	}

	if (m_to_3D_ms)
	{
		gl.deleteTextures(1, &m_to_3D_ms);

		m_to_3D_ms = 0;
	}

	if (m_to_3D_ms_immutable)
	{
		gl.deleteTextures(1, &m_to_3D_ms_immutable);

		m_to_3D_ms_immutable = 0;
	}

	m_to_invalid			   = 0;
	m_internalformat_invalid   = 0;
	m_max_texture_size		   = 1;
	m_max_samples			   = 1;
	m_max_array_texture_layers = 1;

	while (GL_NO_ERROR != gl.getError())
		;
}

/******************************** Texture SubImage Errors Test Implementation   ********************************/

/** @brief Texture SubImage Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
SubImageErrorsTest::SubImageErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_subimage_errors", "Texture SubImage Errors Test")
	, m_to_1D_empty(0)
	, m_to_2D_empty(0)
	, m_to_3D_empty(0)
	, m_to_1D(0)
	, m_to_2D(0)
	, m_to_3D(0)
	, m_to_1D_compressed(0)
	, m_to_2D_compressed(0)
	, m_to_3D_compressed(0)
	, m_to_rectangle_compressed(0)
	, m_to_invalid(0)
	, m_bo(0)
	, m_format_invalid(0)
	, m_type_invalid(0)
	, m_max_texture_size(1)
	, m_reference_compressed_1D(DE_NULL)
	, m_reference_compressed_2D(DE_NULL)
	, m_reference_compressed_3D(DE_NULL)
	, m_reference_compressed_rectangle(DE_NULL)
	, m_reference_compressed_1D_size(0)
	, m_reference_compressed_2D_size(0)
	, m_reference_compressed_3D_size(0)
	, m_reference_compressed_rectangle_size(0)
	, m_reference_compressed_1D_format(0)
	, m_reference_compressed_2D_format(0)
	, m_reference_compressed_3D_format(0)
	, m_reference_compressed_rectangle_format(0)
	, m_not_matching_compressed_1D_format(0)
	, m_not_matching_compressed_1D_size(0)
	, m_not_matching_compressed_2D_format(0)
	, m_not_matching_compressed_2D_size(0)
	, m_not_matching_compressed_3D_format(0)
	, m_not_matching_compressed_3D_size(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Texture SubImage Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult SubImageErrorsTest::iterate()
{
	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		Prepare();

		is_ok &= Test1D();
		is_ok &= Test2D();
		is_ok &= Test3D();
		is_ok &= Test1DCompressed();
		is_ok &= Test2DCompressed();
		is_ok &= Test3DCompressed();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Prepare test's objects.
 */
void SubImageErrorsTest::Prepare()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Auxiliary objects setup. */

	/* 1D */
	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_empty);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 2D */
	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_empty);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 3D */
	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D_empty);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 1D */
	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_1D, m_to_1D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage1D(GL_TEXTURE_1D, 0, s_reference_internalformat, s_reference_width, 0, s_reference_format,
				  GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	/* 2D */
	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_2D, m_to_2D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
				  s_reference_format, GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	/* 3D */
	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_3D, m_to_3D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage3D(GL_TEXTURE_3D, 0, s_reference_internalformat, s_reference_width, s_reference_height,
				  s_reference_depth, 0, s_reference_format, GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	/* 1D Compressed */
	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_1D, m_to_1D_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage1D(GL_TEXTURE_1D, 0, s_reference_internalformat_compressed, s_reference_width, 0, s_reference_format,
				  GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	glw::GLint is_compressed = 0;

	gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");

	if (is_compressed)
	{
		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_reference_compressed_1D_format);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		m_reference_compressed_1D_size = 0;

		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &m_reference_compressed_1D_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		if (m_reference_compressed_1D_size)
		{
			m_reference_compressed_1D = new glw::GLubyte[m_reference_compressed_1D_size];

			gl.getCompressedTexImage(GL_TEXTURE_1D, 0, m_reference_compressed_1D);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
		}
	}

	/* 2D Compressed */
	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_2D, m_to_2D_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, 0,
				  s_reference_format, GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

	is_compressed = 0;

	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");

	if (is_compressed)
	{
		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_reference_compressed_2D_format);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		m_reference_compressed_2D_size = 0;

		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &m_reference_compressed_2D_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		if (m_reference_compressed_2D_size)
		{
			m_reference_compressed_2D = new glw::GLubyte[m_reference_compressed_2D_size];

			gl.getCompressedTexImage(GL_TEXTURE_2D, 0, m_reference_compressed_2D);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
		}
	}

	/* 3D Compressed */
	gl.createTextures(GL_TEXTURE_2D_ARRAY, 1, &m_to_3D_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_3D_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height,
				  s_reference_depth, 0, s_reference_format, GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D has failed");

	is_compressed = 0;

	gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");

	if (is_compressed)
	{
		gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_INTERNAL_FORMAT,
								  &m_reference_compressed_3D_format);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		m_reference_compressed_3D_size = 0;

		gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
								  &m_reference_compressed_3D_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		if (m_reference_compressed_3D_size)
		{
			m_reference_compressed_3D = new glw::GLubyte[m_reference_compressed_3D_size];

			gl.getCompressedTexImage(GL_TEXTURE_2D_ARRAY, 0, m_reference_compressed_3D);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
		}
	}

	/* RECTANGLE Compressed */
	gl.createTextures(GL_TEXTURE_RECTANGLE, 1, &m_to_rectangle_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_RECTANGLE, m_to_rectangle_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage2D(GL_TEXTURE_RECTANGLE, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height,
				  0, s_reference_format, GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

	is_compressed = 0;

	gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");

	if (is_compressed)
	{
		gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT,
								  &m_reference_compressed_rectangle_format);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		m_reference_compressed_rectangle_size = 0;

		gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
								  &m_reference_compressed_rectangle_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		if (m_reference_compressed_rectangle_size)
		{
			m_reference_compressed_rectangle = new glw::GLubyte[m_reference_compressed_rectangle_size];

			gl.getCompressedTexImage(GL_TEXTURE_RECTANGLE, 0, m_reference_compressed_rectangle);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed");
		}
	}

	/* Buffer object */
	gl.createBuffers(1, &m_bo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed");

	gl.namedBufferData(m_bo, s_reference_size, s_reference, GL_STATIC_COPY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");

	/* Invalid values */

	/* invalid texture object */
	while (gl.isTexture(++m_to_invalid))
		;
	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");

	/* invalid internal format */
	static const glw::GLenum all_formats[] = { GL_STENCIL_INDEX,
											   GL_DEPTH_COMPONENT,
											   GL_DEPTH_STENCIL,
											   GL_RED,
											   GL_GREEN,
											   GL_BLUE,
											   GL_RG,
											   GL_RGB,
											   GL_RGBA,
											   GL_BGR,
											   GL_BGRA,
											   GL_RED_INTEGER,
											   GL_GREEN_INTEGER,
											   GL_BLUE_INTEGER,
											   GL_RG_INTEGER,
											   GL_RGB_INTEGER,
											   GL_RGBA_INTEGER,
											   GL_BGR_INTEGER,
											   GL_BGRA_INTEGER };

	static const glw::GLuint all_internal_formats_count = sizeof(all_formats) / sizeof(all_formats[0]);

	bool is_valid	= true;
	m_format_invalid = 0;

	while (is_valid)
	{
		is_valid = false;
		m_format_invalid++;
		for (glw::GLuint i = 0; i < all_internal_formats_count; ++i)
		{
			if (all_formats[i] == m_format_invalid)
			{
				is_valid = true;
				break;
			}
		}
	}

	/* Invalid type. */
	static const glw::GLenum all_types[] = { GL_UNSIGNED_BYTE,
											 GL_BYTE,
											 GL_UNSIGNED_SHORT,
											 GL_SHORT,
											 GL_UNSIGNED_INT,
											 GL_INT,
											 GL_HALF_FLOAT,
											 GL_FLOAT,
											 GL_UNSIGNED_BYTE_3_3_2,
											 GL_UNSIGNED_BYTE_2_3_3_REV,
											 GL_UNSIGNED_SHORT_5_6_5,
											 GL_UNSIGNED_SHORT_5_6_5_REV,
											 GL_UNSIGNED_SHORT_4_4_4_4,
											 GL_UNSIGNED_SHORT_4_4_4_4_REV,
											 GL_UNSIGNED_SHORT_5_5_5_1,
											 GL_UNSIGNED_SHORT_1_5_5_5_REV,
											 GL_UNSIGNED_INT_8_8_8_8,
											 GL_UNSIGNED_INT_8_8_8_8_REV,
											 GL_UNSIGNED_INT_10_10_10_2,
											 GL_UNSIGNED_INT_2_10_10_10_REV,
											 GL_UNSIGNED_INT_24_8,
											 GL_UNSIGNED_INT_10F_11F_11F_REV,
											 GL_UNSIGNED_INT_5_9_9_9_REV,
											 GL_FLOAT_32_UNSIGNED_INT_24_8_REV };

	static const glw::GLuint all_types_count = sizeof(all_types) / sizeof(all_types[0]);

	is_valid	   = true;
	m_type_invalid = 0;

	while (is_valid)
	{
		is_valid = false;
		m_type_invalid++;
		for (glw::GLuint i = 0; i < all_types_count; ++i)
		{
			if (all_types[i] == m_type_invalid)
			{
				is_valid = true;
				break;
			}
		}
	}

	/* Maximum texture size.*/
	gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

	glw::GLenum not_matching_format					   = GL_RED;
	glw::GLenum not_matching_internalformat_compressed = GL_COMPRESSED_RED;

	/* 1D Compressed with a non matching format. We need to do all the allocation to get the correct image size */
	glw::GLuint to_1D_compressed_not_matching;

	gl.createTextures(GL_TEXTURE_1D, 1, &to_1D_compressed_not_matching);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_1D, to_1D_compressed_not_matching);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage1D(GL_TEXTURE_1D, 0, not_matching_internalformat_compressed, s_reference_width, 0, s_reference_format,
				  GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed");

	is_compressed = 0;

	gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");

	if (is_compressed)
	{
		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_1D_format);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		m_not_matching_compressed_1D_size = 0;

		gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
								  &m_not_matching_compressed_1D_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
	}

	gl.deleteTextures(1, &to_1D_compressed_not_matching);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 2D Compressed with a non matching format. We need to do all the allocation to get the correct image size */
	glw::GLuint to_2D_compressed_not_matching;

	gl.createTextures(GL_TEXTURE_2D, 1, &to_2D_compressed_not_matching);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_2D, to_2D_compressed_not_matching);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage2D(GL_TEXTURE_2D, 0, not_matching_internalformat_compressed, s_reference_width, s_reference_height, 0,
				  not_matching_format, GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

	is_compressed = 0;

	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");

	if (is_compressed)
	{
		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_2D_format);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		m_not_matching_compressed_2D_size = 0;

		gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
								  &m_not_matching_compressed_2D_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
	}

	gl.deleteTextures(1, &to_2D_compressed_not_matching);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 3D Compressed with a non matching format. We need to do all the allocation to get the correct image size */
	glw::GLuint to_3D_compressed_not_matching;

	gl.createTextures(GL_TEXTURE_3D, 1, &to_3D_compressed_not_matching);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.bindTexture(GL_TEXTURE_3D, to_3D_compressed_not_matching);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

	gl.texImage3D(GL_TEXTURE_3D, 0, not_matching_internalformat_compressed, s_reference_width, s_reference_height,
				  s_reference_depth, 0, not_matching_format, GL_UNSIGNED_BYTE, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D has failed");

	is_compressed = 0;

	gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_COMPRESSED, &is_compressed);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed");

	if (is_compressed)
	{
		gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_3D_format);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");

		m_not_matching_compressed_3D_size = 0;

		gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
								  &m_not_matching_compressed_3D_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed");
	}

	gl.deleteTextures(1, &to_3D_compressed_not_matching);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");
}

/** @brief Test (negative) of TextureSubImage1D
 *
 *  @return Test result.
 */
bool SubImageErrorsTest::Test1D()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if
	 texture is not the name of an existing texture object. */
	{
		gl.textureSubImage1D(m_to_invalid, 0, 0, s_reference_width, s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "texture is not the name of an existing texture object.");
	}

	/* Check that INVALID_ENUM is generated by TextureSubImage1D if format is
	 not an accepted format constant. */
	{
		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, m_format_invalid, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage1D",
								  "format is not an accepted format constant.");
	}

	/* Check that INVALID_ENUM is generated by TextureSubImage1D if type is not
	 an accepted type constant. */
	{
		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, m_type_invalid, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage1D",
								  "type is not an accepted type constant.");
	}

	/* Check that INVALID_VALUE is generated by TextureSubImage1D if level is
	 less than 0. */
	{
		gl.textureSubImage1D(m_to_1D, -1, 0, s_reference_width, s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "level is less than 0.");
	}

	/* Check that INVALID_VALUE may be generated by TextureSubImage1D if level
	 is greater than log2 max, where max is the returned value of
	 MAX_TEXTURE_SIZE. */
	{
		gl.textureSubImage1D(m_to_1D, m_max_texture_size, 0, s_reference_width, s_reference_format, s_reference_type,
							 s_reference);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D",
							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
	}

	/* Check that INVALID_VALUE is generated by TextureSubImage1D if
	 xoffset<-b, or if (xoffset+width)>(w-b), where w is the TEXTURE_WIDTH,
	 and b is the width of the TEXTURE_BORDER of the texture image being
	 modified. Note that w includes twice the border width. */
	{
		gl.textureSubImage1D(m_to_1D, 0, -1, s_reference_width, s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D",
								  "xoffset<-b, where b is the width of the TEXTURE_BORDER.");

		gl.textureSubImage1D(m_to_1D, 0, 1, s_reference_width + 1, s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_VALUE, "glTextureSubImage1D",
			"(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER.");
	}

	/*Check that INVALID_VALUE is generated by TextureSubImage1D if width is less than 0. */
	{
#ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH
		gl.textureSubImage1D(m_to_1D, 0, 0, -1, s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "width is less than 0.");
#endif
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if type
	 is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV,
	 UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */
	{
		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_BYTE_3_3_2, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_BYTE_3_3_2 and format is not RGB.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_BYTE_2_3_3_REV,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_6_5,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_SHORT_5_6_5 and format is not RGB.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_6_5_REV,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB.");
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if type
	 is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV,
	 UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV,
	 UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2,
	 or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */
	{
		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4_REV,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_5_5_1,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_1_5_5_5_REV,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_8_8_8_8,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_8_8_8_8_REV,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_10_10_10_2,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA.");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_2_10_10_10_REV,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA.");
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if a
	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
	 and the buffer object's data store is currently mapped. */
	{
		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);

		if (GL_NO_ERROR == gl.getError())
		{
			gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type, NULL);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
									  "the buffer object's data store is currently mapped.");

			gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
		}
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if a
	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
	 and the data would be unpacked from the buffer object such that the
	 memory reads required would exceed the data store size. */
	{
		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type,
							 glu::BufferOffsetAsPointer(s_reference_size * 2));
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the "
								  "data would be unpacked from the buffer object such that the memory reads required "
								  "would exceed the data store size.");

		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage1D if a
	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
	 and pixels is not evenly divisible into the number of bytes needed to
	 store in memory a datum indicated by type. */
	{
		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type,
							 glu::BufferOffsetAsPointer(1));
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D",
								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels "
								  "is not evenly divisible into the number of bytes needed to store in memory a datum "
								  "indicated by type.");

		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
	}

	return is_ok;
}

/** @brief Test (negative) of TextureSubImage2D
 *
 *  @return Test result.
 */
bool SubImageErrorsTest::Test2D()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if
	 texture is not the name of an existing texture object. */
	{
		gl.textureSubImage2D(m_to_invalid, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "texture is not the name of an existing texture object.");
	}

	/* Check that INVALID_ENUM is generated by TextureSubImage2D if format is
	 not an accepted format constant. */
	{
		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, m_format_invalid,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage2D",
								  "format is not an accepted format constant.");
	}

	/* Check that INVALID_ENUM is generated by TextureSubImage2D if type is not
	 an accepted type constant. */
	{
		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 m_type_invalid, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage2D",
								  "type is not an accepted type constant.");
	}

	/* Check that INVALID_VALUE is generated by TextureSubImage2D if level is
	 less than 0. */
	{
		gl.textureSubImage2D(m_to_2D, -1, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "level is less than 0.");
	}

	/* Check that INVALID_VALUE may be generated by TextureSubImage2D if level
	 is greater than log2 max, where max is the returned value of
	 MAX_TEXTURE_SIZE. */
	{
		gl.textureSubImage2D(m_to_2D, m_max_texture_size, 0, 0, s_reference_width, s_reference_height,
							 s_reference_format, s_reference_type, s_reference);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
	}

	/* Check that INVALID_VALUE may be generated by TextureSubImage2D if level
	 is greater than log2 max, where max is the returned value of
	 MAX_TEXTURE_SIZE.
	 Check that INVALID_VALUE is generated by TextureSubImage2D if
	 xoffset<-b, (xoffset+width)>(w-b), yoffset<-b, or
	 (yoffset+height)>(h-b), where w is the TEXTURE_WIDTH, h is the
	 TEXTURE_HEIGHT, and b is the border width of the texture image being
	 modified. Note that w and h include twice the border width. */
	{
		gl.textureSubImage2D(m_to_2D, 0, -1, 0, s_reference_width, s_reference_height, s_reference_format,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
								  "xoffset<-b, where b is the width of the TEXTURE_BORDER.");

		gl.textureSubImage2D(m_to_2D, 0, 1, 0, s_reference_width + 1, s_reference_height, s_reference_format,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
			"(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER.");

		gl.textureSubImage2D(m_to_2D, 0, 0, -1, s_reference_width, s_reference_height, s_reference_format,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
								  "yoffset<-b, where b is the height of the TEXTURE_BORDER.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 1, s_reference_width + 1, s_reference_height, s_reference_format,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_VALUE, "glTextureSubImage2D",
			"(yoffset+height)>(h-b), where h is the TEXTURE_HEIGHT, b is the width of the TEXTURE_BORDER.");
	}

	/*Check that INVALID_VALUE is generated by TextureSubImage2D if width or height is less than 0. */
	{
#ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH
		gl.textureSubImage2D(m_to_2D, 0, 0, 0, -1, s_reference_height, s_reference_format, s_reference_type,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "width is less than 0.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, -1, s_reference_format, s_reference_type,
							 s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "height is less than 0.");
#endif
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if type
	 is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV,
	 UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */
	{
		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_BYTE_3_3_2, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_BYTE_3_3_2 and format is not RGB.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_BYTE_2_3_3_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_SHORT_5_6_5, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_SHORT_5_6_5 and format is not RGB.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_SHORT_5_6_5_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB.");
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if type
	 is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV,
	 UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV,
	 UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2,
	 or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */
	{
		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_SHORT_4_4_4_4, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_SHORT_4_4_4_4_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_SHORT_5_5_5_1, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_SHORT_1_5_5_5_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_INT_8_8_8_8, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_INT_8_8_8_8_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_INT_10_10_10_2, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA.");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 GL_UNSIGNED_INT_2_10_10_10_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA.");
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if a
	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
	 and the buffer object's data store is currently mapped. */
	{
		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);

		if (GL_NO_ERROR == gl.getError())
		{
			gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
								 s_reference_type, NULL);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
									  "the buffer object's data store is currently mapped.");

			gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
		}
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if a
	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
	 and the data would be unpacked from the buffer object such that the
	 memory reads required would exceed the data store size. */
	{
		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 s_reference_type, glu::BufferOffsetAsPointer(s_reference_size * 2));
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the "
								  "data would be unpacked from the buffer object such that the memory reads required "
								  "would exceed the data store size.");

		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage2D if a
	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
	 and pixels is not evenly divisible into the number of bytes needed to
	 store in memory a datum indicated by type. */
	{
		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format,
							 s_reference_type, glu::BufferOffsetAsPointer(1));
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D",
								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels "
								  "is not evenly divisible into the number of bytes needed to store in memory a datum "
								  "indicated by type.");

		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
	}

	return is_ok;
}

/** @brief Test (negative) of TextureSubImage3D
 *
 *  @return Test result.
 */
bool SubImageErrorsTest::Test3D()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if
	 texture is not the name of an existing texture object. */
	{
		gl.textureSubImage3D(m_to_invalid, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "texture is not the name of an existing texture object.");
	}

	/* Check that INVALID_ENUM is generated by TextureSubImage3D if format is
	 not an accepted format constant. */
	{
		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 m_format_invalid, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage3D",
								  "format is not an accepted format constant.");
	}

	/* Check that INVALID_ENUM is generated by TextureSubImage3D if type is not
	 an accepted type constant. */
	{
		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, m_type_invalid, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage3D",
								  "type is not an accepted type constant.");
	}

	/* Check that INVALID_VALUE is generated by TextureSubImage3D if level is
	 less than 0. */
	{
		gl.textureSubImage3D(m_to_3D, -1, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D", "level is less than 0.");
	}

	/* Check that INVALID_VALUE may be generated by TextureSubImage1D if level
	 is greater than log2 max, where max is the returned value of
	 MAX_TEXTURE_SIZE. */
	{
		gl.textureSubImage3D(m_to_3D, m_max_texture_size, 0, 0, 0, s_reference_width, s_reference_height,
							 s_reference_depth, s_reference_format, s_reference_type, s_reference);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");
	}

	/* Check that INVALID_VALUE is generated by TextureSubImage3D if
	 xoffset<-b, (xoffset+width)>(w-b), yoffset<-b, or
	 (yoffset+height)>(h-b), or zoffset<-b, or (zoffset+depth)>(d-b), where w
	 is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT, d is the TEXTURE_DEPTH
	 and b is the border width of the texture image being modified. Note
	 that w, h, and d include twice the border width. */
	{
		gl.textureSubImage3D(m_to_3D, 0, -1, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
								  "xoffset<-b, where b is the width of the TEXTURE_BORDER.");

		gl.textureSubImage3D(m_to_3D, 0, 1, 0, 0, s_reference_width + 1, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
			"(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER.");

		gl.textureSubImage3D(m_to_3D, 0, 0, -1, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
								  "yoffset<-b, where b is the width of the TEXTURE_BORDER.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 1, 0, s_reference_width + 1, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
			"(yoffset+height)>(h-b), where h is the TEXTURE_HEIGHT, b is the width of the TEXTURE_BORDER.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, -1, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
								  "zoffset<-b, where b is the depth of the TEXTURE_BORDER.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 1, s_reference_width + 1, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_VALUE, "glTextureSubImage3D",
			"(zoffset+width)>(d-b), where d is the TEXTURE_DEPTH, b is the width of the TEXTURE_BORDER.");
	}

	/*Check that INVALID_VALUE is generated by TextureSubImage3D if width or height or depth is less than 0. */
	{
#ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH
		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, -1, s_reference_height, s_reference_depth, s_reference_format,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "width is less than 0.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, -1, s_reference_depth, s_reference_format,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "height is less than 0.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, -1, s_reference_format,
							 s_reference_type, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "depth is less than 0.");
#endif
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if type
	 is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV,
	 UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */
	{
		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_BYTE_3_3_2, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_BYTE_3_3_2 and format is not RGB.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_BYTE_2_3_3_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_SHORT_5_6_5, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_SHORT_5_6_5 and format is not RGB.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_SHORT_5_6_5_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB.");
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if type
	 is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV,
	 UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV,
	 UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2,
	 or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */
	{
		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_SHORT_5_5_5_1, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_SHORT_1_5_5_5_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_INT_8_8_8_8, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_INT_8_8_8_8_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_INT_10_10_10_2, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA.");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, GL_UNSIGNED_INT_2_10_10_10_REV, s_reference);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA.");
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if a
	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
	 and the buffer object's data store is currently mapped. */
	{
		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);

		if (GL_NO_ERROR == gl.getError())
		{
			gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
								 s_reference_format, s_reference_type, NULL);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
									  "the buffer object's data store is currently mapped.");

			gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
		}
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if a
	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
	 and the data would be unpacked from the buffer object such that the
	 memory reads required would exceed the data store size. */
	{
		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, glu::BufferOffsetAsPointer(s_reference_size * 2));
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the "
								  "data would be unpacked from the buffer object such that the memory reads required "
								  "would exceed the data store size.");

		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
	}

	/* Check that INVALID_OPERATION is generated by TextureSubImage3D if a
	 non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target
	 and pixels is not evenly divisible into the number of bytes needed to
	 store in memory a datum indicated by type. */
	{
		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth,
							 s_reference_format, s_reference_type, glu::BufferOffsetAsPointer(1));
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D",
								  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels "
								  "is not evenly divisible into the number of bytes needed to store in memory a datum "
								  "indicated by type.");

		gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
	}

	return is_ok;
}

/** @brief Test (negative) of TextureSubImage1DCompressed
 *
 *  @return Test result.
 */
bool SubImageErrorsTest::Test1DCompressed()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Do tests only if compressed 1D textures are supported. */
	if (DE_NULL != m_reference_compressed_1D)
	{
		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D
		 if texture is not the name of an existing texture object. */
		{
			gl.compressedTextureSubImage1D(m_to_invalid, 0, 0, s_reference_width, m_reference_compressed_1D_format,
										   m_reference_compressed_1D_size, m_reference_compressed_1D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
									  "texture is not the name of an existing texture object.");
		}

		/* Check that INVALID_ENUM is generated by CompressedTextureSubImage1D if
		 internalformat is not one of the generic compressed internal formats:
		 COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA.
		 COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */
		{
			/* GL_COMPRESSED_RG_RGTC2 is not 1D as specification says. */
			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width, GL_COMPRESSED_RG_RGTC2,
										   m_reference_compressed_1D_size, m_reference_compressed_1D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage1D",
									  "internalformat is of the generic compressed internal formats: COMPRESSED_RED, "
									  "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or "
									  "COMPRESSED_SRGB_ALPHA.");
		}

		/* Check that INVALID_OPERATION is generated if format does not match the
		 internal format of the texture image being modified, since these
		 commands do not provide for image format conversion. */
		{
			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
										   m_not_matching_compressed_1D_format, m_not_matching_compressed_1D_size,
										   m_reference_compressed_1D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
									  "format does not match the internal format of the texture image being modified, "
									  "since these commands do not provide for image format conversion.");
		}

		/* Check that INVALID_VALUE is generated by CompressedTextureSubImage1D if
		 imageSize is not consistent with the format, dimensions, and contents of
		 the specified compressed image data. */
		{
			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
										   m_reference_compressed_1D_format, m_reference_compressed_1D_size - 1,
										   m_reference_compressed_1D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage1D",
									  "imageSize is not consistent with the format, dimensions, and contents of the "
									  "specified compressed image data.");
		}

		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D
		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
		 target and the buffer object's data store is currently mapped. */
		{
			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

			gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);

			if (GL_NO_ERROR == gl.getError())
			{
				gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
											   m_reference_compressed_1D_format, m_reference_compressed_1D_size, NULL);
				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
										  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target "
										  "and the buffer object's data store is currently mapped.");

				gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

				gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
			}
		}

		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D
		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
		 target and the data would be unpacked from the buffer object such that
		 the memory reads required would exceed the data store size. */
		{
			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

			gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width,
										   m_reference_compressed_1D_format, m_reference_compressed_1D_size,
										   glu::BufferOffsetAsPointer(s_reference_size * 2));
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D",
									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
									  "the buffer object's data store is currently mapped.");

			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
		}
	}

	return is_ok;
}

/** @brief Test (negative) of TextureSubImage2DCompressed
 *
 *  @return Test result.
 */
bool SubImageErrorsTest::Test2DCompressed()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Do tests only if compressed 2D textures are supported. */
	if (DE_NULL != m_reference_compressed_2D)
	{
		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
		 if texture is not the name of an existing texture object. */
		{
			gl.compressedTextureSubImage2D(m_to_invalid, 0, 0, 0, s_reference_width, s_reference_height,
										   m_reference_compressed_2D_format, m_reference_compressed_2D_size,
										   m_reference_compressed_2D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
									  "texture is not the name of an existing texture object.");
		}

		/* Check that INVALID_ENUM is generated by CompressedTextureSubImage2D if
		 internalformat is of the generic compressed internal formats:
		 COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA.
		 COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */
		{
			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
										   GL_COMPRESSED_RG, m_reference_compressed_2D_size, m_reference_compressed_2D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage2D",
									  "internalformat is of the generic compressed internal formats: COMPRESSED_RED, "
									  "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or "
									  "COMPRESSED_SRGB_ALPHA.");
		}

		/* Check that INVALID_OPERATION is generated if format does not match the
		 internal format of the texture image being modified, since these
		 commands do not provide for image format conversion. */
		{
			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
										   m_not_matching_compressed_2D_format, m_not_matching_compressed_2D_size,
										   m_reference_compressed_2D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
									  "format does not match the internal format of the texture image being modified, "
									  "since these commands do not provide for image format conversion.");
		}

		/* Check that INVALID_VALUE is generated by CompressedTextureSubImage2D if
		 imageSize is not consistent with the format, dimensions, and contents of
		 the specified compressed image data. */
		{
			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
										   m_reference_compressed_2D_format, m_reference_compressed_2D_size - 1,
										   m_reference_compressed_2D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage2D",
									  "imageSize is not consistent with the format, dimensions, and contents of the "
									  "specified compressed image data.");
		}

		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
		 target and the buffer object's data store is currently mapped. */
		{
			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

			gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);

			if (GL_NO_ERROR == gl.getError())
			{
				gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
											   m_reference_compressed_2D_format, m_reference_compressed_2D_size, NULL);
				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
										  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target "
										  "and the buffer object's data store is currently mapped.");

				gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

				gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
			}
		}

		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
		 target and the data would be unpacked from the buffer object such that
		 the memory reads required would exceed the data store size. */
		{
			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

			gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height,
										   m_reference_compressed_2D_format, m_reference_compressed_2D_size,
										   glu::BufferOffsetAsPointer(s_reference_size * 2));
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
									  "the buffer object's data store is currently mapped.");

			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
		}

		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D
		 if the effective target is TEXTURE_RECTANGLE. */
		if (DE_NULL !=
			m_reference_compressed_rectangle) /* Do test only if rectangle compressed texture is supported by the implementation. */
		{
			gl.compressedTextureSubImage2D(m_to_rectangle_compressed, 0, 0, 0, s_reference_width, s_reference_height,
										   m_reference_compressed_rectangle_format,
										   m_reference_compressed_rectangle_size, m_reference_compressed_rectangle);

			if (m_context.getContextInfo().isExtensionSupported("GL_NV_texture_rectangle_compressed"))
			{
				is_ok &= CheckErrorAndLog(m_context, GL_NO_ERROR, "glCompressedTextureSubImage2D",
										  "a rectangle texture object is used with this function.");
			}
			else
			{
				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D",
										  "a rectangle texture object is used with this function.");
			}
		}
	}

	return is_ok;
}

/** @brief Test (negative) of TextureSubImage3DCompressed
 *
 *  @return Test result.
 */
bool SubImageErrorsTest::Test3DCompressed()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Do tests only if compressed 3D textures are supported. */
	if (DE_NULL != m_reference_compressed_3D)
	{
		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D
		 if texture is not the name of an existing texture object. */
		{
			gl.compressedTextureSubImage3D(m_to_invalid, 0, 0, 0, 0, s_reference_width, s_reference_height,
										   s_reference_depth, m_reference_compressed_3D_format,
										   m_reference_compressed_3D_size, m_reference_compressed_3D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
									  "texture is not the name of an existing texture object.");
		}

		/* Check that INVALID_ENUM is generated by CompressedTextureSubImage3D if
		 internalformat is of the generic compressed internal formats:
		 COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA.
		 COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */
		{
			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
										   s_reference_depth, GL_COMPRESSED_RG, m_reference_compressed_3D_size,
										   m_reference_compressed_3D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage3D",
									  "internalformat is of the generic compressed internal formats: COMPRESSED_RED, "
									  "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or "
									  "COMPRESSED_SRGB_ALPHA.");
		}

		/* Check that INVALID_OPERATION is generated if format does not match the
		 internal format of the texture image being modified, since these
		 commands do not provide for image format conversion. */
		{
			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
										   s_reference_depth, m_not_matching_compressed_3D_format,
										   m_not_matching_compressed_3D_size, m_reference_compressed_3D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
									  "format does not match the internal format of the texture image being modified, "
									  "since these commands do not provide for image format conversion.");
		}

		/* Check that INVALID_VALUE is generated by CompressedTextureSubImage3D if
		 imageSize is not consistent with the format, dimensions, and contents of
		 the specified compressed image data. */
		{
			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
										   s_reference_depth, m_reference_compressed_3D_format,
										   m_reference_compressed_3D_size - 1, m_reference_compressed_3D);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage3D",
									  "imageSize is not consistent with the format, dimensions, and contents of the "
									  "specified compressed image data.");
		}

		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D
		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
		 target and the buffer object's data store is currently mapped. */
		{
			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

			gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);

			if (GL_NO_ERROR == gl.getError())
			{
				gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
											   s_reference_depth, m_reference_compressed_3D_format,
											   m_reference_compressed_3D_size, NULL);
				is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
										  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target "
										  "and the buffer object's data store is currently mapped.");

				gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

				gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
			}
		}

		/* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D
		 if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER
		 target and the data would be unpacked from the buffer object such that
		 the memory reads required would exceed the data store size. */
		{
			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

			gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height,
										   s_reference_depth, m_reference_compressed_3D_format,
										   m_reference_compressed_3D_size, glu::BufferOffsetAsPointer(s_reference_size * 2));
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D",
									  "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and "
									  "the buffer object's data store is currently mapped.");

			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
		}
	}

	return is_ok;
}

/** @brief Clean GL objects, test variables and GL errors.
 */
void SubImageErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Cleanup. */
	if (m_to_1D_empty)
	{
		gl.deleteTextures(1, &m_to_1D_empty);

		m_to_1D_empty = 0;
	}

	if (m_to_2D_empty)
	{
		gl.deleteTextures(1, &m_to_2D_empty);

		m_to_2D_empty = 0;
	}

	if (m_to_3D_empty)
	{
		gl.deleteTextures(1, &m_to_3D_empty);

		m_to_3D_empty = 0;
	}

	if (m_to_1D)
	{
		gl.deleteTextures(1, &m_to_1D);

		m_to_1D = 0;
	}

	if (m_to_2D)
	{
		gl.deleteTextures(1, &m_to_2D);

		m_to_2D = 0;
	}

	if (m_to_3D)
	{
		gl.deleteTextures(1, &m_to_3D);

		m_to_3D = 0;
	}

	if (m_to_1D_compressed)
	{
		gl.deleteTextures(1, &m_to_1D_compressed);

		m_to_1D_compressed = 0;
	}

	if (m_to_2D_compressed)
	{
		gl.deleteTextures(1, &m_to_2D_compressed);

		m_to_2D_compressed = 0;
	}

	if (m_to_3D_compressed)
	{
		gl.deleteTextures(1, &m_to_3D_compressed);

		m_to_3D_compressed = 0;
	}

	if (m_to_rectangle_compressed)
	{
		gl.deleteTextures(1, &m_to_rectangle_compressed);

		m_to_rectangle_compressed = 0;
	}

	if (m_bo)
	{
		gl.deleteBuffers(1, &m_bo);

		m_bo = 0;
	}

	m_to_invalid	   = 0;
	m_format_invalid   = 0;
	m_type_invalid	 = 0;
	m_max_texture_size = 1;

	if (DE_NULL != m_reference_compressed_1D)
	{
		delete[] m_reference_compressed_1D;

		m_reference_compressed_1D = NULL;
	}

	if (DE_NULL != m_reference_compressed_2D)
	{
		delete[] m_reference_compressed_2D;

		m_reference_compressed_2D = NULL;
	}

	if (DE_NULL != m_reference_compressed_3D)
	{
		delete[] m_reference_compressed_3D;

		m_reference_compressed_3D = NULL;
	}

	if (DE_NULL != m_reference_compressed_rectangle)
	{
		delete[] m_reference_compressed_rectangle;

		m_reference_compressed_rectangle = NULL;
	}

	m_reference_compressed_1D_format		= 0;
	m_reference_compressed_2D_format		= 0;
	m_reference_compressed_3D_format		= 0;
	m_reference_compressed_rectangle_format = 0;
	m_reference_compressed_1D_size			= 0;
	m_reference_compressed_2D_size			= 0;
	m_reference_compressed_3D_size			= 0;
	m_reference_compressed_rectangle_size   = 0;
	m_not_matching_compressed_1D_format		= 0;
	m_not_matching_compressed_1D_size		= 0;
	m_not_matching_compressed_2D_format		= 0;
	m_not_matching_compressed_2D_size		= 0;
	m_not_matching_compressed_3D_format		= 0;
	m_not_matching_compressed_3D_size		= 0;

	while (GL_NO_ERROR != gl.getError())
		;
}

/** Reference data */
const glw::GLushort SubImageErrorsTest::s_reference[] = {
	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,

	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,

	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff,

	0x0,  0x0,  0x0,  0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x88, 0x0,  0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0,  0xff,
	0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff,
	0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0,  0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff
};

/** Reference data parameters. */
const glw::GLuint SubImageErrorsTest::s_reference_size						= sizeof(s_reference);
const glw::GLuint SubImageErrorsTest::s_reference_width						= 4;
const glw::GLuint SubImageErrorsTest::s_reference_height					= 4;
const glw::GLuint SubImageErrorsTest::s_reference_depth						= 4;
const glw::GLenum SubImageErrorsTest::s_reference_internalformat			= GL_RG8;
const glw::GLenum SubImageErrorsTest::s_reference_internalformat_compressed = GL_COMPRESSED_RG;
const glw::GLenum SubImageErrorsTest::s_reference_format = GL_RG; /* !Must not be a RGB, RGBA, or BGRA */
const glw::GLenum SubImageErrorsTest::s_reference_type   = GL_UNSIGNED_SHORT;

/******************************** Copy Errors Test Implementation   ********************************/

/** @brief Copy Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CopyErrorsTest::CopyErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_copy_errors", "Texture Copy Errors Test")
	, m_fbo(0)
	, m_fbo_ms(0)
	, m_fbo_incomplete(0)
	, m_to_src(0)
	, m_to_src_ms(0)
	, m_to_1D_dst(0)
	, m_to_2D_dst(0)
	, m_to_3D_dst(0)
	, m_to_invalid(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Copy Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult CopyErrorsTest::iterate()
{
	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		Prepare();

		is_ok &= Test1D();
		is_ok &= Test2D();
		is_ok &= Test3D();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Prepare test's objects and values.
 */
void CopyErrorsTest::Prepare()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Auxiliary objects setup. */

	/* Framebuffer. */
	gl.genFramebuffers(1, &m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_src);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.textureStorage2D(m_to_src, 1, s_internalformat, s_width, s_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");

	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_src, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		throw 0;
	}

	gl.viewport(0, 0, s_width, s_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");

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

	/* Framebuffer Multisample. */
	gl.genFramebuffers(1, &m_fbo_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_src_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.textureStorage2DMultisample(m_to_src_ms, 1, s_internalformat, s_width, s_height, false);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");

	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_to_src_ms, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed.");

	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
	{
		throw 0;
	}

	gl.viewport(0, 0, s_width, s_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");

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

	/* Framebuffer Incomplete. */
	gl.createFramebuffers(1, &m_fbo_incomplete);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glcreateFramebuffers call failed.");

	/* 1D */
	gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.textureStorage1D(m_to_1D_dst, 1, s_internalformat, s_width);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");

	/* 2D */
	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.textureStorage2D(m_to_2D_dst, 1, s_internalformat, s_width, s_height);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");

	/* 3D */
	gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D_dst);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	gl.textureStorage3D(m_to_3D_dst, 1, s_internalformat, s_width, s_height, s_depth);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed");

	/* invalid texture object */
	while (gl.isTexture(++m_to_invalid))
		;
	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");
}

/** @brief Test (negative) of CopyTextureSubImage1D
 *
 *  @return Test result.
 */
bool CopyErrorsTest::Test1D()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Bind framebuffer. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	/* Check that INVALID_FRAMEBUFFER_OPERATION is generated by
	 CopyTextureSubImage1D if the object bound to READ_FRAMEBUFFER_BINDING is
	 not framebuffer complete. */
	{
		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage1D",
								  "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete.");
	}

	/* Bind framebuffer. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.readBuffer(GL_COLOR_ATTACHMENT0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if
	 texture is not the name of an existing texture object, or if the
	 effective target of texture is not TEXTURE_1D. */
	{
		gl.copyTextureSubImage1D(m_to_invalid, 0, 0, 0, 0, s_width);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D",
								  "texture is not the name of an existing texture object.");

		gl.copyTextureSubImage1D(m_to_2D_dst, 0, 0, 0, 0, s_width);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D",
								  "the effective target of texture is not TEXTURE_1D.");
	}

	/* Check that INVALID_VALUE is generated by CopyTextureSubImage1D if level is less than 0. */
	{
		gl.copyTextureSubImage1D(m_to_1D_dst, -1, 0, 0, 0, s_width);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D", "level is less than 0.");
	}

	/* Check that INVALID_VALUE is generated by CopyTextureSubImage1D if
	 xoffset<0, or (xoffset+width)>w, where w is the TEXTURE_WIDTH of the
	 texture image being modified. */
	{
		gl.copyTextureSubImage1D(m_to_1D_dst, 0, -1, 0, 0, s_width);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D", "xoffset<0.");

		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 1, 0, 0, s_width);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D",
							 "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified.");
	}

	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if
	 the read buffer is NONE. */
	gl.readBuffer(GL_NONE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	{
		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D", "the read buffer is NONE.");
	}

	/* Bind multisample framebuffer. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.readBuffer(GL_COLOR_ATTACHMENT0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if
	 the effective value of SAMPLE_BUFFERS for the read
	 framebuffer is one. */
	{
		gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D",
								  "the effective value of SAMPLE_BUFFERS for the read framebuffer is one.");
	}

	return is_ok;
}

/** @brief Test (negative) of CopyTextureSubImage2D
 *
 *  @return Test result.
 */
bool CopyErrorsTest::Test2D()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Bind framebuffer. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	/* Check that INVALID_FRAMEBUFFER_OPERATION is generated by
	 CopyTextureSubImage2D if the object bound to READ_FRAMEBUFFER_BINDING is
	 not framebuffer complete. */
	{
		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage2D",
								  "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete.");
	}

	/* Bind framebuffer. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.readBuffer(GL_COLOR_ATTACHMENT0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if
	 texture is not the name of an existing texture object, or if the
	 effective target of texture is not TEXTURE_2D. */
	{
		gl.copyTextureSubImage2D(m_to_invalid, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D",
								  "texture is not the name of an existing texture object.");

		gl.copyTextureSubImage2D(m_to_1D_dst, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D",
			"the effective target of does not correspond to one of the texture targets supported by the function..");
	}

	/* Check that INVALID_VALUE is generated by CopyTextureSubImage2D if level is less than 0. */
	{
		gl.copyTextureSubImage2D(m_to_2D_dst, -1, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "level is less than 0.");
	}

	/* Check that INVALID_VALUE is generated by CopyTextureSubImage2D if
	 xoffset<0, (xoffset+width)>w, yoffset<0, or (yoffset+height)>0, where w
	 is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT and of the texture image
	 being modified. */
	{
		gl.copyTextureSubImage2D(m_to_2D_dst, 0, -1, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "xoffset<0.");

		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 1, 0, 0, 0, s_width, s_height);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D",
							 "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified.");

		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, -1, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "yoffset<0.");

		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 1, 0, 0, s_width, s_height);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D",
							 "(yoffset+height)>h, where h is the TEXTURE_HEIGHT of the texture image being modified.");
	}

	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if
	 the read buffer is NONE. */
	gl.readBuffer(GL_NONE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	{
		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D", "the read buffer is NONE.");
	}

	/* Bind multisample framebuffer. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.readBuffer(GL_COLOR_ATTACHMENT0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if
	 the effective value of SAMPLE_BUFFERS for the read
	 framebuffer is one. */
	{
		gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D",
								  "the effective value of SAMPLE_BUFFERS for the read framebuffer is one.");
	}

	return is_ok;
}

/** @brief Test (negative) of CopyTextureSubImage3D
 *
 *  @return Test result.
 */
bool CopyErrorsTest::Test3D()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Bind framebuffer. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	/* Check that INVALID_FRAMEBUFFER_OPERATION is generated by
	 CopyTextureSubImage3D if the object bound to READ_FRAMEBUFFER_BINDING is
	 not framebuffer complete. */
	{
		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage3D",
								  "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete.");
	}

	/* Bind framebuffer. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.readBuffer(GL_COLOR_ATTACHMENT0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if
	 texture is not the name of an existing texture object, or if the
	 effective target of texture is not supported by the function. */
	{
		gl.copyTextureSubImage3D(m_to_invalid, 0, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D",
								  "texture is not the name of an existing texture object.");

		gl.copyTextureSubImage3D(m_to_1D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D",
			"the effective target of does not correspond to one of the texture targets supported by the function..");
	}

	/* Check that INVALID_VALUE is generated by CopyTextureSubImage3D if level is less than 0. */
	{
		gl.copyTextureSubImage3D(m_to_3D_dst, -1, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "level is less than 0.");
	}

	/* Check that INVALID_VALUE is generated by CopyTextureSubImage3D if
	 xoffset<0, (xoffset+width)>w, yoffset<0, (yoffset+height)>h, zoffset<0,
	 or (zoffset+1)>d, where w is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT,
	 d is the TEXTURE_DEPTH and of the texture image being modified. Note
	 that w, h, and d include twice the border width.  */
	{
		gl.copyTextureSubImage3D(m_to_3D_dst, 0, -1, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "xoffset<0.");

		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 1, 0, 0, 0, 0, s_width, s_height);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D",
							 "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified.");

		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, -1, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "yoffset<0.");

		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 1, 0, 0, 0, s_width, s_height);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D",
							 "(yoffset+height)>h, where h is the TEXTURE_HEIGHT of the texture image being modified.");

		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, -1, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "zoffset<0.");

		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, s_depth + 1, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D",
								  "(zoffset+1)>d, where d is the TEXTURE_DEPTH of the texture image being modified.");
	}

	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if
	 the read buffer is NONE. */
	gl.readBuffer(GL_NONE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	{
		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D", "the read buffer is NONE.");
	}

	/* Bind multisample framebuffer. */
	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	gl.readBuffer(GL_COLOR_ATTACHMENT0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");

	/* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if
	 the effective value of SAMPLE_BUFFERS for the read
	 framebuffer is one. */
	{
		gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D",
								  "the effective value of SAMPLE_BUFFERS for the read framebuffer is one.");
	}

	return is_ok;
}

/** @brief Clean GL objects, test variables and GL errors.
 */
void CopyErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Cleanup. */
	if (m_fbo)
	{
		gl.deleteFramebuffers(1, &m_fbo);

		m_fbo = 0;
	}

	if (m_fbo_ms)
	{
		gl.deleteFramebuffers(1, &m_fbo_ms);

		m_fbo_ms = 0;
	}

	if (m_fbo_incomplete)
	{
		gl.deleteFramebuffers(1, &m_fbo_incomplete);

		m_fbo_incomplete = 0;
	}

	if (m_to_src)
	{
		gl.deleteTextures(1, &m_to_src);

		m_to_src = 0;
	}

	if (m_to_src_ms)
	{
		gl.deleteTextures(1, &m_to_src_ms);

		m_to_src_ms = 0;
	}

	if (m_to_1D_dst)
	{
		gl.deleteTextures(1, &m_to_1D_dst);

		m_to_1D_dst = 0;
	}

	if (m_to_2D_dst)
	{
		gl.deleteTextures(1, &m_to_2D_dst);

		m_to_2D_dst = 0;
	}

	if (m_to_3D_dst)
	{
		gl.deleteTextures(1, &m_to_3D_dst);

		m_to_3D_dst = 0;
	}

	m_to_invalid = 0;

	while (GL_NO_ERROR != gl.getError())
		;
}

/* Test's parameters. */
const glw::GLuint CopyErrorsTest::s_width		   = 4;
const glw::GLuint CopyErrorsTest::s_height		   = 4;
const glw::GLuint CopyErrorsTest::s_depth		   = 4;
const glw::GLuint CopyErrorsTest::s_internalformat = GL_RGBA8;

/******************************** Parameter Setup Errors Test Implementation   ********************************/

/** @brief Parameter Setup Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ParameterSetupErrorsTest::ParameterSetupErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_parameter_setup_errors", "Texture Parameter Setup Errors Test")
	, m_to_2D(0)
	, m_to_2D_ms(0)
	, m_to_rectangle(0)
	, m_to_invalid(0)
	, m_pname_invalid(0)
	, m_depth_stencil_mode_invalid(0)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Parameter Setup Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ParameterSetupErrorsTest::iterate()
{
	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	try
	{
		Prepare();

		is_ok &= Testf();
		is_ok &= Testi();
		is_ok &= Testfv();
		is_ok &= Testiv();
		is_ok &= TestIiv();
		is_ok &= TestIuiv();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	Clean();

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** @brief Test's preparations.
 */
void ParameterSetupErrorsTest::Prepare()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Auxiliary objects setup. */

	/* 2D */
	gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* 3D */
	gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* RECTANGLE */
	gl.createTextures(GL_TEXTURE_RECTANGLE, 1, &m_to_rectangle);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed");

	/* Invalid texture object. */
	while (gl.isTexture(++m_to_invalid))
		;
	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed");

	/* Invalid parameter name. */
	glw::GLenum all_pnames[] = { GL_DEPTH_STENCIL_TEXTURE_MODE,
								 GL_TEXTURE_BASE_LEVEL,
								 GL_TEXTURE_COMPARE_FUNC,
								 GL_TEXTURE_COMPARE_MODE,
								 GL_TEXTURE_LOD_BIAS,
								 GL_TEXTURE_MIN_FILTER,
								 GL_TEXTURE_MAG_FILTER,
								 GL_TEXTURE_MIN_LOD,
								 GL_TEXTURE_MAX_LOD,
								 GL_TEXTURE_MAX_LEVEL,
								 GL_TEXTURE_SWIZZLE_R,
								 GL_TEXTURE_SWIZZLE_G,
								 GL_TEXTURE_SWIZZLE_B,
								 GL_TEXTURE_SWIZZLE_A,
								 GL_TEXTURE_WRAP_S,
								 GL_TEXTURE_WRAP_T,
								 GL_TEXTURE_WRAP_R,
								 GL_TEXTURE_BORDER_COLOR,
								 GL_TEXTURE_SWIZZLE_RGBA };
	glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]);

	bool is_valid = true;

	while (is_valid)
	{
		is_valid = false;
		++m_pname_invalid;

		for (glw::GLuint i = 0; i < all_pnames_count; ++i)
		{
			if (all_pnames[i] == m_pname_invalid)
			{
				is_valid = true;

				break;
			}
		}
	}

	/* Invalid depth stencil mode name. */
	glw::GLenum all_depth_stencil_modes[]	 = { GL_DEPTH_COMPONENT, GL_STENCIL_INDEX };
	glw::GLuint all_depth_stencil_modes_count = sizeof(all_depth_stencil_modes) / sizeof(all_depth_stencil_modes[0]);

	is_valid = true;

	while (is_valid)
	{
		is_valid = false;
		++m_depth_stencil_mode_invalid;

		for (glw::GLuint i = 0; i < all_depth_stencil_modes_count; ++i)
		{
			if (all_depth_stencil_modes[i] == m_depth_stencil_mode_invalid)
			{
				is_valid = true;

				break;
			}
		}
	}
}

/** @brief Test (negative) of TextureParameterf
 *
 *  @return Test result.
 */
bool ParameterSetupErrorsTest::Testf()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
	 not one of the accepted defined values. */
	{
		gl.textureParameterf(m_to_2D, m_pname_invalid, 1.f);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
								  "pname is not one of the accepted defined values.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if params
	 should have a defined constant value (based on the value of pname) and
	 does not. */
	{
		gl.textureParameterf(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, (glw::GLfloat)m_depth_stencil_mode_invalid);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
							 "params should have a defined constant value (based on the value of pname) and does not.");
	}
	/* Check that INVALID_ENUM is generated if TextureParameter{if} is called
	 for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or
	 TEXTURE_SWIZZLE_RGBA). */
	{
		gl.textureParameterf(m_to_2D, GL_TEXTURE_BORDER_COLOR, 1.f);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
							 "called for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or TEXTURE_SWIZZLE_RGBA).");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
	{
		gl.textureParameterf(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, 1.f);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and either of pnames
	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
	 MIRRORED_REPEAT or REPEAT. */
	{
		gl.textureParameterf(m_to_rectangle, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
	 permitted). */
	{
		gl.textureParameterf(m_to_rectangle, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
	 value other than zero. */
	{
		gl.textureParameterf(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, 1.f);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if
	 texture is not the name of an existing texture object. */
	{
		gl.textureParameterf(m_to_invalid, GL_TEXTURE_LOD_BIAS, 1.f);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
								  "texture is not the name of an existing texture object.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
	 set to any value other than zero. */
	{
		gl.textureParameterf(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, 1.f);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
								  "any value other than zero. ");
	}

	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
	 negative. */
	{
		gl.textureParameterf(m_to_2D, GL_TEXTURE_BASE_LEVEL, -1.f);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterf",
								  "pname is TEXTURE_BASE_LEVEL and param is negative.");

		gl.textureParameterf(m_to_2D, GL_TEXTURE_MAX_LEVEL, -1.f);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterf",
								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
	}

	return is_ok;
}

/** @brief Test (negative) of TextureParameteri
 *
 *  @return Test result.
 */
bool ParameterSetupErrorsTest::Testi()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
	 not one of the accepted defined values. */
	{
		gl.textureParameteri(m_to_2D, m_pname_invalid, 1);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
								  "pname is not one of the accepted defined values.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if params
	 should have a defined constant value (based on the value of pname) and
	 does not. */
	{
		gl.textureParameteri(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, m_depth_stencil_mode_invalid);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
							 "params should have a defined constant value (based on the value of pname) and does not.");
	}
	/* Check that INVALID_ENUM is generated if TextureParameter{if} is called
	 for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or
	 TEXTURE_SWIZZLE_RGBA). */
	{
		gl.textureParameteri(m_to_2D, GL_TEXTURE_BORDER_COLOR, 1);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
							 "called for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or TEXTURE_SWIZZLE_RGBA).");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
	{
		gl.textureParameteri(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, 1);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and either of pnames
	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
	 MIRRORED_REPEAT or REPEAT. */
	{
		gl.textureParameteri(m_to_rectangle, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
	 permitted). */
	{
		gl.textureParameteri(m_to_rectangle, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
	 value other than zero. */
	{
		gl.textureParameteri(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, 1);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if
	 texture is not the name of an existing texture object. */
	{
		gl.textureParameteri(m_to_invalid, GL_TEXTURE_LOD_BIAS, 1);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
								  "texture is not the name of an existing texture object.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
	 set to any value other than zero. */
	{
		gl.textureParameteri(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, 1);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
								  "any value other than zero. ");
	}

	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
	 negative. */
	{
		gl.textureParameteri(m_to_2D, GL_TEXTURE_BASE_LEVEL, -1);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteri",
								  "pname is TEXTURE_BASE_LEVEL and param is negative.");

		gl.textureParameteri(m_to_2D, GL_TEXTURE_MAX_LEVEL, -1);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteri",
								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
	}

	return is_ok;
}

/** @brief Test (negative) of TextureParameterfv
 *
 *  @return Test result.
 */
bool ParameterSetupErrorsTest::Testfv()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	glw::GLfloat one						= 1.f;
	glw::GLfloat minus_one					= -1.f;
	glw::GLfloat depth_stencil_mode_invalid = (glw::GLfloat)m_depth_stencil_mode_invalid;
	glw::GLfloat wrap_invalid				= (glw::GLfloat)GL_MIRROR_CLAMP_TO_EDGE;
	glw::GLfloat min_filter_invalid			= (glw::GLfloat)GL_NEAREST_MIPMAP_NEAREST;

	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
	 not one of the accepted defined values. */
	{
		gl.textureParameterfv(m_to_2D, m_pname_invalid, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
								  "pname is not one of the accepted defined values.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if params
	 should have a defined constant value (based on the value of pname) and
	 does not. */
	{
		gl.textureParameterfv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
							 "params should have a defined constant value (based on the value of pname) and does not.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
	{
		gl.textureParameterfv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and either of pnames
	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
	 MIRRORED_REPEAT or REPEAT. */
	{
		gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
	 permitted). */
	{
		gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
	 value other than zero. */
	{
		gl.textureParameterfv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if
	 texture is not the name of an existing texture object. */
	{
		gl.textureParameterfv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
								  "texture is not the name of an existing texture object.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
	 set to any value other than zero. */
	{
		gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
								  "any value other than zero. ");
	}

	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
	 negative. */
	{
		gl.textureParameterfv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterfv",
								  "pname is TEXTURE_BASE_LEVEL and param is negative.");

		gl.textureParameterfv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterfv",
								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
	}

	return is_ok;
}

/** @brief Test (negative) of TextureParameteriv
 *
 *  @return Test result.
 */
bool ParameterSetupErrorsTest::Testiv()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	glw::GLint one						  = 1;
	glw::GLint minus_one				  = -1;
	glw::GLint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid;
	glw::GLint wrap_invalid				  = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE;
	glw::GLint min_filter_invalid		  = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST;

	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
	 not one of the accepted defined values. */
	{
		gl.textureParameteriv(m_to_2D, m_pname_invalid, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
								  "pname is not one of the accepted defined values.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if params
	 should have a defined constant value (based on the value of pname) and
	 does not. */
	{
		gl.textureParameteriv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
							 "params should have a defined constant value (based on the value of pname) and does not.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
	{
		gl.textureParameteriv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and either of pnames
	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
	 MIRRORED_REPEAT or REPEAT. */
	{
		gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
	 permitted). */
	{
		gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
	 value other than zero. */
	{
		gl.textureParameteriv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if
	 texture is not the name of an existing texture object. */
	{
		gl.textureParameteriv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
								  "texture is not the name of an existing texture object.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
	 set to any value other than zero. */
	{
		gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
								  "any value other than zero. ");
	}

	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
	 negative. */
	{
		gl.textureParameteriv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteriv",
								  "pname is TEXTURE_BASE_LEVEL and param is negative.");

		gl.textureParameteriv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteriv",
								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
	}

	return is_ok;
}

/** @brief Test (negative) of TextureParameterIiv
 *
 *  @return Test result.
 */
bool ParameterSetupErrorsTest::TestIiv()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	glw::GLint one						  = 1;
	glw::GLint minus_one				  = -1;
	glw::GLint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid;
	glw::GLint wrap_invalid				  = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE;
	glw::GLint min_filter_invalid		  = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST;

	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
	 not one of the accepted defined values. */
	{
		gl.textureParameterIiv(m_to_2D, m_pname_invalid, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
								  "pname is not one of the accepted defined values.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if params
	 should have a defined constant value (based on the value of pname) and
	 does not. */
	{
		gl.textureParameterIiv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
							 "params should have a defined constant value (based on the value of pname) and does not.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
	{
		gl.textureParameterIiv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and either of pnames
	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
	 MIRRORED_REPEAT or REPEAT. */
	{
		gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
	 permitted). */
	{
		gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
	 value other than zero. */
	{
		gl.textureParameterIiv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if
	 texture is not the name of an existing texture object. */
	{
		gl.textureParameterIiv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
								  "texture is not the name of an existing texture object.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
	 set to any value other than zero. */
	{
		gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
								  "any value other than zero. ");
	}

	/* Check that INVALID_VALUE is generated by TextureParameter* if pname is
	 TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is
	 negative. */
	{
		gl.textureParameterIiv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterIiv",
								  "pname is TEXTURE_BASE_LEVEL and param is negative.");

		gl.textureParameterIiv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterIiv",
								  "pname is TEXTURE_MAX_LEVEL and param is negative.");
	}

	return is_ok;
}

/** @brief Test (negative) of TextureParameterIuiv
 *
 *  @return Test result.
 */
bool ParameterSetupErrorsTest::TestIuiv()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Result. */
	bool is_ok = true;

	glw::GLuint one						   = 1;
	glw::GLuint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid;
	glw::GLuint wrap_invalid			   = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE;
	glw::GLuint min_filter_invalid		   = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST;

	/* Check that INVALID_ENUM is generated by TextureParameter* if pname is
	 not one of the accepted defined values. */
	{
		gl.textureParameterIuiv(m_to_2D, m_pname_invalid, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
								  "pname is not one of the accepted defined values.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if params
	 should have a defined constant value (based on the value of pname) and
	 does not. */
	{
		gl.textureParameterIuiv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
							 "params should have a defined constant value (based on the value of pname) and does not.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */
	{
		gl.textureParameterIuiv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
								  "the  effective target is either TEXTURE_2D_MULTISAMPLE or  "
								  "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and either of pnames
	 TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE,
	 MIRRORED_REPEAT or REPEAT. */
	{
		gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
								  "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or "
								  "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT.");
	}

	/* Check that INVALID_ENUM is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is
	 set to a value other than NEAREST or LINEAR (no mipmap filtering is
	 permitted). */
	{
		gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a "
								  "value other than NEAREST or LINEAR (no mipmap filtering is permitted).");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is either TEXTURE_2D_MULTISAMPLE or
	 TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a
	 value other than zero. */
	{
		gl.textureParameterIuiv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one);

		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
							 "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, "
							 "and pname TEXTURE_BASE_LEVEL is set to a value other than zero.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if
	 texture is not the name of an existing texture object. */
	{
		gl.textureParameterIuiv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
								  "texture is not the name of an existing texture object.");
	}

	/* Check that INVALID_OPERATION is generated by TextureParameter* if the
	 effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is
	 set to any value other than zero. */
	{
		gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one);

		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv",
								  "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to "
								  "any value other than zero. ");
	}

	return is_ok;
}

/** @brief Clean GL objects, test variables and GL errors.
 */
void ParameterSetupErrorsTest::Clean()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Cleanup. */
	if (m_to_2D)
	{
		gl.deleteTextures(1, &m_to_2D);

		m_to_2D = 0;
	}

	if (m_to_2D_ms)
	{
		gl.deleteTextures(1, &m_to_2D_ms);

		m_to_2D_ms = 0;
	}

	if (m_to_rectangle)
	{
		gl.deleteTextures(1, &m_to_rectangle);

		m_to_rectangle = 0;
	}

	if (m_to_invalid)
	{
		gl.deleteTextures(1, &m_to_invalid);

		m_to_invalid = 0;
	}

	m_to_invalid	= 0;
	m_pname_invalid = 0;

	while (GL_NO_ERROR != gl.getError())
		;
}

/******************************** Generate Mipmap Errors Test Implementation   ********************************/

/** @brief Generate Mipmap Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
GenerateMipmapErrorsTest::GenerateMipmapErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_generate_mipmap_errors", "Texture Generate Mipmap Errors Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Generate Mipmap Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult GenerateMipmapErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Objects. */
	glw::GLuint texture_invalid = 0;
	glw::GLuint texture_cube	= 0;

	try
	{
		/* Preparations. */

		/* incomplete cube map */
		gl.genTextures(1, &texture_cube);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture_cube);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, s_reference_internalformat, s_reference_width,
					  s_reference_height, 0, s_reference_format, s_reference_type, s_reference_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

		/* invalid texture */
		while (gl.isTexture(++texture_invalid))
			;

		/* Check that INVALID_OPERATION is generated by GenerateTextureMipmap if
		 texture is not the name of an existing texture object. */
		gl.generateTextureMipmap(texture_invalid);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGenerateTextureMipmap",
								  "texture is not the name of an existing texture object.");

		/* Check that INVALID_OPERATION is generated by GenerateTextureMipmap if
		 target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and the specified
		 texture object is not cube complete or cube array complete,
		 respectively. */
		gl.generateTextureMipmap(texture_cube);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGenerateTextureMipmap",
								  "target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and the specified texture "
								  "object is not cube complete or cube array complete, respectively.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture_cube)
	{
		gl.deleteTextures(1, &texture_cube);
	}

	while (GL_NO_ERROR != gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/** Reference data. */
const glw::GLubyte GenerateMipmapErrorsTest::s_reference_data[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
																	0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };

/** Reference data parameters. */
const glw::GLuint GenerateMipmapErrorsTest::s_reference_width		   = 4;
const glw::GLuint GenerateMipmapErrorsTest::s_reference_height		   = 4;
const glw::GLenum GenerateMipmapErrorsTest::s_reference_internalformat = GL_R8;
const glw::GLenum GenerateMipmapErrorsTest::s_reference_format		   = GL_RED;
const glw::GLenum GenerateMipmapErrorsTest::s_reference_type		   = GL_UNSIGNED_BYTE;

/******************************** Bind Unit Errors Test Implementation   ********************************/

/** @brief Bind Unit Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
BindUnitErrorsTest::BindUnitErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_bind_unit_errors", "Texture Bind Unit Errors Test")
{
	/* Intentionally left blank. */
}

/** @brief IterateBind Unit Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult BindUnitErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Objects. */
	glw::GLuint texture_invalid = 0;

	try
	{
		/* Prepare invalid texture */
		while (gl.isTexture(++texture_invalid))
			;

		/* incomplete cube map */

		/* Check that INVALID_OPERATION error is generated if texture is not zero
		 or the name of an existing texture object. */
		gl.bindTextureUnit(0, texture_invalid);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glBindTextureUnit",
								  "texture is not zero or the name of an existing texture object.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	while (GL_NO_ERROR != gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Image Query Errors Test Implementation   ********************************/

/** @brief Image Query Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ImageQueryErrorsTest::ImageQueryErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_image_query_errors", "Texture Image Query Errors Test")
{
	/* Intentionally left blank. */
}

/** Reference data. */
const glw::GLuint ImageQueryErrorsTest::s_reference_data[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
															   0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };

/** Reference data parameters. */
const glw::GLuint ImageQueryErrorsTest::s_reference_width					  = 4;
const glw::GLuint ImageQueryErrorsTest::s_reference_height					  = 4;
const glw::GLuint ImageQueryErrorsTest::s_reference_size					  = sizeof(s_reference_data);
const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat			  = GL_R8;
const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat_int		  = GL_R8I;
const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat_compressed = GL_COMPRESSED_RED_RGTC1;
const glw::GLenum ImageQueryErrorsTest::s_reference_format					  = GL_RED;
const glw::GLenum ImageQueryErrorsTest::s_reference_type					  = GL_UNSIGNED_INT;

/** @brief Iterate Image Query Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ImageQueryErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Objects. */
	glw::GLuint buffer										  = 0;
	glw::GLuint texture_invalid								  = 0;
	glw::GLuint texture_2D									  = 0;
	glw::GLuint texture_2D_int								  = 0;
	glw::GLuint texture_2D_ms								  = 0;
	glw::GLuint texture_2D_stencil							  = 0;
	glw::GLuint texture_2D_compressed						  = 0;
	glw::GLuint texture_cube								  = 0;
	glw::GLuint texture_rectangle							  = 0;
	glw::GLint  max_level									  = 0;
	char		store[s_reference_size * 6 /* for cubemap */] = {};

	try
	{
		/* Preparations. */

		/* Buffer. */
		gl.createBuffers(1, &buffer);

		gl.namedBufferData(buffer, s_reference_size + 1, NULL, GL_STATIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed");

		/* 2D texture */
		gl.genTextures(1, &texture_2D);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_2D, texture_2D);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
					  s_reference_format, s_reference_type, s_reference_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

		/* 2D texture */
		gl.genTextures(1, &texture_2D);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_2D, texture_2D);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
					  s_reference_format, s_reference_type, s_reference_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

		/* incomplete cube map */
		gl.genTextures(1, &texture_cube);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture_cube);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, s_reference_internalformat, s_reference_width,
					  s_reference_height, 0, s_reference_format, s_reference_type, s_reference_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

		/* 2D multisample */
		gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &texture_2D_ms);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.textureStorage2DMultisample(texture_2D_ms, 1, s_reference_internalformat, s_reference_width,
									   s_reference_height, false);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");

		/* 2D stencil */
		gl.createTextures(GL_TEXTURE_2D, 1, &texture_2D_stencil);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.textureStorage2D(texture_2D_stencil, 1, GL_STENCIL_INDEX8, s_reference_width, s_reference_height);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed");

		/* 2D compressed texture  */
		gl.genTextures(1, &texture_2D_compressed);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_2D, texture_2D_compressed);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, 0,
					  s_reference_format, s_reference_type, s_reference_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_level); /* assuming that x > log(x) */
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

		/* Rectangle texture */
		gl.genTextures(1, &texture_rectangle);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_RECTANGLE, texture_rectangle);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texImage2D(GL_TEXTURE_RECTANGLE, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0,
					  s_reference_format, s_reference_type, s_reference_data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

		/* invalid texture */
		while (gl.isTexture(++texture_invalid))
			;

		/* Tests. */

		/* Check that INVALID_OPERATION is generated by GetTextureImage functions if
		 resulting texture target is not an accepted value TEXTURE_1D,
		 TEXTURE_2D, TEXTURE_3D, TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY,
		 TEXTURE_CUBE_MAP_ARRAY, TEXTURE_RECTANGLE, and TEXTURE_CUBE_MAP. */
		gl.getTextureImage(texture_2D_ms, 0, s_reference_format, s_reference_type, s_reference_size, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
								  "resulting texture target is not an accepted value TEXTURE_1D, TEXTURE_2D, "
								  "TEXTURE_3D, TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, "
								  "TEXTURE_RECTANGLE, and TEXTURE_CUBE_MAP.");

		/* Check that INVALID_OPERATION is generated by GetTextureImage
		 if texture is not the name of an existing texture object. */
		gl.getTextureImage(texture_invalid, 0, s_reference_format, s_reference_type, s_reference_size, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
								  "texture is not the name of an existing texture object.");

		/* Check that INVALID_OPERATION error is generated by GetTextureImage if
		 the effective target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and
		 the texture object is not cube complete or cube array complete,
		 respectively. */
		gl.getTextureImage(texture_cube, 0, s_reference_format, s_reference_type, s_reference_size * 6, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
								  "the effective target is TEXTURE_CUBE_MAP and the texture object is not cube "
								  "complete or cube array complete, respectively.");

		/* Check that GL_INVALID_VALUE is generated if level is less than 0 or
		 larger than the maximum allowable level. */
		gl.getTextureImage(texture_2D, -1, s_reference_format, s_reference_type, s_reference_size, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage", "level is less than 0.");

		gl.getTextureImage(texture_2D, max_level, s_reference_format, s_reference_type, s_reference_size, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage",
								  "level is larger than the maximum allowable level.");

		/* Check that INVALID_VALUE error is generated if level is non-zero and the
		 effective target is TEXTURE_RECTANGLE. */
		gl.getTextureImage(texture_rectangle, 1, s_reference_format, s_reference_type, s_reference_size, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage",
								  "level is non-zero and the effective target is TEXTURE_RECTANGLE.");

		/* Check that INVALID_OPERATION error is generated if any of the following
		 mismatches between format and the internal format of the texture image
		 exist:
		 -  format is a color format (one of the formats in table 8.3 whose
		 target is the color buffer) and the base internal format of the
		 texture image is not a color format.
		 -  format is DEPTH_COMPONENT and the base internal format is  not
		 DEPTH_COMPONENT or DEPTH_STENCIL
		 -  format is DEPTH_STENCIL and the base internal format is not
		 DEPTH_STENCIL
		 -  format is STENCIL_INDEX and the base internal format is not
		 STENCIL_INDEX or DEPTH_STENCIL
		 -  format is one of the integer formats in table 8.3 and the internal
		 format of the texture image is not integer, or format is not one of
		 the integer formats in table 8.3 and the internal format is integer. */
		gl.getTextureImage(texture_2D_stencil, 0, s_reference_format /* red */, s_reference_type, s_reference_size,
						   store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
								  "format is a color format (one of the formats in table 8.3 whose target is the color "
								  "buffer) and the base internal format of the texture image is not a color format.");

		gl.getTextureImage(texture_2D, 0, GL_DEPTH_COMPONENT, s_reference_type, s_reference_size, store);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_OPERATION, "glGetTextureImage",
			"format is DEPTH_COMPONENT and the base internal format is not DEPTH_COMPONENT or DEPTH_STENCIL.");

		gl.getTextureImage(texture_2D, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, s_reference_size, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
								  "format is DEPTH_STENCIL and the base internal format is not DEPTH_STENCIL.");

		gl.getTextureImage(texture_2D, 0, GL_STENCIL_INDEX, s_reference_type, s_reference_size, store);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_OPERATION, "glGetTextureImage",
			"format is STENCIL_INDEX and the base internal format is not STENCIL_INDEX or DEPTH_STENCIL.");

		gl.getTextureImage(texture_2D, 0, GL_RED_INTEGER, s_reference_type, s_reference_size, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
								  "format is one of the integer formats in table 8.3 and the internal format of the "
								  "texture image is not integer.");

		gl.getTextureImage(texture_2D_int, 0, GL_RED, s_reference_type, s_reference_size, store);
		is_ok &= CheckErrorAndLog(
			m_context, GL_INVALID_OPERATION, "glGetTextureImage",
			"format is not one of the integer formats in table 8.3 and the internal format is integer.");

		/* Check that INVALID_OPERATION error is generated if a pixel pack buffer
		 object is bound and packing the texture image into the buffer's memory
		 would exceed the size of the buffer. */
		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type, s_reference_size,
						   glu::BufferOffsetAsPointer(1 * sizeof(GLuint)));
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
								  "a pixel pack buffer object is bound and packing the texture image into the buffer's "
								  "memory would exceed the size of the buffer.");

		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		/* Check that INVALID_OPERATION error is generated if a pixel pack buffer
		 object is bound and pixels is not evenly divisible by the number of
		 basic machine units needed to store in memory the GL data type
		 corresponding to type (see table 8.2). */
		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type, s_reference_size,
						   glu::BufferOffsetAsPointer(1));
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
								  "a pixel pack buffer object is bound and pixels is not evenly divisible by the "
								  "number of basic machine units needed to store in memory the GL data type "
								  "corresponding to type (see table 8.2).");

		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		/* Check that INVALID_OPERATION error is generated by GetTextureImage if
		 the buffer size required to store the requested data is greater than
		 bufSize. */
		gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type,
						   s_reference_size - sizeof(s_reference_data[0]), store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage",
								  "the buffer size required to store the requested data is greater than bufSize.");

		/* Check that INVALID_OPERATION is generated by GetCompressedTextureImage
		 if texture is not the name of an existing texture object. */
		gl.getCompressedTextureImage(texture_invalid, 0, s_reference_size, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
								  "texture is not the name of an existing texture object.");

		/* Check that INVALID_VALUE is generated by GetCompressedTextureImage if
		 level is less than zero or greater than the maximum number of LODs
		 permitted by the implementation. */
		gl.getCompressedTextureImage(texture_2D_compressed, -1, s_reference_size, store);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetCompressedTextureImage", "level is less than zero.");

		gl.getCompressedTextureImage(texture_2D_compressed, max_level, s_reference_size, store);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetCompressedTextureImage",
								  "level is greater than the maximum number of LODs permitted by the implementation.");

		/* Check that INVALID_OPERATION is generated if GetCompressedTextureImage
		 is used to retrieve a texture that is in an uncompressed internal
		 format. */
		gl.getCompressedTextureImage(texture_2D, 0, s_reference_size, store);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
							 "the function is used to retrieve a texture that is in an uncompressed internal format.");

		/* Check that INVALID_OPERATION is generated by GetCompressedTextureImage
		 if a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER
		 target, the buffer storage was not initialized with BufferStorage using
		 MAP_PERSISTENT_BIT flag, and the buffer object's data store is currently
		 mapped. */
		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.mapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE);

		if (GL_NO_ERROR == gl.getError())
		{
			gl.getCompressedTextureImage(texture_2D_compressed, 0, s_reference_size, NULL);
			is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
									  "a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER target, the "
									  "buffer storage was not initialized with BufferStorage using MAP_PERSISTENT_BIT "
									  "flag, and the buffer object's data store is currently mapped.");

			gl.unmapBuffer(GL_PIXEL_PACK_BUFFER);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer has failed");
		}
		else
		{
			throw 0;
		}

		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		/* Check that INVALID_OPERATION is generated by GetCompressedTextureImage
		 if a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER
		 target and the data would be packed to the buffer object such that the
		 memory writes required would exceed the data store size. */
		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");

		gl.getCompressedTextureImage(texture_2D_compressed, 0, s_reference_size, glu::BufferOffsetAsPointer(s_reference_size - 1));
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage",
								  "a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER target and the data "
								  "would be packed to the buffer object such that the memory writes required would "
								  "exceed the data store size.");

		gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);
	}

	if (texture_2D)
	{
		gl.deleteTextures(1, &texture_2D);
	}

	if (texture_2D_int)
	{
		gl.deleteTextures(1, &texture_2D_int);
	}

	if (texture_2D_stencil)
	{
		gl.deleteTextures(1, &texture_2D_stencil);
	}

	if (texture_2D_ms)
	{
		gl.deleteTextures(1, &texture_2D_ms);
	}

	if (texture_2D_compressed)
	{
		gl.deleteTextures(1, &texture_2D_compressed);
	}

	if (texture_cube)
	{
		gl.deleteTextures(1, &texture_cube);
	}

	if (texture_rectangle)
	{
		gl.deleteTextures(1, &texture_rectangle);
	}

	while (GL_NO_ERROR != gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Level Parameter Query Errors Test Implementation   ********************************/

/** @brief Image Query Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
LevelParameterErrorsTest::LevelParameterErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_level_parameter_errors", "Texture Level Parameter Query Errors Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Level Parameter Query Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult LevelParameterErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Objects. */
	glw::GLuint texture_2D		= 0;
	glw::GLuint texture_invalid = 0;
	glw::GLint  max_level		= 0;
	glw::GLenum pname_invalid   = 0;

	glw::GLfloat storef[4] = {};
	glw::GLint   storei[4] = {};

	try
	{
		/* Preparations. */

		/* 2D texture */
		gl.genTextures(1, &texture_2D);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		gl.bindTexture(GL_TEXTURE_2D, texture_2D);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");

		gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8, 1, 1);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed");

		/* Limits. */
		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_level); /* assuming that x > log(x) */
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");

		/* invalid texture */
		while (gl.isTexture(++texture_invalid))
			;

		/* invalid pname */
		glw::GLenum all_pnames[] = { GL_TEXTURE_WIDTH,
									 GL_TEXTURE_HEIGHT,
									 GL_TEXTURE_DEPTH,
									 GL_TEXTURE_SAMPLES,
									 GL_TEXTURE_FIXED_SAMPLE_LOCATIONS,
									 GL_TEXTURE_INTERNAL_FORMAT,
									 GL_TEXTURE_RED_SIZE,
									 GL_TEXTURE_GREEN_SIZE,
									 GL_TEXTURE_BLUE_SIZE,
									 GL_TEXTURE_ALPHA_SIZE,
									 GL_TEXTURE_DEPTH_SIZE,
									 GL_TEXTURE_STENCIL_SIZE,
									 GL_TEXTURE_SHARED_SIZE,
									 GL_TEXTURE_RED_TYPE,
									 GL_TEXTURE_GREEN_TYPE,
									 GL_TEXTURE_BLUE_TYPE,
									 GL_TEXTURE_ALPHA_TYPE,
									 GL_TEXTURE_DEPTH_TYPE,
									 GL_TEXTURE_COMPRESSED,
									 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
									 GL_TEXTURE_BUFFER_DATA_STORE_BINDING,
									 GL_TEXTURE_BUFFER_OFFSET,
									 GL_TEXTURE_BUFFER_SIZE };

		glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]);

		bool is_valid = true;

		while (is_valid)
		{
			is_valid = false;

			++pname_invalid;

			for (glw::GLuint i = 0; i < all_pnames_count; ++i)
			{
				if (all_pnames[i] == pname_invalid)
				{
					is_valid = true;

					break;
				}
			}
		}

		/* Tests. */

		/* Check that INVALID_OPERATION is generated by GetTextureLevelParameterfv
		 and GetTextureLevelParameteriv functions if texture is not the name of
		 an existing texture object. */
		gl.getTextureLevelParameterfv(texture_invalid, 0, GL_TEXTURE_WIDTH, storef);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameterfv",
								  "texture is not the name of an existing texture object.");

		gl.getTextureLevelParameteriv(texture_invalid, 0, GL_TEXTURE_WIDTH, storei);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameteriv",
								  "texture is not the name of an existing texture object.");

		/* Check that INVALID_VALUE is generated by GetTextureLevelParameter* if
		 level is less than 0. */
		gl.getTextureLevelParameterfv(texture_2D, -1, GL_TEXTURE_WIDTH, storef);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameterfv", "level is less than 0.");

		gl.getTextureLevelParameteriv(texture_2D, -1, GL_TEXTURE_WIDTH, storei);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameteriv", "level is less than 0.");

		/* Check that INVALID_ENUM error is generated by GetTextureLevelParameter*
		 if pname is not one of supported constants. */
		gl.getTextureLevelParameterfv(texture_2D, 0, pname_invalid, storef);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureLevelParameterfv",
								  "pname is not one of supported constants.");

		gl.getTextureLevelParameteriv(texture_2D, 0, pname_invalid, storei);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureLevelParameteriv",
								  "pname is not one of supported constants.");

		/* Check that INVALID_VALUE may be generated if level is greater than
		 log2 max, where max is the returned value of MAX_TEXTURE_SIZE. */
		gl.getTextureLevelParameterfv(texture_2D, max_level, GL_TEXTURE_WIDTH, storef);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameterfv",
							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");

		gl.getTextureLevelParameteriv(texture_2D, max_level, GL_TEXTURE_WIDTH, storei);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameteriv",
							 "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE.");

		/* Check that INVALID_OPERATION is generated by GetTextureLevelParameter*
		 if TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an
		 uncompressed internal format or on proxy targets. */
		gl.getTextureLevelParameterfv(texture_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, storef);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameterfv",
								  "TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an uncompressed "
								  "internal format or on proxy targets.");

		gl.getTextureLevelParameteriv(texture_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, storei);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameteriv",
								  "TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an uncompressed "
								  "internal format or on proxy targets.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture_2D)
	{
		gl.deleteTextures(1, &texture_2D);
	}

	while (GL_NO_ERROR != gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

/******************************** Parameter Query Errors Test Implementation   ********************************/

/** @brief Parameter Query Errors Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ParameterErrorsTest::ParameterErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "textures_parameter_errors", "Texture Parameter Query Errors Test")
{
	/* Intentionally left blank. */
}

/** @brief Iterate Parameter Query Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ParameterErrorsTest::iterate()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Get context setup. */
	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");

	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");

		return STOP;
	}

	/* Running tests. */
	bool is_ok	= true;
	bool is_error = false;

	/* Objects. */
	glw::GLuint texture_2D		= 0;
	glw::GLuint texture_buffer  = 0;
	glw::GLuint texture_invalid = 0;
	glw::GLenum pname_invalid   = 0;

	glw::GLfloat storef[4] = {};
	glw::GLint   storei[4] = {};
	glw::GLuint  storeu[4] = {};

	try
	{
		/* Preparations. */

		/* 2D texture */
		gl.createTextures(GL_TEXTURE_2D, 1, &texture_2D);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		/* Buffer texture */
		gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");

		/* invalid texture */
		while (gl.isTexture(++texture_invalid))
			;

		/* invalid pname */
		glw::GLenum all_pnames[] = { GL_IMAGE_FORMAT_COMPATIBILITY_TYPE,
									 GL_TEXTURE_IMMUTABLE_FORMAT,
									 GL_TEXTURE_IMMUTABLE_LEVELS,
									 GL_TEXTURE_TARGET,
									 GL_TEXTURE_VIEW_MIN_LEVEL,
									 GL_TEXTURE_VIEW_NUM_LEVELS,
									 GL_TEXTURE_VIEW_MIN_LAYER,
									 GL_TEXTURE_VIEW_NUM_LAYERS,
									 GL_DEPTH_STENCIL_TEXTURE_MODE,
									 GL_DEPTH_COMPONENT,
									 GL_STENCIL_INDEX,
									 GL_TEXTURE_BASE_LEVEL,
									 GL_TEXTURE_BORDER_COLOR,
									 GL_TEXTURE_COMPARE_MODE,
									 GL_TEXTURE_COMPARE_FUNC,
									 GL_TEXTURE_LOD_BIAS,
									 GL_TEXTURE_MAG_FILTER,
									 GL_TEXTURE_MAX_LEVEL,
									 GL_TEXTURE_MAX_LOD,
									 GL_TEXTURE_MIN_FILTER,
									 GL_TEXTURE_MIN_LOD,
									 GL_TEXTURE_SWIZZLE_R,
									 GL_TEXTURE_SWIZZLE_G,
									 GL_TEXTURE_SWIZZLE_B,
									 GL_TEXTURE_SWIZZLE_A,
									 GL_TEXTURE_SWIZZLE_RGBA,
									 GL_TEXTURE_WRAP_S,
									 GL_TEXTURE_WRAP_T,
									 GL_TEXTURE_WRAP_R };

		glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]);

		bool is_valid = true;

		while (is_valid)
		{
			is_valid = false;

			++pname_invalid;

			for (glw::GLuint i = 0; i < all_pnames_count; ++i)
			{
				if (all_pnames[i] == pname_invalid)
				{
					is_valid = true;

					break;
				}
			}
		}

		/* Tests. */

		/* Check that INVALID_ENUM is generated by glGetTextureParameter* if pname
		 is not an accepted value. */
		gl.getTextureParameterfv(texture_2D, pname_invalid, storef);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterfv", "pname is not an accepted value.");

		gl.getTextureParameterIiv(texture_2D, pname_invalid, storei);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterIiv", "pname is not an accepted value.");

		gl.getTextureParameterIuiv(texture_2D, pname_invalid, storeu);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterIuiv",
								  "pname is not an accepted value.");

		gl.getTextureParameteriv(texture_2D, pname_invalid, storei);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameteriv", "pname is not an accepted value.");

		/* Check that INVALID_OPERATION is generated by glGetTextureParameter* if
		 texture is not the name of an existing texture object. */
		gl.getTextureParameterfv(texture_invalid, GL_TEXTURE_TARGET, storef);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterfv",
								  "texture is not the name of an existing texture object.");

		gl.getTextureParameterIiv(texture_invalid, GL_TEXTURE_TARGET, storei);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIiv",
								  "texture is not the name of an existing texture object.");

		gl.getTextureParameterIuiv(texture_invalid, GL_TEXTURE_TARGET, storeu);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIuiv",
								  "texture is not the name of an existing texture object.");

		gl.getTextureParameteriv(texture_invalid, GL_TEXTURE_TARGET, storei);
		is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameteriv",
								  "texture is not the name of an existing texture object.");

		/* Check that INVALID_OPERATION error is generated if the effective target is
		 not one of the supported texture targets (eg. TEXTURE_BUFFER). */
		gl.getTextureParameterfv(texture_buffer, GL_TEXTURE_TARGET, storef);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterfv",
							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");

		gl.getTextureParameterIiv(texture_buffer, GL_TEXTURE_TARGET, storei);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIiv",
							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");

		gl.getTextureParameterIuiv(texture_buffer, GL_TEXTURE_TARGET, storeu);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIuiv",
							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");

		gl.getTextureParameteriv(texture_buffer, GL_TEXTURE_TARGET, storei);
		is_ok &=
			CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameteriv",
							 "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER).");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Cleanup. */
	if (texture_2D)
	{
		gl.deleteTextures(1, &texture_2D);
	}

	if (texture_buffer)
	{
		gl.deleteTextures(1, &texture_buffer);
	}

	while (GL_NO_ERROR != gl.getError())
		;

	/* Result's setup. */
	if (is_ok)
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		if (is_error)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
		}
		else
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		}
	}

	return STOP;
}

} /* Textures namespace. */
} /* DirectStateAccess namespace. */
} /* gl4cts namespace. */
