/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2015-2018 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  glcKHRDebugTests.cpp
 * \brief Implements conformance tests for "KHR Debug" functionality.
 */ /*-------------------------------------------------------------------*/

#include "glcKHRDebugTests.hpp"

#include "gluPlatform.hpp"
#include "gluRenderConfig.hpp"
#include "gluRenderContext.hpp"
#include "gluStrUtil.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTestLog.hpp"
//
//#include <string>

#define DEBUG_ENBALE_MESSAGE_CALLBACK 0

#if DEBUG_ENBALE_MESSAGE_CALLBACK
//#include <iomanip>
#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */

using namespace glw;

namespace glcts
{
namespace KHRDebug
{
/** Macro, verifies generated error, logs error message and throws failure
 *
 * @param expected_error Expected error value
 * @param error_message  Message logged if generated error is not the expected one
 **/
#define CHECK_ERROR(expected_error, error_message)                                                      \
	{                                                                                                   \
		GLenum generated_error = m_gl->getError();                                                      \
                                                                                                        \
		if (expected_error != generated_error)                                                          \
		{                                                                                               \
			m_testCtx.getLog()                                                                          \
				<< tcu::TestLog::Message << "File: " << __FILE__ << ", line: " << __LINE__              \
				<< ". Got wrong error: " << glu::getErrorStr(generated_error)                           \
				<< ", expected: " << glu::getErrorStr(expected_error) << ", message: " << error_message \
				<< tcu::TestLog::EndMessage;                                                            \
			TestBase::done();                                                                           \
			TCU_FAIL("Invalid error generated");                                                        \
		}                                                                                               \
	}

/** Pop all groups from stack
 *
 * @param gl GL functions
 **/
void cleanGroupStack(const Functions* gl)
{
	while (1)
	{
		gl->popDebugGroup();

		const GLenum err = gl->getError();

		if (GL_STACK_UNDERFLOW == err)
		{
			break;
		}

		GLU_EXPECT_NO_ERROR(err, "PopDebugGroup");
	}
}

/** Extracts all messages from log
 *
 * @param gl GL functions
 **/
void cleanMessageLog(const Functions* gl)
{
	static const GLuint count = 16;

	while (1)
	{
		GLuint ret = gl->getDebugMessageLog(count /* count */, 0 /* bufSize */, 0 /* sources */, 0 /* types */,
											0 /* ids */, 0 /* severities */, 0 /* lengths */, 0 /* messageLog */);

		GLU_EXPECT_NO_ERROR(gl->getError(), "GetDebugMessageLog");

		if (0 == ret)
		{
			break;
		}
	}
}

/** Fill stack of groups
 *
 * @param gl GL functions
 **/
void fillGroupStack(const Functions* gl)
{
	static const GLchar  message[] = "Foo";
	static const GLsizei length	= (GLsizei)(sizeof(message) / sizeof(message[0]));

	while (1)
	{
		gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, length /* length */,
						   message /* message */);

		const GLenum err = gl->getError();

		if (GL_STACK_OVERFLOW == err)
		{
			break;
		}

		GLU_EXPECT_NO_ERROR(err, "PopDebugGroup");
	}
}

/** Constructor
 * Creates and set as current new context that should be used by test.
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be created
 **/
TestBase::TestBase(tcu::TestContext& testContext, glu::ApiType apiType, bool is_debug)
	: m_gl(0), m_is_debug(is_debug), m_rc(0), m_testContext(testContext), m_apiType(apiType)
{
	/* Nothing to be done here */
}

/** Destructor
 * Destroys context used by test and set original context as current
 **/
TestBase::~TestBase()
{
	if (0 != m_rc)
	{
		done();
	}
}

/** Initialize rendering context
 **/
void TestBase::init()
{
	if (true == m_is_debug)
	{
		initDebug();
	}
	else
	{
		initNonDebug();
	}

	/* Get functions */
	m_gl = &m_rc->getFunctions();
}

/** Prepares debug context
 **/
void TestBase::initDebug()
{
	tcu::Platform&	platform = m_testContext.getPlatform();
	glu::RenderConfig renderCfg(glu::ContextType(m_apiType, glu::CONTEXT_DEBUG));

	const tcu::CommandLine& commandLine = m_testContext.getCommandLine();
	parseRenderConfig(&renderCfg, commandLine);

	if (commandLine.getSurfaceType() != tcu::SURFACETYPE_WINDOW)
		throw tcu::NotSupportedError("Test not supported in non-windowed context");

	m_rc = createRenderContext(platform, commandLine, renderCfg);
	m_rc->makeCurrent();
}

/** Prepares non-debug context
 **/
void TestBase::initNonDebug()
{
	tcu::Platform&	platform = m_testContext.getPlatform();
	glu::RenderConfig renderCfg(glu::ContextType(m_apiType, glu::ContextFlags(0)));

	const tcu::CommandLine& commandLine = m_testContext.getCommandLine();
	parseRenderConfig(&renderCfg, commandLine);

	if (commandLine.getSurfaceType() != tcu::SURFACETYPE_WINDOW)
		throw tcu::NotSupportedError("Test not supported in non-windowed context");

	m_rc = createRenderContext(platform, commandLine, renderCfg);
	m_rc->makeCurrent();
}

/** Finalize rendering context
 **/
void TestBase::done()
{
	/* Delete context used by test and make no context current */
	delete m_rc;

	m_rc = 0;
	m_gl = 0;
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
APIErrorsTest::APIErrorsTest(tcu::TestContext& testCtx, glu::ApiType apiType, bool is_debug, const GLchar* name)
	: TestBase(testCtx, apiType, is_debug), TestCase(testCtx, name, "Verifies that errors are generated as expected")
{
	/* Nothing to be done */
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult APIErrorsTest::iterate()
{
	/* Initialize rendering context */
	TestBase::init();

	/* Get maximum label length */
	GLint max_label = 0;

	m_gl->getIntegerv(GL_MAX_LABEL_LENGTH, &max_label);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	/* Prepare too long label */
	std::vector<GLchar> too_long_label;

	too_long_label.resize(max_label + 2);

	for (GLint i = 0; i <= max_label; ++i)
	{
		too_long_label[i] = 'f';
	}

	too_long_label[max_label + 1] = 0;

	/* Get maximum message length */
	GLint max_length = 0;

	m_gl->getIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &max_length);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	/* Prepare too long message */
	std::vector<GLchar> too_long_message;

	too_long_message.resize(max_length + 2);

	for (GLint i = 0; i <= max_length; ++i)
	{
		too_long_message[i] = 'f';
	}

	too_long_message[max_length + 1] = 0;

	/* Get maximum number of groups on stack */
	GLint max_groups = 0;

	m_gl->getIntegerv(GL_MAX_DEBUG_GROUP_STACK_DEPTH, &max_groups);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	/*
	 * DebugMessageControl function should generate:
	 * - INVALID_ENUM when <source> is invalid;
	 * - INVALID_ENUM when <type> is invalid;
	 * - INVALID_ENUM when <severity> is invalid;
	 * - INVALID_VALUE when <count> is negative;
	 * - INVALID_OPERATION when <count> is not zero and <source> is DONT_CARE;
	 * - INVALID_OPERATION when <count> is not zero and <type> is DONT_CARE;
	 * - INVALID_OPERATION when <count> is not zero and <severity> is not
	 * DONT_CARE.
	 */
	{
		static const GLuint  ids[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
		static const GLsizei n_ids = (GLsizei)(sizeof(ids) / sizeof(ids[0]));

		m_gl->debugMessageControl(GL_ARRAY_BUFFER /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DEBUG_SEVERITY_LOW /* severity */, 0 /* count */, 0 /* ids */,
								  GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageControl with <source> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_ARRAY_BUFFER /* type */,
								  GL_DEBUG_SEVERITY_LOW /* severity */, 0 /* count */, 0 /* ids */,
								  GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageControl with <type> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_ARRAY_BUFFER /* severity */, 0 /* count */, 0 /* ids */, GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageControl with <severity> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DEBUG_SEVERITY_LOW /* severity */, -1 /* count */, ids /* ids */,
								  GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_VALUE, "DebugMessageControl with <count> set to -1");

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DONT_CARE /* severity */, n_ids /* count */, ids /* ids */, GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_OPERATION, "DebugMessageControl with <source> set to GL_DONT_CARE and non zero <count>");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DONT_CARE /* type */,
								  GL_DONT_CARE /* severity */, n_ids /* count */, ids /* ids */, GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_OPERATION, "DebugMessageControl with <type> set to GL_DONT_CARE and non zero <count>");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DEBUG_SEVERITY_LOW /* severity */, n_ids /* count */, ids /* ids */,
								  GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_OPERATION,
					"DebugMessageControl with <severity> set to GL_DEBUG_SEVERITY_LOW and non zero <count>");
	}

	/*
	 * GetDebugMessageLog function should generate:
	 * - INVALID_VALUE when <bufSize> is negative and messageLog is not NULL.
	 */
	{
		static const GLsizei bufSize = 32;
		static const GLuint  count   = 4;

		GLenum  ids[count];
		GLsizei lengths[count];
		GLchar  messageLog[bufSize];
		GLenum  types[count];
		GLenum  severities[count];
		GLenum  sources[count];

		m_gl->getDebugMessageLog(count /* count */, -1 /* bufSize */, sources, types, ids, severities, lengths,
								 messageLog);
		CHECK_ERROR(GL_INVALID_VALUE, "GetDebugMessageLog with <bufSize> set to -1");
	}

	/*
	 * DebugMessageInsert function should generate:
	 * - INVALID_ENUM when <source> is not DEBUG_SOURCE_APPLICATION or
	 * DEBUG_SOURCE_THIRD_PARTY;
	 * - INVALID_ENUM when <type> is invalid;
	 * - INVALID_ENUM when <severity> is invalid;
	 * - INVALID_VALUE when length of string <buf> is not less than
	 * MAX_DEBUG_MESSAGE_LENGTH.
	 */
	{
		static const GLchar  message[] = "Foo";
		static const GLsizei length	= (GLsizei)(sizeof(message) / sizeof(message[0]));

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */,
								 0 /* id */, GL_DEBUG_SEVERITY_LOW /* severity */, length /* length */,
								 message /* message */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageInsert with <source> set to GL_DEBUG_SOURCE_API");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_ARRAY_BUFFER /* type */, 0 /* id */,
								 GL_DEBUG_SEVERITY_LOW /* severity */, length /* length */, message /* message */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageInsert with <type> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */,
								 0 /* id */, GL_ARRAY_BUFFER /* severity */, length /* length */,
								 message /* message */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageInsert with <severity> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */,
								 0 /* id */, GL_DEBUG_SEVERITY_LOW /* severity */, max_length + 1 /* length */,
								 message /* message */);
		CHECK_ERROR(GL_INVALID_VALUE, "DebugMessageInsert with <length> set to GL_MAX_DEBUG_MESSAGE_LENGTH + 1");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */,
								 0 /* id */, GL_DEBUG_SEVERITY_LOW /* severity */, -1 /* length */,
								 &too_long_message[0] /* message */);
		CHECK_ERROR(GL_INVALID_VALUE, "DebugMessageInsert with too long message");
	}

	/*
	 * PushDebugGroup function should generate:
	 * - INVALID_ENUM when <source> is not DEBUG_SOURCE_APPLICATION or
	 * DEBUG_SOURCE_THIRD_PARTY;
	 * - INVALID_VALUE when length of string <message> is not less than
	 * MAX_DEBUG_MESSAGE_LENGTH;
	 * - STACK_OVERFLOW when stack contains MAX_DEBUG_GROUP_STACK_DEPTH entries.
	 */
	{
		static const GLchar  message[] = "Foo";
		static const GLsizei length	= (GLsizei)(sizeof(message) / sizeof(message[0]));

		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_API /* source */, 1 /* id */, length /* length */, message /* message */);
		CHECK_ERROR(GL_INVALID_ENUM, "PushDebugGroup with <source> set to GL_DEBUG_SOURCE_API");

		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, max_length + 1 /* length */,
							 message /* message */);
		CHECK_ERROR(GL_INVALID_VALUE, "PushDebugGroup with <length> set to GL_MAX_DEBUG_MESSAGE_LENGTH + 1");

		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, -1 /* length */,
							 &too_long_message[0] /* message */);
		CHECK_ERROR(GL_INVALID_VALUE, "PushDebugGroup with too long message");

		/* Clean stack */
		cleanGroupStack(m_gl);

		/* Fill stack */
		for (GLint i = 0; i < max_groups - 1; ++i)
		{
			m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, length /* length */,
								 message /* message */);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "PushDebugGroup");
		}

		/* Overflow stack */
		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, length /* length */,
							 message /* message */);
		CHECK_ERROR(GL_STACK_OVERFLOW, "PushDebugGroup called GL_MAX_DEBUG_GROUP_STACK_DEPTH times");

		/* Clean stack */
		cleanGroupStack(m_gl);
	}

	/*
	 * PopDebugGroup function should generate:
	 * - STACK_UNDERFLOW when stack contains no entries.
	 */
	{
		fillGroupStack(m_gl);

		for (GLint i = 0; i < max_groups - 1; ++i)
		{
			m_gl->popDebugGroup();

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

		m_gl->popDebugGroup();
		CHECK_ERROR(GL_STACK_UNDERFLOW, "PopDebugGroup called GL_MAX_DEBUG_GROUP_STACK_DEPTH times");
	}

	/*
	 * ObjectLabel function should generate:
	 * - INVALID_ENUM when <identifier> is invalid;
	 * - INVALID_VALUE when if <name> is not valid object name of type specified by
	 * <identifier>;
	 * - INVALID_VALUE when length of string <label> is not less than
	 * MAX_LABEL_LENGTH.
	 */
	{
		static const GLchar  label[] = "Foo";
		static const GLsizei length  = (GLsizei)(sizeof(label) / sizeof(label[0]));

		GLuint texture_id = 0;
		GLuint invalid_id = 1;
		m_gl->genTextures(1, &texture_id);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GenTextures");
		m_gl->bindTexture(GL_TEXTURE_BUFFER, texture_id);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "BindTexture");

		try
		{
			m_gl->objectLabel(GL_TEXTURE_BUFFER /* identifier */, texture_id /* name */, length /* length */,
							  label /* label */);
			CHECK_ERROR(GL_INVALID_ENUM, "ObjectLabel with <identifier> set to GL_TEXTURE_BUFFER");

			while (GL_TRUE == m_gl->isTexture(invalid_id))
			{
				invalid_id += 1;
			}

			m_gl->objectLabel(GL_TEXTURE /* identifier */, invalid_id /* name */, length /* length */,
							  label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectLabel with <name> set to not generated value");

			m_gl->objectLabel(GL_TEXTURE /* identifier */, texture_id /* name */, max_label + 1 /* length */,
							  label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectLabel with <label> set to MAX_LABEL_LENGTH + 1");

			m_gl->objectLabel(GL_TEXTURE /* identifier */, texture_id /* name */, -1 /* length */,
							  &too_long_label[0] /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectLabel with too long label");
		}
		catch (const std::exception& exc)
		{
			m_gl->deleteTextures(1, &texture_id);
			TCU_FAIL(exc.what());
		}

		m_gl->deleteTextures(1, &texture_id);
	}

	/*
	 * GetObjectLabel function should generate:
	 * - INVALID_ENUM when <identifier> is invalid;
	 * - INVALID_VALUE when if <name> is not valid object name of type specified by
	 * <identifier>;
	 * - INVALID_VALUE when <bufSize> is negative.
	 */
	{
		static const GLsizei bufSize = 32;

		GLchar  label[bufSize];
		GLsizei length = 0;

		GLuint texture_id = 0;
		GLuint invalid_id = 1;
		m_gl->genTextures(1, &texture_id);
		m_gl->bindTexture(GL_TEXTURE_2D, texture_id);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GenTextures");

		try
		{
			m_gl->getObjectLabel(GL_TEXTURE_BUFFER /* identifier */, texture_id /* name */, bufSize /* bufSize */,
								 &length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_ENUM, "GetObjectLabel with <identifier> set to GL_TEXTURE_BUFFER");

			while (GL_TRUE == m_gl->isTexture(invalid_id))
			{
				invalid_id += 1;
			}

			m_gl->getObjectLabel(GL_TEXTURE /* identifier */, invalid_id /* name */, bufSize /* bufSize */,
								 &length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "GetObjectLabel with <name> set to not generated value");

			m_gl->getObjectLabel(GL_TEXTURE /* identifier */, invalid_id /* name */, -1 /* bufSize */,
								 &length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "GetObjectLabel with <bufSize> set to -1");
		}
		catch (const std::exception& exc)
		{
			m_gl->deleteTextures(1, &texture_id);
			TCU_FAIL(exc.what());
		}

		m_gl->deleteTextures(1, &texture_id);
	}

	/*
	 * ObjectPtrLabel function should generate:
	 * - INVALID_VALUE when <ptr> is not the name of sync object;
	 * - INVALID_VALUE when length of string <label> is not less than
	 * MAX_LABEL_LENGTH.
	 */
	{
		static const GLchar  label[] = "Foo";
		static const GLsizei length  = (GLsizei)(sizeof(label) / sizeof(label[0]));

		GLsync sync_id	= 0;
		GLsync invalid_id = 0;
		sync_id			  = m_gl->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "FenceSync");

		try
		{
			while (GL_TRUE == m_gl->isSync(invalid_id))
			{
				invalid_id = (GLsync)(((unsigned long long)invalid_id) + 1);
			}

			m_gl->objectPtrLabel(invalid_id /* name */, length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectPtrLabel with <ptr> set to not generated value");

			m_gl->objectPtrLabel(sync_id /* name */, max_label + 1 /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectPtrLabel with <length> set to MAX_LABEL_LENGTH + 1");

			m_gl->objectPtrLabel(sync_id /* name */, -1 /* length */, &too_long_label[0] /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectPtrLabel with too long label");
		}
		catch (const std::exception& exc)
		{
			m_gl->deleteSync(sync_id);
			TCU_FAIL(exc.what());
		}

		m_gl->deleteSync(sync_id);
	}

	/*
	 * GetObjectPtrLabel function should generate:
	 * - INVALID_VALUE when <ptr> is not the name of sync object;
	 * - INVALID_VALUE when <bufSize> is negative.
	 */
	{
		static const GLsizei bufSize = 32;

		GLchar  label[bufSize];
		GLsizei length = 0;

		GLsync sync_id	= 0;
		GLsync invalid_id = 0;
		sync_id			  = m_gl->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "FenceSync");

		try
		{
			while (GL_TRUE == m_gl->isSync(invalid_id))
			{
				invalid_id = (GLsync)(((unsigned long long)invalid_id) + 1);
			}

			m_gl->getObjectPtrLabel(invalid_id /* name */, bufSize /* bufSize */, &length /* length */,
									label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "GetObjectPtrLabel with <ptr> set to not generated value");

			m_gl->getObjectPtrLabel(sync_id /* name */, -1 /* bufSize */, &length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "GetObjectPtrLabel with <bufSize> set to -1");
		}
		catch (const std::exception& exc)
		{
			m_gl->deleteSync(sync_id);
			TCU_FAIL(exc.what());
		}

		m_gl->deleteSync(sync_id);
	}

	/*
	 * GetPointerv function should generate:
	 * - INVALID_ENUM when <pname> is invalid.
	 **/
	{
		GLuint  uint;
		GLuint* uint_ptr = &uint;

		m_gl->getPointerv(GL_ARRAY_BUFFER, (GLvoid**)&uint_ptr);
		CHECK_ERROR(GL_INVALID_ENUM, "GetPointerv with <pname> set to GL_ARRAY_BUFFER");
	}

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
LabelsTest::LabelsTest(tcu::TestContext& testCtx, glu::ApiType apiType, bool is_debug, const GLchar* name)
	: TestCase(testCtx, name, "Verifies that labels can be assigned and queried"), TestBase(testCtx, apiType, is_debug)
{
	/* Nothing to be done */
}

/** Represnets case for LabelsTest **/
struct labelsTestCase
{
	GLenum m_identifier;
	GLuint (*m_create)(const glw::Functions* gl, const glu::RenderContext*);
	GLvoid (*m_destroy)(const glw::Functions* gl, GLuint id);
	const GLchar* m_name;
};

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult LabelsTest::iterate()
{
	static const labelsTestCase test_cases[] = {
		{ GL_BUFFER, createBuffer, deleteBuffer, "Buffer" },
		{ GL_FRAMEBUFFER, createFramebuffer, deleteFramebuffer, "Framebuffer" },
		{ GL_PROGRAM, createProgram, deleteProgram, "Program" },
		{ GL_PROGRAM_PIPELINE, createProgramPipeline, deleteProgramPipeline, "ProgramPipeline" },
		{ GL_QUERY, createQuery, deleteQuery, "Query" },
		{ GL_RENDERBUFFER, createRenderbuffer, deleteRenderbuffer, "Renderbuffer" },
		{ GL_SAMPLER, createSampler, deleteSampler, "Sampler" },
		{ GL_SHADER, createShader, deleteShader, "Shader" },
		{ GL_TEXTURE, createTexture, deleteTexture, "Texture" },
		{ GL_TRANSFORM_FEEDBACK, createTransformFeedback, deleteTransformFeedback, "TransformFeedback" },
		{ GL_VERTEX_ARRAY, createVertexArray, deleteVertexArray, "VertexArray" },
	};

	static const size_t n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);

	static const GLsizei bufSize	  = 32;
	static const GLchar  label[]	  = "foo";
	static const GLsizei label_length = (GLsizei)(sizeof(label) / sizeof(label[0]) - 1);

	/* Initialize render context */
	TestBase::init();

	/* For each test case */
	for (size_t test_case_index = 0; test_case_index < n_test_cases; ++test_case_index)
	{
		const labelsTestCase& test_case = test_cases[test_case_index];

		const GLenum identifier = test_case.m_identifier;
		const GLuint id			= test_case.m_create(m_gl, m_rc);

		try
		{
			GLchar  buffer[bufSize] = "HelloWorld";
			GLsizei length;

			/*
			 * - query label; It is expected that result will be an empty string and length
			 * will be zero;
			 */
			m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (0 != length)
			{
				TCU_FAIL("Just created object has label of length != 0");
			}

			if (0 != buffer[0])
			{
				TCU_FAIL("Just created object has not empty label");
			}

			/*
			 * - assign label to object;
			 * - query label; It is expected that result will be equal to the provided
			 * label and length will be correct;
			 */
			m_gl->objectLabel(identifier, id, -1 /* length */, label);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "ObjectLabel");

			m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (label_length != length)
			{
				TCU_FAIL("Length is different than length of set label");
			}

			if (0 != strcmp(buffer, label))
			{
				TCU_FAIL("Different label returned");
			}

			/*
			 * - query length only; Correct value is expected;
			 */
			length = 0;

			m_gl->getObjectLabel(identifier, id, 0 /* bufSize */, &length, 0 /* label */);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (label_length != length)
			{
				TCU_FAIL("Invalid length returned when label and bufSize are set to 0");
			}

			/*
			 * - query label with <bufSize> less than actual length of label; It is
			 * expected that only <bufSize> characters will be stored in buffer (including
			 * NULL);
			 */
			length = 0;
			strcpy(buffer, "HelloWorld");

			m_gl->getObjectLabel(identifier, id, 2 /* bufSize */, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (buffer[0] != label[0])
			{
				TCU_FAIL("Different label returned");
			}

			if (buffer[1] != 0)
			{
				TCU_FAIL("GetObjectLabel did not stored NULL at the end of string");
			}

			if (buffer[2] != 'l')
			{
				TCU_FAIL("GetObjectLabel overflowed buffer");
			}

			/*
			 * - query label with <bufSize> equal zero; It is expected that buffer contents
			 * will not be modified;
			 */
			length = 0;
			strcpy(buffer, "HelloWorld");

			m_gl->getObjectLabel(identifier, id, 0 /* bufSize */, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (0 != strcmp(buffer, "HelloWorld"))
			{
				TCU_FAIL("GetObjectLabel modified buffer, bufSize set to 0");
			}

			/*
			 * - assign empty string as label to object;
			 * - query label, it is expected that result will be an empty string and length
			 * will be zero;
			 */
			m_gl->objectLabel(identifier, id, -1 /* length */, "");
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "ObjectLabel");

			m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (0 != length)
			{
				TCU_FAIL("Label length is != 0, empty string was set");
			}

			if (0 != buffer[0])
			{
				TCU_FAIL("Non empty label returned, empty string was set");
			}

			/*
			 * - assign NULL as label to object;
			 * - query label, it is expected that result will be an empty string and length
			 * will be zero;
			 */
			m_gl->objectLabel(identifier, id, 2, 0 /* label */);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "ObjectLabel");

			m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (0 != length)
			{
				TCU_FAIL("Label length is != 0, label was removed");
			}

			if (0 != buffer[0])
			{
				TCU_FAIL("Different label returned, label was removed");
			}
		}
		catch (const std::exception& exc)
		{
			test_case.m_destroy(m_gl, id);

			m_testCtx.getLog()
				<< tcu::TestLog::Message << "Error during test case: " << test_case.m_name << tcu::TestLog::EndMessage;

			TCU_FAIL(exc.what());
		}

		test_case.m_destroy(m_gl, id);
	}

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Create buffer
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createBuffer(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;

	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createBuffers(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateBuffers");
	}
	else
	{
		gl->genBuffers(1, &id);
		gl->bindBuffer(GL_ARRAY_BUFFER, id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenBuffers");
	}

	return id;
}

/** Create FBO
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createFramebuffer(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createFramebuffers(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateFramebuffers");
	}
	else
	{
		GLint currentFbo;
		gl->getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &currentFbo);
		gl->genFramebuffers(1, &id);
		gl->bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
		gl->bindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFbo);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenFramebuffers / BindFramebuffer");
	}

	return id;
}

/** Create program
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createProgram(const Functions* gl, const glu::RenderContext*)
{
	GLuint id = gl->createProgram();
	GLU_EXPECT_NO_ERROR(gl->getError(), "CreateProgram");

	return id;
}

/** Create pipeline
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createProgramPipeline(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createProgramPipelines(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateProgramPipelines");
	}
	else
	{
		gl->genProgramPipelines(1, &id);
		gl->bindProgramPipeline(id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenProgramPipelines / BindProgramPipeline");
	}

	return id;
}

/** Create query
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createQuery(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createQueries(GL_TIMESTAMP, 1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateQueries");
	}
	else
	{
		gl->genQueries(1, &id);
		gl->beginQuery(GL_SAMPLES_PASSED, id);
		gl->endQuery(GL_SAMPLES_PASSED);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenQueries / BeginQuery / EndQuery");
	}

	return id;
}

/** Create render buffer
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createRenderbuffer(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;

	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createRenderbuffers(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateRenderbuffers");
	}
	else
	{
		gl->genRenderbuffers(1, &id);
		gl->bindRenderbuffer(GL_RENDERBUFFER, id);
		gl->bindRenderbuffer(GL_RENDERBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenRenderbuffers / BindRenderbuffer");
	}

	return id;
}

/** Create sampler
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createSampler(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createSamplers(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateSamplers");
	}
	else
	{
		gl->genSamplers(1, &id);
		gl->bindSampler(0, id);
		gl->bindSampler(0, 0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenSamplers / BindSampler");
	}

	return id;
}

/** Create shader
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createShader(const Functions* gl, const glu::RenderContext*)
{
	GLuint id = gl->createShader(GL_VERTEX_SHADER);
	GLU_EXPECT_NO_ERROR(gl->getError(), "CreateShader");

	return id;
}

/** Create texture
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createTexture(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createTextures(GL_TEXTURE_2D, 1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateTextures");
	}
	else
	{
		gl->genTextures(1, &id);
		gl->bindTexture(GL_TEXTURE_2D, id);
		gl->bindTexture(GL_TEXTURE_2D, 0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenTextures / BindTexture");
	}

	return id;
}

/** Create XFB
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createTransformFeedback(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createTransformFeedbacks(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateTransformFeedbacks");
	}
	else
	{
		gl->genTransformFeedbacks(1, &id);
		gl->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, id);
		gl->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenTransformFeedbacks / BindTransformFeedback");
	}

	return id;
}

/** Create VAO
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createVertexArray(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;

	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createVertexArrays(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateVertexArrays");
	}
	else
	{
		gl->genVertexArrays(1, &id);
		gl->bindVertexArray(id);
		gl->bindVertexArray(0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenVertexArrays / BindVertexArrays");
	}

	return id;
}

/** Destroy buffer
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteBuffer(const Functions* gl, GLuint id)
{
	gl->deleteBuffers(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteBuffers");
}

/** Destroy FBO
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteFramebuffer(const Functions* gl, GLuint id)
{
	gl->deleteFramebuffers(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteFramebuffers");
}

/** Destroy program
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteProgram(const Functions* gl, GLuint id)
{
	gl->deleteProgram(id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteProgram");
}

/** Destroy pipeline
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteProgramPipeline(const Functions* gl, GLuint id)
{
	gl->deleteProgramPipelines(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteProgramPipelines");
}

/** Destroy query
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteQuery(const Functions* gl, GLuint id)
{
	gl->deleteQueries(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteQueries");
}

/** Destroy render buffer
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteRenderbuffer(const Functions* gl, GLuint id)
{
	gl->deleteRenderbuffers(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteRenderbuffers");
}

/** Destroy sampler
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteSampler(const Functions* gl, GLuint id)
{
	gl->deleteSamplers(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteSamplers");
}

/** Destroy shader
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteShader(const Functions* gl, GLuint id)
{
	gl->deleteShader(id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteShader");
}

/** Destroy texture
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteTexture(const Functions* gl, GLuint id)
{
	gl->deleteTextures(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteTextures");
}

/** Destroy XFB
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteTransformFeedback(const Functions* gl, GLuint id)
{
	gl->deleteTransformFeedbacks(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteTransformFeedbacks");
}

/** Destroy VAO
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteVertexArray(const Functions* gl, GLuint id)
{
	gl->deleteVertexArrays(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteVertexArrays");
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
ReceivingMessagesTest::ReceivingMessagesTest(tcu::TestContext& testCtx, glu::ApiType apiType)
	: TestCase(testCtx, "receiving_messages", "Verifies that messages can be received")
	, TestBase(testCtx, apiType, true /* is_debug */)
{
	/* Nothing to be done */
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult ReceivingMessagesTest::iterate()
{
	static const size_t bufSize		  = 32;
	static const GLchar label[]		  = "foo";
	static const size_t label_length  = sizeof(label) / sizeof(label[0]) - 1;
	static const size_t read_messages = 4;

	GLuint callback_counter   = 0;
	GLint  max_debug_messages = 0;

	/* Initialize render context */
	TestBase::init();

	/* Get max number of debug messages */
	m_gl->getIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES, &max_debug_messages);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	/*
	 * - verify that the state of DEBUG_OUTPUT is enabled as it should be by
	 * default;
	 * - verify that state of DEBUG_CALLBACK_FUNCTION and
	 * DEBUG_CALLBACK_USER_PARAM are NULL;
	 */
	{
		inspectDebugState(GL_TRUE, 0 /* cb */, 0 /* info */);
	}

	/*
	 * Ignore spurious performance messages
	 */
	m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_PERFORMANCE /* type */,
							  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */);

	/*
	 * - insert a message with DebugMessageInsert;
	 * - inspect message log to check if the message is reported;
	 * - inspect message log again, there should be no messages;
	 */
	{
		GLchar  messageLog[bufSize];
		GLenum  sources[read_messages];
		GLenum  types[read_messages];
		GLuint  ids[read_messages];
		GLenum  severities[read_messages];
		GLsizei lengths[read_messages];

		cleanMessageLog(m_gl);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, sources /* sources */,
											  types /* types */, ids /* ids */, severities /* severities */,
											  lengths /* lengths */, messageLog /* messageLog */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

		if (1 != ret)
		{
			m_testCtx.getLog() << tcu::TestLog::Message
												<< "GetDebugMessageLog returned invalid number of messages: " << ret
												<< ", expected 1" << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_SOURCE_APPLICATION != sources[0])
		{
			TCU_FAIL("Invalid source value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_TYPE_ERROR != types[0])
		{
			TCU_FAIL("Invalid type value returned by GetDebugMessageLog");
		}

		if (11 != ids[0])
		{
			TCU_FAIL("Invalid id value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_SEVERITY_HIGH != severities[0])
		{
			TCU_FAIL("Invalid severity value returned by GetDebugMessageLog");
		}

		// DebugMessageInsert's length does not include null-terminated character (if length is positive)
		// But GetDebugMessageLog's length include null-terminated character
		// OpenGL 4.5 Core Spec, Page 530 and Page 535
		if (label_length + 1 != lengths[0])
		{
			TCU_FAIL("Invalid length value returned by GetDebugMessageLog");
		}

		if (0 != strcmp(label, messageLog))
		{
			TCU_FAIL("Invalid message returned by GetDebugMessageLog");
		}
	}

	/*
	 * - disable DEBUG_OUTPUT;
	 * - insert a message with DebugMessageInsert;
	 * - inspect message log again, there should be no messages;
	 */
	{
		m_gl->disable(GL_DEBUG_OUTPUT);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Disable");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(0);
	}

	/*
	 * - enable DEBUG_OUTPUT;
	 * - register debug message callback with DebugMessageCallback;
	 * - verify that the state of DEBUG_CALLBACK_FUNCTION and
	 * DEBUG_CALLBACK_USER_PARAM are correct;
	 * - insert a message with DebugMessageInsert;
	 * - it is expected that debug message callback will be executed for
	 * the message;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->enable(GL_DEBUG_OUTPUT);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Enable");

		m_gl->debugMessageCallback(debug_proc, &callback_counter);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageCallback");

		inspectDebugState(GL_TRUE, debug_proc, &callback_counter);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectCallbackCounter(callback_counter, 1);

		inspectMessageLog(0);
	}

	/*
	 * - disable DEBUG_OUTPUT;
	 * - insert a message with DebugMessageInsert;
	 * - debug message callback should not be called;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->disable(GL_DEBUG_OUTPUT);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Disable");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectCallbackCounter(callback_counter, 1);

		inspectMessageLog(0);
	}

	/*
	 * - enable DEBUG_OUTPUT;
	 * - execute DebugMessageControl with <type> DEBUG_TYPE_ERROR, <severity>
	 * DEBUG_SEVERITY_HIGH and <enabled> FALSE;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_ERROR
	 * and <severity> DEBUG_SEVERITY_MEDIUM;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
	 * and <severity> DEBUG_SEVERITY_HIGH;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
	 * and <severity> DEBUG_SEVERITY_LOW;
	 * - debug message callback should not be called;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->enable(GL_DEBUG_OUTPUT);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Enable");

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */);

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DONT_CARE /* type */,
								  GL_DEBUG_SEVERITY_HIGH /* severity */, 0 /* counts */, 0 /* ids */,
								  GL_FALSE /* enabled */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_MEDIUM /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_LOW /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectCallbackCounter(callback_counter, 1);

		inspectMessageLog(0);
	}

	/*
	 * - set NULL as debug message callback;
	 * - verify that state of DEBUG_CALLBACK_FUNCTION and
	 * DEBUG_CALLBACK_USER_PARAM are NULL;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_ERROR
	 * and <severity> DEBUG_SEVERITY_MEDIUM;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
	 * and <severity> DEBUG_SEVERITY_HIGH;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
	 * and <severity> DEBUG_SEVERITY_LOW;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->debugMessageCallback(0, 0);

		inspectDebugState(GL_TRUE, 0, 0);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_MEDIUM /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_LOW /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(0);
	}

	/*
	 * - execute DebugMessageControl to enable messages of <type> DEBUG_TYPE_ERROR
	 * and <severity> DEBUG_SEVERITY_HIGH.
	 */
	{
		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_TRUE /* enabled */);

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DONT_CARE /* type */,
								  GL_DEBUG_SEVERITY_HIGH /* severity */, 0 /* counts */, 0 /* ids */,
								  GL_TRUE /* enabled */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl");
	}

	/*
	 * - insert MAX_DEBUG_LOGGED_MESSAGES + 1 unique messages with
	 * DebugMessageInsert;
	 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that
	 * MAX_DEBUG_LOGGED_MESSAGES will be reported;
	 */
	{
		for (GLint i = 0; i < max_debug_messages + 1; ++i)
		{
			m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */,
									 i /* id */, GL_DEBUG_SEVERITY_MEDIUM /* severity */, label_length /* length */,
									 label);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");
		}

		GLint n_debug_messages = 0;

		m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

		if (n_debug_messages != max_debug_messages)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected "
				<< max_debug_messages << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES");
		}
	}

	/*
	 * If MAX_DEBUG_LOGGED_MESSAGES is greater than 1:
	 * - inspect first half of the message log by specifying proper <count>; Verify
	 * that messages are reported in order from the oldest to the newest; Check
	 * that <count> messages were stored into provided buffers;
	 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that <count> messages
	 * were removed from log;
	 * - inspect rest of the message log with <bufSize> too small to held last
	 * message; Verify that messages are reported in order from the oldest to the
	 * newest; Verify that maximum <bufSize> characters were written to
	 * <messageLog>;
	 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that one message is
	 * available;
	 * - fetch the message and verify it is the newest one;
	 */
	if (1 != max_debug_messages)
	{
		GLint half_count	   = max_debug_messages / 2;
		GLint n_debug_messages = 0;
		GLint rest_count	   = max_debug_messages - half_count;

		GLsizei buf_size = (GLsizei)((half_count + 1) * (label_length + 1));

		std::vector<GLchar>  messageLog;
		std::vector<GLenum>  sources;
		std::vector<GLenum>  types;
		std::vector<GLuint>  ids;
		std::vector<GLenum>  severities;
		std::vector<GLsizei> lengths;

		messageLog.resize(buf_size);
		sources.resize(half_count + 1);
		types.resize(half_count + 1);
		ids.resize(half_count + 1);
		severities.resize(half_count + 1);
		lengths.resize(half_count + 1);

		GLuint ret = m_gl->getDebugMessageLog(half_count /* count */, buf_size /* bufSize */, &sources[0] /* sources */,
											  &types[0] /* types */, &ids[0] /* ids */, &severities[0] /* severities */,
											  &lengths[0] /* lengths */, &messageLog[0] /* messageLog */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

		if (ret != (GLuint)half_count)
		{
			m_testCtx.getLog() << tcu::TestLog::Message
												<< "GetDebugMessageLog returned unexpected number of messages: " << ret
												<< ", expected " << half_count << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid number of meessages");
		}

		m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

		if (n_debug_messages != rest_count)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected "
				<< rest_count << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES");
		}

		for (GLint i = 0; i < half_count; ++i)
		{
			if (GL_DEBUG_SOURCE_APPLICATION != sources[i])
			{
				TCU_FAIL("Invalid source value returned by GetDebugMessageLog");
			}

			if (GL_DEBUG_TYPE_ERROR != types[i])
			{
				TCU_FAIL("Invalid type value returned by GetDebugMessageLog");
			}

			if ((GLuint)i != ids[i])
			{
				TCU_FAIL("Invalid id value returned by GetDebugMessageLog");
			}

			if (GL_DEBUG_SEVERITY_MEDIUM != severities[i])
			{
				TCU_FAIL("Invalid severity value returned by GetDebugMessageLog");
			}

			// DebugMessageInsert's length does not include null-terminated character (if length is positive)
			// But GetDebugMessageLog's length include null-terminated character
			// OpenGL 4.5 Core Spec, Page 530 and Page 535
			if (label_length + 1 != lengths[i])
			{
				TCU_FAIL("Invalid length value returned by GetDebugMessageLog");
			}

			if (0 != strcmp(label, &messageLog[i * (label_length + 1)]))
			{
				TCU_FAIL("Invalid message returned by GetDebugMessageLog");
			}
		}

		/* */
		buf_size = (GLsizei)((rest_count - 1) * (label_length + 1) + label_length);
		memset(&messageLog[0], 0, messageLog.size());

		ret = m_gl->getDebugMessageLog(rest_count /* count */, buf_size /* bufSize */, &sources[0] /* sources */,
									   &types[0] /* types */, &ids[0] /* ids */, &severities[0] /* severities */,
									   &lengths[0] /* lengths */, &messageLog[0] /* messageLog */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

		if (ret != (GLuint)(rest_count - 1))
		{
			m_testCtx.getLog() << tcu::TestLog::Message
												<< "GetDebugMessageLog returned unexpected number of messages: " << ret
												<< ", expected " << (rest_count - 1) << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid number of meessages");
		}

		m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

		if (n_debug_messages != 1)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected "
				<< (rest_count - 1) << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES");
		}

		for (GLint i = 0; i < (rest_count - 1); ++i)
		{
			if (GL_DEBUG_SOURCE_APPLICATION != sources[i])
			{
				TCU_FAIL("Invalid source value returned by GetDebugMessageLog");
			}

			if (GL_DEBUG_TYPE_ERROR != types[i])
			{
				TCU_FAIL("Invalid type value returned by GetDebugMessageLog");
			}

			if ((GLuint)(i + half_count) != ids[i])
			{
				TCU_FAIL("Invalid id value returned by GetDebugMessageLog");
			}

			if (GL_DEBUG_SEVERITY_MEDIUM != severities[i])
			{
				TCU_FAIL("Invalid severity value returned by GetDebugMessageLog");
			}

			// DebugMessageInsert's length does not include null-terminated character (if length is positive)
			// But GetDebugMessageLog's length include null-terminated character
			// OpenGL 4.5 Core Spec, Page 530 and Page 535
			if (label_length + 1 != lengths[i])
			{
				TCU_FAIL("Invalid length value returned by GetDebugMessageLog");
			}

			if (0 != strcmp(label, &messageLog[i * (label_length + 1)]))
			{
				TCU_FAIL("Invalid message returned by GetDebugMessageLog");
			}
		}

		/* */
		memset(&messageLog[0], 0, messageLog.size());

		ret = m_gl->getDebugMessageLog(rest_count /* count */, buf_size /* bufSize */, &sources[0] /* sources */,
									   &types[0] /* types */, &ids[0] /* ids */, &severities[0] /* severities */,
									   &lengths[0] /* lengths */, &messageLog[0] /* messageLog */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

		if (ret != 1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message
												<< "GetDebugMessageLog returned unexpected number of messages: " << ret
												<< ", expected 1" << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid number of meessages");
		}

		m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

		if (n_debug_messages != 0)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected 1"
				<< tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES");
		}

		if (GL_DEBUG_SOURCE_APPLICATION != sources[0])
		{
			TCU_FAIL("Invalid source value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_TYPE_ERROR != types[0])
		{
			TCU_FAIL("Invalid type value returned by GetDebugMessageLog");
		}

		if ((GLuint)(max_debug_messages - 1) != ids[0])
		{
			TCU_FAIL("Invalid id value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_SEVERITY_MEDIUM != severities[0])
		{
			TCU_FAIL("Invalid severity value returned by GetDebugMessageLog");
		}

		// DebugMessageInsert's length does not include null-terminated character (if length is positive)
		// But GetDebugMessageLog's length include null-terminated character
		// OpenGL 4.5 Core Spec, Page 530 and Page 535
		if (label_length + 1 != lengths[0])
		{
			TCU_FAIL("Invalid length value returned by GetDebugMessageLog");
		}

		if (0 != strcmp(label, &messageLog[0]))
		{
			TCU_FAIL("Invalid message returned by GetDebugMessageLog");
		}
	}

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Debug callback used by the test, increase counter by one
 *
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param info    Pointer to uint counter
 **/
void ReceivingMessagesTest::debug_proc(glw::GLenum /* source */, glw::GLenum /* type */, glw::GLuint /* id */,
										glw::GLenum /* severity */, glw::GLsizei /* length */,
										const glw::GLchar* /* message */, const void* info)
{
	GLuint* counter = (GLuint*)info;

	*counter += 1;
}

/** Inspects state of DEBUG_OUTPUT and debug callback
 *
 * @param expected_state     Expected state of DEBUG_OUTPUT
 * @param expected_callback  Expected state of DEBUG_CALLBACK_FUNCTION
 * @param expected_user_info Expected state of DEBUG_CALLBACK_USER_PARAM
 **/
void ReceivingMessagesTest::inspectDebugState(GLboolean expected_state, GLDEBUGPROC expected_callback,
											   GLvoid* expected_user_info) const
{
	GLboolean debug_state = -1;
	m_gl->getBooleanv(GL_DEBUG_OUTPUT, &debug_state);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetBooleanv");

	if (expected_state != debug_state)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "State of DEBUG_OUTPUT: " << debug_state
											<< ", expected " << expected_state << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid state of DEBUG_OUTPUT");
	}

	GLvoid* callback_procedure = 0;
	m_gl->getPointerv(GL_DEBUG_CALLBACK_FUNCTION, &callback_procedure);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetPointerv");

	if (expected_callback != callback_procedure)
	{
		TCU_FAIL("Invalid state of DEBUG_CALLBACK_FUNCTION");
	}

	GLvoid* callback_user_info = 0;
	m_gl->getPointerv(GL_DEBUG_CALLBACK_USER_PARAM, &callback_user_info);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetPointerv");

	if (expected_user_info != callback_user_info)
	{
		TCU_FAIL("Invalid state of DEBUG_CALLBACK_USER_PARAM");
	}
}

/** Inspects value of counter used by callback
 *
 * @param callback_counter            Reference to counter
 * @param expected_number_of_messages Expected value of counter
 **/
void ReceivingMessagesTest::inspectCallbackCounter(GLuint& callback_counter, GLuint expected_number_of_messages) const
{
	m_gl->finish();
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Finish");

	if (expected_number_of_messages != callback_counter)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message << "Debug callback was executed invalid number of times: " << callback_counter
			<< ", expected " << expected_number_of_messages << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid execution of debug callback");
	}
}

/** Inspects amount of messages stored in log
 *
 * @param expected_number_of_messages Expected number of messages
 **/
void ReceivingMessagesTest::inspectMessageLog(GLuint expected_number_of_messages) const
{
	static const size_t bufSize		  = 32;
	static const size_t read_messages = 4;

	GLchar  messageLog[bufSize];
	GLenum  sources[read_messages];
	GLenum  types[read_messages];
	GLuint  ids[read_messages];
	GLenum  severities[read_messages];
	GLsizei lengths[read_messages];

	GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, sources /* sources */,
										  types /* types */, ids /* ids */, severities /* severities */,
										  lengths /* lengths */, messageLog /* messageLog */);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

	if (expected_number_of_messages != ret)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
											<< "GetDebugMessageLog returned invalid number of messages: " << ret
											<< ", expected " << expected_number_of_messages << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid value returned by GetDebugMessageLog");
	}
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
GroupsTest::GroupsTest(tcu::TestContext& testCtx, glu::ApiType apiType)
	: TestCase(testCtx, "groups", "Verifies that groups can be used to control generated messages")
	, TestBase(testCtx, apiType, true /* is_debug */)
{
	/* Nothing to be done */
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult GroupsTest::iterate()
{
	static const GLchar label[]		 = "foo";
	static const size_t label_length = sizeof(label) / sizeof(label[0]) - 1;

	/* Initialize render context */
	TestBase::init();

	cleanMessageLog(m_gl);

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1;
	 */
	inspectGroupStack(1);

	/*
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check if the message is reported;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check if the message is reported;
	 */
	{
		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
	}

	/*
	 * - push debug group with unique <id> and <message>;
	 * - inspect message log to check if the message about push is reported;
	 * - disable messages with <type> DEBUG_TYPE_ERROR;
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check there are no messages;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check if the message is reported;
	 */
	{
		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 0xabcd0123 /* id */, -1 /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "PushDebugGroup");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_PUSH_GROUP /* type */,
						  0xabcd0123 /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */,
						  label);

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		verifyEmptyLog();

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
	}

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2;
	 */
	inspectGroupStack(2);

	/*
	 * - push debug group with unique <id> and <message>;
	 * - inspect message log to check if the message about push is reported;
	 * - disable messages with <type> DEBUG_TYPE_OTHER;
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check there are no messages;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 0x0123abcd /* id */, -1 /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "PushDebugGroup");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_PUSH_GROUP /* type */,
						  0x0123abcd /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */,
						  label);

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_OTHER /* type */,
								  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		verifyEmptyLog();

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		verifyEmptyLog();
	}

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 3;
	 */
	inspectGroupStack(3);

	/*
	 * - pop debug group;
	 * - inspect message log to check if the message about pop is reported and
	 * corresponds with the second push;
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check there are no messages;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check if the message is reported;
	 */
	{
		m_gl->popDebugGroup();
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "PopDebugGroup");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_POP_GROUP /* type */,
						  0x0123abcd /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */,
						  label);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		verifyEmptyLog();

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
	}

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2;
	 */
	inspectGroupStack(2);

	/*
	 * - pop debug group;
	 * - inspect message log to check if the message about pop is reported and
	 * corresponds with the first push;
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check if the message is reported;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check if the message is reported;
	 */
	{
		m_gl->popDebugGroup();
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "PopDebugGroup");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_POP_GROUP /* type */,
						  0xabcd0123 /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */,
						  label);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
	}

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1;
	 */
	inspectGroupStack(1);

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Inspects amount of groups on stack
 *
 * @param expected_depth Expected number of groups
 **/
void GroupsTest::inspectGroupStack(GLuint expected_depth) const
{
	GLint stack_depth = 0;

	m_gl->getIntegerv(GL_DEBUG_GROUP_STACK_DEPTH, &stack_depth);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	if (expected_depth != (GLuint)stack_depth)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
											<< "State of DEBUG_GROUP_STACK_DEPTH: " << stack_depth << ", expected "
											<< expected_depth << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid state of DEBUG_GROUP_STACK_DEPTH");
	}
}

/** Inspects first message stored in log
 *
 * @param expected_source   Expected source of messages
 * @param expected_type     Expected type of messages
 * @param expected_id       Expected id of messages
 * @param expected_severity Expected severity of messages
 * @param expected_length   Expected length of messages
 * @param expected_label    Expected label of messages
 **/
void GroupsTest::inspectMessageLog(glw::GLenum expected_source, glw::GLenum expected_type, glw::GLuint expected_id,
								   glw::GLenum expected_severity, glw::GLsizei expected_length,
								   const glw::GLchar* expected_label) const
{
	static const size_t bufSize		  = 32;
	static const size_t read_messages = 1;

	GLchar  messageLog[bufSize];
	GLenum  source;
	GLenum  type;
	GLuint  id;
	GLenum  severity;
	GLsizei length;

	GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, &source /* sources */,
										  &type /* types */, &id /* ids */, &severity /* severities */,
										  &length /* lengths */, messageLog /* messageLog */);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

	if (0 == ret)
	{
		TCU_FAIL("GetDebugMessageLog returned 0 messages");
	}

	if (expected_source != source)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got message with invalid source: " << source
											<< ", expected " << expected_source << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid source of message");
	}

	if (expected_type != type)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got message with invalid type: " << type
											<< ", expected " << expected_type << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid type of message");
	}

	if (expected_id != id)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got message with invalid id: " << id
											<< ", expected " << expected_id << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid id of message");
	}

	if (expected_severity != severity)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
											<< "Got message with invalid severity: " << severity << ", expected "
											<< expected_severity << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid severity of message");
	}

	// DebugMessageInsert's length does not include null-terminated character (if length is positive)
	// But GetDebugMessageLog's length include null-terminated character
	// OpenGL 4.5 Core Spec, Page 530 and Page 535
	if (expected_length + 1 != length)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got message with invalid length: " << length
											<< ", expected " << expected_length << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid length of message");
	}

	if (0 != strcmp(expected_label, messageLog))
	{
		m_testCtx.getLog() << tcu::TestLog::Message
											<< "Got message with invalid message: " << messageLog << ", expected "
											<< expected_label << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid message");
	}
}

/** Verifies that message log is empty
 *
 **/
void GroupsTest::verifyEmptyLog() const
{
	static const size_t bufSize		  = 32;
	static const size_t read_messages = 1;

	GLchar  messageLog[bufSize];
	GLenum  source;
	GLenum  type;
	GLuint  id;
	GLenum  severity;
	GLsizei length;

	GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, &source /* sources */,
										  &type /* types */, &id /* ids */, &severity /* severities */,
										  &length /* lengths */, messageLog /* messageLog */);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

	if (0 != ret)
	{
		TCU_FAIL("GetDebugMessageLog returned unexpected messages");
	}
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
SynchronousCallsTest::SynchronousCallsTest(tcu::TestContext& testCtx, glu::ApiType apiType)
	: TestCase(testCtx, "synchronous_calls", "Verifies that messages can be received")
	, TestBase(testCtx, apiType, true /* is_debug */)
{
	/* Create pthread_key_t visible to all threads
	 * The key has value NULL associated with it in all existing
	 * or about to be created threads
	 */
	m_uid = 0;
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult SynchronousCallsTest::iterate()
{
	m_uid++;

	/* associate  some unique id with the current thread */
	m_tls.set((void*)(deUintptr)m_uid);

	static const GLchar label[] = "foo";

	GLuint buffer_id = 0;

	/* Initialize render context */
	TestBase::init();

	/* - set callback_executed to 0; */
	int callback_executed = 0;

	/*
	 *- enable DEBUG_OUTPUT_SYNCHRONOUS;
	 */
	m_gl->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Enable");

	/*
	 * - register debug message callback with DebugMessageCallback; Provide the
	 * instance of UserParam structure as <userParam>; Routine should do the
	 * following:
	 *   * set callback_executed to 1;
	 */
	m_gl->debugMessageCallback(debug_proc, &callback_executed);
	try
	{
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageCallback");

		/*
		 * - insert a message with DebugMessageInsert;
		 */
		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, -1 /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		/* Make sure execution finished before we check results */
		m_gl->finish();
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Finish");

		/*
		 * - check if:
		 *   * callback_executed is set to 1;
		 */
		if (1 != callback_executed)
		{
			TCU_FAIL("callback_executed is not set to 1");
		}

		/* Check that the message was recorded by the current thread */
		if ((deUintptr)(m_tls.get()) != m_uid)
		{
			TCU_FAIL("thread id stored by callback is not the same as \"test\" thread");
		}

		/*
		 * - reset callback_executed;
		 */
		callback_executed = 0;

		/*
		 * - execute BindBufferBase with GL_ARRAY_BUFFER <target>, GL_INVALID_ENUM
		 * error should be generated;
		 */
		m_gl->genBuffers(1, &buffer_id);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GenBuffers");

		m_gl->bindBufferBase(GL_ARRAY_BUFFER, 0 /* index */, buffer_id);
		if (GL_INVALID_ENUM != m_gl->getError())
		{
			TCU_FAIL("Unexpected error generated");
		}

		/* Make sure execution finished before we check results */
		m_gl->finish();
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Finish");

		/*
		 * - test pass if:
		 *   * callback_executed is set to 0 - implementation does not send messages;
		 *   * callback_executed is set to 1 and thread_id is the same
		 *   as "test" thread - implementation sent message to proper thread;
		 */
		if (1 == callback_executed)
		{
			/* Check that the error was recorded by the current thread */
			if ((deUintptr)(m_tls.get()) != m_uid)
			{
				TCU_FAIL("thread id stored by callback is not the same as \"test\" thread");
			}
		}

		/* Clean */
		m_gl->deleteBuffers(1, &buffer_id);
		buffer_id = 0;
	}
	catch (const std::exception& exc)
	{
		if (0 != buffer_id)
		{
			m_gl->deleteBuffers(1, &buffer_id);
			buffer_id = 0;
		}

		TCU_FAIL(exc.what());
	}

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Destructor */
SynchronousCallsTest::~SynchronousCallsTest(void)
{
}

/** Debug callback used by the test, sets callback_executed to 1 and stores 0 to tls
 *
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param info    Pointer to uint counter
 **/
void SynchronousCallsTest::debug_proc(glw::GLenum /* source */, glw::GLenum /* type */, glw::GLuint /* id */,
									  glw::GLenum /* severity */, glw::GLsizei /* length */,
									  const glw::GLchar* /* message */, const void* info)
{
	int* callback_executed = (int*)info;

	*callback_executed = 1;
}
} /* KHRDebug */

/** Constructor.
 *
 *  @param context Rendering context.
 **/
KHRDebugTests::KHRDebugTests(tcu::TestContext& testCtx, glu::ApiType apiType)
	: TestCaseGroup(testCtx, "khr_debug", "Verifies \"khr debug\" functionality")
	, m_apiType(apiType)

{
	/* Left blank on purpose */
}

/** Initializes a khr_debug test group.
 *
 **/
void KHRDebugTests::init(void)
{
	addChild(new KHRDebug::APIErrorsTest(m_testCtx, m_apiType, false, "api_errors_non_debug"));
	addChild(new KHRDebug::LabelsTest(m_testCtx, m_apiType, false, "labels_non_debug"));
	addChild(new KHRDebug::ReceivingMessagesTest(m_testCtx, m_apiType));
	addChild(new KHRDebug::GroupsTest(m_testCtx, m_apiType));
	addChild(new KHRDebug::APIErrorsTest(m_testCtx, m_apiType, true, "api_errors_debug"));
	addChild(new KHRDebug::LabelsTest(m_testCtx, m_apiType, true, "labels_debug"));
	addChild(new KHRDebug::SynchronousCallsTest(m_testCtx, m_apiType));
}

} /* glcts namespace */
