/*-------------------------------------------------------------------------
 * 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  gl4cDirectStateAccessBuffersTests.cpp
 * \brief Conformance tests for the Direct State Access feature functionality (Buffer access part).
 */ /*-----------------------------------------------------------------------------------------------------------*/

/* 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 Buffers
{
/******************************** Creation Test Implementation   ********************************/

/** @brief Creation Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
CreationTest::CreationTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_creation", "Buffer 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;

	/* Buffers' objects */
	static const glw::GLuint buffers_count = 2;

	glw::GLuint buffers_legacy[buffers_count] = {};
	glw::GLuint buffers_dsa[buffers_count]	= {};

	try
	{
		/* Check legacy state creation. */
		gl.genBuffers(buffers_count, buffers_legacy);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");

		for (glw::GLuint i = 0; i < buffers_count; ++i)
		{
			if (gl.isBuffer(buffers_legacy[i]))
			{
				is_ok = false;

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

		/* Check direct state creation. */
		gl.createBuffers(buffers_count, buffers_dsa);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers have failed");

		for (glw::GLuint i = 0; i < buffers_count; ++i)
		{
			if (!gl.isBuffer(buffers_dsa[i]))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog() << tcu::TestLog::Message
													<< "CreateBuffers has not created default objects."
													<< tcu::TestLog::EndMessage;
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

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

			buffers_legacy[i] = 0;
		}

		if (buffers_dsa[i])
		{
			gl.deleteBuffers(1, &buffers_dsa[i]);

			buffers_dsa[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;
}

/******************************** Data Test Implementation   ********************************/

/** @brief Data Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
DataTest::DataTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_data", "Buffer Objects Data Test")
	, m_pNamedBufferData(DE_NULL)
	, m_pNamedBufferSubData(DE_NULL)
	, m_pNamedBufferStorage(DE_NULL)
	, m_pCopyNamedBufferSubData(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Data Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult DataTest::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;

	m_pNamedBufferData		  = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
	m_pNamedBufferSubData	 = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
	m_pNamedBufferStorage	 = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
	m_pCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;

	try
	{
		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pNamedBufferSubData) ||
			(DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pCopyNamedBufferSubData))
		{
			throw 0;
		}

		/* BufferData tests */
		static const glw::GLenum hints[] = { GL_STREAM_DRAW,  GL_STREAM_READ,  GL_STREAM_COPY,
											 GL_STATIC_DRAW,  GL_STATIC_READ,  GL_STATIC_COPY,
											 GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY };
		static const glw::GLuint hints_count = sizeof(hints) / sizeof(hints[0]);

		for (glw::GLuint i = 0; i < hints_count; ++i)
		{
			is_ok &= TestCase(&DataTest::UploadUsingNamedBufferData, hints[i]);
			is_ok &= TestCase(&DataTest::UploadUsingNamedBufferSubData, hints[i]);
			is_ok &= TestCase(&DataTest::UploadUsingCopyNamedBufferSubData, hints[i]);
		}

		/* BufferStorage Tests */
		static const glw::GLenum bits[] = { GL_MAP_READ_BIT | GL_DYNAMIC_STORAGE_BIT,
											GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT,
											GL_MAP_READ_BIT | GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT,
											GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT };
		static const glw::GLuint bits_count = sizeof(bits) / sizeof(bits[0]);

		for (glw::GLuint i = 0; i < bits_count; ++i)
		{
			is_ok &= TestCase(&DataTest::UploadUsingNamedBufferStorage, bits[i]);
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* 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 Data uploading test case function.
 *
 *  @param [in] UploadDataFunction      Function pointer to the tested data uploading function.
 *  @param [in] parameter               Storage Parameter to be used with the function (function dependent).
 *
 *  @return True if test case succeeded, false otherwise.
 */
bool DataTest::TestCase(void (DataTest::*UploadDataFunction)(glw::GLuint, glw::GLenum), glw::GLenum parameter)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint buffer   = 0;
	bool		is_ok	= true;
	bool		is_error = false;

	try
	{
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		(this->*UploadDataFunction)(buffer, parameter);

		gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");

		glw::GLuint* data = (glw::GLuint*)gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer failed.");

		is_ok = compare(data, s_reference, s_reference_count);

		if (!is_ok)
		{
			LogFail(UploadDataFunction, parameter, data, s_reference, s_reference_count);
		}

		gl.unmapBuffer(GL_ARRAY_BUFFER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer failed.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;

		LogError(UploadDataFunction, parameter);
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
	}

	if (is_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief NamedBufferData data upload function.
 *
 *  @param [in] id                      Buffer id to be uploaded.
 *  @param [in] parameter               Storage Parameter to be used with the function, one of:
 *                                       -  GL_STREAM_DRAW,
 *                                       -  GL_STREAM_READ,
 *                                       -  GL_STREAM_COPY,
 *                                       -  GL_STATIC_DRAW,
 *                                       -  GL_STATIC_READ,
 *                                       -  GL_STATIC_COPY,
 *                                       -  GL_DYNAMIC_DRAW,
 *                                       -  GL_DYNAMIC_READ and
 *                                       -  GL_DYNAMIC_COPY.
 */
void DataTest::UploadUsingNamedBufferData(glw::GLuint id, glw::GLenum parameter)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	m_pNamedBufferData(id, s_reference_size, s_reference, parameter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");
}

/** @brief NamedBufferSubData data upload function.
 *
 *  @param [in] id                      Buffer id to be uploaded.
 *  @param [in] parameter               Storage parameter to be used with the NamedBufferData for
 *                                      the storage allocation (before call to NamedBufferSubData), one of:
 *                                       -  GL_STREAM_DRAW,
 *                                       -  GL_STREAM_READ,
 *                                       -  GL_STREAM_COPY,
 *                                       -  GL_STATIC_DRAW,
 *                                       -  GL_STATIC_READ,
 *                                       -  GL_STATIC_COPY,
 *                                       -  GL_DYNAMIC_DRAW,
 *                                       -  GL_DYNAMIC_READ and
 *                                       -  GL_DYNAMIC_COPY.
 */
void DataTest::UploadUsingNamedBufferSubData(glw::GLuint id, glw::GLenum parameter)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	m_pNamedBufferData(id, s_reference_size, DE_NULL, parameter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");

	m_pNamedBufferSubData(id, 0, s_reference_size, s_reference);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferSubData failed.");
}

/** @brief NamedBufferStorage data upload function.
 *
 *  @param [in] id                      Buffer id to be uploaded.
 *  @param [in] parameter               Storage Parameter to be used with the function, one of:
 *                                       - GL_MAP_READ_BIT | GL_DYNAMIC_STORAGE_BIT,
 *                                       - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
 *                                       - GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT,
 *                                       - GL_MAP_READ_BIT | GL_MAP_COHERENT_BIT,
 *                                       - GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT
 */
void DataTest::UploadUsingNamedBufferStorage(glw::GLuint id, glw::GLenum parameter)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	m_pNamedBufferStorage(id, s_reference_size, s_reference, parameter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferStorage failed.");
}

/** @brief CopyNamedBufferSubData data upload function (uses auxiliary buffer object).
 *
 *  @param [in] id                      Buffer id to be uploaded.
 *  @param [in] parameter               Storage parameter to be used with the NamedBufferData for
 *                                      the auxiliary buffer object storage allocation
 *                                      (before call to CopyNamedBufferSubData), one of:
 *                                       -  GL_STREAM_DRAW,
 *                                       -  GL_STREAM_READ,
 *                                       -  GL_STREAM_COPY,
 *                                       -  GL_STATIC_DRAW,
 *                                       -  GL_STATIC_READ,
 *                                       -  GL_STATIC_COPY,
 *                                       -  GL_DYNAMIC_DRAW,
 *                                       -  GL_DYNAMIC_READ and
 *                                       -  GL_DYNAMIC_COPY.
 */
void DataTest::UploadUsingCopyNamedBufferSubData(glw::GLuint id, glw::GLenum parameter)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	m_pNamedBufferData(id, s_reference_size, DE_NULL, parameter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");

	glw::GLuint auxiliary_buffer	   = 0;
	bool		auxiliary_buffer_is_ok = true;

	try
	{
		gl.genBuffers(1, &auxiliary_buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers failed.");

		gl.bindBuffer(GL_ARRAY_BUFFER, auxiliary_buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");

		gl.bufferData(GL_ARRAY_BUFFER, s_reference_size, s_reference, parameter);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData failed.");

		m_pCopyNamedBufferSubData(auxiliary_buffer, id, 0, 0, s_reference_size);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyNamedBufferSubData failed.");
	}
	catch (...)
	{
		auxiliary_buffer_is_ok = false;
	}

	if (auxiliary_buffer)
	{
		gl.deleteBuffers(1, &auxiliary_buffer);
	}

	if (!auxiliary_buffer_is_ok)
	{
		throw 0;
	}
}

/** @brief Compare two unsigned integer arrays.
 *
 *  @param [in] data                    Data to be compared.
 *  @param [in] reference               Reference data to be compared to.
 *  @param [in] count                   Number of elements to be compared.
 *
 *  @return True if count of data the elements are equal to reference counterparts, false otherwise.
 */
bool DataTest::compare(const glw::GLuint* data, const glw::GLuint* reference, const glw::GLsizei count)
{
	for (glw::GLsizei i = 0; i < count; ++i)
	{
		if (data[i] != reference[i])
		{
			return false;
		}
	}
	return true;
}

/** @brief Prepare error message and log it.
 *
 *  @param [in] UploadDataFunction      Upload function pointer which have failed, one of:
 *                                       -  DataTest::UploadUsingNamedBufferData,
 *                                       -  DataTest::UploadUsingNamedBufferSubData
 *                                       -  DataTest::UploadUsingNamedBufferStorage and
 *                                       -  DataTest::UploadUsingCopyNamedBufferSubData.
 *  @param [in] parameter               Parameter which was passed to function.
 *  @param [in] data                    Data which was downloaded.
 *  @param [in] reference               Reference data.
 *  @param [in] count                   Number of elements compared.
 */
void DataTest::LogFail(void (DataTest::*UploadDataFunction)(glw::GLuint, glw::GLenum), glw::GLenum parameter,
					   const glw::GLuint* data, const glw::GLuint* reference, const glw::GLsizei count)
{
	std::string the_log = "The test of ";

	if (UploadDataFunction == &DataTest::UploadUsingNamedBufferData)
	{
		the_log.append("glNamedBufferData");
	}
	else
	{
		if (UploadDataFunction == &DataTest::UploadUsingNamedBufferSubData)
		{
			the_log.append("glNamedBufferSubData");
		}
		else
		{
			if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
			{
				the_log.append("glNamedBufferStorage");
			}
			else
			{
				if (UploadDataFunction == &DataTest::UploadUsingCopyNamedBufferSubData)
				{
					the_log.append("glCopyNamedBufferSubData");
				}
				else
				{
					the_log.append("uknown upload function");
				}
			}
		}
	}

	if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
	{
		the_log.append(" called with usage parameter ");

		std::stringstream bitfield_string_stream;
		bitfield_string_stream << glu::getBufferMapFlagsStr(parameter);
		the_log.append(bitfield_string_stream.str());
	}
	else
	{
		the_log.append(" called with usage parameter ");
		the_log.append(glu::getUsageName(parameter));
	}
	the_log.append(". Buffer data is equal to [");

	for (glw::GLsizei i = 0; i < count; ++i)
	{
		std::stringstream number;

		number << data[i];

		the_log.append(number.str());

		if (i != count - 1)
		{
			the_log.append(", ");
		}
	}

	the_log.append("], but [");

	for (glw::GLsizei i = 0; i < count; ++i)
	{
		std::stringstream number;

		number << reference[i];

		the_log.append(number.str());

		if (i != count - 1)
		{
			the_log.append(", ");
		}
	}

	the_log.append("] was expected.");

	m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
}

void DataTest::LogError(void (DataTest::*UploadDataFunction)(glw::GLuint, glw::GLenum), glw::GLenum parameter)
{
	std::string the_log = "Unexpected error occurred during the test of ";

	if (UploadDataFunction == &DataTest::UploadUsingNamedBufferData)
	{
		the_log.append("glNamedBufferData");
	}
	else
	{
		if (UploadDataFunction == &DataTest::UploadUsingNamedBufferSubData)
		{
			the_log.append("glNamedBufferSubData");
		}
		else
		{
			if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
			{
				the_log.append("glNamedBufferStorage");
			}
			else
			{
				if (UploadDataFunction == &DataTest::UploadUsingCopyNamedBufferSubData)
				{
					the_log.append("glCopyNamedBufferSubData");
				}
				else
				{
					the_log.append("uknown upload function");
				}
			}
		}
	}

	if (UploadDataFunction == &DataTest::UploadUsingNamedBufferStorage)
	{
		the_log.append(" called with usage parameter ");

		std::stringstream bitfield_string_stream;
		bitfield_string_stream << glu::getBufferMapFlagsStr(parameter);
		the_log.append(bitfield_string_stream.str());
	}
	else
	{
		the_log.append(" called with usage parameter ");
		the_log.append(glu::getUsageName(parameter));
	}
	the_log.append(".");

	m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
}

const glw::GLuint DataTest::s_reference[] = {
	0, 1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
};																	 //!< Reference data.
const glw::GLsizei DataTest::s_reference_size = sizeof(s_reference); //!< Size of the reference data.
const glw::GLsizei DataTest::s_reference_count =
	s_reference_size / sizeof(s_reference[0]); //!< NUmber of elements of the reference data.

/******************************** Clear Test Implementation   ********************************/

/** @brief Data Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ClearTest::ClearTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_clear", "Buffer Objects Clear Test")
	, m_pNamedBufferData(DE_NULL)
	, m_pClearNamedBufferData(DE_NULL)
	, m_pClearNamedBufferSubData(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief ClearNamedBufferData wrapper implementation.
 *
 *  @note USE_SUB_DATA == false, so ClearNamedBufferData will be used.
 *
 *  @param [in] buffer                  ID of the buffer to be cleared.
 *  @param [in] internalformat          GL internal format for clearing, one of the listed in test class description.
 *  @param [in] size                    Size of the data.
 *  @param [in] format                  GL Format of the data.
 *  @param [in] type                    GL Type of the data element.
 *  @param [in] data                    Data to be cleared with.
 */
template <>
void ClearTest::ClearNamedBuffer<false>(glw::GLuint buffer, glw::GLenum internalformat, glw::GLsizei size,
										glw::GLenum format, glw::GLenum type, glw::GLvoid* data)
{
	(void)size;
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	m_pClearNamedBufferData(buffer, internalformat, format, type, data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedBufferData failed.");
}

/** @brief ClearNamedBufferSubData wrapper implementation.
 *
 *  @note USE_SUB_DATA == true, so ClearNamedBufferSubData will be used.
 *
 *  @param [in] buffer                  ID of the buffer to be cleared.
 *  @param [in] internalformat          GL internal format for clearing, one of the listed in test class description.
 *  @param [in] size                    Size of the data.
 *  @param [in] format                  GL Format of the data.
 *  @param [in] type                    GL Type of the data element.
 *  @param [in] data                    Data to be cleared with.
 */
template <>
void ClearTest::ClearNamedBuffer<true>(glw::GLuint buffer, glw::GLenum internalformat, glw::GLsizei size,
									   glw::GLenum format, glw::GLenum type, glw::GLvoid* data)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	m_pClearNamedBufferSubData(buffer, internalformat, 0, size, format, type, data);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedBufferData failed.");
}

/** @brief Compare two arrays with elements of type T == GLfloat (specialized).
 *
 *  @param [in] data                    Data to be compared.
 *  @param [in] reference               Reference data to be compared to.
 *  @param [in] count                   Number of elements to be compared.
 *
 *  @return True if count of data the elements are equal to reference counterparts, false otherwise.
 */
template <>
bool ClearTest::Compare<glw::GLfloat>(const glw::GLfloat* data, const glw::GLfloat* reference, const glw::GLsizei count)
{
	for (glw::GLsizei i = 0; i < count; ++i)
	{
		if (de::abs(data[i] - reference[i]) > 0.00001 /* Precision. */)
		{
			return false;
		}
	}
	return true;
}

/** @brief Compare two arrays with elements of type T.
 *
 *  @tparam     T                       Type of data to be compared (anything which is not GLfloat.
 *                                      Floating point numbers have another specialized implementation,
 *                                      which accounts the precision issues.
 *
 *  @param [in] data                    Data to be compared.
 *  @param [in] reference               Reference data to be compared to.
 *  @param [in] count                   Number of elements to be compared.
 *
 *  @return True if count of data the elements are equal to reference counterparts, false otherwise.
 */
template <typename T>
bool ClearTest::Compare(const T* data, const T* reference, const glw::GLsizei count)
{
	for (glw::GLsizei i = 0; i < count; ++i)
	{
		if (data[i] != reference[i])
		{
			return false;
		}
	}
	return true;
}

/** @brief Prepare error message and log it.
 *
 *  @tparam     T                       Type of data to which was tested.
 *
 *  @param [in] internalformat          Internal format used for clearing, one of the listed in test class description.
 *  @param [in] data                    Data which was used for clear test.
 *  @param [in] reference               Reference data.
 *  @param [in] count                   Number of elements to be compared.
 */
template <typename T>
void ClearTest::LogFail(bool use_sub_data, glw::GLenum internalformat, const T* data, const T* reference,
						const glw::GLsizei count)
{
	(void)internalformat;
	std::string the_log = "The test of ";

	if (use_sub_data)
	{
		the_log.append("ClearNamedBufferSubData has failed for internalformat ");
	}
	else
	{
		the_log.append("ClearNamedBufferData has failed for internalformat ");
	}

	//the_log.append(glu::getPixelFormatName(internalformat));
	the_log.append(". Cleared buffer data is equal to [");

	for (glw::GLsizei i = 0; i < count; ++i)
	{
		std::stringstream number;

		number << data[i];

		the_log.append(number.str());

		if (i != count - 1)
		{
			the_log.append(", ");
		}
	}

	the_log.append("], but [");

	for (glw::GLsizei i = 0; i < count; ++i)
	{
		std::stringstream number;

		number << reference[i];

		the_log.append(number.str());

		if (i != count - 1)
		{
			the_log.append(", ");
		}
	}

	the_log.append("] was expected.");

	m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
}

void ClearTest::LogError(bool use_sub_data, glw::GLenum internalformat)
{
	(void)internalformat;
	std::string the_log = "Unexpected error occurred during Test of ";

	if (use_sub_data)
	{
		the_log.append("ClearNamedBufferSubData with internalformat ");
	}
	else
	{
		the_log.append("ClearNamedBufferData with internalformat ");
	}

	//the_log.append(glu::getPixelFormatName(internalformat));

	m_context.getTestContext().getLog() << tcu::TestLog::Message << the_log << tcu::TestLog::EndMessage;
}

/** @brief Run CLearing test case.
 *
 *  @tparam     T                       Type of data to which to be tested.
 *  @tparam     USE_SUB_DATA            If true ClearNamedBufferSubData will be used, ClearNamedBufferData otherwise.
 *
 *  @param [in] internalformat          Internal format used for clearing, one of the listed in test class description.
 *  @param [in] count                   Number of elements.
 *  @param [in] internalformat          Data format to be used for clearing.
 *  @param [in] data                    Data to be used with clear test.
 *
 *  @return True if test case succeeded, false otherwise.
 */
template <typename T, bool USE_SUB_DATA>
bool ClearTest::TestClearNamedBufferData(glw::GLenum internalformat, glw::GLsizei count, glw::GLenum format,
										 glw::GLenum type, T* data)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	glw::GLuint buffer   = 0;
	bool		is_ok	= true;
	bool		is_error = false;

	try
	{
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferData(buffer, static_cast<glw::GLsizei>(count * sizeof(T)), NULL, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");

		ClearNamedBuffer<USE_SUB_DATA>(buffer, internalformat, static_cast<glw::GLsizei>(count * sizeof(T)), format,
									   type, data);

		gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");

		T* _data = (T*)gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer failed.");

		is_ok = Compare<T>(_data, data, count);

		if (!is_ok)
		{
			/* Log. */
			LogFail<T>(USE_SUB_DATA, internalformat, _data, data, count);
		}

		gl.unmapBuffer(GL_ARRAY_BUFFER);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer failed.");
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;

		LogError(USE_SUB_DATA, internalformat);
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
	}

	if (is_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Iterate Data Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ClearTest::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;

	m_pNamedBufferData		   = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
	m_pClearNamedBufferData	= (PFNGLCLEARNAMEDBUFFERDATA)gl.clearNamedBufferData;
	m_pClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATA)gl.clearNamedBufferSubData;

	try
	{
		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pClearNamedBufferData) ||
			(DE_NULL == m_pClearNamedBufferSubData))
		{
			throw 0;
		}

		{
			/* unsigned byte norm component ClearNamedBufferData tests */
			glw::GLubyte reference[4] = { 5, 1, 2, 3 };

			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_R8, 1, GL_RED, GL_UNSIGNED_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_RG8, 2, GL_RG, GL_UNSIGNED_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_RGBA8, 4, GL_RGBA, GL_UNSIGNED_BYTE, reference);

			/* unsigned byte norm component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_R8, 1, GL_RED, GL_UNSIGNED_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_RG8, 2, GL_RG, GL_UNSIGNED_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_RGBA8, 4, GL_RGBA, GL_UNSIGNED_BYTE, reference);

			/* unsigned byte component ClearNamedBufferData tests */
			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_R8UI, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_RG8UI, 2, GL_RG_INTEGER, GL_UNSIGNED_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLubyte, false>(GL_RGBA8UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, reference);

			/* unsigned byte component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_R8UI, 1, GL_RED_INTEGER, GL_UNSIGNED_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_RG8UI, 2, GL_RG_INTEGER, GL_UNSIGNED_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLubyte, true>(GL_RGBA8UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, reference);
		}

		{
			/* signed byte component ClearNamedBufferData tests */
			glw::GLbyte reference[4] = { 5, 1, -2, 3 };

			is_ok &= TestClearNamedBufferData<glw::GLbyte, false>(GL_R8I, 1, GL_RED_INTEGER, GL_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLbyte, false>(GL_RG8I, 2, GL_RG_INTEGER, GL_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLbyte, false>(GL_RGBA8I, 4, GL_RGBA_INTEGER, GL_BYTE, reference);

			/* signed byte component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLbyte, true>(GL_R8I, 1, GL_RED_INTEGER, GL_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLbyte, true>(GL_RG8I, 2, GL_RG_INTEGER, GL_BYTE, reference);
			is_ok &= TestClearNamedBufferData<glw::GLbyte, true>(GL_RGBA8I, 4, GL_RGBA_INTEGER, GL_BYTE, reference);
		}

		{
			/* unsigned short norm component ClearNamedBufferData tests */
			glw::GLushort reference[4] = { 5, 1, 2, 3 };

			is_ok &= TestClearNamedBufferData<glw::GLushort, false>(GL_R16, 1, GL_RED, GL_UNSIGNED_SHORT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLushort, false>(GL_RG16, 2, GL_RG, GL_UNSIGNED_SHORT, reference);
			is_ok &=
				TestClearNamedBufferData<glw::GLushort, false>(GL_RGBA16, 4, GL_RGBA, GL_UNSIGNED_SHORT, reference);

			/* unsigned short norm component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_R16, 1, GL_RED, GL_UNSIGNED_SHORT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_RG16, 2, GL_RG, GL_UNSIGNED_SHORT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_RGBA16, 4, GL_RGBA, GL_UNSIGNED_SHORT, reference);

			/* unsigned short component ClearNamedBufferData tests */
			is_ok &= TestClearNamedBufferData<glw::GLushort, false>(GL_R16UI, 1, GL_RED_INTEGER, GL_UNSIGNED_SHORT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLushort, false>(GL_RG16UI, 2, GL_RG_INTEGER, GL_UNSIGNED_SHORT, reference);
			is_ok &=
				TestClearNamedBufferData<glw::GLushort, false>(GL_RGBA16UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, reference);

			/* unsigned short component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_R16UI, 1, GL_RED_INTEGER, GL_UNSIGNED_SHORT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLushort, true>(GL_RG16UI, 2, GL_RG_INTEGER, GL_UNSIGNED_SHORT, reference);
			is_ok &=
				TestClearNamedBufferData<glw::GLushort, true>(GL_RGBA16UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, reference);
		}

		{
			/* signed short component ClearNamedBufferData tests */
			glw::GLshort reference[4] = { 5, 1, -2, 3 };

			is_ok &= TestClearNamedBufferData<glw::GLshort, false>(GL_R16I, 1, GL_RED_INTEGER, GL_SHORT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLshort, false>(GL_RG16I, 2, GL_RG_INTEGER, GL_SHORT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLshort, false>(GL_RGBA16I, 4, GL_RGBA_INTEGER, GL_SHORT, reference);

			/* signed short component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLshort, true>(GL_R16I, 1, GL_RED_INTEGER, GL_SHORT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLshort, true>(GL_RG16I, 2, GL_RG_INTEGER, GL_SHORT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLshort, true>(GL_RGBA16I, 4, GL_RGBA_INTEGER, GL_SHORT, reference);
		}

		{
			/* unsigned int component ClearNamedBufferData tests */
			glw::GLuint reference[4] = { 5, 1, 2, 3 };

			is_ok &= TestClearNamedBufferData<glw::GLuint, false>(GL_R32UI, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLuint, false>(GL_RG32UI, 2, GL_RG_INTEGER, GL_UNSIGNED_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLuint, false>(GL_RGB32UI, 3, GL_RGB_INTEGER, GL_UNSIGNED_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLuint, false>(GL_RGBA32UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_INT, reference);

			/* unsigned int component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLuint, true>(GL_R32UI, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLuint, true>(GL_RG32UI, 2, GL_RG_INTEGER, GL_UNSIGNED_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLuint, true>(GL_RGB32UI, 3, GL_RGB_INTEGER, GL_UNSIGNED_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLuint, true>(GL_RGBA32UI, 4, GL_RGBA_INTEGER, GL_UNSIGNED_INT, reference);
		}

		{
			/* signed int component ClearNamedBufferData tests */
			glw::GLint reference[4] = { 5, 1, -2, 3 };

			is_ok &= TestClearNamedBufferData<glw::GLint, false>(GL_R32I, 1, GL_RED_INTEGER, GL_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLint, false>(GL_RG32I, 2, GL_RG_INTEGER, GL_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLint, false>(GL_RGB32I, 3, GL_RGB_INTEGER, GL_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLint, false>(GL_RGBA32I, 4, GL_RGBA_INTEGER, GL_INT, reference);

			/* signed int component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLint, true>(GL_R32I, 1, GL_RED_INTEGER, GL_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLint, true>(GL_RG32I, 2, GL_RG_INTEGER, GL_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLint, true>(GL_RGB32I, 3, GL_RGB_INTEGER, GL_INT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLint, true>(GL_RGBA32I, 4, GL_RGBA_INTEGER, GL_INT, reference);
		}

		{
			/* half float component ClearNamedBufferData tests */
			glw::GLhalf reference[4] = { 0x3C00 /* 1.0hf */, 0x0000 /* 0.0hf */, 0xC000 /* -2.0hf */,
										 0x3555 /* 0.333333333hf */ };

			is_ok &= TestClearNamedBufferData<glw::GLhalf, false>(GL_R16F, 1, GL_RED, GL_HALF_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLhalf, false>(GL_RG16F, 2, GL_RG, GL_HALF_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLhalf, false>(GL_RGBA16F, 4, GL_RGBA, GL_HALF_FLOAT, reference);

			/* half float component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLhalf, true>(GL_R16F, 1, GL_RED, GL_HALF_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLhalf, true>(GL_RG16F, 2, GL_RG, GL_HALF_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLhalf, true>(GL_RGBA16F, 4, GL_RGBA, GL_HALF_FLOAT, reference);
		}

		{
			/* float component ClearNamedBufferData tests */
			glw::GLfloat reference[4] = { 1.f, 0.f, -2.f, 0.3333333333f };

			is_ok &= TestClearNamedBufferData<glw::GLfloat, false>(GL_R32F, 1, GL_RED, GL_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLfloat, false>(GL_RG32F, 2, GL_RG, GL_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLfloat, false>(GL_RGB32F, 3, GL_RGB, GL_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLfloat, false>(GL_RGBA32F, 4, GL_RGBA, GL_FLOAT, reference);

			/* float component ClearNamedBufferSubData tests */
			is_ok &= TestClearNamedBufferData<glw::GLfloat, true>(GL_R32F, 1, GL_RED, GL_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLfloat, true>(GL_RG32F, 2, GL_RG, GL_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLfloat, true>(GL_RGB32F, 3, GL_RGB, GL_FLOAT, reference);
			is_ok &= TestClearNamedBufferData<glw::GLfloat, true>(GL_RGBA32F, 4, GL_RGBA, GL_FLOAT, reference);
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* 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;
}

/******************************** Map Read Only Test Implementation   ********************************/

/** @brief Map Read Only Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
MapReadOnlyTest::MapReadOnlyTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_map_read_only", "Buffer Objects Map Read Only Test")
	, m_pNamedBufferData(DE_NULL)
	, m_pMapNamedBuffer(DE_NULL)
	, m_pUnmapNamedBuffer(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Map Read Only Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult MapReadOnlyTest::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;

	glw::GLuint buffer = 0;

	m_pNamedBufferData  = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
	m_pMapNamedBuffer   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
	m_pUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;

	try
	{
		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pUnmapNamedBuffer))
		{
			throw 0;
		}

		/* Buffer creation. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		/* Buffer's storage allocation and reference data upload. */
		m_pNamedBufferData(buffer, s_reference_size, s_reference, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");

		/* Mapping with new named buffer map function. */
		glw::GLuint* data = (glw::GLuint*)m_pMapNamedBuffer(buffer, GL_READ_ONLY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

		if (DE_NULL == data)
		{
			/* Log. */
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glMapNamedBuffer returned NULL pointer, but buffer's data was expected."
				<< tcu::TestLog::EndMessage;
		}
		else
		{
			/* Comparison results with reference data. */
			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
			{
				is_ok &= (data[i] == s_reference[i]);
			}

			if (!is_ok)
			{
				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glMapNamedBuffer returned pointer to data which is not identical to reference data."
					<< tcu::TestLog::EndMessage;
			}

			/* Unmapping with new named buffer unmap function. */
			if (GL_TRUE != m_pUnmapNamedBuffer(buffer))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glUnmapNamedBuffer called on mapped buffer has returned GL_FALSE, but GL_TRUE was expected."
					<< tcu::TestLog::EndMessage;
			}
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = false;
	}

	/* 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;
}

const glw::GLuint  MapReadOnlyTest::s_reference[]	 = { 0, 1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096 };
const glw::GLsizei MapReadOnlyTest::s_reference_size  = sizeof(s_reference);
const glw::GLsizei MapReadOnlyTest::s_reference_count = s_reference_size / sizeof(s_reference[0]);

/******************************** Map Read Write Test Implementation   ********************************/

/** @brief Map Read Write Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
MapReadWriteTest::MapReadWriteTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_map_read_write", "Buffer Objects Map Read Write Test")
	, m_pNamedBufferData(DE_NULL)
	, m_pMapNamedBuffer(DE_NULL)
	, m_pUnmapNamedBuffer(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Map Read Write Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult MapReadWriteTest::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;

	glw::GLuint buffer = 0;

	m_pNamedBufferData  = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
	m_pMapNamedBuffer   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
	m_pUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;

	try
	{
		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pUnmapNamedBuffer))
		{
			throw 0;
		}

		/* Buffer creation. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		/* Buffer's storage allocation and reference data upload. */
		m_pNamedBufferData(buffer, s_reference_size, s_reference, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");

		/* Mapping with new named buffer map function. */
		glw::GLuint* data = (glw::GLuint*)m_pMapNamedBuffer(buffer, GL_READ_WRITE);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

		if (DE_NULL == data)
		{
			/* Log. */
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glMapNamedBuffer returned NULL pointer, but buffer's data was expected."
				<< tcu::TestLog::EndMessage;
		}
		else
		{
			/* Comparison results with reference data. */
			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
			{
				is_ok &= (data[i] == s_reference[i]);
			}

			if (!is_ok)
			{
				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glMapNamedBuffer returned pointer to data which is not identical to reference data."
					<< tcu::TestLog::EndMessage;
			}

			/* Writting inverted reference data. */
			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
			{
				data[i] = s_reference[s_reference_count - i - 1];
			}

			/* Unmapping with new named buffer unmap function. */
			if (GL_TRUE != m_pUnmapNamedBuffer(buffer))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glUnmapNamedBuffer called on mapped buffer has returned GL_FALSE, but GL_TRUE was expected."
					<< tcu::TestLog::EndMessage;
			}
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");

			data = DE_NULL;

			data = (glw::GLuint*)m_pMapNamedBuffer(buffer, GL_READ_WRITE);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			if (DE_NULL == data)
			{
				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glMapNamedBuffer returned NULL pointer, but buffer's data was expected."
					<< tcu::TestLog::EndMessage;
			}
			else
			{
				/* Comparison results with inverted reference data. */
				for (glw::GLsizei i = 0; i < s_reference_count; ++i)
				{
					is_ok &= (data[i] == s_reference[s_reference_count - i - 1]);
				}

				/* Unmapping with new named buffer unmap function. */
				if (GL_TRUE != m_pUnmapNamedBuffer(buffer))
				{
					is_ok = false;

					/* Log. */
					m_context.getTestContext().getLog()
						<< tcu::TestLog::Message
						<< "glUnmapNamedBuffer called on mapped buffer has returned GL_FALSE, but GL_TRUE was expected."
						<< tcu::TestLog::EndMessage;
				}
				GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = false;
	}

	/* 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;
}

const glw::GLuint MapReadWriteTest::s_reference[] = {
	0, 1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
};																			 //!< Reference data.
const glw::GLsizei MapReadWriteTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
const glw::GLsizei MapReadWriteTest::s_reference_count =
	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.

/******************************** Map Write Only Test Implementation   ********************************/

/** @brief Map Write Only Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
MapWriteOnlyTest::MapWriteOnlyTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_map_write_only", "Buffer Objects Map Write Only Test")
	, m_pNamedBufferData(DE_NULL)
	, m_pMapNamedBuffer(DE_NULL)
	, m_pUnmapNamedBuffer(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Map Write Only Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult MapWriteOnlyTest::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;

	glw::GLuint buffer = 0;

	m_pNamedBufferData  = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
	m_pMapNamedBuffer   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
	m_pUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;

	try
	{
		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pUnmapNamedBuffer))
		{
			throw 0;
		}

		/* Buffer creation. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		/* Buffer's storage allocation. */
		m_pNamedBufferData(buffer, s_reference_size, NULL, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");

		/* Mapping with new named buffer map function. */
		glw::GLuint* data = (glw::GLuint*)m_pMapNamedBuffer(buffer, GL_WRITE_ONLY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

		if (DE_NULL == data)
		{
			/* Log. */
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message << "glMapNamedBuffer returned NULL pointer, but buffer's data was expected."
				<< tcu::TestLog::EndMessage;
		}
		else
		{
			/* Reference data upload. */
			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
			{
				data[i] = s_reference[i];
			}

			/* Unmapping with new named buffer unmap function. */
			if (GL_TRUE != m_pUnmapNamedBuffer(buffer))
			{
				is_ok = false;

				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glUnmapNamedBuffer called on mapped buffer has returned GL_FALSE, but GL_TRUE was expected."
					<< tcu::TestLog::EndMessage;
			}
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");

			/* Mapping data, the old way. */
			gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");

			data = DE_NULL;

			data = (glw::GLuint*)gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer failed.");

			/* Comparison results with reference data. */
			for (glw::GLsizei i = 0; i < s_reference_count; ++i)
			{
				is_ok &= (data[i] == s_reference[i]);
			}

			if (!is_ok)
			{
				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glMapNamedBuffer, called with GL_WRITE_ONLY access flag, had not stored the reference data."
					<< tcu::TestLog::EndMessage;
			}

			gl.unmapBuffer(GL_ARRAY_BUFFER);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer failed.");
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = false;
	}

	/* 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;
}

const glw::GLuint MapWriteOnlyTest::s_reference[] = {
	0, 1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
};																			 //!< Reference data.
const glw::GLsizei MapWriteOnlyTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
const glw::GLsizei MapWriteOnlyTest::s_reference_count =
	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.

/******************************** Buffers Range Map Read Bit Test Implementation   ********************************/

/** @brief Buffers Range Map Read Bit Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
MapRangeReadBitTest::MapRangeReadBitTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_map_range_read_bit", "Buffer Objects Map Range Read Bit Test")
	, m_pNamedBufferStorage(DE_NULL)
	, m_pMapNamedBufferRange(DE_NULL)
	, m_pUnmapNamedBuffer(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Buffers Range Map Read Bit Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult MapRangeReadBitTest::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;

	glw::GLuint buffer = 0;

	m_pNamedBufferStorage  = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
	m_pMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
	m_pUnmapNamedBuffer	= (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;

	try
	{
		if ((DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pMapNamedBufferRange) ||
			(DE_NULL == m_pUnmapNamedBuffer))
		{
			throw 0;
		}

		glw::GLbitfield access_flags[] = { GL_MAP_READ_BIT, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT,
										   GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT };

		glw::GLuint access_flags_count = sizeof(access_flags) / sizeof(access_flags[0]);

		for (glw::GLuint i = 0; i < access_flags_count; ++i)
		{
			/* Buffer creation. */
			gl.createBuffers(1, &buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

			/* Buffer's storage allocation and reference data upload. */
			m_pNamedBufferStorage(buffer, s_reference_size, s_reference, access_flags[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");

			/* Mapping with first half of named buffer. */
			glw::GLuint* data = (glw::GLuint*)m_pMapNamedBufferRange(buffer, 0, s_reference_size / 2, access_flags[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBufferRange failed.");

			/* Check with reference. */
			is_ok &= CompareWithReference(data, 0, s_reference_size / 2);

			/* Unmapping with new named buffer unmap function. */
			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");

			/* Mapping with second half of named buffer. */
			data = (glw::GLuint*)m_pMapNamedBufferRange(buffer, s_reference_size / 2, s_reference_size / 2,
														access_flags[i]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBufferRange failed.");

			/* Check with reference. */
			is_ok &= CompareWithReference(data, s_reference_size / 2, s_reference_size / 2);

			/* Unmapping with new named buffer unmap function. */
			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");

			/* Clean up. */
			if (buffer)
			{
				gl.deleteBuffers(1, &buffer);

				buffer = 0;
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 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;
}

/** @brief Compare array of unsigned integers with subrange of reference values (s_reference).
 *
 *  @param [in] data        Data to be compared.
 *  @param [in] offset      Offset in the reference data.
 *  @param [in] length      Length of the data to be compared.
 *
 *  @return True if comparison succeeded, false otherwise.
 */
bool MapRangeReadBitTest::CompareWithReference(glw::GLuint* data, glw::GLintptr offset, glw::GLsizei length)
{
	if (DE_NULL == data)
	{
		/* Log. */
		m_context.getTestContext().getLog()
			<< tcu::TestLog::Message << "glMapNamedBufferRange called with offset " << offset << " and length "
			<< length << " returned NULL pointer, but buffer's data was expected." << tcu::TestLog::EndMessage;
	}
	else
	{
		glw::GLuint start = static_cast<glw::GLuint>((offset) / sizeof(s_reference[0]));
		glw::GLuint end   = static_cast<glw::GLuint>((offset + length) / sizeof(s_reference[0]));

		/* Comparison results with reference data. */
		for (glw::GLuint i = start; i < end; ++i)
		{
#if (DE_COMPILER == DE_COMPILER_GCC)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
			if (data[i - start] != s_reference[i])
			{
				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "glMapNamedBufferRange called with offset " << offset << " and length "
					<< length << " returned pointer to data which is not identical to reference data."
					<< tcu::TestLog::EndMessage;

				return false;
			}
#if (DE_COMPILER == DE_COMPILER_GCC)
#pragma GCC diagnostic pop
#endif
		}
	}

	return true;
}

const glw::GLuint MapRangeReadBitTest::s_reference[] = {
	1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
};																				//!< Reference data.
const glw::GLsizei MapRangeReadBitTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
const glw::GLsizei MapRangeReadBitTest::s_reference_count =
	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.

/******************************** Buffers Range Map Write Bit Test Implementation   ********************************/

/** @brief Buffers Range Map Write Bit Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
MapRangeWriteBitTest::MapRangeWriteBitTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_map_range_write_bit", "Buffer Objects Map Range Write Bit Test")
	, m_pNamedBufferStorage(DE_NULL)
	, m_pMapNamedBufferRange(DE_NULL)
	, m_pUnmapNamedBuffer(DE_NULL)
	, m_pFlushMappedNamedBufferRange(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Buffers Range Map Read Bit Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult MapRangeWriteBitTest::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;

	glw::GLuint buffer = 0;

	m_pNamedBufferStorage		   = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
	m_pMapNamedBufferRange		   = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
	m_pUnmapNamedBuffer			   = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;
	m_pFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGE)gl.flushMappedNamedBufferRange;

	try
	{
		if ((DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pMapNamedBufferRange) ||
			(DE_NULL == m_pUnmapNamedBuffer) || (DE_NULL == m_pFlushMappedNamedBufferRange))
		{
			throw 0;
		}

		struct
		{
			glw::GLbitfield creation;
			glw::GLbitfield first_mapping;
			glw::GLbitfield second_mapping;
		} access_flags[] = {
			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT },
			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
			  GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT },
			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, GL_MAP_WRITE_BIT },
			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT,
			  GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT },
			{ GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT }
		};

		glw::GLuint access_flags_count = sizeof(access_flags) / sizeof(access_flags[0]);

		for (glw::GLuint i = 0; i < access_flags_count; ++i)
		{
			/* Buffer creation. */
			gl.createBuffers(1, &buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

			/* Buffer's storage allocation and reference data upload. */
			m_pNamedBufferStorage(buffer, s_reference_size, DE_NULL, access_flags[i].creation);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferStorage failed.");

			/* Mapping with first half of named buffer. */
			glw::GLuint* data =
				(glw::GLuint*)m_pMapNamedBufferRange(buffer, 0, s_reference_size / 2, access_flags[i].first_mapping);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBufferRange failed.");

			/* Write to mapped buffer. */
			for (glw::GLsizei j = 0; j < s_reference_count / 2; ++j)
			{
				data[j] = s_reference[j];
			}

			/* Flush, if needed. */
			glw::GLenum flush_error = GL_NO_ERROR;

			if (GL_MAP_FLUSH_EXPLICIT_BIT & access_flags[i].first_mapping)
			{
				m_pFlushMappedNamedBufferRange(buffer, 0, s_reference_size / 2);

				flush_error = gl.getError();
			}

			/* Unmapping with new named buffer unmap function. */
			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(flush_error, "glFlushMappedNamedBufferRange failed.");
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");

			/* Mapping with second half of named buffer. */
			data = (glw::GLuint*)m_pMapNamedBufferRange(buffer, s_reference_size / 2, s_reference_size / 2,
														access_flags[i].second_mapping);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBufferRange failed.");

			/* Write to mapped buffer. */
			for (glw::GLsizei j = 0; j < s_reference_count / 2; ++j)
			{
				data[j] = s_reference[j + s_reference_count / 2];
			}

			/* Flush, if needed. */
			flush_error = GL_NO_ERROR;

			if (GL_MAP_FLUSH_EXPLICIT_BIT & access_flags[i].second_mapping)
			{
				m_pFlushMappedNamedBufferRange(buffer, 0, s_reference_size / 2);

				flush_error = gl.getError();
			}

			/* Unmapping with new named buffer unmap function. */
			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(flush_error, "glFlushMappedNamedBufferRange failed.");
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");

			/* Check that previous mappings correctly filled buffer with reference data. */
			is_ok &= CompareWithReference(buffer, access_flags[i].first_mapping | access_flags[i].second_mapping);

			/* Clean up. */
			if (buffer)
			{
				gl.deleteBuffers(1, &buffer);

				buffer = 0;
			}
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 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;
}

/** @brief Compare buffer's content with the reference values (s_reference) and log possible failure.
 *
 *  @param [in] buffer          Buffer to be tested.
 *  @param [in] access_flag     Access flag used during test's mapping (for failure logging purposes).
 *
 *  @return True if comparison succeeded, false otherwise.
 */
bool MapRangeWriteBitTest::CompareWithReference(glw::GLuint buffer, glw::GLbitfield access_flag)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Map buffer with legacy API. */
	gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer failed.");

	glw::GLuint* data = (glw::GLuint*)gl.mapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer failed.");

	/* Default return value. */
	bool is_ok = true;

	if (DE_NULL != data)
	{
		/* Comparison results with reference data. */
		for (glw::GLsizei i = 0; i < s_reference_count; ++i)
		{
			if (data[i] != s_reference[i])
			{
				std::string access_string = "GL_MAP_WRITE_BIT";

				if (GL_MAP_INVALIDATE_RANGE_BIT & access_flag)
				{
					access_string = "(GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT)";
				}

				if (GL_MAP_INVALIDATE_BUFFER_BIT & access_flag)
				{
					access_string = "(GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT)";
				}

				if (GL_MAP_FLUSH_EXPLICIT_BIT & access_flag)
				{
					access_string = "(GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT)";
				}

				if (GL_MAP_UNSYNCHRONIZED_BIT & access_flag)
				{
					access_string = "(GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT)";
				}

				/* Log. */
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message << "Test of glMapNamedBufferRange with access flag " << access_string
					<< " failed to fill the buffer with reference data." << tcu::TestLog::EndMessage;

				is_ok = false;

				break;
			}
		}
	}

	/* Unmap buffer. */
	gl.unmapBuffer(GL_ARRAY_BUFFER);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer failed.");

	return is_ok;
}

const glw::GLuint MapRangeWriteBitTest::s_reference[] = {
	1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
};																				 //!< Reference data.
const glw::GLsizei MapRangeWriteBitTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
const glw::GLsizei MapRangeWriteBitTest::s_reference_count =
	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.

/******************************** Get Named Buffer SubData Query Test Implementation   ********************************/

/** @brief Get Named Buffer SubData Query Test's static constants. */
const glw::GLuint SubDataQueryTest::s_reference[] = {
	1, 2, 4, 8, 16, 64, 128, 256, 512, 1024, 2048, 4096
};																			 //!< Reference data.
const glw::GLsizei SubDataQueryTest::s_reference_size = sizeof(s_reference); //!< Reference data size.
const glw::GLsizei SubDataQueryTest::s_reference_count =
	s_reference_size / sizeof(s_reference[0]); //!< Reference data elements' count.

/** @brief Get Named Buffer SubData Query Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
SubDataQueryTest::SubDataQueryTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_get_named_buffer_subdata", "Buffer Objects Get Named Buffer SubData Query Test")
	, m_pNamedBufferData(DE_NULL)
	, m_pGetNamedBufferSubData(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Get Named Buffer SubData Query Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult SubDataQueryTest::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;

	glw::GLuint buffer = 0;

	m_pNamedBufferData		 = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
	m_pGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATA)gl.getNamedBufferSubData;

	try
	{
		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pGetNamedBufferSubData))
		{
			throw 0;
		}

		/* Buffer creation. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		/* Buffer's storage allocation and reference data upload. */
		m_pNamedBufferData(buffer, s_reference_size, s_reference, GL_DYNAMIC_COPY);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData failed.");

		/* Mapping with new named buffer map function. */
		glw::GLuint data[s_reference_count] = {};
		m_pGetNamedBufferSubData(buffer, 0, s_reference_size / 2, data);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetNamedBufferSubData failed.");

		m_pGetNamedBufferSubData(buffer, s_reference_size / 2, s_reference_size / 2, &data[s_reference_count / 2]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetNamedBufferSubData failed.");

		/* Comparison results with reference data. */
		for (glw::GLsizei i = 0; i < s_reference_count; ++i)
		{
			is_ok &= (data[i] == s_reference[i]);
		}

		if (!is_ok)
		{
			/* Log. */
			m_context.getTestContext().getLog()
				<< tcu::TestLog::Message
				<< "glGetNamedBufferSubData returned data which is not identical to reference data."
				<< tcu::TestLog::EndMessage;
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = false;
	}

	/* 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;
}

/******************************** Defaults Test Implementation   ********************************/

/** @brief Defaults Query Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
DefaultsTest::DefaultsTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_defaults", "Buffer Objects Defaults Test")
	, m_pNamedBufferData(DE_NULL)
	, m_pGetNamedBufferParameteri64v(DE_NULL)
	, m_pGetNamedBufferParameteriv(DE_NULL)
	, m_pGetNamedBufferPointerv(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Compare value with the reference.
 *
 *  @param [in] value               Value to be compared.
 *  @param [in] reference_value     Reference value for comparison.
 *  @param [in] pname_string        String of parameter name of the value (for logging).
 *  @param [in] function_string     String of function which returned the value (for logging).
 *
 *  @return True if value is equal to reference value, false otherwise. False solution is logged.
 */
template <typename T>
bool DefaultsTest::CheckValue(const T value, const T reference_value, const glw::GLchar* pname_string,
							  const glw::GLchar* function_string)
{
	if (reference_value != value)
	{
		/* Log. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function_string << " called with "
											<< pname_string << " parameter name returned " << value << ", but "
											<< reference_value << " was expected." << tcu::TestLog::EndMessage;

		return false;
	}
	return true;
}

/** @brief Iterate 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;

	glw::GLuint buffer = 0;

	m_pNamedBufferData			   = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
	m_pGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64V)gl.getNamedBufferParameteri64v;
	m_pGetNamedBufferParameteriv   = (PFNGLGETNAMEDBUFFERPARAMETERIV)gl.getNamedBufferParameteriv;
	m_pGetNamedBufferPointerv	  = (PFNGLGETNAMEDBUFFERPOINTERV)gl.getNamedBufferPointerv;

	try
	{
		if ((DE_NULL == m_pNamedBufferData) || (DE_NULL == m_pGetNamedBufferParameteri64v) ||
			(DE_NULL == m_pGetNamedBufferParameteriv) || (DE_NULL == m_pGetNamedBufferPointerv))
		{
			throw 0;
		}

		/* Buffer creation. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		/* Test data for glGetNamedBufferParameteri*v. */
		static const struct
		{
			glw::GLenum		   pname;
			const glw::GLchar* pname_string;
			glw::GLint		   expected_data;
		} test_values[] = { { GL_BUFFER_SIZE, "GL_BUFFER_SIZE", 0 },
							{ GL_BUFFER_USAGE, "GL_BUFFER_USAGE", GL_STATIC_DRAW },
							{ GL_BUFFER_ACCESS, "GL_BUFFER_ACCESS", GL_READ_WRITE },
							{ GL_BUFFER_ACCESS_FLAGS, "GL_BUFFER_ACCESS_FLAGS", 0 },
							{ GL_BUFFER_IMMUTABLE_STORAGE, "GL_BUFFER_IMMUTABLE_STORAGE", GL_FALSE },
							{ GL_BUFFER_MAPPED, "GL_BUFFER_MAPPED", GL_FALSE },
							{ GL_BUFFER_MAP_OFFSET, "GL_BUFFER_MAP_OFFSET", 0 },
							{ GL_BUFFER_MAP_LENGTH, "GL_BUFFER_MAP_LENGTH", 0 },
							{ GL_BUFFER_STORAGE_FLAGS, "GL_BUFFER_STORAGE_FLAGS", 0 } };

		static const glw::GLuint test_dictionary_count = sizeof(test_values) / sizeof(test_values[0]);

		/* Test glGetNamedBufferParameteriv. */
		for (glw::GLuint i = 0; i < test_dictionary_count; ++i)
		{
			glw::GLint data = -1;

			m_pGetNamedBufferParameteriv(buffer, test_values[i].pname, &data);

			is_ok &= CheckParameterError(test_values[i].pname_string, "glGetNamedBufferParameteriv");

			is_ok &= CheckValue<glw::GLint>(data, test_values[i].expected_data, test_values[i].pname_string,
											"glGetNamedBufferParameteriv");
		}

		/* Test glGetNamedBufferParameteri64v. */
		for (glw::GLuint i = 0; i < test_dictionary_count; ++i)
		{
			glw::GLint64 data = -1;

			m_pGetNamedBufferParameteri64v(buffer, test_values[i].pname, &data);

			is_ok &= CheckParameterError(test_values[i].pname_string, "glGetNamedBufferParameteri64v");

			is_ok &= CheckValue<glw::GLint64>(data, (glw::GLint64)test_values[i].expected_data,
											  test_values[i].pname_string, "glGetNamedBufferParameteri64v");
		}

		/* Test glGetNamedBufferPointerv. */
		{
			glw::GLvoid* data = (glw::GLvoid*)1;

			m_pGetNamedBufferPointerv(buffer, GL_BUFFER_MAP_POINTER, &data);

			is_ok &= CheckParameterError("GL_BUFFER_MAP_POINTER", "glGetNamedBufferPointer");

			is_ok &= CheckValue<glw::GLvoid*>(data, (glw::GLvoid*)DE_NULL, "GL_BUFFER_MAP_POINTER",
											  "glGetNamedBufferParameteriv");
		}
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean up. */
	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 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;
}

/** @brief Check for GL error and log.
 *
 *  @param [in] pname_string        String of parameter name of the value (for logging).
 *  @param [in] function_string     String of function which returned the value (for logging).
 *
 *  @return True if error was generated, false otherwise. False solution is logged.
 */
bool DefaultsTest::CheckParameterError(const glw::GLchar* pname_string, const glw::GLchar* function_string)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Error check. */
	if (glw::GLenum error = gl.getError())
	{
		/* Log. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function_string << " called with "
											<< pname_string << " parameter name unexpectedly returned "
											<< glu::getErrorStr(error) << "error." << tcu::TestLog::EndMessage;

		return false;
	}

	return true;
}

/******************************** Errors Test Implementation   ********************************/

/** @brief Errors Query Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
ErrorsTest::ErrorsTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_errors", "Buffer Objects Errors Test")
	, m_pClearNamedBufferData(DE_NULL)
	, m_pClearNamedBufferSubData(DE_NULL)
	, m_pCopyNamedBufferSubData(DE_NULL)
	, m_pFlushMappedNamedBufferRange(DE_NULL)
	, m_pGetNamedBufferParameteri64v(DE_NULL)
	, m_pGetNamedBufferParameteriv(DE_NULL)
	, m_pGetNamedBufferPointerv(DE_NULL)
	, m_pGetNamedBufferSubData(DE_NULL)
	, m_pMapNamedBuffer(DE_NULL)
	, m_pMapNamedBufferRange(DE_NULL)
	, m_pNamedBufferData(DE_NULL)
	, m_pNamedBufferStorage(DE_NULL)
	, m_pNamedBufferSubData(DE_NULL)
	, m_pUnmapNamedBuffer(DE_NULL)
{
	/* Intentionally left blank. */
}

/** @brief Iterate Errors Test cases.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult ErrorsTest::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;

	/* API function pointers setup. */
	m_pClearNamedBufferData		   = (PFNGLCLEARNAMEDBUFFERDATA)gl.clearNamedBufferData;
	m_pClearNamedBufferSubData	 = (PFNGLCLEARNAMEDBUFFERSUBDATA)gl.clearNamedBufferSubData;
	m_pCopyNamedBufferSubData	  = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;
	m_pFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGE)gl.flushMappedNamedBufferRange;
	m_pGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64V)gl.getNamedBufferParameteri64v;
	m_pGetNamedBufferParameteriv   = (PFNGLGETNAMEDBUFFERPARAMETERIV)gl.getNamedBufferParameteriv;
	m_pGetNamedBufferPointerv	  = (PFNGLGETNAMEDBUFFERPOINTERV)gl.getNamedBufferPointerv;
	m_pGetNamedBufferSubData	   = (PFNGLGETNAMEDBUFFERSUBDATA)gl.getNamedBufferSubData;
	m_pMapNamedBuffer			   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
	m_pMapNamedBufferRange		   = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
	m_pNamedBufferData			   = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
	m_pNamedBufferStorage		   = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
	m_pNamedBufferSubData		   = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
	m_pUnmapNamedBuffer			   = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;

	try
	{
		/* API function pointers check. */
		if ((DE_NULL == m_pClearNamedBufferData) || (DE_NULL == m_pClearNamedBufferSubData) ||
			(DE_NULL == m_pCopyNamedBufferSubData) || (DE_NULL == m_pFlushMappedNamedBufferRange) ||
			(DE_NULL == m_pGetNamedBufferParameteri64v) || (DE_NULL == m_pGetNamedBufferParameteriv) ||
			(DE_NULL == m_pGetNamedBufferPointerv) || (DE_NULL == m_pGetNamedBufferSubData) ||
			(DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pMapNamedBufferRange) || (DE_NULL == m_pNamedBufferData) ||
			(DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pNamedBufferSubData) ||
			(DE_NULL == m_pUnmapNamedBuffer))
		{
			throw 0;
		}

		/* Running test cases.                              Cleaning errors. */
		is_ok &= TestErrorsOfClearNamedBufferData();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfClearNamedBufferSubData();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfCopyNamedBufferSubData();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfCreateBuffers();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfFlushMappedNamedBufferRange();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfGetNamedBufferParameter();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfGetNamedBufferPointerv();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfGetNamedBufferSubData();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfMapNamedBuffer();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfMapNamedBufferRange();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfNamedBufferData();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfNamedBufferStorage();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfNamedBufferSubData();
		while (gl.getError())
			;
		is_ok &= TestErrorsOfUnmapNamedBuffer();
		while (gl.getError())
			;
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* 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;
}

/** Check if error was generated and if it is equal to expected value. Log possible failure.
 *
 *  @param [in] function_name               Tested Function.
 *  @param [in] expected_error              Expected error function.
 *  @param [in] when_shall_be_generated     Description when shall the error occure.
 *
 *  @return True if GL error is equal to the expected value, false otherwise.
 */
bool ErrorsTest::ErrorCheckAndLog(const glw::GLchar* function_name, const glw::GLenum expected_error,
								  const glw::GLchar* when_shall_be_generated)
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Error value storage. */
	glw::GLenum error = GL_NO_ERROR;

	/* Error comparision. */
	if (expected_error != (error = gl.getError()))
	{
		/* Log. */
		m_context.getTestContext().getLog() << tcu::TestLog::Message << function_name << " does not generate "
											<< glu::getErrorStr(expected_error) << when_shall_be_generated
											<< "The error value of " << glu::getErrorStr(error) << " was observed."
											<< tcu::TestLog::EndMessage;

		/* Error cleanup. */
		while (gl.getError())
			;

		/* Check failed. */
		return false;
	}

	/* Error was equal to expected. */
	return true;
}

/** @brief Test Errors Of ClearNamedBufferData function.
 *
 *  Check that INVALID_OPERATION is generated by ClearNamedBufferData if
 *  buffer is not the name of an existing buffer object.
 *
 *  Check that INVALID_ENUM is generated by ClearNamedBufferData if
 *  internal format is not one of the valid sized internal formats listed in
 *  the table above.
 *
 *  Check that INVALID_OPERATION is generated by ClearNamedBufferData if
 *  any part of the specified range of the buffer object is mapped with
 *  MapBufferRange or MapBuffer, unless it was mapped with the
 *  MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
 *
 *  Check that INVALID_VALUE is generated by ClearNamedBufferData if
 *  format is not a valid format, or type is not a valid type.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfClearNamedBufferData()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint buffer	 = 0;
	glw::GLbyte dummy_data = 0;

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data,
							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferStorage failed.");

		/* Test invalid buffer name error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pClearNamedBufferData(not_a_buffer_name, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test invalid sized internal format error behavior. */
		{
			/* Prepare for invalid sized internal format error behavior verification. */
			static const glw::GLenum valid_internal_formats[] = {
				GL_R8,		GL_R16,		GL_R16F,	GL_R32F,	 GL_R8I,	  GL_R16I,	GL_R32I,
				GL_R8UI,	GL_R16UI,   GL_R32UI,   GL_RG8,		 GL_RG16,	 GL_RG16F,   GL_RG32F,
				GL_RG8I,	GL_RG16I,   GL_RG32I,   GL_RG8UI,	GL_RG16UI,   GL_RG32UI,  GL_RGB32F,
				GL_RGB32I,  GL_RGB32UI, GL_RGBA8,   GL_RGBA16,   GL_RGBA16F,  GL_RGBA32F, GL_RGBA8I,
				GL_RGBA16I, GL_RGBA32I, GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI, GL_NONE
			};
			static const glw::GLenum valid_internal_formats_last =
				sizeof(valid_internal_formats) / sizeof(valid_internal_formats[0]) - 1;

			glw::GLenum invalid_internal_format = 0;

			while (&valid_internal_formats[valid_internal_formats_last] !=
				   std::find(&valid_internal_formats[0], &valid_internal_formats[valid_internal_formats_last],
							 (++invalid_internal_format)))
				;

			/* Test. */
			m_pClearNamedBufferData(buffer, invalid_internal_format, GL_RED, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_ENUM,
									  " if internal format is not one of the valid sized internal formats "
									  "(GL_R8, GL_R16, GL_R16F, GL_R32F, GL_R8I, GL_R16I, GL_R32I, GL_R8UI,"
									  " GL_R16UI, GL_R32UI, GL_RG8, GL_RG16, GL_RG16F, GL_RG32F, GL_RG8I, GL_RG16I,"
									  " GL_RG32I, GL_RG8UI, GL_RG16UI, GL_RG32UI, GL_RGB32F, GL_RGB32I, GL_RGB32UI,"
									  " GL_RGBA8, GL_RGBA16, GL_RGBA16F, GL_RGBA32F, GL_RGBA8I, GL_RGBA16I, GL_RGBA32I,"
									  " GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI).");
		}

		/* Test of mapped buffer clear error behavior verification (glMapNamedBuffer version). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pClearNamedBufferData(buffer, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_OPERATION,
									  " if any part of the specified range of the buffer"
									  " object is mapped with MapBuffer, unless it was mapped with "
									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of mapped buffer clear error behavior verification (glMapNamedBufferRange version). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pClearNamedBufferData(buffer, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_INVALID_OPERATION,
									  " if any part of the specified range of the buffer"
									  " object is mapped with MapBufferRange, unless it was mapped with "
									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of persistently mapped buffer clear error with behavior verification (glMapNamedBufferRange version). */
		{
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pClearNamedBufferData(buffer, GL_R8, GL_RED, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferData", GL_NO_ERROR,
									  " if any part of the specified range of the buffer"
									  " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
									  " bit set in the MapBufferRange access flags.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test invalid format error behavior. */
		{
			/* Prepare for invalid format error behavior verification. */
			static const glw::GLenum valid_formats[] = { GL_RED,		   GL_RG,
														 GL_RGB,		   GL_BGR,
														 GL_RGBA,		   GL_BGRA,
														 GL_RED_INTEGER,   GL_RG_INTEGER,
														 GL_RGB_INTEGER,   GL_BGR_INTEGER,
														 GL_RGBA_INTEGER,  GL_BGRA_INTEGER,
														 GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
														 GL_DEPTH_STENCIL };
			static const glw::GLenum valid_formats_last = sizeof(valid_formats) / sizeof(valid_formats[0]) - 1;

			glw::GLenum invalid_format = 0;

			while (&valid_formats[valid_formats_last] !=
				   std::find(&valid_formats[0], &valid_formats[valid_formats_last], (++invalid_format)))
				;

			/* Test. */
			m_pClearNamedBufferData(buffer, GL_R8, invalid_format, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog(
				"glClearNamedBufferData", GL_INVALID_VALUE,
				" if format is not a valid format "
				"(one of GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, "
				"GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, GL_RGBA_INTEGER, GL_BGRA_INTEGER, "
				"GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL).");
		}

		/* Test invalid type error behavior. */
		{
			/* Prepare for invalid type error behavior verification. */
			static const glw::GLenum valid_types[] = { GL_RED,			 GL_RG,
													   GL_RGB,			 GL_BGR,
													   GL_RGBA,			 GL_BGRA,
													   GL_RED_INTEGER,   GL_RG_INTEGER,
													   GL_RGB_INTEGER,   GL_BGR_INTEGER,
													   GL_RGBA_INTEGER,  GL_BGRA_INTEGER,
													   GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
													   GL_DEPTH_STENCIL };
			static const glw::GLenum valid_types_last = sizeof(valid_types) / sizeof(valid_types[0]) - 1;

			glw::GLenum invalid_type = 0;

			while (&valid_types[valid_types_last] !=
				   std::find(&valid_types[0], &valid_types[valid_types_last], (++invalid_type)))
				;

			/* Test. */
			m_pClearNamedBufferData(buffer, GL_R8, GL_RED, invalid_type, &dummy_data);

			is_ok &= ErrorCheckAndLog(
				"glClearNamedBufferData", GL_INVALID_VALUE,
				" if format is not a valid type "
				"(one of GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, "
				"GL_SHORT, GL_UNSIGNED_INT, GL_INT, 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, and GL_UNSIGNED_INT_2_10_10_10_REV).");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of ClearNamedBufferSubData function.
 *
 *  Check that INVALID_OPERATION is generated by ClearNamedBufferSubData
 *  if buffer is not the name of an existing buffer object.
 *
 *  Check that INVALID_ENUM is generated by ClearNamedBufferSubData if
 *  internal format is not one of the valid sized internal formats listed in
 *  the table above.
 *
 *  Check that INVALID_VALUE is generated by ClearNamedBufferSubData if
 *  offset or range are not multiples of the number of basic machine units
 *  per-element for the internal format specified by internal format. This
 *  value may be computed by multiplying the number of components for
 *  internal format from the table by the size of the base type from the
 *  specification table.
 *
 *  Check that INVALID_VALUE is generated by ClearNamedBufferSubData if
 *  offset or size is negative, or if offset+size is greater than the value
 *  of BUFFER_SIZE for the buffer object.
 *
 *  Check that INVALID_OPERATION is generated by ClearNamedBufferSubData
 *  if any part of the specified range of the buffer object is mapped with
 *  MapBufferRange or MapBuffer, unless it was mapped with the
 *  MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
 *
 *  Check that INVALID_VALUE is generated by ClearNamedBufferSubData if format is not
 *  a valid format, or type is not a valid type.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfClearNamedBufferSubData()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer		   = 0;
	glw::GLubyte dummy_data[4] = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data,
							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pClearNamedBufferSubData(not_a_buffer_name, GL_R8, 0, sizeof(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE,
									   &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test invalid sized internal format error behavior. */
		{
			/* Prepare for invalid sized internal format error behavior verification. */
			static const glw::GLenum valid_internal_formats[] = {
				GL_R8,		GL_R16,		GL_R16F,	GL_R32F,	 GL_R8I,	  GL_R16I,	GL_R32I,
				GL_R8UI,	GL_R16UI,   GL_R32UI,   GL_RG8,		 GL_RG16,	 GL_RG16F,   GL_RG32F,
				GL_RG8I,	GL_RG16I,   GL_RG32I,   GL_RG8UI,	GL_RG16UI,   GL_RG32UI,  GL_RGB32F,
				GL_RGB32I,  GL_RGB32UI, GL_RGBA8,   GL_RGBA16,   GL_RGBA16F,  GL_RGBA32F, GL_RGBA8I,
				GL_RGBA16I, GL_RGBA32I, GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI, GL_NONE
			};
			static const glw::GLenum valid_internal_formats_last =
				sizeof(valid_internal_formats) / sizeof(valid_internal_formats[0]) - 1;

			glw::GLenum invalid_internal_format = 0;

			while (&valid_internal_formats[valid_internal_formats_last] !=
				   std::find(&valid_internal_formats[0], &valid_internal_formats[valid_internal_formats_last],
							 (++invalid_internal_format)))
				;

			/* Test. */
			m_pClearNamedBufferData(buffer, invalid_internal_format, GL_RGBA, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_ENUM,
									  " if internal format is not one of the valid sized internal formats "
									  "(GL_R8, GL_R16, GL_R16F, GL_R32F, GL_R8I, GL_R16I, GL_R32I, GL_R8UI,"
									  " GL_R16UI, GL_R32UI, GL_RG8, GL_RG16, GL_RG16F, GL_RG32F, GL_RG8I, GL_RG16I,"
									  " GL_RG32I, GL_RG8UI, GL_RG16UI, GL_RG32UI, GL_RGB32F, GL_RGB32I, GL_RGB32UI,"
									  " GL_RGBA8, GL_RGBA16, GL_RGBA16F, GL_RGBA32F, GL_RGBA8I, GL_RGBA16I, GL_RGBA32I,"
									  " GL_RGBA8UI, GL_RGBA16UI, GL_RGBA32UI).");
		}

		/* Test incorrect offset alignment error behavior. */
		{
			/* Test. */
			m_pClearNamedBufferSubData(buffer, GL_RGBA8, sizeof(dummy_data[0]), sizeof(dummy_data), GL_RGBA,
									   GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE,
									  "if offset is not multiples of the number of basic machine units (GLubyte)"
									  "per-element for the internal format (GL_RGBA) specified by internal format.");
		}

		/* Test incorrect range alignment error behavior. */
		{
			m_pClearNamedBufferSubData(buffer, GL_RGBA8, 0, sizeof(dummy_data) - sizeof(dummy_data[0]), GL_RGBA,
									   GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE,
									  "if range is not multiples of the number of basic machine units (GLubyte)"
									  "per-element for the internal format (GL_RGBA) specified by internal format.");
		}

		/* Test negative offset error behavior. */
		{
			/* Test. */
			m_pClearNamedBufferSubData(buffer, GL_R8, -1, sizeof(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
		}

		/* Test negative size error behavior. */
		{
			/* Test. */
			m_pClearNamedBufferSubData(buffer, GL_R8, 0, -((glw::GLsizei)sizeof(dummy_data)), GL_RGBA, GL_UNSIGNED_BYTE,
									   &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
		}

		/* Test size overflow error behavior. */
		{
			/* Test. */
			m_pClearNamedBufferSubData(buffer, GL_R8, 0, 2 * sizeof(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE,
									   &dummy_data);

			is_ok &= ErrorCheckAndLog(
				"glClearNamedBufferSubData", GL_INVALID_VALUE,
				" if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
		}

		/* Test of mapped buffer clear error behavior verification (glMapNamedBuffer version). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_OPERATION,
									  " if any part of the specified range of the buffer"
									  " object is mapped with MapBuffer, unless it was mapped with "
									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of mapped buffer clear error behavior verification (glMapNamedBufferRange version). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_INVALID_OPERATION,
									  " if any part of the specified range of the buffer"
									  " object is mapped with MapBufferRange, unless it was mapped with "
									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of persistently mapped buffer clear error with behavior verification (glMapNamedBufferRange version). */
		{
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(dummy_data), GL_RGBA, GL_UNSIGNED_BYTE, &dummy_data);

			is_ok &= ErrorCheckAndLog("glClearNamedBufferSubData", GL_NO_ERROR,
									  " if any part of the specified range of the buffer"
									  " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
									  " bit set in the MapBufferRange access flags.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test invalid format error behavior. */
		{
			/* Prepare for invalid format error behavior verification. */
			static const glw::GLenum valid_formats[] = { GL_RED,		   GL_RG,
														 GL_RGB,		   GL_BGR,
														 GL_RGBA,		   GL_BGRA,
														 GL_RED_INTEGER,   GL_RG_INTEGER,
														 GL_RGB_INTEGER,   GL_BGR_INTEGER,
														 GL_RGBA_INTEGER,  GL_BGRA_INTEGER,
														 GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
														 GL_DEPTH_STENCIL };
			static const glw::GLenum valid_formats_last = sizeof(valid_formats) / sizeof(valid_formats[0]) - 1;

			glw::GLenum invalid_format = 0;

			while (&valid_formats[valid_formats_last] !=
				   std::find(&valid_formats[0], &valid_formats[valid_formats_last], (++invalid_format)))
				;

			/* Test. */
			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(dummy_data), invalid_format, GL_UNSIGNED_BYTE,
									   &dummy_data);

			is_ok &= ErrorCheckAndLog(
				"glClearNamedBufferSubData", GL_INVALID_VALUE,
				" if format is not a valid format "
				"(one of GL_RED, GL_RG, GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, "
				"GL_RED_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER, GL_RGBA_INTEGER, GL_BGRA_INTEGER, "
				"GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL).");
		}

		/* Test invalid type error behavior. */
		{
			/* Prepare for invalid type error behavior verification. */
			static const glw::GLenum valid_types[] = { GL_RED,			 GL_RG,
													   GL_RGB,			 GL_BGR,
													   GL_RGBA,			 GL_BGRA,
													   GL_RED_INTEGER,   GL_RG_INTEGER,
													   GL_RGB_INTEGER,   GL_BGR_INTEGER,
													   GL_RGBA_INTEGER,  GL_BGRA_INTEGER,
													   GL_STENCIL_INDEX, GL_DEPTH_COMPONENT,
													   GL_DEPTH_STENCIL, GL_NONE };
			static const glw::GLenum valid_types_last = sizeof(valid_types) / sizeof(valid_types[0]) - 1;

			glw::GLenum invalid_type = 0;

			while (&valid_types[valid_types_last] !=
				   std::find(&valid_types[0], &valid_types[valid_types_last], (++invalid_type)))
				;

			/* Test. */
			m_pClearNamedBufferSubData(buffer, GL_R8, 0, sizeof(dummy_data), GL_RGBA, invalid_type, &dummy_data);

			is_ok &= ErrorCheckAndLog(
				"glClearNamedBufferSubData", GL_INVALID_VALUE,
				" if format is not a valid type "
				"(one of GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, "
				"GL_SHORT, GL_UNSIGNED_INT, GL_INT, 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, and GL_UNSIGNED_INT_2_10_10_10_REV).");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of CopyNamedBufferSubData function.
 *
 *  Check that INVALID_OPERATION is generated by CopyNamedBufferSubData if readBuffer
 *  or writeBuffer is not the name of an existing buffer object.
 *
 *  Check that INVALID_VALUE is generated by CopyNamedBufferSubData if any of
 *  readOffset, writeOffset or size is negative, if readOffset+size is
 *  greater than the size of the source buffer object (its value of
 *  BUFFER_SIZE), or if writeOffset+size is greater than the size of the
 *  destination buffer object.
 *
 *  Check that INVALID_VALUE is generated by CopyNamedBufferSubData if the
 *  source and destination are the same buffer object, and the ranges
 *  [readOffset,readOffset+size) and [writeOffset,writeOffset+size) overlap.
 *
 *  Check that INVALID_OPERATION is generated by CopyNamedBufferSubData if
 *  either the source or destination buffer object is mapped with
 *  MapBufferRange or MapBuffer, unless they were mapped with the
 *  MAP_PERSISTENT bit set in the MapBufferRange access flags.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfCopyNamedBufferSubData()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer_r	  = 0;
	glw::GLuint  buffer_w	  = 0;
	glw::GLubyte dummy_data[4] = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer_r);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer_r, sizeof(dummy_data), &dummy_data,
							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		gl.createBuffers(1, &buffer_w);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer_w, sizeof(dummy_data), &dummy_data,
							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pCopyNamedBufferSubData(not_a_buffer_name, buffer_w, 0, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
									  " if readBuffer is not the name of an existing buffer object.");

			m_pCopyNamedBufferSubData(buffer_r, not_a_buffer_name, 0, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
									  " if writeBuffer is not the name of an existing buffer object.");
		}

		/* Test negative read offset error behavior. */
		{
			/* Test. */
			m_pCopyNamedBufferSubData(buffer_r, buffer_w, -1, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE, "if readOffset is negative.");
		}

		/* Test negative write offset error behavior. */
		{
			/* Test. */
			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, -1, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE, "if writeOffset is negative.");
		}

		/* Test negative size error behavior. */
		{
			/* Test. */
			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, -1);

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE, "if size is negative.");
		}

		/* Test overflow size error behavior. */
		{
			/* Test. */
			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, 2 * sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
									  " if size is greater than the size of the source buffer object.");
		}

		/* Test overflow read offset and size error behavior. */
		{
			/* Test. */
			m_pCopyNamedBufferSubData(buffer_r, buffer_w, sizeof(dummy_data) / 2, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
									  " if readOffset+size is greater than the size of the source buffer object.");
		}

		/* Test overflow write offset and size error behavior. */
		{
			/* Test. */
			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, sizeof(dummy_data) / 2, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
									  " if writeOffset+size is greater than the size of the source buffer object.");
		}

		/* Test same buffer overlapping error behavior. */
		{
			/* Test. */
			m_pCopyNamedBufferSubData(buffer_w, buffer_w, 0, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_VALUE,
									  " if the source and destination are the same buffer object, and the ranges"
									  " [readOffset,readOffset+size) and [writeOffset,writeOffset+size) overlap.");
		}

		/* Test of mapped read buffer copy error behavior verification (glMapNamedBuffer version). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer_r, GL_READ_ONLY);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
									  " if the source buffer object is mapped with MapBuffer.");

			m_pUnmapNamedBuffer(buffer_r);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of mapped write buffer copy error behavior verification (glMapNamedBuffer version). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer_w, GL_READ_ONLY);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
									  " if the destination buffer object is mapped with MapBuffer.");

			m_pUnmapNamedBuffer(buffer_w);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of mapped read buffer copy error behavior verification (glMapNamedBufferRange version). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer_r, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
									  " if the source buffer object is mapped with MapBuffer.");

			m_pUnmapNamedBuffer(buffer_r);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of mapped write buffer copy error behavior verification (glMapNamedBufferRange version). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer_w, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_INVALID_OPERATION,
									  " if the destination buffer object is mapped with MapBuffer.");

			m_pUnmapNamedBuffer(buffer_w);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of persistently mapped read buffer copy error with behavior verification. */
		{
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer_r, 0, sizeof(dummy_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_NO_ERROR,
									  " if the source buffer object is mapped using "
									  "MapBufferRange with the MAP_PERSISTENT bit "
									  "set in the access flags.");

			m_pUnmapNamedBuffer(buffer_r);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of persistently mapped write buffer copy error with behavior verification. */
		{
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer_w, 0, sizeof(dummy_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pCopyNamedBufferSubData(buffer_r, buffer_w, 0, 0, sizeof(dummy_data));

			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");
			is_ok &= ErrorCheckAndLog("glCopyNamedBufferSubData", GL_NO_ERROR,
									  " if the destination buffer object is mapped using "
									  "MapBufferRange with the MAP_PERSISTENT bit "
									  "set in the access flags.");

			m_pUnmapNamedBuffer(buffer_w);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer_r)
	{
		gl.deleteBuffers(1, &buffer_r);

		buffer_r = 0;
	}

	if (buffer_r)
	{
		gl.deleteBuffers(1, &buffer_r);

		buffer_r = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of CreateBuffers function.
 *
 *  Check that INVALID_VALUE is generated by CreateBuffers if n is negative.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfCreateBuffers()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok = true;

	/* Test. */
	glw::GLuint buffer = 0;

	gl.createBuffers(-1, &buffer);

	is_ok &= ErrorCheckAndLog("glCreateBuffers", GL_INVALID_VALUE, " if n is negative.");

	/* Sanity check. */
	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		/* Possible error cleanup. */
		while (gl.getError())
			;
	}

	return is_ok;
}

/** @brief Test Errors Of FlushMappedNamedBufferRange function.
 *
 *  Check that INVALID_OPERATION is generated by FlushMappedNamedBufferRange
 *  if buffer is not the name of an existing buffer object.
 *
 *  Check that INVALID_VALUE is generated by FlushMappedNamedBufferRange if
 *  offset or length is negative, or if offset + length exceeds the size of
 *  the mapping.
 *
 *  Check that INVALID_OPERATION is generated by FlushMappedNamedBufferRange
 *  if the buffer object is not mapped, or is mapped without the
 *  MAP_FLUSH_EXPLICIT_BIT flag.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfFlushMappedNamedBufferRange()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer		   = 0;
	glw::GLubyte dummy_data[4] = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name flush error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pFlushMappedNamedBufferRange(not_a_buffer_name, 0, 1);

			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test negative offset flush error behavior. */
		{
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pFlushMappedNamedBufferRange(buffer, -1, 1);

			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE, " if offset is negative.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test negative length flush error behavior. */
		{
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pFlushMappedNamedBufferRange(buffer, 0, -1);

			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE, " if length is negative.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test length exceeds the mapping size flush error behavior. */
		{
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data) / 2, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE,
									  " if length exceeds the size of the mapping.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test offset + length exceeds the mapping size flush error behavior. */
		{
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pFlushMappedNamedBufferRange(buffer, 1, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_VALUE,
									  " if offset + length exceeds the size of the mapping.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test not mapped buffer flush error behavior. */
		{
			m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_OPERATION,
									  " if the buffer object is not mapped.");
		}

		/* Test buffer flush without the MAP_FLUSH_EXPLICIT_BIT error behavior. */
		{
			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_WRITE_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pFlushMappedNamedBufferRange(buffer, 0, sizeof(dummy_data));

			is_ok &= ErrorCheckAndLog("glFlushMappedNamedBufferRange", GL_INVALID_OPERATION,
									  " if the buffer is mapped without the MAP_FLUSH_EXPLICIT_BIT flag.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of GetNamedBufferParameteriv
 *         and GetNamedBufferParameteri64v functions.
 *
 *  Check that INVALID_OPERATION is generated by GetNamedBufferParameter* if
 *  buffer is not the name of an existing buffer object.
 *
 *  Check that INVALID_ENUM is generated by GetNamedBufferParameter* if
 *  pname is not one of the buffer object parameter names: BUFFER_ACCESS,
 *  BUFFER_ACCESS_FLAGS, BUFFER_IMMUTABLE_STORAGE, BUFFER_MAPPED,
 *  BUFFER_MAP_LENGTH, BUFFER_MAP_OFFSET, BUFFER_SIZE, BUFFER_STORAGE_FLAGS,
 *  BUFFER_USAGE.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfGetNamedBufferParameter()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer		   = 0;
	glw::GLubyte dummy_data[4] = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name in GetNamedBufferParameteriv function error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			glw::GLint value = 0;

			/* Test. */
			m_pGetNamedBufferParameteriv(not_a_buffer_name, GL_BUFFER_MAPPED, &value);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteriv", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test invalid buffer name in GetNamedBufferParameteri64v function error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			glw::GLint64 value = 0;

			/* Test. */
			m_pGetNamedBufferParameteri64v(not_a_buffer_name, GL_BUFFER_MAPPED, &value);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteri64v", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test invalid parameter name in GetNamedBufferParameteriv function error behavior. */
		{
			/* Prepare for invalid parameter name error behavior verification. */
			static const glw::GLenum valid_parameters[] = {
				GL_BUFFER_ACCESS, GL_BUFFER_ACCESS_FLAGS,  GL_BUFFER_IMMUTABLE_STORAGE,
				GL_BUFFER_MAPPED, GL_BUFFER_MAP_LENGTH,	GL_BUFFER_MAP_OFFSET,
				GL_BUFFER_SIZE,   GL_BUFFER_STORAGE_FLAGS, GL_BUFFER_USAGE,
				GL_NONE
			};
			static const glw::GLenum valid_parameters_last = sizeof(valid_parameters) / sizeof(valid_parameters[0]) - 1;

			glw::GLint value = 0;

			glw::GLenum invalid_parameter = 0;

			while (&valid_parameters[valid_parameters_last] !=
				   std::find(&valid_parameters[0], &valid_parameters[valid_parameters_last], (++invalid_parameter)))
				;

			/* Test. */
			m_pGetNamedBufferParameteriv(buffer, invalid_parameter, &value);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteriv", GL_INVALID_ENUM,
									  " if pname is not one of the buffer object parameter names: BUFFER_ACCESS,"
									  " BUFFER_ACCESS_FLAGS, BUFFER_IMMUTABLE_STORAGE, BUFFER_MAPPED,"
									  " BUFFER_MAP_LENGTH, BUFFER_MAP_OFFSET, BUFFER_SIZE, BUFFER_STORAGE_FLAGS,"
									  " BUFFER_USAGE.");
		}

		/* Test invalid parameter name in GetNamedBufferParameteri64v function error behavior. */
		{
			/* Prepare for invalid parameter name error behavior verification. */
			static const glw::GLenum valid_parameters[] = {
				GL_BUFFER_ACCESS, GL_BUFFER_ACCESS_FLAGS,  GL_BUFFER_IMMUTABLE_STORAGE,
				GL_BUFFER_MAPPED, GL_BUFFER_MAP_LENGTH,	GL_BUFFER_MAP_OFFSET,
				GL_BUFFER_SIZE,   GL_BUFFER_STORAGE_FLAGS, GL_BUFFER_USAGE,
				GL_NONE
			};
			static const glw::GLenum valid_parameters_last = sizeof(valid_parameters) / sizeof(valid_parameters[0]) - 1;

			glw::GLint64 value = 0;

			glw::GLenum invalid_parameter = 0;

			while (&valid_parameters[valid_parameters_last] !=
				   std::find(&valid_parameters[0], &valid_parameters[valid_parameters_last], (++invalid_parameter)))
				;

			/* Test. */
			m_pGetNamedBufferParameteri64v(buffer, invalid_parameter, &value);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferParameteri64v", GL_INVALID_ENUM,
									  " if pname is not one of the buffer object parameter names: BUFFER_ACCESS,"
									  " BUFFER_ACCESS_FLAGS, BUFFER_IMMUTABLE_STORAGE, BUFFER_MAPPED,"
									  " BUFFER_MAP_LENGTH, BUFFER_MAP_OFFSET, BUFFER_SIZE, BUFFER_STORAGE_FLAGS,"
									  " BUFFER_USAGE.");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of GetNamedBufferPointerv function.
 *
 *  Check that INVALID_OPERATION is generated by GetNamedBufferPointerv
 *  if buffer is not the name of an existing buffer object.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfGetNamedBufferPointerv()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer		   = 0;
	glw::GLubyte dummy_data[4] = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name in GetNamedBufferPointerv function error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			glw::GLvoid* pointer = DE_NULL;

			/* Test. */
			m_pGetNamedBufferPointerv(not_a_buffer_name, GL_BUFFER_MAP_POINTER, &pointer);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferPointerv", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of GetNamedBufferSubData function.
 *
 *  Check that INVALID_OPERATION is generated by GetNamedBufferSubData if
 *  buffer is not the name of an existing buffer object.
 *
 *  Check that INVALID_VALUE is generated by GetNamedBufferSubData if offset
 *  or size is negative, or if offset+size is greater than the value of
 *  BUFFER_SIZE for the buffer object.
 *
 *  Check that INVALID_OPERATION is generated by GetNamedBufferSubData if
 *  the buffer object is mapped with MapBufferRange or MapBuffer, unless it
 *  was mapped with the MAP_PERSISTENT_BIT bit set in the MapBufferRange
 *  access flags.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfGetNamedBufferSubData()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer		   = 0;
	glw::GLubyte dummy_data[4] = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name in pGetNamedBufferSubData function error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Query storage. */
			glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};

			/* Test. */
			m_pGetNamedBufferSubData(not_a_buffer_name, 0, sizeof(dummy_data_query), dummy_data_query);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test negative offset error behavior. */
		{
			/* Query storage. */
			glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};

			/* Test. */
			m_pGetNamedBufferSubData(buffer, -1, sizeof(dummy_data_query), dummy_data_query);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE, " if offset is negative.");
		}

		/* Test negative size error behavior. */
		{
			/* Query storage. */
			glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};

			/* Test. */
			m_pGetNamedBufferSubData(buffer, 0, -1, dummy_data_query);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE, " if size is negative.");
		}

		/* Test size overflow error behavior. */
		{
			/* Query storage. */
			glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};

			/* Test. */
			m_pGetNamedBufferSubData(buffer, 0, 2 * sizeof(dummy_data_query), dummy_data_query);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
									  " if size is greater than the value of BUFFER_SIZE for the buffer object.");
		}

		/* Test offset+size overflow error behavior. */
		{
			/* Query storage. */
			glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};

			/* Test. */
			m_pGetNamedBufferSubData(buffer, sizeof(dummy_data_query) / 2, sizeof(dummy_data_query), dummy_data_query);

			is_ok &=
				ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
								 " if offset+size is greater than the value of BUFFER_SIZE for the buffer object.");
		}

		/* Test offset overflow error behavior. */
		{
			/* Query storage. */
			glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};

			/* Test. */
			m_pGetNamedBufferSubData(buffer, sizeof(dummy_data_query) + 1, 0, dummy_data_query);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_VALUE,
									  " if offset is greater than the value of BUFFER_SIZE for the buffer object.");
		}

		/* Test mapped buffer query error behavior. */
		{
			/* Query storage. */
			glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};

			/* Test. */
			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_WRITE_ONLY);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pGetNamedBufferSubData(buffer, 0, sizeof(dummy_data_query), dummy_data_query);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
									  " if the buffer object is mapped with MapBufferRange.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test mapped buffer query error behavior. */
		{
			/* Query storage. */
			glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};

			/* Test. */
			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_WRITE_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pGetNamedBufferSubData(buffer, 0, sizeof(dummy_data_query), dummy_data_query);

			is_ok &= ErrorCheckAndLog("glGetNamedBufferSubData", GL_INVALID_OPERATION,
									  " if the buffer object is mapped with MapBufferRange.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test persistently mapped buffer query behavior. */
		{
			/* Query storage. */
			glw::GLubyte dummy_data_query[sizeof(dummy_data) / sizeof(dummy_data[0])] = {};

			/* Test. */
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pGetNamedBufferSubData(buffer, 0, sizeof(dummy_data_query), dummy_data_query);

			is_ok &= ErrorCheckAndLog(
				"glGetNamedBufferSubData", GL_NO_ERROR,
				" if the buffer object is mapped with MapBufferRange with GL_MAP_PERSISTENT_BIT flag.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of MapNamedBuffer function.
 *
 *  Check that INVALID_OPERATION is generated by MapNamedBuffer if buffer is
 *  not the name of an existing buffer object.
 *
 *  Check that INVALID_ENUM is generated by MapNamedBuffer if access is not
 *  READ_ONLY, WRITE_ONLY, or READ_WRITE.
 *
 *  Check that INVALID_OPERATION is generated by MapNamedBuffer if the
 *  buffer object is in a mapped state.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfMapNamedBuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer		   = 0;
	glw::GLubyte dummy_data[4] = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pMapNamedBuffer(not_a_buffer_name, GL_READ_ONLY);

			is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test access flag error behavior. */
		{
			/* Prepare for invalid type error behavior verification. */
			static const glw::GLenum valid_access_flags[] = { GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE, GL_NONE };
			static const glw::GLenum valid_access_flags_last =
				sizeof(valid_access_flags) / sizeof(valid_access_flags[0]) - 1;

			glw::GLenum invalid_access_flags = 0;

			while (&valid_access_flags[valid_access_flags_last] !=
				   std::find(&valid_access_flags[0], &valid_access_flags[valid_access_flags_last],
							 (++invalid_access_flags)))
				;

			/* Test. */
			glw::GLbyte* mapped_data = (glw::GLbyte*)m_pMapNamedBuffer(buffer, invalid_access_flags);

			is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_ENUM,
									  " if access is not READ_ONLY, WRITE_ONLY, or READ_WRITE.");

			/* Sanity unmapping. */
			if (DE_NULL != mapped_data)
			{
				m_pUnmapNamedBuffer(buffer);
				while (gl.getError())
					;
			}
		}

		/* Test mapping of mapped buffer error behavior. */
		{
			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer.");

			glw::GLbyte* subsequent_mapped_data = (glw::GLbyte*)m_pMapNamedBuffer(buffer, GL_READ_ONLY);

			is_ok &= ErrorCheckAndLog("glMapNamedBuffer", GL_INVALID_OPERATION,
									  " if the buffer object is in a mapped state.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");

			if (subsequent_mapped_data)
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glMapNamedBuffer called on mapped buffer returned non-NULL pointer when error shall occure."
					   "This may lead to undefined behavior during next tests (object still may be mapped). "
					   "Test was terminated prematurely."
					<< tcu::TestLog::EndMessage;
				throw 0;
			}
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of MapNamedBufferRange function.
 *
 *  Check that INVALID_OPERATION is generated by MapNamedBufferRange if
 *  buffer is not the name of an existing buffer object.
 *
 *  Check that INVALID_VALUE is generated by MapNamedBufferRange if offset
 *  or length is negative, if offset+length is greater than the value of
 *  BUFFER_SIZE for the buffer object, or if access has any bits set other
 *  than those defined above.
 *
 *  Check that INVALID_OPERATION is generated by MapNamedBufferRange for any
 *  of the following conditions:
 *   -  length is zero.
 *   -  The buffer object is already in a mapped state.
 *   -  Neither MAP_READ_BIT nor MAP_WRITE_BIT is set.
 *   -  MAP_READ_BIT is set and any of MAP_INVALIDATE_RANGE_BIT,
 *      MAP_INVALIDATE_BUFFER_BIT or MAP_UNSYNCHRONIZED_BIT is set.
 *   -  MAP_FLUSH_EXPLICIT_BIT is set and MAP_WRITE_BIT is not set.
 *   -  Any of MAP_READ_BIT, MAP_WRITE_BIT, MAP_PERSISTENT_BIT, or
 *      MAP_COHERENT_BIT are set, but the same bit is not included in the
 *      buffer's storage flags.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfMapNamedBufferRange()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer				  = 0;
	glw::GLuint  buffer_special_flags = 0;
	glw::GLubyte dummy_data[4]		  = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data,
							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pMapNamedBufferRange(not_a_buffer_name, 0, sizeof(dummy_data), GL_MAP_READ_BIT);

			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test negative offset error behavior. */
		{
			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, -1, sizeof(dummy_data), GL_MAP_READ_BIT);

			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE, " if offset is negative.");

			/* Sanity unmapping. */
			if (DE_NULL != mapped_data)
			{
				m_pUnmapNamedBuffer(buffer);
				while (gl.getError())
					;
			}
		}

		/* Test negative length error behavior. */
		{
			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, -1, GL_MAP_READ_BIT);

			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE, " if length is negative.");

			/* Sanity unmapping. */
			if (DE_NULL != mapped_data)
			{
				m_pUnmapNamedBuffer(buffer);
				while (gl.getError())
					;
			}
		}

		/* Test length overflow error behavior. */
		{
			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data) * 2, GL_MAP_READ_BIT);

			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE,
									  " if length is greater than the value of BUFFER_SIZE"
									  " for the buffer object, or if access has any bits set other"
									  " than those defined above.");

			/* Sanity unmapping. */
			if (DE_NULL != mapped_data)
			{
				m_pUnmapNamedBuffer(buffer);
				while (gl.getError())
					;
			}
		}

		/* Test (offset+length) overflow error behavior. */
		{
			glw::GLvoid* mapped_data =
				m_pMapNamedBufferRange(buffer, sizeof(dummy_data) / 2, sizeof(dummy_data), GL_MAP_READ_BIT);

			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_VALUE,
									  " if offset+length is greater than the value of BUFFER_SIZE"
									  " for the buffer object, or if access has any bits set other"
									  " than those defined above.");

			/* Sanity unmapping. */
			if (DE_NULL != mapped_data)
			{
				m_pUnmapNamedBuffer(buffer);
				while (gl.getError())
					;
			}
		}

		/* Test zero length error behavior. */
		{
			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, 0, GL_MAP_READ_BIT);

			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, " if length is zero.");

			/* Sanity unmapping. */
			if (DE_NULL != mapped_data)
			{
				m_pUnmapNamedBuffer(buffer);
				while (gl.getError())
					;
			}
		}

		/* Test mapping of mapped buffer error behavior. */
		{
			m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer.");

			glw::GLvoid* subsequent_mapped_data =
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT);

			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
									  " if the buffer object is in a mapped state.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");

			if (subsequent_mapped_data)
			{
				m_context.getTestContext().getLog()
					<< tcu::TestLog::Message
					<< "glMapNamedBufferRange called on mapped buffer returned non-NULL pointer when error shall "
					   "occure."
					   "This may lead to undefined behavior during next tests (object still may be mapped). "
					   "Test was terminated prematurely."
					<< tcu::TestLog::EndMessage;
				throw 0;
			}
		}

		/* Test access flag read and write bits are not set error behavior. */
		{
			glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), 0);

			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
									  " if neither MAP_READ_BIT nor MAP_WRITE_BIT is set.");

			/* Sanity unmapping. */
			if (DE_NULL != mapped_data)
			{
				m_pUnmapNamedBuffer(buffer);
				while (gl.getError())
					;
			}
		}

		/* Test read access invalid flags error behavior. */
		{
			glw::GLenum read_access_invalid_flags[] = { GL_MAP_INVALIDATE_RANGE_BIT, GL_MAP_INVALIDATE_BUFFER_BIT,
														GL_MAP_UNSYNCHRONIZED_BIT };
			const glw::GLchar* read_access_invalid_flags_log[] = {
				" if MAP_READ_BIT is set with MAP_INVALIDATE_RANGE_BIT.",
				" if MAP_READ_BIT is set with MAP_INVALIDATE_BUFFER_BIT.",
				" if MAP_READ_BIT is set with MAP_UNSYNCHRONIZED_BIT."
			};
			glw::GLuint read_access_invalid_flags_count =
				sizeof(read_access_invalid_flags) / sizeof(read_access_invalid_flags[0]);

			for (glw::GLuint i = 0; i < read_access_invalid_flags_count; ++i)
			{
				glw::GLvoid* mapped_data = m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data),
																  GL_MAP_READ_BIT | read_access_invalid_flags[i]);

				is_ok &=
					ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, read_access_invalid_flags_log[i]);

				/* Sanity unmapping. */
				if (DE_NULL != mapped_data)
				{
					m_pUnmapNamedBuffer(buffer);
					while (gl.getError())
						;
				}
			}
		}

		/* Test access flush bit without write bit error behavior. */
		{
			glw::GLvoid* mapped_data =
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);

			is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION,
									  " if MAP_FLUSH_EXPLICIT_BIT is set and MAP_WRITE_BIT is not set.");

			/* Sanity unmapping. */
			if (DE_NULL != mapped_data)
			{
				m_pUnmapNamedBuffer(buffer);
				while (gl.getError())
					;
			}
		}

		/* Test incompatible buffer flag error behavior. */
		{
			glw::GLenum buffer_flags[] = { GL_MAP_WRITE_BIT, GL_MAP_READ_BIT, GL_MAP_WRITE_BIT,
										   GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT };
			glw::GLenum mapping_flags[] = { GL_MAP_READ_BIT, GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT,
											GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT };
			const glw::GLchar* mapping_flags_log[] = {
				" if MAP_READ_BIT is set, but the same bit is not included in the buffer's storage flags.",
				" if MAP_WRITE_BIT is set, but the same bit is not included in the buffer's storage flags.",
				" if MAP_PERSISTENT_BIT is set, but the same bit is not included in the buffer's storage flags.",
				" if MAP_COHERENT_BIT is set, but the same bit is not included in the buffer's storage flags."
			};
			glw::GLuint flags_count = sizeof(mapping_flags) / sizeof(mapping_flags[0]);

			for (glw::GLuint i = 0; i < flags_count; ++i)
			{
				/* Create buffer. */
				gl.createBuffers(1, &buffer_special_flags);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

				m_pNamedBufferStorage(buffer_special_flags, sizeof(dummy_data), &dummy_data, buffer_flags[i]);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

				/* Test mapping. */
				glw::GLvoid* mapped_data =
					m_pMapNamedBufferRange(buffer_special_flags, 0, sizeof(dummy_data), mapping_flags[i]);

				is_ok &= ErrorCheckAndLog("glMapNamedBufferRange", GL_INVALID_OPERATION, mapping_flags_log[i]);

				/* Sanity unmapping. */
				if (DE_NULL != mapped_data)
				{
					m_pUnmapNamedBuffer(buffer);
					while (gl.getError())
						;
				}

				/* Releasing buffer. */
				if (buffer_special_flags)
				{
					gl.deleteBuffers(1, &buffer_special_flags);

					buffer_special_flags = 0;
				}
			}
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (buffer_special_flags)
	{
		gl.deleteBuffers(1, &buffer_special_flags);

		buffer_special_flags = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of NamedBufferData function.
 *
 *          Check that INVALID_OPERATION is generated by NamedBufferData if buffer
 *          is not the name of an existing buffer object.
 *
 *          Check that INVALID_ENUM is generated by NamedBufferData if usage is not
 *          STREAM_DRAW, STREAM_READ, STREAM_COPY, STATIC_DRAW, STATIC_READ,
 *          STATIC_COPY, DYNAMIC_DRAW, DYNAMIC_READ or DYNAMIC_COPY.
 *
 *          Check that INVALID_VALUE is generated by NamedBufferData if size is
 *          negative.
 *
 *          Check that INVALID_OPERATION is generated by NamedBufferData if the
 *          BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfNamedBufferData()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint				buffer			 = 0;
	glw::GLuint				immutable_buffer = 0;
	glw::GLubyte			dummy_data[4]	= {};
	std::stack<glw::GLuint> too_much_buffers;

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		gl.createBuffers(1, &immutable_buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(immutable_buffer, sizeof(dummy_data), &dummy_data, GL_MAP_READ_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pNamedBufferData(not_a_buffer_name, sizeof(dummy_data), dummy_data, GL_DYNAMIC_COPY);

			is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test invalid usage error behavior. */
		{
			/* Prepare for invalid type error behavior verification. */
			static const glw::GLenum valid_usages[] = { GL_STREAM_DRAW,  GL_STREAM_READ,  GL_STREAM_COPY,
														GL_STATIC_DRAW,  GL_STATIC_READ,  GL_STATIC_COPY,
														GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY,
														GL_NONE };
			static const glw::GLenum valid_usages_last = sizeof(valid_usages) / sizeof(valid_usages[0]) - 1;

			glw::GLenum invalid_usage = 0;

			while (&valid_usages[valid_usages_last] !=
				   std::find(&valid_usages[0], &valid_usages[valid_usages_last], (++invalid_usage)))
				;

			/* Test. */
			m_pNamedBufferData(buffer, sizeof(dummy_data), dummy_data, invalid_usage);

			is_ok &=
				ErrorCheckAndLog("glNamedBufferData", GL_INVALID_ENUM,
								 " if usage is not STREAM_DRAW, STREAM_READ, STREAM_COPY, STATIC_DRAW, STATIC_READ,"
								 " STATIC_COPY, DYNAMIC_DRAW, DYNAMIC_READ or DYNAMIC_COPY.");
		}

		/* Test negative size error behavior. */
		{
			m_pNamedBufferData(buffer, -1, dummy_data, GL_DYNAMIC_COPY);

			is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_VALUE, " if size is negative.");
		}

		/* Test immutable buffer error behavior. */
		{
			m_pNamedBufferData(immutable_buffer, sizeof(dummy_data) / 2, dummy_data, GL_DYNAMIC_COPY);

			is_ok &= ErrorCheckAndLog("glNamedBufferData", GL_INVALID_OPERATION,
									  " if the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE.");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	while (!too_much_buffers.empty())
	{
		glw::GLuint tmp_buffer = too_much_buffers.top();

		if (tmp_buffer)
		{
			gl.deleteBuffers(1, &tmp_buffer);
		}

		too_much_buffers.pop();
	}

	if (immutable_buffer)
	{
		gl.deleteBuffers(1, &immutable_buffer);

		immutable_buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of NamedBufferStorage function.
 *
 *  Check that INVALID_OPERATION is generated by NamedBufferStorage if
 *  buffer is not the name of an existing buffer object.
 *
 *  Check that INVALID_VALUE is generated by NamedBufferStorage if size is
 *  less than or equal to zero.
 *
 *  Check that INVALID_VALUE is generated by NamedBufferStorage if flags has
 *  any bits set other than DYNAMIC_STORAGE_BIT, MAP_READ_BIT,
 *  MAP_WRITE_BIT, MAP_PERSISTENT_BIT, MAP_COHERENT_BIT or
 *  CLIENT_STORAGE_BIT.
 *
 *  Check that INVALID_VALUE error is generated by NamedBufferStorage if
 *  flags contains MAP_PERSISTENT_BIT but does not contain at least one of
 *  MAP_READ_BIT or MAP_WRITE_BIT.
 *
 *  Check that INVALID_VALUE is generated by NamedBufferStorage if flags
 *  contains MAP_COHERENT_BIT, but does not also contain MAP_PERSISTENT_BIT.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfNamedBufferStorage()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint				buffer		  = 0;
	glw::GLubyte			dummy_data[4] = {};
	std::stack<glw::GLuint> too_much_buffers;

	try
	{
		/* Test invalid buffer name error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pNamedBufferStorage(not_a_buffer_name, sizeof(dummy_data), dummy_data, GL_MAP_WRITE_BIT);

			is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test negative or zero size error behavior. */
		{
			/* Object creation. */
			gl.createBuffers(1, &buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

			/* Test negative size. */
			m_pNamedBufferStorage(buffer, -1, dummy_data, GL_DYNAMIC_COPY);

			is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if size is negative.");

			/* Test zero size. */
			m_pNamedBufferStorage(buffer, 0, dummy_data, GL_DYNAMIC_COPY);

			is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if size zero.");

			/* Clean-up. */
			gl.deleteBuffers(1, &buffer);

			buffer = 0;

			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
		}

		/* Test invalid usage bit error behavior. */
		{
			/* Prepare for invalid type error behavior verification. */
			glw::GLuint valid_bits = GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
									 GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT;

			if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_buffer"))
			{
				valid_bits |= GL_SPARSE_STORAGE_BIT_ARB;
			}

			if (m_context.getContextInfo().isExtensionSupported("GL_NV_gpu_multicast") ||
				m_context.getContextInfo().isExtensionSupported("GL_NVX_linked_gpu_multicast"))
			{
				valid_bits |= GL_PER_GPU_STORAGE_BIT_NV;
			}

			if (m_context.getContextInfo().isExtensionSupported("GL_NVX_cross_process_interop"))
			{
				valid_bits |= GL_EXTERNAL_STORAGE_BIT_NVX;
			}

			glw::GLuint invalid_bits = ~valid_bits;

			glw::GLuint bits_count = CHAR_BIT * sizeof(invalid_bits);

			/* Test. */
			for (glw::GLuint i = 0; i < bits_count; ++i)
			{
				glw::GLuint possibly_invalid_bit = (1 << i);

				if (invalid_bits & possibly_invalid_bit)
				{
					/* Object creation. */
					gl.createBuffers(1, &buffer);
					GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

					/* Test invalid bit. */
					m_pNamedBufferStorage(buffer, sizeof(dummy_data), dummy_data, possibly_invalid_bit);

					is_ok &=
						ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE,
										 " if flags has any bits set other than DYNAMIC_STORAGE_BIT, MAP_READ_BIT,"
										 " MAP_WRITE_BIT, MAP_PERSISTENT_BIT, MAP_COHERENT_BIT or CLIENT_STORAGE_BIT.");

					/* Release object. */
					gl.deleteBuffers(1, &buffer);

					buffer = 0;

					GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
				}
			}
		}

		/* Test improper persistent bit behavior error behavior. */
		{
			/* Object creation. */
			gl.createBuffers(1, &buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

			/* Test. */
			m_pNamedBufferStorage(buffer, sizeof(dummy_data), dummy_data, GL_MAP_PERSISTENT_BIT);

			is_ok &= ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE, " if flags contains MAP_PERSISTENT_BIT "
																				"but does not contain at least one of "
																				"MAP_READ_BIT or MAP_WRITE_BIT.");

			/* Clean-up. */
			gl.deleteBuffers(1, &buffer);

			buffer = 0;

			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
		}

		/* Test improper persistent bit behavior error behavior. */
		{
			/* Object creation. */
			gl.createBuffers(1, &buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

			/* Test. */
			m_pNamedBufferStorage(buffer, sizeof(dummy_data), dummy_data,
								  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_COHERENT_BIT);

			is_ok &=
				ErrorCheckAndLog("glNamedBufferStorage", GL_INVALID_VALUE,
								 " if flags contains MAP_COHERENT_BIT, but does not also contain MAP_PERSISTENT_BIT.");

			/* Clean-up. */
			gl.deleteBuffers(1, &buffer);

			buffer = 0;

			GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers failed.");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	while (!too_much_buffers.empty())
	{
		glw::GLuint tmp_buffer = too_much_buffers.top();

		if (tmp_buffer)
		{
			gl.deleteBuffers(1, &tmp_buffer);
		}

		too_much_buffers.pop();
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of NamedBufferSubData function.
 *
 *  Check that INVALID_OPERATION is generated by NamedBufferSubData if
 *  buffer is not the name of an existing buffer object.
 *
 *  Check that INVALID_VALUE is generated by NamedBufferSubData if offset or
 *  size is negative, or if offset+size is greater than the value of
 *  BUFFER_SIZE for the specified buffer object.
 *
 *  Check that INVALID_OPERATION is generated by NamedBufferSubData if any
 *  part of the specified range of the buffer object is mapped with
 *  MapBufferRange or MapBuffer, unless it was mapped with the
 *  MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.
 *
 *  Check that INVALID_OPERATION is generated by NamedBufferSubData if the
 *  value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE
 *  and the value of BUFFER_STORAGE_FLAGS for the buffer object does not
 *  have the DYNAMIC_STORAGE_BIT bit set.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfNamedBufferSubData()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer					  = 0;
	glw::GLuint  immutable_storage_buffer = 0;
	glw::GLubyte dummy_data[4]			  = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data,
							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		gl.createBuffers(1, &immutable_storage_buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(immutable_storage_buffer, sizeof(dummy_data), &dummy_data, GL_MAP_READ_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pNamedBufferSubData(not_a_buffer_name, 0, sizeof(dummy_data), &dummy_data);

			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test negative offset error behavior. */
		{
			/* Test. */
			m_pNamedBufferSubData(buffer, -1, sizeof(dummy_data), &dummy_data);

			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
		}

		/* Test negative size error behavior. */
		{
			/* Test. */
			m_pNamedBufferSubData(buffer, 0, -1, &dummy_data);

			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_VALUE, " if offset or size is negative.");
		}

		/* Test size overflow error behavior. */
		{
			/* Test. */
			m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data) * 2, &dummy_data);

			is_ok &= ErrorCheckAndLog(
				"glNamedBufferSubData", GL_INVALID_VALUE,
				" if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
		}

		/* Test offset+size overflow error behavior. */
		{
			/* Test. */
			m_pNamedBufferSubData(buffer, sizeof(dummy_data) / 2, sizeof(dummy_data), &dummy_data);

			is_ok &= ErrorCheckAndLog(
				"glNamedBufferSubData", GL_INVALID_VALUE,
				" if offset+size is greater than the value of BUFFER_SIZE for the specified buffer object.");
		}

		/* Test of mapped buffer subdata error behavior verification (with glMapBuffer). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBuffer(buffer, GL_READ_ONLY);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data), &dummy_data);

			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
									  " if any part of the specified range of the buffer"
									  " object is mapped with MapBuffer, unless it was mapped with "
									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of mapped buffer subdata error behavior verification (with glMapBufferRange). */
		{
			(void)(glw::GLbyte*) m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data), &dummy_data);

			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
									  " if any part of the specified range of the buffer"
									  " object is mapped with MapBufferRange, unless it was mapped with "
									  "the MAP_PERSISTENT_BIT bit set in the MapBufferRange access flags.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test of persistently mapped buffer clear error with behavior verification. */
		{
			(void)(glw::GLbyte*)
				m_pMapNamedBufferRange(buffer, 0, sizeof(dummy_data), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glMapNamedBuffer failed.");

			m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data), &dummy_data);

			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_NO_ERROR,
									  " if any part of the specified range of the buffer"
									  " object is mapped with MapBuffer with the MAP_PERSISTENT_BIT"
									  " bit set in the MapBufferRange access flags.");

			m_pUnmapNamedBuffer(buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapNamedBuffer failed.");
		}

		/* Test DYNAMIC_STORAGE_BIT bit off immutable buffer not set error behavior. */
		{
			/* Test. */
			m_pNamedBufferSubData(immutable_storage_buffer, 0, sizeof(dummy_data), &dummy_data);

			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_INVALID_OPERATION,
									  " if the value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE"
									  " and the value of BUFFER_STORAGE_FLAGS for the buffer object does not"
									  " have the DYNAMIC_STORAGE_BIT bit set.");
		}

		/* Test DYNAMIC_STORAGE_BIT bit off immutable buffer set no error behavior. */
		{
			/* Test. */
			m_pNamedBufferSubData(buffer, 0, sizeof(dummy_data), &dummy_data);

			is_ok &= ErrorCheckAndLog("glNamedBufferSubData", GL_NO_ERROR,
									  " if the value of the BUFFER_IMMUTABLE_STORAGE flag of the buffer object is TRUE"
									  " and the value of BUFFER_STORAGE_FLAGS for the buffer object"
									  " have the DYNAMIC_STORAGE_BIT bit set.");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (immutable_storage_buffer)
	{
		gl.deleteBuffers(1, &immutable_storage_buffer);

		buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/** @brief Test Errors Of UnmapNamedBuffer function.
 *
 *  Check that INVALID_OPERATION is generated by UnmapNamedBuffer if buffer
 *  is not the name of an existing buffer object.
 *
 *  Check that INVALID_OPERATION is generated by UnmapNamedBuffer if the
 *  buffer object is not in a mapped state.
 *
 *  True if test case succeeded, false otherwise.
 */
bool ErrorsTest::TestErrorsOfUnmapNamedBuffer()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Return value. */
	bool is_ok			= true;
	bool internal_error = false;

	/* Common variables. */
	glw::GLuint  buffer		   = 0;
	glw::GLubyte dummy_data[4] = {};

	try
	{
		/* Common preparations. */
		gl.createBuffers(1, &buffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers failed.");

		m_pNamedBufferStorage(buffer, sizeof(dummy_data), &dummy_data,
							  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBuffeStorage failed.");

		/* Test invalid buffer name error behavior. */
		{
			/* Prepare for invalid buffer name error behavior verification. */
			glw::GLuint not_a_buffer_name = 0;

			while (gl.isBuffer(++not_a_buffer_name))
				;

			/* Test. */
			m_pUnmapNamedBuffer(not_a_buffer_name);

			is_ok &= ErrorCheckAndLog("glUnmapNamedBuffer", GL_INVALID_OPERATION,
									  " if buffer is not the name of an existing buffer object.");
		}

		/* Test not mapped buffer error behavior verification. */
		{
			m_pUnmapNamedBuffer(buffer);

			is_ok &= ErrorCheckAndLog("glUnmapNamedBuffer", GL_INVALID_OPERATION,
									  " if the buffer object is not in a mapped state.");
		}
	}
	catch (...)
	{
		is_ok		   = false;
		internal_error = true;
	}

	if (buffer)
	{
		gl.deleteBuffers(1, &buffer);

		buffer = 0;
	}

	if (internal_error)
	{
		throw 0;
	}

	return is_ok;
}

/******************************** Functional Test Implementation   ********************************/

/** @brief Vertex shader source code */
const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 450\n"
													  "\n"
													  "in  int data_in;\n"
													  "out int data_out;\n"
													  "\n"
													  "void main()\n"
													  "{\n"
													  "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
													  "\n"
													  "    data_out = data_in * data_in;\n"
													  "}\n";

/** @brief Fragment shader source code */
const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 450\n"
														"\n"
														"out vec4 color;\n"
														"\n"
														"void main()\n"
														"{\n"
														"    color = vec4(0.0);\n"
														"}\n";

const glw::GLchar FunctionalTest::s_vertex_shader_input_name[] =
	"data_in"; //!< Vertex shader's name of the input attribute.

const glw::GLchar* FunctionalTest::s_vertex_shader_output_name =
	"data_out"; //!< Vertex shader's name of the transform feedback varying.

const glw::GLint FunctionalTest::s_initial_data_a[] = {
	1, 2, 3, 4, 5, 5
}; //!< Initial data to be uploaded for the input buffer.

const glw::GLint FunctionalTest::s_initial_data_b[] = {
	0, 0, 0, 0, 0, 0, 36
}; //!< Initial data to be uploaded for the output buffer.

const glw::GLint FunctionalTest::s_expected_data[] = {
	0, 1, 4, 9, 16, 25, 36
}; //!< Expected result which shall be read from output buffer.

/** @brief Functional Test constructor.
 *
 *  @param [in] context     OpenGL context.
 */
FunctionalTest::FunctionalTest(deqp::Context& context)
	: deqp::TestCase(context, "buffers_functional", "Buffer Objects Functional Test")
	, m_pClearNamedBufferData(DE_NULL)
	, m_pClearNamedBufferSubData(DE_NULL)
	, m_pCopyNamedBufferSubData(DE_NULL)
	, m_pFlushMappedNamedBufferRange(DE_NULL)
	, m_pGetNamedBufferParameteri64v(DE_NULL)
	, m_pGetNamedBufferParameteriv(DE_NULL)
	, m_pGetNamedBufferPointerv(DE_NULL)
	, m_pGetNamedBufferSubData(DE_NULL)
	, m_pMapNamedBuffer(DE_NULL)
	, m_pMapNamedBufferRange(DE_NULL)
	, m_pNamedBufferData(DE_NULL)
	, m_pNamedBufferStorage(DE_NULL)
	, m_pNamedBufferSubData(DE_NULL)
	, m_pUnmapNamedBuffer(DE_NULL)
	, m_po(0)
	, m_vao(0)
	, m_bo_in(0)
	, m_bo_out(0)
	, m_attrib_location(-1)
{
	/* Intentionally left blank. */
}

/** @brief Run Functional Test.
 *
 *  @return Iteration result.
 */
tcu::TestNode::IterateResult FunctionalTest::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;

	/* API function pointers setup. */
	m_pClearNamedBufferData		   = (PFNGLCLEARNAMEDBUFFERDATA)gl.clearNamedBufferData;
	m_pClearNamedBufferSubData	 = (PFNGLCLEARNAMEDBUFFERSUBDATA)gl.clearNamedBufferSubData;
	m_pCopyNamedBufferSubData	  = (PFNGLCOPYNAMEDBUFFERSUBDATA)gl.copyNamedBufferSubData;
	m_pFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGE)gl.flushMappedNamedBufferRange;
	m_pGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64V)gl.getNamedBufferParameteri64v;
	m_pGetNamedBufferParameteriv   = (PFNGLGETNAMEDBUFFERPARAMETERIV)gl.getNamedBufferParameteriv;
	m_pGetNamedBufferPointerv	  = (PFNGLGETNAMEDBUFFERPOINTERV)gl.getNamedBufferPointerv;
	m_pGetNamedBufferSubData	   = (PFNGLGETNAMEDBUFFERSUBDATA)gl.getNamedBufferSubData;
	m_pMapNamedBuffer			   = (PFNGLMAPNAMEDBUFFER)gl.mapNamedBuffer;
	m_pMapNamedBufferRange		   = (PFNGLMAPNAMEDBUFFERRANGE)gl.mapNamedBufferRange;
	m_pNamedBufferData			   = (PFNGLNAMEDBUFFERDATA)gl.namedBufferData;
	m_pNamedBufferStorage		   = (PFNGLNAMEDBUFFERSTORAGE)gl.namedBufferStorage;
	m_pNamedBufferSubData		   = (PFNGLNAMEDBUFFERSUBDATA)gl.namedBufferSubData;
	m_pUnmapNamedBuffer			   = (PFNGLUNMAPNAMEDBUFFER)gl.unmapNamedBuffer;

	try
	{
		/* API function pointers check. */
		if ((DE_NULL == m_pClearNamedBufferData) || (DE_NULL == m_pClearNamedBufferSubData) ||
			(DE_NULL == m_pCopyNamedBufferSubData) || (DE_NULL == m_pFlushMappedNamedBufferRange) ||
			(DE_NULL == m_pGetNamedBufferParameteri64v) || (DE_NULL == m_pGetNamedBufferParameteriv) ||
			(DE_NULL == m_pGetNamedBufferPointerv) || (DE_NULL == m_pGetNamedBufferSubData) ||
			(DE_NULL == m_pMapNamedBuffer) || (DE_NULL == m_pMapNamedBufferRange) || (DE_NULL == m_pNamedBufferData) ||
			(DE_NULL == m_pNamedBufferStorage) || (DE_NULL == m_pNamedBufferSubData) ||
			(DE_NULL == m_pUnmapNamedBuffer))
		{
			throw 0;
		}

		/* Running test. */
		BuildProgram();
		PrepareVertexArrayObject();

		is_ok = is_ok && PrepareInputBuffer();
		is_ok = is_ok && PrepareOutputBuffer();

		if (is_ok)
		{
			Draw();
		}

		is_ok = is_ok && CheckArrayBufferImmutableFlag();
		is_ok = is_ok && CheckTransformFeedbackBufferSize();
		is_ok = is_ok && CheckTransformFeedbackResult();
	}
	catch (...)
	{
		is_ok	= false;
		is_error = true;
	}

	/* Clean Up. */
	Cleanup();

	/* 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 Build test's GL program */
void FunctionalTest::BuildProgram()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	struct Shader
	{
		glw::GLchar const* 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;
				}
			}
		}

		/* Tranform feedback varying */
		gl.transformFeedbackVaryings(m_po, 1, &s_vertex_shader_output_name, GL_INTERLEAVED_ATTRIBS);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");

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

		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram 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 (m_po)
	{
		gl.useProgram(m_po);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
	}

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

/** @brief Prepare empty vertex array object and bind it. */
void FunctionalTest::PrepareVertexArrayObject()
{
	/* 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 failed.");

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

/** Prepare input buffer in the way described in test specification (see class comment). */
bool FunctionalTest::PrepareInputBuffer()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Constants. */
	static const glw::GLint zero = 0;
	static const glw::GLint one  = 1;

	/* Buffer preparation */
	gl.createBuffers(1, &m_bo_in);

	if (GL_NO_ERROR == gl.getError())
	{
		/* Storage and last (6th) element preparation. */
		m_pNamedBufferStorage(m_bo_in, sizeof(s_initial_data_a), s_initial_data_a,
							  GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT);

		if (GL_NO_ERROR == gl.getError())
		{
			/* First element preparation. */
			m_pClearNamedBufferSubData(m_bo_in, GL_R8, 0, sizeof(glw::GLint), GL_RED, GL_INT, &zero);

			if (GL_NO_ERROR == gl.getError())
			{
				/* Second element preparation. */
				m_pNamedBufferSubData(m_bo_in, 1 /* 2nd element */ * sizeof(glw::GLint), sizeof(glw::GLint), &one);

				if (GL_NO_ERROR == gl.getError())
				{
					/* Third element preparation. */
					glw::GLint* p = (glw::GLint*)m_pMapNamedBuffer(m_bo_in, GL_WRITE_ONLY);

					if ((GL_NO_ERROR == gl.getError()) || (DE_NULL == p))
					{
						p[2] = 2;

						m_pUnmapNamedBuffer(m_bo_in);

						if (GL_NO_ERROR == gl.getError())
						{
							/* Fifth element preparation. */
							m_pCopyNamedBufferSubData(m_bo_in, m_bo_in, sizeof(glw::GLint) * 3, sizeof(glw::GLint) * 4,
													  sizeof(glw::GLint));

							if (GL_NO_ERROR == gl.getError())
							{
								/* Fourth element preparation. */
								p = (glw::GLint*)m_pMapNamedBufferRange(
									m_bo_in, sizeof(glw::GLint) * 3, sizeof(glw::GLint),
									GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);

								if (GL_NO_ERROR == gl.getError())
								{
									/* Write to mapped buffer. */
									*p = 3;

									/* Flush test. */
									m_pFlushMappedNamedBufferRange(m_bo_in, 0, sizeof(glw::GLint));

									if (GL_NO_ERROR == gl.getError())
									{
										/* Mapped Buffer Pointer query. */
										glw::GLvoid* is_p = DE_NULL;
										m_pGetNamedBufferPointerv(m_bo_in, GL_BUFFER_MAP_POINTER, &is_p);

										if (GL_NO_ERROR == gl.getError())
										{
											/* Mapped Buffer pointer query check. */
											if (p == is_p)
											{
												/* Unmapping. */
												m_pUnmapNamedBuffer(m_bo_in);

												if (GL_NO_ERROR == gl.getError())
												{
													/* Setup buffer as input for vertex shader. */
													m_attrib_location =
														gl.getAttribLocation(m_po, s_vertex_shader_input_name);
													GLU_EXPECT_NO_ERROR(gl.getError(),
																		"glGetAttribLocation call failed.");

													gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_in);
													GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");

													gl.vertexAttribIPointer(m_attrib_location, 1, GL_INT, 0, NULL);
													GLU_EXPECT_NO_ERROR(gl.getError(),
																		"glVertexAttribIPointer call failed.");

													gl.enableVertexAttribArray(m_attrib_location);
													GLU_EXPECT_NO_ERROR(gl.getError(),
																		"glEnableVertexAttribArray call failed.");

													return true;
												}
												else
												{
													m_context.getTestContext().getLog()
														<< tcu::TestLog::Message << "UnmapNamedBuffer has failed."
														<< tcu::TestLog::EndMessage;
												}
											}
											else
											{
												m_pUnmapNamedBuffer(m_bo_in);
												m_context.getTestContext().getLog()
													<< tcu::TestLog::Message
													<< "Pointer returned by GetNamedBufferPointerv is not proper."
													<< tcu::TestLog::EndMessage;
											}
										}
										else
										{
											m_pUnmapNamedBuffer(m_bo_in);
											m_context.getTestContext().getLog() << tcu::TestLog::Message
																				<< "GetNamedBufferPointerv has failed."
																				<< tcu::TestLog::EndMessage;
										}
									}
									else
									{
										m_pUnmapNamedBuffer(m_bo_in);
										m_context.getTestContext().getLog() << tcu::TestLog::Message
																			<< "FlushMappedNamedBufferRange has failed."
																			<< tcu::TestLog::EndMessage;
									}
								}
								else
								{
									m_context.getTestContext().getLog() << tcu::TestLog::Message
																		<< "MapNamedBufferRange has failed."
																		<< tcu::TestLog::EndMessage;
								}
							}
							else
							{
								m_context.getTestContext().getLog() << tcu::TestLog::Message
																	<< "CopyNamedBufferSubData has failed."
																	<< tcu::TestLog::EndMessage;
							}
						}
						else
						{
							m_context.getTestContext().getLog()
								<< tcu::TestLog::Message << "UnmapNamedBuffer has failed." << tcu::TestLog::EndMessage;
						}
					}
					else
					{
						m_context.getTestContext().getLog() << tcu::TestLog::Message << "MapNamedBuffer has failed."
															<< tcu::TestLog::EndMessage;
					}
				}
				else
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedBufferSubData has failed."
														<< tcu::TestLog::EndMessage;
				}
			}
			else
			{
				m_context.getTestContext().getLog() << tcu::TestLog::Message << "ClearNamedBufferSubData has failed."
													<< tcu::TestLog::EndMessage;
			}
		}
		else
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedBufferStorage has failed."
												<< tcu::TestLog::EndMessage;
		}
	}
	else
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "CreateBuffers has failed."
											<< tcu::TestLog::EndMessage;
	}

	return false;
}

/** Prepare output buffer in the way described in test specification (see class comment). */
bool FunctionalTest::PrepareOutputBuffer()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Buffer preparation */
	gl.genBuffers(1, &m_bo_out);

	if (GL_NO_ERROR == gl.getError())
	{
		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_out);

		if (GL_NO_ERROR == gl.getError())
		{
			m_pNamedBufferData(m_bo_out, sizeof(s_initial_data_b), s_initial_data_b, GL_DYNAMIC_COPY);

			if (GL_NO_ERROR == gl.getError())
			{
				gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_out, 0,
								   sizeof(s_initial_data_a) /* intentionally sizeof(a) < sizeof(b) */);

				if (GL_NO_ERROR == gl.getError())
				{
					return true;
				}
				else
				{
					m_context.getTestContext().getLog() << tcu::TestLog::Message << "BindBufferRange has failed."
														<< tcu::TestLog::EndMessage;
					throw 0; /* This function is not being tested, throw test internal error */
				}
			}
			else
			{
				m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedBufferData has failed."
													<< tcu::TestLog::EndMessage;
			}
		}
		else
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "BindBuffer has failed."
												<< tcu::TestLog::EndMessage;
			throw 0; /* This function is not being tested, throw test internal error */
		}
	}
	else
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GenBuffers has failed."
											<< tcu::TestLog::EndMessage;
		throw 0; /* This function is not being tested, throw test internal error */
	}

	return false;
}

/** Draw with the test program and transform feedback. */
void FunctionalTest::Draw()
{
	/* Shortcut for GL functionality */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Draw using transform feedback. */
	gl.disable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");

	gl.beginTransformFeedback(GL_POINTS);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");

	gl.drawArrays(GL_POINTS, 0, sizeof(s_initial_data_a) / sizeof(s_initial_data_a[0]));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");

	gl.endTransformFeedback();
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");

	gl.enable(GL_RASTERIZER_DISCARD);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
}

/** @brief Check that input buffer is immutable using GetNamedBufferParameteriv function. */
bool FunctionalTest::CheckArrayBufferImmutableFlag()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Local query storage. */
	glw::GLint is_storage_immutable = -1;

	/* Querry. */
	m_pGetNamedBufferParameteriv(m_bo_in, GL_BUFFER_IMMUTABLE_STORAGE, &is_storage_immutable);

	/* Error checking. */
	if (GL_NO_ERROR == gl.getError())
	{
		/* Return value checking. */
		if (-1 != is_storage_immutable)
		{
			/* Test. */
			if (GL_TRUE == is_storage_immutable)
			{
				return true;
			}
			else
			{
				m_context.getTestContext().getLog() << tcu::TestLog::Message
													<< "Input buffer storage is unexpectedly mutable."
													<< tcu::TestLog::EndMessage;
			}
		}
		else
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message
												<< "GetNamedBufferParameteriv has not returned a data."
												<< tcu::TestLog::EndMessage;
		}
	}
	else
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedBufferParameteriv has failed."
											<< tcu::TestLog::EndMessage;
	}

	return false;
}

/** @brief Check that output buffer size using GetNamedBufferParameteri64v function. */
bool FunctionalTest::CheckTransformFeedbackBufferSize()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Local query storage. */
	glw::GLint64 size = -1;

	/* Querry. */
	m_pGetNamedBufferParameteri64v(m_bo_out, GL_BUFFER_SIZE, &size);

	/* Error checking. */
	if (GL_NO_ERROR == gl.getError())
	{
		/* Return value checking. */
		if (-1 != size)
		{
			/* Test. */
			if (sizeof(s_initial_data_b) == size)
			{
				return true;
			}
			else
			{
				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Output buffer size is " << size
													<< ", but " << sizeof(s_initial_data_b) << " was expected."
													<< tcu::TestLog::EndMessage;
			}
		}
		else
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message
												<< "GetNamedBufferParameteri64v has not returned a data."
												<< tcu::TestLog::EndMessage;
		}
	}
	else
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedBufferParameteri64v has failed."
											<< tcu::TestLog::EndMessage;
	}

	return false;
}

/** @brief Check that results of the test are equal to the expected reference values. */
bool FunctionalTest::CheckTransformFeedbackResult()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	/* Local data storage. */
	glw::GLint output_data[sizeof(s_initial_data_b) / sizeof(s_initial_data_b[0])] = {};

	/* Fetch data. */
	m_pGetNamedBufferSubData(m_bo_out, 0, sizeof(output_data), output_data);

	/* Error checking. */
	if (GL_NO_ERROR == gl.getError())
	{
		for (glw::GLuint i = 0; i < sizeof(s_initial_data_b) / sizeof(s_initial_data_b[0]); ++i)
		{
			if (s_expected_data[i] != output_data[i])
			{
				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Expected data is not equal to results."
													<< tcu::TestLog::EndMessage;
				return false;
			}
		}

		return true;
	}
	else
	{
		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedBufferSubData has failed."
											<< tcu::TestLog::EndMessage;
	}
	return false;
}

/** Clean all test's GL objects and state. */
void FunctionalTest::Cleanup()
{
	/* Shortcut for GL functionality. */
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

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

		gl.deleteProgram(m_po);

		m_po = 0;
	}

	if (m_vao)
	{
		gl.deleteVertexArrays(1, &m_vao);

		m_vao = 0;
	}

	if (0 <= m_attrib_location)
	{
		gl.disableVertexAttribArray(m_attrib_location);

		m_attrib_location = -1;
	}

	if (m_bo_in)
	{
		gl.deleteBuffers(1, &m_bo_in);

		m_bo_in = 0;
	}

	if (m_bo_out)
	{
		gl.deleteBuffers(1, &m_bo_out);

		m_bo_out = 0;
	}

	/* Make sure that rasterizer is turned on (default). */
	gl.enable(GL_RASTERIZER_DISCARD);

	/* Clean all errors. */
	while (gl.getError())
		;
}

} /* Buffers namespace. */
} /* DirectStateAccess namespace. */
} /* gl4cts namespace. */
