/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * 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 Debug output (KHR_debug) tests
 *//*--------------------------------------------------------------------*/

#include "es31fDebugTests.hpp"

#include "es31fNegativeTestShared.hpp"
#include "es31fNegativeBufferApiTests.hpp"
#include "es31fNegativeTextureApiTests.hpp"
#include "es31fNegativeShaderApiTests.hpp"
#include "es31fNegativeFragmentApiTests.hpp"
#include "es31fNegativeVertexArrayApiTests.hpp"
#include "es31fNegativeStateApiTests.hpp"
#include "es31fNegativeAtomicCounterTests.hpp"
#include "es31fNegativeShaderImageLoadStoreTests.hpp"
#include "es31fNegativeShaderFunctionTests.hpp"
#include "es31fNegativeShaderDirectiveTests.hpp"
#include "es31fNegativePreciseTests.hpp"
#include "es31fNegativeAdvancedBlendEquationTests.hpp"

#include "deUniquePtr.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deSTLUtil.hpp"
#include "deMutex.hpp"
#include "deThread.h"

#include "gluRenderContext.hpp"
#include "gluContextInfo.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluStrUtil.hpp"

#include "glwDefs.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include "tes31Context.hpp"
#include "tcuTestContext.hpp"
#include "tcuCommandLine.hpp"
#include "tcuResultCollector.hpp"

#include "glsStateQueryUtil.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{
using namespace glw;

using std::string;
using std::vector;
using std::set;
using std::map;
using de::MovePtr;

using tcu::ResultCollector;
using tcu::TestLog;
using glu::CallLogWrapper;

using NegativeTestShared::NegativeTestContext;

static const GLenum s_debugTypes[] =
{
	GL_DEBUG_TYPE_ERROR,
	GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR,
	GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR,
	GL_DEBUG_TYPE_PORTABILITY,
	GL_DEBUG_TYPE_PERFORMANCE,
	GL_DEBUG_TYPE_OTHER,
	GL_DEBUG_TYPE_MARKER,
	GL_DEBUG_TYPE_PUSH_GROUP,
	GL_DEBUG_TYPE_POP_GROUP,
};

static const GLenum s_debugSeverities[] =
{
	GL_DEBUG_SEVERITY_HIGH,
    GL_DEBUG_SEVERITY_MEDIUM,
    GL_DEBUG_SEVERITY_LOW,
    GL_DEBUG_SEVERITY_NOTIFICATION,
};

static bool isKHRDebugSupported (Context& ctx)
{
	const bool isES32 = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	return isES32 || ctx.getContextInfo().isExtensionSupported("GL_KHR_debug");
}

class BaseCase;

class DebugMessageTestContext : public NegativeTestContext
{
public:
				DebugMessageTestContext		(BaseCase&					host,
											 glu::RenderContext&		renderCtx,
											 const glu::ContextInfo&	ctxInfo,
											 tcu::TestLog&				log,
											 tcu::ResultCollector&		results,
											 bool						enableLog);
				~DebugMessageTestContext	(void);

	void		expectMessage				(GLenum source, GLenum type);

private:
	BaseCase&	m_debugHost;
};

class TestFunctionWrapper
{
public:
	typedef void (*CoreTestFunc)(NegativeTestContext& ctx);
	typedef void (*DebugTestFunc)(DebugMessageTestContext& ctx);

				TestFunctionWrapper	(void);
	explicit	TestFunctionWrapper	(CoreTestFunc func);
	explicit	TestFunctionWrapper	(DebugTestFunc func);

	void		call				(DebugMessageTestContext& ctx) const;

private:
	enum FuncType
	{
		TYPE_NULL = 0,
		TYPE_CORE,
		TYPE_DEBUG,
	};
	FuncType m_type;

	union
	{
		CoreTestFunc	coreFn;
		DebugTestFunc	debugFn;
	} m_func;
};

TestFunctionWrapper::TestFunctionWrapper (void)
	: m_type(TYPE_NULL)
{
}

TestFunctionWrapper::TestFunctionWrapper (CoreTestFunc func)
	: m_type(TYPE_CORE)
{
	m_func.coreFn = func;
}

TestFunctionWrapper::TestFunctionWrapper (DebugTestFunc func)
	: m_type(TYPE_DEBUG)
{
	m_func.debugFn = func;
}

void TestFunctionWrapper::call (DebugMessageTestContext& ctx) const
{
	if (m_type == TYPE_CORE)
		m_func.coreFn(static_cast<NegativeTestContext&>(ctx));
	else if (m_type == TYPE_DEBUG)
		m_func.debugFn(ctx);
	else
		DE_ASSERT(false);
}

void emitMessages (DebugMessageTestContext& ctx, GLenum source)
{
	for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_debugTypes); typeNdx++)
	{
		for (int severityNdx = 0; severityNdx < DE_LENGTH_OF_ARRAY(s_debugSeverities); severityNdx++)
		{
			const GLenum type		= s_debugTypes[typeNdx];
			const GLenum severity	= s_debugSeverities[severityNdx];
			const string msg		= string("Application generated message with type ") + glu::getDebugMessageTypeName(type)
									  + " and severity " + glu::getDebugMessageSeverityName(severity);

			// Use severity as ID, guaranteed unique
			ctx.glDebugMessageInsert(source, type, severity, severity, -1, msg.c_str());
			ctx.expectMessage(source, type);
		}
	}
}

void application_messages (DebugMessageTestContext& ctx)
{
	ctx.beginSection("Messages with source of GL_DEBUG_SOURCE_APPLICATION");
	emitMessages(ctx, GL_DEBUG_SOURCE_APPLICATION);
	ctx.endSection();
}

void thirdparty_messages (DebugMessageTestContext& ctx)
{
	ctx.beginSection("Messages with source of GL_DEBUG_SOURCE_THIRD_PARTY");
	emitMessages(ctx, GL_DEBUG_SOURCE_THIRD_PARTY);
	ctx.endSection();
}

void push_pop_messages (DebugMessageTestContext& ctx)
{
	ctx.beginSection("Push/Pop Debug Group");

	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Application group 1");
	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP);
	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 2, -1, "Application group 1-1");
	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP);
	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 3, -1, "Application group 1-1-1");
	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP);
	ctx.glPopDebugGroup();
	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP);
	ctx.glPopDebugGroup();
	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP);

	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 4, -1, "Application group 1-2");
	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP);
	ctx.glPopDebugGroup();
	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP);

	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_THIRD_PARTY, 4, -1, "3rd Party group 1-3");
	ctx.expectMessage(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_PUSH_GROUP);
	ctx.glPopDebugGroup();
	ctx.expectMessage(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_POP_GROUP);
	ctx.glPopDebugGroup();
	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP);

	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_THIRD_PARTY, 4, -1, "3rd Party group 2");
	ctx.expectMessage(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_PUSH_GROUP);
	ctx.glPopDebugGroup();
	ctx.expectMessage(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_POP_GROUP);

	ctx.endSection();
}

struct FunctionContainer
{
	TestFunctionWrapper	function;
	const char*			name;
	const char*			desc;
};

vector<FunctionContainer> getUserMessageFuncs (void)
{
	FunctionContainer funcs[] =
	{
		{ TestFunctionWrapper(application_messages),	"application_messages", "Externally generated messages from the application"	},
		{ TestFunctionWrapper(thirdparty_messages),		"third_party_messages",	"Externally generated messages from a third party"		},
		{ TestFunctionWrapper(push_pop_messages),		"push_pop_stack",		"Messages from pushing/popping debug groups"			},
	};

	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
}

// Data required to uniquely identify a debug message
struct MessageID
{
	GLenum source;
	GLenum type;
	GLuint id;

	MessageID (void) : source(GL_NONE), type(GL_NONE), id(0) {}
	MessageID (GLenum source_, GLenum type_, GLuint id_) : source(source_), type(type_), id(id_) {}

	bool operator== (const MessageID& rhs) const { return source == rhs.source && type == rhs.type && id == rhs.id;}
	bool operator!= (const MessageID& rhs) const { return source != rhs.source || type != rhs.type || id != rhs.id;}
	bool operator<  (const MessageID& rhs) const
	{
		return source < rhs.source || (source == rhs.source && (type < rhs.type || (type == rhs.type && id < rhs.id)));
	}
};

std::ostream& operator<< (std::ostream& str, const MessageID &id)
{
	return str << glu::getDebugMessageSourceStr(id.source) << ", "	<< glu::getDebugMessageTypeStr(id.type) << ", " << id.id;
}

// All info from a single debug message
struct MessageData
{
	MessageID	id;
	GLenum		severity;
	string		message;

	MessageData (void) : id(MessageID()), severity(GL_NONE) {}
	MessageData (const MessageID& id_, GLenum severity_, const string& message_) : id(id_) , severity(severity_) , message(message_) {}
};

extern "C" typedef void GLW_APIENTRY DebugCallbackFunc(GLenum, GLenum, GLuint, GLenum, GLsizei, const char*, void*);

// Base class
class BaseCase : public NegativeTestShared::ErrorCase
{
public:
								BaseCase			(Context&					ctx,
													 const char*				name,
													 const char*				desc);
	virtual						~BaseCase			(void) {}

	virtual IterateResult		iterate				(void) = 0;

	virtual void				expectMessage		(GLenum source, GLenum type);
	virtual void				expectError			(GLenum error0, GLenum error1);

protected:
	struct VerificationResult {
		const qpTestResult	result;
		const string		resultMessage;
		const string		logMessage;

		VerificationResult (qpTestResult result_, const string& resultMessage_, const string& logMessage_)
			: result(result_), resultMessage(resultMessage_), logMessage(logMessage_) {}
	};

	static DebugCallbackFunc	callbackHandle;
	virtual void				callback			(GLenum source, GLenum type, GLuint id, GLenum severity, const std::string& message);


	VerificationResult			verifyMessageCount	(const MessageID& id, GLenum severity, int refCount, int resCount, bool messageEnabled) const;

	// Verify a single message instance against expected attributes
	void						verifyMessage		(const MessageData& message, GLenum source, GLenum type, GLuint id, GLenum severity);
	void						verifyMessage		(const MessageData& message, GLenum source, GLenum type);

	bool						verifyMessageExists	(const MessageData& message, GLenum source, GLenum type);
	void						verifyMessageGroup	(const MessageData& message, GLenum source, GLenum type);
	void						verifyMessageString	(const MessageData& message);

	bool						isDebugContext		(void) const;

	tcu::ResultCollector		m_results;
};

void BaseCase::callbackHandle (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, void* userParam)
{
	static_cast<BaseCase*>(userParam)->callback(source, type, id, severity, string(message, &message[length]));
}

BaseCase::BaseCase (Context& ctx, const char* name, const char* desc)
	: ErrorCase(ctx, name, desc)
{
}

void BaseCase::expectMessage (GLenum source, GLenum type)
{
	DE_UNREF(source);
	DE_UNREF(type);
}

void BaseCase::expectError (GLenum error0, GLenum error1)
{
	if (error0 != GL_NO_ERROR || error1 != GL_NO_ERROR)
		expectMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR);
	else
		expectMessage(GL_DONT_CARE, GL_DONT_CARE);
}

void BaseCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
{
	DE_UNREF(source);
	DE_UNREF(type);
	DE_UNREF(id);
	DE_UNREF(severity);
	DE_UNREF(message);
}

BaseCase::VerificationResult BaseCase::verifyMessageCount (const MessageID& id, GLenum severity, int refCount, int resCount, bool messageEnabled) const
{
	std::stringstream log;

	// This message should not be filtered out
	if (messageEnabled)
	{
		if (resCount != refCount)
		{
			/*
			 * Technically nothing requires the implementation to be consistent in terms
			 * of the messages it produces in most situations, allowing the set of messages
			 * produced to vary between executions. This function splits messages
			 * into deterministic and non-deterministic to facilitate handling of such messages.
			 *
			 * Non-deterministic messages that are present in differing quantities in filtered and
			 * unfiltered runs will not fail the test case unless in direct violation of a filter:
			 * the implementation may produce an arbitrary number of such messages when they are
			 * not filtered out and none when they are filtered.
			 *
			 * A list of error source/type combinations with their assumed behaviour and
			 * the rationale for expecting such behaviour follows
			 *
			 * For API/shader messages we assume that the following types are deterministic:
			 *   DEBUG_TYPE_ERROR                 Errors specified by spec and should always be produced
			 *
			 * For API messages the following types are assumed to be non-deterministic
			 * and treated as quality warnings since the underlying reported issue does not change between calls:
			 *   DEBUG_TYPE_DEPRECATED_BEHAVIOR   Reasonable to only report first instance
             *   DEBUG_TYPE_UNDEFINED_BEHAVIOR    Reasonable to only report first instance
             *   DEBUG_TYPE_PORTABILITY           Reasonable to only report first instance
			 *
			 * For API messages the following types are assumed to be non-deterministic
			 * and do not affect test results.
			 *   DEBUG_TYPE_PERFORMANCE           May be tied to arbitrary factors, reasonable to report only first instance
             *   DEBUG_TYPE_OTHER                 Definition allows arbitrary contents
			 *
			 * For 3rd party and application messages the following types are deterministic:
             *   DEBUG_TYPE_MARKER                Only generated by test
			 *   DEBUG_TYPE_PUSH_GROUP            Only generated by test
			 *   DEBUG_TYPE_POP_GROUP             Only generated by test
			 *   All others                       Only generated by test
			 *
			 * All messages with category of window system or other are treated as non-deterministic
			 * and do not effect test results since they can be assumed to be outside control of
			 * both the implementation and test case
			 *
			 */

			const bool isDeterministic	= id.source == GL_DEBUG_SOURCE_APPLICATION ||
										  id.source == GL_DEBUG_SOURCE_THIRD_PARTY ||
										  ((id.source == GL_DEBUG_SOURCE_API || id.source == GL_DEBUG_SOURCE_SHADER_COMPILER) && id.type == GL_DEBUG_TYPE_ERROR);

			const bool canIgnore		= id.source == GL_DEBUG_SOURCE_WINDOW_SYSTEM || id.source == GL_DEBUG_SOURCE_OTHER;

			if (isDeterministic)
			{
				if (resCount > refCount)
				{
					log << "Extra instances of message were found: (" << id << ") with "
						<< glu::getDebugMessageSeverityStr(severity)
						<< " (got " << resCount << ", expected " << refCount << ")";
					return VerificationResult(QP_TEST_RESULT_FAIL, "Extra instances of a deterministic message were present", log.str());
				}
				else
				{
					log << "Instances of message were missing: (" << id << ") with "
						<< glu::getDebugMessageSeverityStr(severity)
						<< " (got " << resCount << ", expected " << refCount << ")";
					return VerificationResult(QP_TEST_RESULT_FAIL, "Message missing", log.str());
				}
			}
			else if(!canIgnore)
			{
				if (resCount > refCount)
				{
					log << "Extra instances of message were found but the message is non-deterministic(warning): (" << id << ") with "
						<< glu::getDebugMessageSeverityStr(severity)
						<< " (got " << resCount << ", expected " << refCount << ")";
					return VerificationResult(QP_TEST_RESULT_QUALITY_WARNING, "Extra instances of a message were present", log.str());
				}
				else
				{
					log << "Instances of message were missing but the message is non-deterministic(warning): (" << id << ") with "
						<< glu::getDebugMessageSeverityStr(severity)
						<< " (got " << resCount << ", expected " << refCount << ")";
					return VerificationResult(QP_TEST_RESULT_QUALITY_WARNING, "Message missing", log.str());
				}
			}
			else
			{
				if (resCount > refCount)
				{
					log << "Extra instances of message were found but the message is non-deterministic(ignored): (" << id << ") with "
						<< glu::getDebugMessageSeverityStr(severity)
						<< " (got " << resCount << ", expected " << refCount << ")";
					return VerificationResult(QP_TEST_RESULT_PASS, "", log.str());
				}
				else
				{
					log << "Instances of message were missing but the message is non-deterministic(ignored): (" << id << ") with "
						<< glu::getDebugMessageSeverityStr(severity)
						<< " (got " << resCount << ", expected " << refCount << ")";
					return VerificationResult(QP_TEST_RESULT_PASS, "", log.str());
				}
			}
		}
		else // Passed as appropriate
		{
			log << "Message was found when expected: ("<< id << ") with "
				<< glu::getDebugMessageSeverityStr(severity);
			return VerificationResult(QP_TEST_RESULT_PASS, "", log.str());
		}
	}
	// Message should be filtered out
	else
	{
		// Filtered out
		if (resCount == 0)
		{
			log << "Message was excluded correctly:  (" << id << ") with "
				<< glu::getDebugMessageSeverityStr(severity);
			return VerificationResult(QP_TEST_RESULT_PASS, "", log.str());
		}
		// Only present in filtered run (ERROR)
		else if (resCount > 0 && refCount == 0)
		{
			log << "A message was not excluded as it should have been: (" << id << ") with "
				<< glu::getDebugMessageSeverityStr(severity)
				<< ". This message was not present in the reference run";
			return VerificationResult(QP_TEST_RESULT_FAIL, "A message was not filtered out", log.str());
		}
		// Present in both runs (ERROR)
		else
		{
			log << "A message was not excluded as it should have been: (" << id << ") with "
				<< glu::getDebugMessageSeverityStr(severity);
			return VerificationResult(QP_TEST_RESULT_FAIL, "A message was not filtered out", log.str());
		}
	}
}

// Return true if message needs further verification
bool BaseCase::verifyMessageExists (const MessageData& message, GLenum source, GLenum type)
{
	TestLog& log = m_testCtx.getLog();

	if (source == GL_DONT_CARE || type == GL_DONT_CARE)
		return false;
	else if (message.id.source == GL_NONE || message.id.type == GL_NONE)
	{
		if (isDebugContext())
		{
			m_results.addResult(QP_TEST_RESULT_FAIL, "Message was not reported as expected");
			log << TestLog::Message << "A message was expected but none was reported" << TestLog::EndMessage;
		}
		else
		{
			m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Verification accuracy is lacking without a debug context");
			log << TestLog::Message << "A message was expected but none was reported. Running without a debug context" << TestLog::EndMessage;
		}
		return false;
	}
	else
		return true;
}

void BaseCase::verifyMessageGroup (const MessageData& message, GLenum source, GLenum type)
{
	TestLog& log = m_testCtx.getLog();

	if (message.id.source != source)
	{
		m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect message source");
		log << TestLog::Message << "Message source was " << glu::getDebugMessageSourceStr(message.id.source)
			<< " when it should have been "  << glu::getDebugMessageSourceStr(source) << TestLog::EndMessage;
	}

	if (message.id.type != type)
	{
		m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect message type");
		log << TestLog::Message << "Message type was " << glu::getDebugMessageTypeStr(message.id.type)
			<< " when it should have been " << glu::getDebugMessageTypeStr(type) << TestLog::EndMessage;
	}
}

void BaseCase::verifyMessageString (const MessageData& message)
{
	TestLog& log = m_testCtx.getLog();

	log << TestLog::Message << "Driver says: \"" << message.message << "\"" << TestLog::EndMessage;

	if (message.message.empty())
	{
		m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Empty message");
		log << TestLog::Message << "Message message was empty" << TestLog::EndMessage;
	}
}

void BaseCase::verifyMessage (const MessageData& message, GLenum source, GLenum type)
{
	if (verifyMessageExists(message, source, type))
	{
		verifyMessageString(message);
		verifyMessageGroup(message, source, type);
	}
}

void BaseCase::verifyMessage (const MessageData& message, GLenum source, GLenum type, GLuint id, GLenum severity)
{
	TestLog& log = m_testCtx.getLog();

	if (verifyMessageExists(message, source, type))
	{
		verifyMessageString(message);
		verifyMessageGroup(message, source, type);

		if (message.id.id != id)
		{
			m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect message id");
			log << TestLog::Message << "Message id was " << message.id.id
				<< " when it should have been " << id << TestLog::EndMessage;
		}

		if (message.severity != severity)
		{
			m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect message severity");
			log << TestLog::Message << "Message severity was " << glu::getDebugMessageSeverityStr(message.severity)
				<< " when it should have been " << glu::getDebugMessageSeverityStr(severity) << TestLog::EndMessage;
		}
	}
}

bool BaseCase::isDebugContext (void) const
{
	return (m_context.getRenderContext().getType().getFlags() & glu::CONTEXT_DEBUG) != 0;
}

// Generate errors, verify that each error results in a callback call
class CallbackErrorCase : public BaseCase
{
public:
								CallbackErrorCase	(Context&				ctx,
													 const char*			name,
													 const char*			desc,
													 TestFunctionWrapper	errorFunc);
	virtual						~CallbackErrorCase	(void) {}

	virtual IterateResult		iterate				(void);

	virtual void				expectMessage		(GLenum source, GLenum type);

private:
	virtual void				callback			(GLenum source, GLenum type, GLuint id, GLenum severity, const string& message);

	const TestFunctionWrapper	m_errorFunc;
	MessageData					m_lastMessage;
};

CallbackErrorCase::CallbackErrorCase (Context&				ctx,
									  const char*			name,
									  const char*			desc,
									  TestFunctionWrapper	errorFunc)
	: BaseCase		(ctx, name, desc)
	, m_errorFunc	(errorFunc)
{
}

CallbackErrorCase::IterateResult CallbackErrorCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	tcu::TestLog&			log		= m_testCtx.getLog();
	DebugMessageTestContext	context	= DebugMessageTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, true);

	gl.enable(GL_DEBUG_OUTPUT);
	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, false); // disable all
	gl.debugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, DE_NULL, true); // enable API errors
	gl.debugMessageControl(GL_DEBUG_SOURCE_APPLICATION, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); // enable application messages
	gl.debugMessageControl(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); // enable third party messages
	gl.debugMessageCallback(callbackHandle, this);

	m_errorFunc.call(context);

	gl.debugMessageCallback(DE_NULL, DE_NULL);
	gl.disable(GL_DEBUG_OUTPUT);

	m_results.setTestContextResult(m_testCtx);

	return STOP;
}

void CallbackErrorCase::expectMessage (GLenum source, GLenum type)
{
	verifyMessage(m_lastMessage, source, type);
	m_lastMessage = MessageData();

	// Reset error so that code afterwards (such as glu::ShaderProgram) doesn't break because of
	// lingering error state.
	m_context.getRenderContext().getFunctions().getError();
}

void CallbackErrorCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
{
	m_lastMessage = MessageData(MessageID(source, type, id), severity, message);
}

// Generate errors, verify that each error results in a log entry
class LogErrorCase : public BaseCase
{
public:
								LogErrorCase	(Context&				context,
												 const char*			name,
												 const char*			desc,
												 TestFunctionWrapper	errorFunc);
	virtual						~LogErrorCase	(void) {}

	virtual IterateResult		iterate			(void);

	virtual void				expectMessage	(GLenum source, GLenum type);

private:
	const TestFunctionWrapper	m_errorFunc;
	MessageData					m_lastMessage;
};

LogErrorCase::LogErrorCase (Context&			ctx,
							const char*			name,
							const char*			desc,
							TestFunctionWrapper	errorFunc)
	: BaseCase		(ctx, name, desc)
	, m_errorFunc	(errorFunc)
{
}

LogErrorCase::IterateResult LogErrorCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	tcu::TestLog&			log		= m_testCtx.getLog();
	DebugMessageTestContext	context	= DebugMessageTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, true);
	GLint					numMsg	= 0;

	gl.enable(GL_DEBUG_OUTPUT);
	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, false); // disable all
	gl.debugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, DE_NULL, true); // enable API errors
	gl.debugMessageCallback(DE_NULL, DE_NULL); // enable logging
	gl.getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMsg);
	gl.getDebugMessageLog(numMsg, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL); // clear log

	m_errorFunc.call(context);

	gl.disable(GL_DEBUG_OUTPUT);
	m_results.setTestContextResult(m_testCtx);

	return STOP;
}

void LogErrorCase::expectMessage (GLenum source, GLenum type)
{
	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	int						numMsg		= 0;
	TestLog&				log			= m_testCtx.getLog();
	MessageData				lastMsg;

	if (source == GL_DONT_CARE || type == GL_DONT_CARE)
		return;

	gl.getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMsg);

	if (numMsg == 0)
	{
		if (isDebugContext())
		{
			m_results.addResult(QP_TEST_RESULT_FAIL, "Error was not reported as expected");
			log << TestLog::Message << "A message was expected but none was reported (empty message log)" << TestLog::EndMessage;
		}
		else
		{
			m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Verification accuracy is lacking without a debug context");
			log << TestLog::Message << "A message was expected but none was reported (empty message log). Running without a debug context" << TestLog::EndMessage;
		}
		return;
	}

	// There may be messages other than the error we are looking for in the log.
	// Strictly nothing prevents the implementation from producing more than the
	// required error from an API call with a defined error. however we assume that
	// since calls that produce an error should not change GL state the implementation
	// should have nothing else to report.
	if (numMsg > 1)
		gl.getDebugMessageLog(numMsg-1, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL); // Clear all but last

	{
		int  msgLen = 0;
		gl.getIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &msgLen);

		TCU_CHECK_MSG(msgLen >= 0, "Negative message length");
		TCU_CHECK_MSG(msgLen < 100000, "Excessively long message");

		lastMsg.message.resize(msgLen);
		gl.getDebugMessageLog(1, msgLen, &lastMsg.id.source, &lastMsg.id.type, &lastMsg.id.id, &lastMsg.severity, &msgLen, &lastMsg.message[0]);
	}

	log << TestLog::Message << "Driver says: \"" << lastMsg.message << "\"" << TestLog::EndMessage;

	verifyMessage(lastMsg, source, type);

	// Reset error so that code afterwards (such as glu::ShaderProgram) doesn't break because of
	// lingering error state.
	m_context.getRenderContext().getFunctions().getError();
}

// Generate errors, verify that calling glGetError afterwards produces desired result
class GetErrorCase : public BaseCase
{
public:
								GetErrorCase	(Context&				ctx,
												 const char*			name,
												 const char*			desc,
												 TestFunctionWrapper	errorFunc);
	virtual						~GetErrorCase	(void) {}

	virtual IterateResult		iterate			(void);

	virtual void				expectMessage	(GLenum source, GLenum type);
	virtual void				expectError		(glw::GLenum error0, glw::GLenum error1);

private:
	const TestFunctionWrapper	m_errorFunc;
};

GetErrorCase::GetErrorCase (Context&			ctx,
							const char*			name,
							const char*			desc,
							TestFunctionWrapper	errorFunc)
	: BaseCase		(ctx, name, desc)
	, m_errorFunc	(errorFunc)
{
}

GetErrorCase::IterateResult GetErrorCase::iterate (void)
{
	tcu::TestLog&			log		= m_testCtx.getLog();
	DebugMessageTestContext	context	= DebugMessageTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, true);

	m_errorFunc.call(context);

	m_results.setTestContextResult(m_testCtx);

	return STOP;
}

void GetErrorCase::expectMessage (GLenum source, GLenum type)
{
	DE_UNREF(source);
	DE_UNREF(type);
	DE_FATAL("GetErrorCase cannot handle anything other than error codes");
}

void GetErrorCase::expectError (glw::GLenum error0, glw::GLenum error1)
{
	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	TestLog&				log		= m_testCtx.getLog();

	const GLenum			result	= gl.getError();

	if (result != error0 && result != error1)
	{
		m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect error was reported");
		if (error0 == error1)
			log << TestLog::Message
				<< glu::getErrorStr(error0) << " was expected but got "
				<< glu::getErrorStr(result)
				<< TestLog::EndMessage;
		else
			log << TestLog::Message
				<< glu::getErrorStr(error0) << " or "
				<< glu::getErrorStr(error1) << " was expected but got "
				<< glu::getErrorStr(result)
				<< TestLog::EndMessage;
		return;
	}
}

// Generate errors, log the types, disable some, regenerate errors, verify correct errors (not)reported
class FilterCase : public BaseCase
{
public:
										FilterCase		(Context&							ctx,
														 const char*						name,
														 const char*						desc,
														 const vector<TestFunctionWrapper>&	errorFuncs);
	virtual								~FilterCase		(void) {}

	virtual IterateResult				iterate			(void);

	virtual void						expectMessage	(GLenum source, GLenum type);

protected:
	struct MessageFilter
	{
		MessageFilter() : source(GL_DONT_CARE), type(GL_DONT_CARE), severity(GL_DONT_CARE), enabled(true) {} // Default to enable all
		MessageFilter(GLenum source_, GLenum type_, GLenum severity_, const vector<GLuint>& ids_, bool enabled_) : source(source_), type(type_), severity(severity_), ids(ids_), enabled(enabled_) {}

		GLenum			source;
		GLenum			type;
		GLenum			severity;
		vector<GLuint>	ids;
		bool			enabled;
	};

	virtual void						callback			(GLenum source, GLenum type, GLuint id, GLenum severity, const string& message);

	vector<MessageData>					genMessages			(bool uselog, const string& desc);

	vector<MessageFilter>				genFilters			(const vector<MessageData>& messages, const vector<MessageFilter>& initial, deUint32 seed, int iterations) const;
	void								applyFilters		(const vector<MessageFilter>& filters) const;
	bool								isEnabled			(const vector<MessageFilter>& filters, const MessageData& message) const;

	void								verify				(const vector<MessageData>&		refMessages,
															 const vector<MessageData>&		filteredMessages,
															 const vector<MessageFilter>&	filters);

	const vector<TestFunctionWrapper>	m_errorFuncs;

	vector<MessageData>*				m_currentErrors;
};

FilterCase::FilterCase (Context&							ctx,
						const char*							name,
						const char*							desc,
						const vector<TestFunctionWrapper>&	errorFuncs)
	: BaseCase			(ctx, name, desc)
	, m_errorFuncs		(errorFuncs)
	, m_currentErrors	(DE_NULL)
{
}

FilterCase::IterateResult FilterCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions& gl = m_context.getRenderContext().getFunctions();

	gl.enable(GL_DEBUG_OUTPUT);
	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	gl.debugMessageCallback(callbackHandle, this);

	try
	{
		gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);

		{
			const vector<MessageData>	refMessages		= genMessages(true, "Reference run");
			const MessageFilter			baseFilter		(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, vector<GLuint>(), true);
			const deUint32				baseSeed		= deStringHash(getName()) ^ m_testCtx.getCommandLine().getBaseSeed();
			const vector<MessageFilter>	filters			= genFilters(refMessages, vector<MessageFilter>(1, baseFilter), baseSeed, 4);
			vector<MessageData>			filteredMessages;

			applyFilters(filters);

			// Generate errors
			filteredMessages = genMessages(false, "Filtered run");

			// Verify
			verify(refMessages, filteredMessages, filters);

			if (!isDebugContext() && refMessages.empty())
				m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Verification accuracy is lacking without a debug context");
		}
	}
	catch (...)
	{
		gl.disable(GL_DEBUG_OUTPUT);
		gl.debugMessageCallback(DE_NULL, DE_NULL);
		throw;
	}

	gl.disable(GL_DEBUG_OUTPUT);
	gl.debugMessageCallback(DE_NULL, DE_NULL);
	m_results.setTestContextResult(m_testCtx);

	return STOP;
}

void FilterCase::expectMessage (GLenum source, GLenum type)
{
	DE_UNREF(source);
	DE_UNREF(type);
}

void FilterCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
{
	if (m_currentErrors)
		m_currentErrors->push_back(MessageData(MessageID(source, type, id), severity, message));
}

vector<MessageData> FilterCase::genMessages (bool uselog, const string& desc)
{
	tcu::TestLog&			log			= m_testCtx.getLog();
	DebugMessageTestContext	context		= DebugMessageTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, uselog);
	tcu::ScopedLogSection	section		(log, "message gen", desc);
	vector<MessageData>		messages;

	m_currentErrors = &messages;

	for (int ndx = 0; ndx < int(m_errorFuncs.size()); ndx++)
		m_errorFuncs[ndx].call(context);

	m_currentErrors = DE_NULL;

	return messages;
}

vector<FilterCase::MessageFilter> FilterCase::genFilters (const vector<MessageData>& messages, const vector<MessageFilter>& initial, deUint32 seed, int iterations) const
{
	de::Random				rng				(seed ^ deInt32Hash(deStringHash(getName())));

	set<MessageID>			tempMessageIds;
	set<GLenum>				tempSources;
	set<GLenum>				tempTypes;
	set<GLenum>				tempSeverities;

	if (messages.empty())
		return initial;

	for (int ndx = 0; ndx < int(messages.size()); ndx++)
	{
		const MessageData& msg = messages[ndx];

		tempMessageIds.insert(msg.id);
		tempSources.insert(msg.id.source);
		tempTypes.insert(msg.id.type);
		tempSeverities.insert(msg.severity);
	}

	{
		// Fetchable by index
		const vector<MessageID> messageIds	(tempMessageIds.begin(), tempMessageIds.end());
		const vector<GLenum>	sources		(tempSources.begin(), tempSources.end());
		const vector<GLenum>	types		(tempTypes.begin(), tempTypes.end());
		const vector<GLenum>	severities	(tempSeverities.begin(), tempSeverities.end());

		vector<MessageFilter>	filters		= initial;

		for (int iteration = 0; iteration < iterations; iteration++)
		{
			switch(rng.getInt(0, 8)) // Distribute so that per-message randomization (the default branch) is prevalent
			{
				case 0:
				{
					const GLenum	source	= sources[rng.getInt(0, int(sources.size()-1))];
					const bool		enabled	= rng.getBool();

					filters.push_back(MessageFilter(source, GL_DONT_CARE, GL_DONT_CARE, vector<GLuint>(), enabled));
					break;
				}

				case 1:
				{
					const GLenum	type	= types[rng.getUint32()%types.size()];
					const bool		enabled	= rng.getBool();

					filters.push_back(MessageFilter(GL_DONT_CARE, type, GL_DONT_CARE, vector<GLuint>(), enabled));
					break;
				}

				case 2:
				{
					const GLenum	severity	= severities[rng.getUint32()%severities.size()];
					const bool		enabled		= rng.getBool();

					filters.push_back(MessageFilter(GL_DONT_CARE, GL_DONT_CARE, severity, vector<GLuint>(), enabled));
					break;
				}

				default:
				{
					const int start = rng.getInt(0, int(messageIds.size()));

					for (int itr = 0; itr < 4; itr++)
					{
						const MessageID&	id		= messageIds[(start+itr)%messageIds.size()];
						const bool			enabled = rng.getBool();

						filters.push_back(MessageFilter(id.source, id.type, GL_DONT_CARE, vector<GLuint>(1, id.id), enabled));
					}
				}
			}
		}

		return filters;
	}
}

void FilterCase::applyFilters (const vector<MessageFilter>& filters) const
{
	TestLog&					log		= m_testCtx.getLog();
	const tcu::ScopedLogSection	section	(log, "", "Setting message filters");
	const glw::Functions&		gl		= m_context.getRenderContext().getFunctions();

	for (size_t filterNdx = 0; filterNdx < filters.size(); filterNdx++)
	{
		const MessageFilter& filter = filters[filterNdx];

		if (filter.ids.empty())
			log << TestLog::Message << "Setting messages with"
				<< " source " << glu::getDebugMessageSourceStr(filter.source)
				<< ", type " << glu::getDebugMessageTypeStr(filter.type)
				<< " and severity " << glu::getDebugMessageSeverityStr(filter.severity)
				<< (filter.enabled ? " to enabled" : " to disabled")
				<< TestLog::EndMessage;
		else
		{
			for (size_t ndx = 0; ndx < filter.ids.size(); ndx++)
				log << TestLog::Message << "Setting message (" << MessageID(filter.source, filter.type, filter.ids[ndx]) << ") to " << (filter.enabled ? "enabled" : "disabled") << TestLog::EndMessage;
		}

		gl.debugMessageControl(filter.source, filter.type, filter.severity, GLsizei(filter.ids.size()), filter.ids.empty() ? DE_NULL : &filter.ids[0], filter.enabled);
	}
}

bool FilterCase::isEnabled (const vector<MessageFilter>& filters, const MessageData& message) const
{
	bool retval = true;

	for (size_t filterNdx = 0; filterNdx < filters.size(); filterNdx++)
	{
		const MessageFilter&	filter	= filters[filterNdx];

		if (filter.ids.empty())
		{
			if (filter.source != GL_DONT_CARE && filter.source != message.id.source)
				continue;

			if (filter.type != GL_DONT_CARE && filter.type != message.id.type)
				continue;

			if (filter.severity != GL_DONT_CARE && filter.severity != message.severity)
				continue;
		}
		else
		{
			DE_ASSERT(filter.source != GL_DONT_CARE);
			DE_ASSERT(filter.type != GL_DONT_CARE);
			DE_ASSERT(filter.severity == GL_DONT_CARE);

			if (filter.source != message.id.source || filter.type != message.id.type)
				continue;

			if (!de::contains(filter.ids.begin(), filter.ids.end(), message.id.id))
				continue;
		}

		retval = filter.enabled;
	}

	return retval;
}

struct MessageMeta
{
	int		refCount;
	int		resCount;
	GLenum	severity;

	MessageMeta (void) : refCount(0), resCount(0), severity(GL_NONE) {}
};

void FilterCase::verify (const vector<MessageData>& refMessages, const vector<MessageData>& resMessages, const vector<MessageFilter>& filters)
{
	TestLog&						log		= m_testCtx.getLog();
	map<MessageID, MessageMeta>		counts;

	log << TestLog::Section("verification", "Verifying");

	// Gather message counts & severities, report severity mismatches if found
	for (size_t refNdx = 0; refNdx < refMessages.size(); refNdx++)
	{
		const MessageData&	msg  = refMessages[refNdx];
		MessageMeta&		meta = counts[msg.id];

		if (meta.severity != GL_NONE && meta.severity != msg.severity)
		{
			log << TestLog::Message << "A message has variable severity between instances: (" << msg.id << ") with severity "
				<< glu::getDebugMessageSeverityStr(meta.severity) << " and " << glu::getDebugMessageSeverityStr(msg.severity) << TestLog::EndMessage;
			m_results.addResult(QP_TEST_RESULT_FAIL, "Message severity changed between instances of the same message");
		}

		meta.refCount++;
		meta.severity = msg.severity;
	}

	for (size_t resNdx = 0; resNdx < resMessages.size(); resNdx++)
	{
		const MessageData&	msg  = resMessages[resNdx];
		MessageMeta&		meta = counts[msg.id];

		if (meta.severity != GL_NONE && meta.severity != msg.severity)
		{
			log << TestLog::Message << "A message has variable severity between instances: (" << msg.id << ") with severity "
				<< glu::getDebugMessageSeverityStr(meta.severity) << " and " << glu::getDebugMessageSeverityStr(msg.severity) << TestLog::EndMessage;
			m_results.addResult(QP_TEST_RESULT_FAIL, "Message severity changed between instances of the same message");
		}

		meta.resCount++;
		meta.severity = msg.severity;
	}

	for (map<MessageID, MessageMeta>::const_iterator itr = counts.begin(); itr != counts.end(); itr++)
	{
		const MessageID&	id			= itr->first;
		const GLenum		severity	= itr->second.severity;

		const int			refCount	= itr->second.refCount;
		const int			resCount	= itr->second.resCount;
		const bool			enabled		= isEnabled(filters, MessageData(id, severity, ""));

		VerificationResult	result		= verifyMessageCount(id, severity, refCount, resCount, enabled);

		log << TestLog::Message << result.logMessage << TestLog::EndMessage;

		if (result.result != QP_TEST_RESULT_PASS)
			m_results.addResult(result.result, result.resultMessage);
	}

	log << TestLog::EndSection;
}

// Filter case that uses debug groups
class GroupFilterCase : public FilterCase
{
public:
							GroupFilterCase		(Context&							ctx,
												 const char*						name,
												 const char*						desc,
												 const vector<TestFunctionWrapper>&	errorFuncs);
	virtual					~GroupFilterCase	(void) {}

	virtual IterateResult	iterate				(void);
};

GroupFilterCase::GroupFilterCase (Context&								ctx,
								  const char*							name,
								  const char*							desc,
								  const vector<TestFunctionWrapper>&	errorFuncs)
	: FilterCase(ctx, name, desc, errorFuncs)
{
}

template<typename T>
vector<T> join(const vector<T>& a, const vector<T>&b)
{
	vector<T> retval;

	retval.reserve(a.size()+b.size());
	retval.insert(retval.end(), a.begin(), a.end());
	retval.insert(retval.end(), b.begin(), b.end());
	return retval;
}

GroupFilterCase::IterateResult GroupFilterCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	tcu::TestLog&			log			= m_testCtx.getLog();

	gl.enable(GL_DEBUG_OUTPUT);
	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	gl.debugMessageCallback(callbackHandle, this);

	try
	{
		gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);

		{

			// Generate reference (all errors)
			const vector<MessageData>	refMessages		= genMessages(true, "Reference run");
			const deUint32				baseSeed		= deStringHash(getName()) ^ m_testCtx.getCommandLine().getBaseSeed();
			const MessageFilter			baseFilter		 (GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, vector<GLuint>(), true);
			const vector<MessageFilter>	filter0			= genFilters(refMessages, vector<MessageFilter>(1, baseFilter), baseSeed, 4);
			vector<MessageData>			resMessages0;

			applyFilters(filter0);

			resMessages0 = genMessages(false, "Filtered run, default debug group");

			// Initial verification
			verify(refMessages, resMessages0, filter0);

			{
				// Generate reference (filters inherited from parent)
				const vector<MessageFilter> filter1base		= genFilters(refMessages, vector<MessageFilter>(), baseSeed ^ 0xDEADBEEF, 4);
				const vector<MessageFilter>	filter1full		= join(filter0, filter1base);
				tcu::ScopedLogSection		section1		(log, "", "Pushing Debug Group");
				vector<MessageData>			resMessages1;

				gl.pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Test Group");
				applyFilters(filter1base);

				// First nested verification
				resMessages1 = genMessages(false, "Filtered run, pushed one debug group");
				verify(refMessages, resMessages1, filter1full);

				{
					// Generate reference (filters iherited again)
					const vector<MessageFilter>	filter2base		= genFilters(refMessages, vector<MessageFilter>(), baseSeed ^ 0x43211234, 4);
					const vector<MessageFilter>	filter2full		= join(filter1full, filter2base);
					tcu::ScopedLogSection		section2		(log, "", "Pushing Debug Group");
					vector<MessageData>			resMessages2;

					gl.pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Nested Test Group");
					applyFilters(filter2base);

					// Second nested verification
					resMessages2 = genMessages(false, "Filtered run, pushed two debug groups");
					verify(refMessages, resMessages2, filter2full);

					gl.popDebugGroup();
				}

				// First restore verification
				resMessages1 = genMessages(false, "Filtered run, popped second debug group");
				verify(refMessages, resMessages1, filter1full);

				gl.popDebugGroup();
			}

			// restore verification
			resMessages0 = genMessages(false, "Filtered run, popped first debug group");
			verify(refMessages, resMessages0, filter0);

			if (!isDebugContext() && refMessages.empty())
				m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Verification accuracy is lacking without a debug context");
		}
	}
	catch (...)
	{
		gl.disable(GL_DEBUG_OUTPUT);
		gl.debugMessageCallback(DE_NULL, DE_NULL);
		throw;
	}

	gl.disable(GL_DEBUG_OUTPUT);
	gl.debugMessageCallback(DE_NULL, DE_NULL);
	m_results.setTestContextResult(m_testCtx);
	return STOP;
}

// Basic grouping functionality
class GroupCase : public BaseCase
{
public:
							GroupCase	(Context&				ctx,
										 const char*			name,
										 const char*			desc);
	virtual					~GroupCase	() {}

	virtual IterateResult	iterate		(void);

private:
	virtual void			callback	(GLenum source, GLenum type, GLuint id, GLenum severity, const string& message);

	MessageData				m_lastMessage;
};

GroupCase::GroupCase (Context&				ctx,
					  const char*			name,
					  const char*			desc)
	: BaseCase(ctx, name, desc)
{
}

GroupCase::IterateResult GroupCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	tcu::TestLog&			log		= m_testCtx.getLog();
	glu::CallLogWrapper		wrapper	(gl, log);

	gl.enable(GL_DEBUG_OUTPUT);
	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, false); // disable all
	gl.debugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, DE_NULL, true); // enable API errors
	gl.debugMessageControl(GL_DEBUG_SOURCE_APPLICATION, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); // enable application messages
	gl.debugMessageControl(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); // enable third party messages
	gl.debugMessageCallback(callbackHandle, this);

	wrapper.enableLogging(true);
	wrapper.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1234, -1, "Pushed debug stack");
	verifyMessage(m_lastMessage, GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP, 1234, GL_DEBUG_SEVERITY_NOTIFICATION);
	wrapper.glPopDebugGroup();
	verifyMessage(m_lastMessage, GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP, 1234, GL_DEBUG_SEVERITY_NOTIFICATION);

	wrapper.glPushDebugGroup(GL_DEBUG_SOURCE_THIRD_PARTY, 4231, -1, "Pushed debug stack");
	verifyMessage(m_lastMessage, GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_PUSH_GROUP, 4231, GL_DEBUG_SEVERITY_NOTIFICATION);
	wrapper.glPopDebugGroup();
	verifyMessage(m_lastMessage, GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_POP_GROUP, 4231, GL_DEBUG_SEVERITY_NOTIFICATION);

	gl.debugMessageCallback(DE_NULL, DE_NULL);
	gl.disable(GL_DEBUG_OUTPUT);

	m_results.setTestContextResult(m_testCtx);

	return STOP;
}

void GroupCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
{
	m_lastMessage = MessageData(MessageID(source, type, id), severity, message);
}

// Asynchronous debug output
class AsyncCase : public BaseCase
{
public:
										AsyncCase			(Context&							ctx,
															 const char*						name,
															 const char*						desc,
															 const vector<TestFunctionWrapper>&	errorFuncs,
															 bool								useCallbacks);
	virtual								~AsyncCase			(void) {}

	virtual IterateResult				iterate				(void);

	virtual void						expectMessage		(glw::GLenum source, glw::GLenum type);

private:
	struct MessageCount
	{
		int received;
		int expected;

		MessageCount(void) : received(0), expected(0) {}
	};
	typedef map<MessageID, MessageCount> MessageCounter;

	enum VerifyState
	{
		VERIFY_PASS = 0,
		VERIFY_MINIMUM,
		VERIFY_FAIL,

		VERIFY_LAST
	};

	virtual void						callback			(glw::GLenum source, glw::GLenum type, glw::GLuint id, glw::GLenum severity, const std::string& message);
	VerifyState							verify				(bool uselog);
	void								fetchLogMessages	(void);

	const vector<TestFunctionWrapper>	m_errorFuncs;
	const bool							m_useCallbacks;

	MessageCounter						m_counts;

	de::Mutex							m_mutex;
};

AsyncCase::AsyncCase (Context&								ctx,
					  const char*							name,
					  const char*							desc,
					  const vector<TestFunctionWrapper>&	errorFuncs,
					  bool									useCallbacks)
	: BaseCase			(ctx, name, desc)
	, m_errorFuncs		(errorFuncs)
	, m_useCallbacks	(useCallbacks)
{
}

AsyncCase::IterateResult AsyncCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	tcu::TestLog&			log			= m_testCtx.getLog();
	DebugMessageTestContext	context		= DebugMessageTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, true);
	const int				maxWait		= 10000; // ms
	const int				warnWait	= 100;

	// Clear log from earlier messages
	{
		GLint numMessages = 0;
		gl.getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);
		gl.getDebugMessageLog(numMessages, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL);
	}

	gl.enable(GL_DEBUG_OUTPUT);
	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, false);

	// Some messages could be dependent on the value of DEBUG_OUTPUT_SYNCHRONOUS so only use API errors which should be generated in all cases
	gl.debugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, DE_NULL, true);

	if (m_useCallbacks) // will use log otherwise
		gl.debugMessageCallback(callbackHandle, this);
	else
		gl.debugMessageCallback(DE_NULL, DE_NULL);

	// Reference run (synchoronous)
	{
		tcu::ScopedLogSection section(log, "reference run", "Reference run (synchronous)");

		for (int ndx = 0; ndx < int(m_errorFuncs.size()); ndx++)
			m_errorFuncs[ndx].call(context);
	}

	if (m_counts.empty())
	{
		if (!isDebugContext())
			m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Need debug context to guarantee implementation behaviour (see command line options)");

		log << TestLog::Message << "Reference run produced no messages, nothing to verify" << TestLog::EndMessage;

		gl.debugMessageCallback(DE_NULL, DE_NULL);
		gl.disable(GL_DEBUG_OUTPUT);

		m_results.setTestContextResult(m_testCtx);
		return STOP;
	}

	for (MessageCounter::iterator itr = m_counts.begin(); itr != m_counts.end(); itr++)
	{
		itr->second.expected = itr->second.received;
		itr->second.received = 0;
	}

	gl.disable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

	// Result run (async)
	for (int ndx = 0; ndx < int(m_errorFuncs.size()); ndx++)
		m_errorFuncs[ndx].call(context);

	// Repatedly try verification, new results may be added to m_receivedMessages at any time
	{
		tcu::ScopedLogSection	section			(log, "result run", "Result run (asynchronous)");
		VerifyState				lastTimelyState = VERIFY_FAIL;

		for (int waited = 0;;)
		{
			const VerifyState	pass = verify(false);
			const int			wait = de::max(50, waited>>2);

			// Pass (possibly due to time limit)
			if (pass == VERIFY_PASS || (pass == VERIFY_MINIMUM && waited >= maxWait))
			{
				verify(true); // log

				// State changed late
				if (waited >= warnWait && lastTimelyState != pass)
					m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Async messages were returned to application somewhat slowly");

				log << TestLog::Message << "Passed after ~" << waited << "ms of waiting" << TestLog::EndMessage;
				break;
			}
			// fail
			else if (waited >= maxWait)
			{
				verify(true); // log

				log << TestLog::Message << "Waited for ~" << waited << "ms without getting all expected messages" << TestLog::EndMessage;
				m_results.addResult(QP_TEST_RESULT_FAIL, "Async messages were not returned to application within a reasonable timeframe");
				break;
			}

			if (waited < warnWait)
				lastTimelyState = pass;

			deSleep(wait);
			waited += wait;

			if (!m_useCallbacks)
				fetchLogMessages();
		}
	}

	gl.debugMessageCallback(DE_NULL, DE_NULL);

	gl.disable(GL_DEBUG_OUTPUT);
	m_results.setTestContextResult(m_testCtx);

	return STOP;
}

void AsyncCase::expectMessage (GLenum source, GLenum type)
{
	// Good time to clean up the queue as this should be called after most messages are generated
	if (!m_useCallbacks)
		fetchLogMessages();

	DE_UNREF(source);
	DE_UNREF(type);
}

void AsyncCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
{
	DE_ASSERT(m_useCallbacks);
	DE_UNREF(severity);
	DE_UNREF(message);

	de::ScopedLock lock(m_mutex);

	m_counts[MessageID(source, type, id)].received++;
}

// Note that we can never guarantee getting all messages back when using logs/fetching as the GL may create more than its log size limit during an arbitrary period of time
void AsyncCase::fetchLogMessages (void)
{
	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
	GLint					numMsg	= 0;

	gl.getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMsg);

	for(int msgNdx = 0; msgNdx < numMsg; msgNdx++)
	{
		int			msgLen = 0;
		MessageData msg;

		gl.getIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &msgLen);

		TCU_CHECK_MSG(msgLen >= 0, "Negative message length");
		TCU_CHECK_MSG(msgLen < 100000, "Excessively long message");

		msg.message.resize(msgLen);
		gl.getDebugMessageLog(1, msgLen, &msg.id.source, &msg.id.type, &msg.id.id, &msg.severity, &msgLen, &msg.message[0]);

		{
			const de::ScopedLock lock(m_mutex); // Don't block during API call

			m_counts[MessageID(msg.id)].received++;
		}
	}
}

AsyncCase::VerifyState AsyncCase::verify (bool uselog)
{
	using std::map;

	VerifyState			retval		= VERIFY_PASS;
	TestLog&			log			= m_testCtx.getLog();

	const de::ScopedLock lock(m_mutex);

	for (map<MessageID, MessageCount>::const_iterator itr = m_counts.begin(); itr != m_counts.end(); itr++)
	{
		const MessageID&	id			= itr->first;

		const int			refCount	= itr->second.expected;
		const int			resCount	= itr->second.received;
		const bool			enabled		= true;

		VerificationResult	result		= verifyMessageCount(id, GL_DONT_CARE, refCount, resCount, enabled);

		if (uselog)
			log << TestLog::Message << result.logMessage << TestLog::EndMessage;

		if (result.result == QP_TEST_RESULT_FAIL)
			retval = VERIFY_FAIL;
		else if (result.result != QP_TEST_RESULT_PASS && retval == VERIFY_PASS)
			retval = VERIFY_MINIMUM;
	}

	return retval;
}

// Tests debug labels
class LabelCase : public TestCase
{
public:
							LabelCase	(Context&				ctx,
										 const char*			name,
										 const char*			desc,
										 GLenum					identifier);
	virtual					~LabelCase	(void) {}

	virtual IterateResult	iterate		(void);

private:
	GLenum					m_identifier;
};

LabelCase::LabelCase (Context&		ctx,
					  const char*			name,
					  const char*			desc,
					  GLenum				identifier)
	: TestCase		(ctx, name, desc)
	, m_identifier	(identifier)
{
}

LabelCase::IterateResult LabelCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	const char*	const		msg			= "This is a debug label";
	GLuint					object		= 0;
	int						outlen		= -1;
	char					buffer[64];

	switch(m_identifier)
	{
		case GL_BUFFER:
			gl.genBuffers(1, &object);
			gl.bindBuffer(GL_ARRAY_BUFFER, object);
			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
			break;

		case GL_SHADER:
			object = gl.createShader(GL_FRAGMENT_SHADER);
			break;

		case GL_PROGRAM:
			object = gl.createProgram();
			break;

		case GL_QUERY:
			gl.genQueries(1, &object);
			gl.beginQuery(GL_ANY_SAMPLES_PASSED, object); // Create
			gl.endQuery(GL_ANY_SAMPLES_PASSED); // Cleanup
			break;

		case GL_PROGRAM_PIPELINE:
			gl.genProgramPipelines(1, &object);
			gl.bindProgramPipeline(object); // Create
			gl.bindProgramPipeline(0); // Cleanup
			break;

		case GL_TRANSFORM_FEEDBACK:
			gl.genTransformFeedbacks(1, &object);
			gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, object);
			gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
			break;

		case GL_SAMPLER:
			gl.genSamplers(1, &object);
			gl.bindSampler(0, object);
			gl.bindSampler(0, 0);
			break;

		case GL_TEXTURE:
			gl.genTextures(1, &object);
			gl.bindTexture(GL_TEXTURE_2D, object);
			gl.bindTexture(GL_TEXTURE_2D, 0);
			break;

		case GL_RENDERBUFFER:
			gl.genRenderbuffers(1, &object);
			gl.bindRenderbuffer(GL_RENDERBUFFER, object);
			gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
			break;

		case GL_FRAMEBUFFER:
			gl.genFramebuffers(1, &object);
			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, object);
			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
			break;

		default:
			DE_FATAL("Invalid identifier");
	}

	gl.objectLabel(m_identifier, object, -1, msg);

	deMemset(buffer, 'X', sizeof(buffer));
	gl.getObjectLabel(m_identifier, object, sizeof(buffer), &outlen, buffer);

	if (outlen == 0)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to query debug label from object");
	else if (deStringEqual(msg, buffer))
	{
		m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		buffer[63] = '\0'; // make sure buffer is null terminated before printing
		m_testCtx.getLog() << TestLog::Message << "Query returned wrong string: expected \"" << msg << "\" but got \"" << buffer << "\"" << TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query returned wrong label");
	}

	switch(m_identifier)
	{
		case GL_BUFFER:				gl.deleteBuffers(1, &object);				break;
		case GL_SHADER:				gl.deleteShader(object);					break;
		case GL_PROGRAM:			gl.deleteProgram(object);					break;
		case GL_QUERY:				gl.deleteQueries(1, &object);				break;
		case GL_PROGRAM_PIPELINE:	gl.deleteProgramPipelines(1, &object);		break;
		case GL_TRANSFORM_FEEDBACK:	gl.deleteTransformFeedbacks(1, &object);	break;
		case GL_SAMPLER:			gl.deleteSamplers(1, &object);				break;
		case GL_TEXTURE:			gl.deleteTextures(1, &object);				break;
		case GL_RENDERBUFFER:		gl.deleteRenderbuffers(1, &object);			break;
		case GL_FRAMEBUFFER:		gl.deleteFramebuffers(1, &object);			break;

		default:
			DE_FATAL("Invalid identifier");
	}

	return STOP;
}


DebugMessageTestContext::DebugMessageTestContext (BaseCase&					host,
												  glu::RenderContext&		renderCtx,
												  const glu::ContextInfo&	ctxInfo,
												  tcu::TestLog&				log,
												  tcu::ResultCollector&		results,
												  bool						enableLog)
	: NegativeTestContext	(host, renderCtx, ctxInfo, log, results, enableLog)
	, m_debugHost			(host)
{
}

DebugMessageTestContext::~DebugMessageTestContext (void)
{
}

void DebugMessageTestContext::expectMessage (GLenum source, GLenum type)
{
	m_debugHost.expectMessage(source, type);
}

class SyncLabelCase : public TestCase
{
public:
							SyncLabelCase	(Context& ctx, const char* name, const char* desc);
	virtual IterateResult	iterate			(void);
};

SyncLabelCase::SyncLabelCase (Context& ctx, const char* name, const char* desc)
	: TestCase(ctx, name, desc)
{
}

SyncLabelCase::IterateResult SyncLabelCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	const char*	const		msg			= "This is a debug label";
	int						outlen		= -1;
	char					buffer[64];

	glw::GLsync				sync		= gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "fenceSync");

	gl.objectPtrLabel(sync, -1, msg);

	deMemset(buffer, 'X', sizeof(buffer));
	gl.getObjectPtrLabel(sync, sizeof(buffer), &outlen, buffer);

	if (outlen == 0)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to query debug label from object");
	else if (deStringEqual(msg, buffer))
	{
		m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	else
	{
		buffer[63] = '\0'; // make sure buffer is null terminated before printing
		m_testCtx.getLog() << TestLog::Message << "Query returned wrong string: expected \"" << msg << "\" but got \"" << buffer << "\"" << TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query returned wrong label");
	}

	gl.deleteSync(sync);

	return STOP;
}

class InitialLabelCase : public TestCase
{
public:
							InitialLabelCase	(Context& ctx, const char* name, const char* desc);
	virtual IterateResult	iterate				(void);
};

InitialLabelCase::InitialLabelCase (Context& ctx, const char* name, const char* desc)
	: TestCase(ctx, name, desc)
{
}

InitialLabelCase::IterateResult InitialLabelCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	tcu::ResultCollector	result		(m_testCtx.getLog(), " // ERROR: ");
	int						outlen		= -1;
	GLuint					shader;
	glw::GLsync				sync;
	char					buffer[64];

	sync = gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "fenceSync");

	shader = gl.createShader(GL_FRAGMENT_SHADER);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "createShader");

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Shader", "Shader object");
		m_testCtx.getLog() << TestLog::Message << "Querying initial value" << TestLog::EndMessage;

		buffer[0] = 'X';
		outlen = -1;
		gl.getObjectLabel(GL_SHADER, shader, sizeof(buffer), &outlen, buffer);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

		if (outlen != 0)
			result.fail("'length' was not zero, got " + de::toString(outlen));
		else if (buffer[0] != '\0')
			result.fail("label was not null terminated");
		else
			m_testCtx.getLog() << TestLog::Message << "Got 0-sized null-terminated string." << TestLog::EndMessage;
	}

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Sync", "Sync object");
		m_testCtx.getLog() << TestLog::Message << "Querying initial value" << TestLog::EndMessage;

		buffer[0] = 'X';
		outlen = -1;
		gl.getObjectPtrLabel(sync, sizeof(buffer), &outlen, buffer);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

		if (outlen != 0)
			result.fail("'length' was not zero, got " + de::toString(outlen));
		else if (buffer[0] != '\0')
			result.fail("label was not null terminated");
		else
			m_testCtx.getLog() << TestLog::Message << "Got 0-sized null-terminated string." << TestLog::EndMessage;
	}

	gl.deleteShader(shader);
	gl.deleteSync(sync);

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class ClearLabelCase : public TestCase
{
public:
							ClearLabelCase		(Context& ctx, const char* name, const char* desc);
	virtual IterateResult	iterate				(void);
};

ClearLabelCase::ClearLabelCase (Context& ctx, const char* name, const char* desc)
	: TestCase(ctx, name, desc)
{
}

ClearLabelCase::IterateResult ClearLabelCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	static const struct
	{
		const char*	description;
		int			length;
	} s_clearMethods[] =
	{
		{ " with NULL label and 0 length",			0	},
		{ " with NULL label and 1 length",			1	},
		{ " with NULL label and negative length",	-1	},
	};

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	tcu::ResultCollector	result		(m_testCtx.getLog(), " // ERROR: ");
	const char*	const		msg			= "This is a debug label";
	int						outlen		= -1;
	GLuint					shader;
	glw::GLsync				sync;
	char					buffer[64];

	sync = gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "fenceSync");

	shader = gl.createShader(GL_FRAGMENT_SHADER);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "createShader");

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Shader", "Shader object");

		for (int methodNdx = 0; methodNdx < DE_LENGTH_OF_ARRAY(s_clearMethods); ++methodNdx)
		{
			m_testCtx.getLog() << TestLog::Message << "Setting label to string: \"" << msg << "\"" << TestLog::EndMessage;
			gl.objectLabel(GL_SHADER, shader, -2,  msg);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectLabel");

			m_testCtx.getLog() << TestLog::Message << "Clearing label " << s_clearMethods[methodNdx].description << TestLog::EndMessage;
			gl.objectLabel(GL_SHADER, shader, s_clearMethods[methodNdx].length, DE_NULL);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectLabel");

			m_testCtx.getLog() << TestLog::Message << "Querying label" << TestLog::EndMessage;
			buffer[0] = 'X';
			outlen = -1;
			gl.getObjectLabel(GL_SHADER, shader, sizeof(buffer), &outlen, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

			if (outlen != 0)
				result.fail("'length' was not zero, got " + de::toString(outlen));
			else if (buffer[0] != '\0')
				result.fail("label was not null terminated");
			else
				m_testCtx.getLog() << TestLog::Message << "Got 0-sized null-terminated string." << TestLog::EndMessage;
		}
	}

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Sync", "Sync object");

		for (int methodNdx = 0; methodNdx < DE_LENGTH_OF_ARRAY(s_clearMethods); ++methodNdx)
		{
			m_testCtx.getLog() << TestLog::Message << "Setting label to string: \"" << msg << "\"" << TestLog::EndMessage;
			gl.objectPtrLabel(sync, -2, msg);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectPtrLabel");

			m_testCtx.getLog() << TestLog::Message << "Clearing label " << s_clearMethods[methodNdx].description << TestLog::EndMessage;
			gl.objectPtrLabel(sync, s_clearMethods[methodNdx].length, DE_NULL);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectPtrLabel");

			m_testCtx.getLog() << TestLog::Message << "Querying label" << TestLog::EndMessage;
			buffer[0] = 'X';
			outlen = -1;
			gl.getObjectPtrLabel(sync, sizeof(buffer), &outlen, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

			if (outlen != 0)
				result.fail("'length' was not zero, got " + de::toString(outlen));
			else if (buffer[0] != '\0')
				result.fail("label was not null terminated");
			else
				m_testCtx.getLog() << TestLog::Message << "Got 0-sized null-terminated string." << TestLog::EndMessage;
		}
	}

	gl.deleteShader(shader);
	gl.deleteSync(sync);

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class SpecifyWithLengthCase : public TestCase
{
public:
							SpecifyWithLengthCase	(Context& ctx, const char* name, const char* desc);
	virtual IterateResult	iterate					(void);
};

SpecifyWithLengthCase::SpecifyWithLengthCase (Context& ctx, const char* name, const char* desc)
	: TestCase(ctx, name, desc)
{
}

SpecifyWithLengthCase::IterateResult SpecifyWithLengthCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	tcu::ResultCollector	result		(m_testCtx.getLog(), " // ERROR: ");
	const char*	const		msg			= "This is a debug label";
	const char*	const		clipMsg		= "This is a de";
	int						outlen		= -1;
	GLuint					shader;
	glw::GLsync				sync;
	char					buffer[64];

	sync = gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "fenceSync");

	shader = gl.createShader(GL_FRAGMENT_SHADER);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "createShader");

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Shader", "Shader object");

		m_testCtx.getLog() << TestLog::Message << "Setting label to string: \"" << msg << "\" with length 12" << TestLog::EndMessage;
		gl.objectLabel(GL_SHADER, shader, 12, msg);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectLabel");

		m_testCtx.getLog() << TestLog::Message << "Querying label" << TestLog::EndMessage;
		deMemset(buffer, 'X', sizeof(buffer));
		gl.getObjectLabel(GL_SHADER, shader, sizeof(buffer), &outlen, buffer);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

		if (outlen != 12)
			result.fail("'length' was not 12, got " + de::toString(outlen));
		else if (deStringEqual(clipMsg, buffer))
		{
			m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		}
		else
		{
			buffer[63] = '\0'; // make sure buffer is null terminated before printing
			m_testCtx.getLog() << TestLog::Message << "Query returned wrong string: expected \"" << clipMsg << "\" but got \"" << buffer << "\"" << TestLog::EndMessage;
			result.fail("Query returned wrong label");
		}
	}

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Sync", "Sync object");

		m_testCtx.getLog() << TestLog::Message << "Setting label to string: \"" << msg << "\" with length 12" << TestLog::EndMessage;
		gl.objectPtrLabel(sync, 12, msg);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectPtrLabel");

		m_testCtx.getLog() << TestLog::Message << "Querying label" << TestLog::EndMessage;
		deMemset(buffer, 'X', sizeof(buffer));
		gl.getObjectPtrLabel(sync, sizeof(buffer), &outlen, buffer);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

		if (outlen != 12)
			result.fail("'length' was not 12, got " + de::toString(outlen));
		else if (deStringEqual(clipMsg, buffer))
		{
			m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		}
		else
		{
			buffer[63] = '\0'; // make sure buffer is null terminated before printing
			m_testCtx.getLog() << TestLog::Message << "Query returned wrong string: expected \"" << clipMsg << "\" but got \"" << buffer << "\"" << TestLog::EndMessage;
			result.fail("Query returned wrong label");
		}
	}

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "ZeroSized", "ZeroSized");

		m_testCtx.getLog() << TestLog::Message << "Setting label to string: \"" << msg << "\" with length 0" << TestLog::EndMessage;
		gl.objectLabel(GL_SHADER, shader, 0, msg);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectLabel");

		m_testCtx.getLog() << TestLog::Message << "Querying label" << TestLog::EndMessage;
		deMemset(buffer, 'X', sizeof(buffer));
		gl.getObjectLabel(GL_SHADER, shader, sizeof(buffer), &outlen, buffer);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

		if (outlen != 0)
			result.fail("'length' was not zero, got " + de::toString(outlen));
		else if (buffer[0] != '\0')
			result.fail("label was not null terminated");
		else
			m_testCtx.getLog() << TestLog::Message << "Got 0-sized null-terminated string." << TestLog::EndMessage;
	}

	gl.deleteShader(shader);
	gl.deleteSync(sync);

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class BufferLimitedLabelCase : public TestCase
{
public:
							BufferLimitedLabelCase	(Context& ctx, const char* name, const char* desc);
	virtual IterateResult	iterate					(void);
};

BufferLimitedLabelCase::BufferLimitedLabelCase (Context& ctx, const char* name, const char* desc)
	: TestCase(ctx, name, desc)
{
}

BufferLimitedLabelCase::IterateResult BufferLimitedLabelCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	tcu::ResultCollector	result		(m_testCtx.getLog(), " // ERROR: ");
	const char*	const		msg			= "This is a debug label";
	int						outlen		= -1;
	GLuint					shader;
	glw::GLsync				sync;
	char					buffer[64];

	sync = gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "fenceSync");

	shader = gl.createShader(GL_FRAGMENT_SHADER);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "createShader");

	{
		const tcu::ScopedLogSection superSection(m_testCtx.getLog(), "Shader", "Shader object");

		m_testCtx.getLog() << TestLog::Message << "Setting label to string: \"" << msg << "\"" << TestLog::EndMessage;
		gl.objectLabel(GL_SHADER, shader, -1, msg);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectLabel");

		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryAll", "Query All");

			m_testCtx.getLog() << TestLog::Message << "Querying whole label, buffer size = 22" << TestLog::EndMessage;
			deMemset(buffer, 'X', sizeof(buffer));
			gl.getObjectLabel(GL_SHADER, shader, 22, &outlen, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

			if (outlen != 21)
				result.fail("'length' was not 21, got " + de::toString(outlen));
			else if (buffer[outlen] != '\0')
				result.fail("Buffer was not null-terminated");
			else if (buffer[outlen+1] != 'X')
				result.fail("Query wrote over buffer bound");
			else if (!deStringEqual(msg, buffer))
			{
				buffer[63] = '\0'; // make sure buffer is null terminated before printing
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
				result.fail("Query returned wrong label");
			}
			else
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		}
		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryAllNoSize", "Query all without size");

			m_testCtx.getLog() << TestLog::Message << "Querying whole label, buffer size = 22" << TestLog::EndMessage;
			deMemset(buffer, 'X', sizeof(buffer));
			gl.getObjectLabel(GL_SHADER, shader, 22, DE_NULL, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

			buffer[63] = '\0'; // make sure buffer is null terminated before strlen

			if (strlen(buffer) != 21)
				result.fail("Buffer length was not 21");
			else if (buffer[21] != '\0')
				result.fail("Buffer was not null-terminated");
			else if (buffer[22] != 'X')
				result.fail("Query wrote over buffer bound");
			else if (!deStringEqual(msg, buffer))
			{
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
				result.fail("Query returned wrong label");
			}
			else
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		}
		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryLess", "Query substring");

			m_testCtx.getLog() << TestLog::Message << "Querying whole label, buffer size = 2" << TestLog::EndMessage;
			deMemset(buffer, 'X', sizeof(buffer));
			gl.getObjectLabel(GL_SHADER, shader, 2, &outlen, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

			if (outlen != 1)
				result.fail("'length' was not 1, got " + de::toString(outlen));
			else if (buffer[outlen] != '\0')
				result.fail("Buffer was not null-terminated");
			else if (buffer[outlen+1] != 'X')
				result.fail("Query wrote over buffer bound");
			else if (!deStringBeginsWith(msg, buffer))
			{
				buffer[63] = '\0'; // make sure buffer is null terminated before printing
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
				result.fail("Query returned wrong label");
			}
			else
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		}
		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryNone", "Query one character");

			m_testCtx.getLog() << TestLog::Message << "Querying whole label, buffer size = 1" << TestLog::EndMessage;
			deMemset(buffer, 'X', sizeof(buffer));
			gl.getObjectLabel(GL_SHADER, shader, 1, &outlen, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

			if (outlen != 0)
				result.fail("'length' was not 0, got " + de::toString(outlen));
			else if (buffer[outlen] != '\0')
				result.fail("Buffer was not null-terminated");
			else if (buffer[outlen+1] != 'X')
				result.fail("Query wrote over buffer bound");
			else
				m_testCtx.getLog() << TestLog::Message << "Query returned zero-sized null-terminated string" << TestLog::EndMessage;
		}
	}

	{
		const tcu::ScopedLogSection superSection(m_testCtx.getLog(), "Sync", "Sync object");

		m_testCtx.getLog() << TestLog::Message << "Setting label to string: \"" << msg << "\"" << TestLog::EndMessage;
		gl.objectPtrLabel(sync, -1, msg);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectPtrLabel");

		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryAll", "Query All");

			m_testCtx.getLog() << TestLog::Message << "Querying whole label, buffer size = 22" << TestLog::EndMessage;
			deMemset(buffer, 'X', sizeof(buffer));
			gl.getObjectPtrLabel(sync, 22, &outlen, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

			if (outlen != 21)
				result.fail("'length' was not 21, got " + de::toString(outlen));
			else if (buffer[outlen] != '\0')
				result.fail("Buffer was not null-terminated");
			else if (buffer[outlen+1] != 'X')
				result.fail("Query wrote over buffer bound");
			else if (!deStringEqual(msg, buffer))
			{
				buffer[63] = '\0'; // make sure buffer is null terminated before printing
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
				result.fail("Query returned wrong label");
			}
			else
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		}
		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryAllNoSize", "Query all without size");

			m_testCtx.getLog() << TestLog::Message << "Querying whole label, buffer size = 22" << TestLog::EndMessage;
			deMemset(buffer, 'X', sizeof(buffer));
			gl.getObjectPtrLabel(sync, 22, DE_NULL, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

			buffer[63] = '\0'; // make sure buffer is null terminated before strlen

			if (strlen(buffer) != 21)
				result.fail("Buffer length was not 21");
			else if (buffer[21] != '\0')
				result.fail("Buffer was not null-terminated");
			else if (buffer[22] != 'X')
				result.fail("Query wrote over buffer bound");
			else if (!deStringEqual(msg, buffer))
			{
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
				result.fail("Query returned wrong label");
			}
			else
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		}
		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryLess", "Query substring");

			m_testCtx.getLog() << TestLog::Message << "Querying whole label, buffer size = 2" << TestLog::EndMessage;
			deMemset(buffer, 'X', sizeof(buffer));
			gl.getObjectPtrLabel(sync, 2, &outlen, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

			if (outlen != 1)
				result.fail("'length' was not 1, got " + de::toString(outlen));
			else if (buffer[outlen] != '\0')
				result.fail("Buffer was not null-terminated");
			else if (buffer[outlen+1] != 'X')
				result.fail("Query wrote over buffer bound");
			else if (!deStringBeginsWith(msg, buffer))
			{
				buffer[63] = '\0'; // make sure buffer is null terminated before printing
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
				result.fail("Query returned wrong label");
			}
			else
				m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
		}
		{
			const tcu::ScopedLogSection section(m_testCtx.getLog(), "QueryNone", "Query one character");

			m_testCtx.getLog() << TestLog::Message << "Querying whole label, buffer size = 1" << TestLog::EndMessage;
			deMemset(buffer, 'X', sizeof(buffer));
			gl.getObjectPtrLabel(sync, 1, &outlen, buffer);
			GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

			if (outlen != 0)
				result.fail("'length' was not 0, got " + de::toString(outlen));
			else if (buffer[outlen] != '\0')
				result.fail("Buffer was not null-terminated");
			else if (buffer[outlen+1] != 'X')
				result.fail("Query wrote over buffer bound");
			else
				m_testCtx.getLog() << TestLog::Message << "Query returned zero-sized null-terminated string" << TestLog::EndMessage;
		}
	}

	gl.deleteShader(shader);
	gl.deleteSync(sync);

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class LabelMaxSizeCase : public TestCase
{
public:
							LabelMaxSizeCase	(Context& ctx, const char* name, const char* desc);
	virtual IterateResult	iterate				(void);
};

LabelMaxSizeCase::LabelMaxSizeCase (Context& ctx, const char* name, const char* desc)
	: TestCase(ctx, name, desc)
{
}

LabelMaxSizeCase::IterateResult LabelMaxSizeCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	tcu::ResultCollector	result		(m_testCtx.getLog(), " // ERROR: ");
	int						maxLabelLen	= -1;
	int						outlen		= -1;
	GLuint					shader;
	glw::GLsync				sync;

	gl.getIntegerv(GL_MAX_LABEL_LENGTH, &maxLabelLen);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "GL_MAX_LABEL_LENGTH");

	m_testCtx.getLog() << TestLog::Message << "GL_MAX_LABEL_LENGTH = " << maxLabelLen << TestLog::EndMessage;

	if (maxLabelLen < 256)
		throw tcu::TestError("maxLabelLen was less than required (256)");
	if (maxLabelLen > 8192)
	{
		m_testCtx.getLog()
			<< TestLog::Message
			<< "GL_MAX_LABEL_LENGTH is very large. Application having larger labels is unlikely, skipping test."
			<< TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		return STOP;
	}

	sync = gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "fenceSync");

	shader = gl.createShader(GL_FRAGMENT_SHADER);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "createShader");

	{
		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Shader", "Shader object");
		std::vector<char>			buffer		(maxLabelLen, 'X');
		std::vector<char>			readBuffer	(maxLabelLen, 'X');

		buffer[maxLabelLen-1] = '\0';

		m_testCtx.getLog() << TestLog::Message << "Setting max length label, with implicit size. (length = -1)" << TestLog::EndMessage;
		gl.objectLabel(GL_SHADER, shader, -1,  &buffer[0]);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectLabel");

		m_testCtx.getLog() << TestLog::Message << "Querying label back" << TestLog::EndMessage;
		outlen = -1;
		gl.getObjectLabel(GL_SHADER, shader, maxLabelLen, &outlen, &readBuffer[0]);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

		if (outlen != maxLabelLen-1)
			result.fail("'length' was not " + de::toString(maxLabelLen-1) + ", got " + de::toString(outlen));
		else if (readBuffer[outlen] != '\0')
			result.fail("Buffer was not null-terminated");

		m_testCtx.getLog() << TestLog::Message << "Setting max length label, with explicit size. (length = " << (maxLabelLen-1) << ")" << TestLog::EndMessage;
		gl.objectLabel(GL_SHADER, shader, maxLabelLen-1,  &buffer[0]);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectLabel");

		m_testCtx.getLog() << TestLog::Message << "Querying label back" << TestLog::EndMessage;
		outlen = -1;
		readBuffer[maxLabelLen-1] = 'X';
		gl.getObjectLabel(GL_SHADER, shader, maxLabelLen, &outlen, &readBuffer[0]);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

		if (outlen != maxLabelLen-1)
			result.fail("'length' was not " + de::toString(maxLabelLen-1) + ", got " + de::toString(outlen));
		else if (readBuffer[outlen] != '\0')
			result.fail("Buffer was not null-terminated");
	}

	{
		const tcu::ScopedLogSection section		(m_testCtx.getLog(), "Sync", "Sync object");
		std::vector<char>			buffer		(maxLabelLen, 'X');
		std::vector<char>			readBuffer	(maxLabelLen, 'X');

		buffer[maxLabelLen-1] = '\0';

		m_testCtx.getLog() << TestLog::Message << "Setting max length label, with implicit size. (length = -1)" << TestLog::EndMessage;
		gl.objectPtrLabel(sync, -1,  &buffer[0]);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectPtrLabel");

		m_testCtx.getLog() << TestLog::Message << "Querying label back" << TestLog::EndMessage;
		outlen = -1;
		gl.getObjectPtrLabel(sync, maxLabelLen, &outlen, &readBuffer[0]);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

		if (outlen != maxLabelLen-1)
			result.fail("'length' was not " + de::toString(maxLabelLen-1) + ", got " + de::toString(outlen));
		else if (readBuffer[outlen] != '\0')
			result.fail("Buffer was not null-terminated");

		m_testCtx.getLog() << TestLog::Message << "Setting max length label, with explicit size. (length = " << (maxLabelLen-1) << ")" << TestLog::EndMessage;
		gl.objectPtrLabel(sync, maxLabelLen-1,  &buffer[0]);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectPtrLabel");

		m_testCtx.getLog() << TestLog::Message << "Querying label back" << TestLog::EndMessage;
		outlen = -1;
		readBuffer[maxLabelLen-1] = 'X';
		gl.getObjectPtrLabel(sync, maxLabelLen, &outlen, &readBuffer[0]);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

		if (outlen != maxLabelLen-1)
			result.fail("'length' was not " + de::toString(maxLabelLen-1) + ", got " + de::toString(outlen));
		else if (readBuffer[outlen] != '\0')
			result.fail("Buffer was not null-terminated");
	}

	gl.deleteShader(shader);
	gl.deleteSync(sync);

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class LabelLengthCase : public TestCase
{
public:
							LabelLengthCase	(Context& ctx, const char* name, const char* desc);
	virtual IterateResult	iterate			(void);
};

LabelLengthCase::LabelLengthCase (Context& ctx, const char* name, const char* desc)
	: TestCase(ctx, name, desc)
{
}

LabelLengthCase::IterateResult LabelLengthCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
	tcu::ResultCollector	result		(m_testCtx.getLog(), " // ERROR: ");
	const char*	const		msg			= "This is a debug label";
	int						outlen		= -1;
	GLuint					shader;
	glw::GLsync				sync;

	sync = gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "fenceSync");

	shader = gl.createShader(GL_FRAGMENT_SHADER);
	GLS_COLLECT_GL_ERROR(result, gl.getError(), "createShader");

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Shader", "Shader object");

		m_testCtx.getLog() << TestLog::Message << "Querying label length" << TestLog::EndMessage;
		outlen = -1;
		gl.getObjectLabel(GL_SHADER, shader, 0, &outlen, DE_NULL);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

		if (outlen != 0)
			result.fail("'length' was not 0, got " + de::toString(outlen));
		else
			m_testCtx.getLog() << TestLog::Message << "Query returned length: " << outlen << TestLog::EndMessage;

		m_testCtx.getLog() << TestLog::Message << "Setting label to string: \"" << msg << "\"" << TestLog::EndMessage;
		gl.objectLabel(GL_SHADER, shader, -1, msg);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectLabel");

		m_testCtx.getLog() << TestLog::Message << "Querying label length" << TestLog::EndMessage;
		outlen = -1;
		gl.getObjectLabel(GL_SHADER, shader, 0, &outlen, DE_NULL);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectLabel");

		if (outlen != 21)
			result.fail("'length' was not 21, got " + de::toString(outlen));
		else
			m_testCtx.getLog() << TestLog::Message << "Query returned length: " << outlen << TestLog::EndMessage;
	}

	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Sync", "Sync object");

		m_testCtx.getLog() << TestLog::Message << "Querying label length" << TestLog::EndMessage;
		outlen = -1;
		gl.getObjectPtrLabel(sync, 0, &outlen, DE_NULL);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

		if (outlen != 0)
			result.fail("'length' was not 0, got " + de::toString(outlen));
		else
			m_testCtx.getLog() << TestLog::Message << "Query returned length: " << outlen << TestLog::EndMessage;

		m_testCtx.getLog() << TestLog::Message << "Setting label to string: \"" << msg << "\"" << TestLog::EndMessage;
		gl.objectPtrLabel(sync, -1, msg);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "objectPtrLabel");

		m_testCtx.getLog() << TestLog::Message << "Querying label length" << TestLog::EndMessage;
		outlen = -1;
		gl.getObjectPtrLabel(sync, 0, &outlen, DE_NULL);
		GLS_COLLECT_GL_ERROR(result, gl.getError(), "getObjectPtrLabel");

		if (outlen != 21)
			result.fail("'length' was not 21, got " + de::toString(outlen));
		else
			m_testCtx.getLog() << TestLog::Message << "Query returned length: " << outlen << TestLog::EndMessage;
	}

	gl.deleteShader(shader);
	gl.deleteSync(sync);

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class LimitQueryCase : public TestCase
{
public:
											LimitQueryCase	(Context&						context,
															 const char*					name,
															 const char*					description,
															 glw::GLenum					target,
															 int							limit,
															 gls::StateQueryUtil::QueryType	type);

	IterateResult							iterate			(void);
private:
	const gls::StateQueryUtil::QueryType	m_type;
	const int								m_limit;
	const glw::GLenum						m_target;
};

LimitQueryCase::LimitQueryCase (Context&						context,
								const char*						name,
								const char*						description,
								glw::GLenum						target,
								int								limit,
								gls::StateQueryUtil::QueryType	type)
	: TestCase	(context, name, description)
	, m_type	(type)
	, m_limit	(limit)
	, m_target	(target)
{
}

LimitQueryCase::IterateResult LimitQueryCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");

	gl.enableLogging(true);
	gls::StateQueryUtil::verifyStateIntegerMin(result, gl, m_target, m_limit, m_type);

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class IsEnabledCase : public TestCase
{
public:
	enum InitialValue
	{
		INITIAL_CTX_IS_DEBUG = 0,
		INITIAL_FALSE,
	};

											IsEnabledCase	(Context&						context,
															 const char*					name,
															 const char*					description,
															 glw::GLenum					target,
															 InitialValue					initial,
															 gls::StateQueryUtil::QueryType	type);

	IterateResult							iterate			(void);
private:
	const gls::StateQueryUtil::QueryType	m_type;
	const glw::GLenum						m_target;
	const InitialValue						m_initial;
};

IsEnabledCase::IsEnabledCase (Context&							context,
							  const char*						name,
							  const char*						description,
							  glw::GLenum						target,
							  InitialValue						initial,
							  gls::StateQueryUtil::QueryType	type)
	: TestCase	(context, name, description)
	, m_type	(type)
	, m_target	(target)
	, m_initial	(initial)
{
}

IsEnabledCase::IterateResult IsEnabledCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");
	bool					initial;

	gl.enableLogging(true);

	if (m_initial == INITIAL_FALSE)
		initial = false;
	else
	{
		DE_ASSERT(m_initial == INITIAL_CTX_IS_DEBUG);
		initial = (m_context.getRenderContext().getType().getFlags() & glu::CONTEXT_DEBUG) != 0;
	}

	// check inital value
	gls::StateQueryUtil::verifyStateBoolean(result, gl, m_target, initial, m_type);

	// check toggle

	gl.glEnable(m_target);
	GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glEnable");

	gls::StateQueryUtil::verifyStateBoolean(result, gl, m_target, true, m_type);

	gl.glDisable(m_target);
	GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glDisable");

	gls::StateQueryUtil::verifyStateBoolean(result, gl, m_target, false, m_type);

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class PositiveIntegerCase : public TestCase
{
public:
											PositiveIntegerCase	(Context&						context,
																 const char*					name,
																 const char*					description,
																 glw::GLenum					target,
																 gls::StateQueryUtil::QueryType	type);

	IterateResult							iterate			(void);
private:
	const gls::StateQueryUtil::QueryType	m_type;
	const glw::GLenum						m_target;
};

PositiveIntegerCase::PositiveIntegerCase (Context&							context,
										  const char*						name,
										  const char*						description,
										  glw::GLenum						target,
										  gls::StateQueryUtil::QueryType	type)
	: TestCase	(context, name, description)
	, m_type	(type)
	, m_target	(target)
{
}

PositiveIntegerCase::IterateResult PositiveIntegerCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");

	gl.enableLogging(true);
	gls::StateQueryUtil::verifyStateIntegerMin(result, gl, m_target, 0, m_type);

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class GroupStackDepthQueryCase : public TestCase
{
public:
											GroupStackDepthQueryCase	(Context&						context,
																		 const char*					name,
																		 const char*					description,
																		 gls::StateQueryUtil::QueryType	type);

	IterateResult							iterate			(void);
private:
	const gls::StateQueryUtil::QueryType	m_type;
};

GroupStackDepthQueryCase::GroupStackDepthQueryCase (Context&						context,
													const char*						name,
													const char*						description,
													gls::StateQueryUtil::QueryType	type)
	: TestCase	(context, name, description)
	, m_type	(type)
{
}

GroupStackDepthQueryCase::IterateResult GroupStackDepthQueryCase::iterate (void)
{
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");

	gl.enableLogging(true);

	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Initial", "Initial");

		gls::StateQueryUtil::verifyStateInteger(result, gl, GL_DEBUG_GROUP_STACK_DEPTH, 1, m_type);
	}

	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Scoped", "Scoped");

		gl.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Application group 1");
		gls::StateQueryUtil::verifyStateInteger(result, gl, GL_DEBUG_GROUP_STACK_DEPTH, 2, m_type);
		gl.glPopDebugGroup();
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

extern "C" void GLW_APIENTRY dummyCallback(GLenum, GLenum, GLuint, GLenum, GLsizei, const char*, void*)
{
	// dummy
}

class DebugCallbackFunctionCase : public TestCase
{
public:
					DebugCallbackFunctionCase	(Context& context, const char* name, const char* description);
	IterateResult	iterate						(void);
};

DebugCallbackFunctionCase::DebugCallbackFunctionCase (Context& context, const char* name, const char* description)
	: TestCase	(context, name, description)
{
}

DebugCallbackFunctionCase::IterateResult DebugCallbackFunctionCase::iterate (void)
{
	using namespace gls::StateQueryUtil;
	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");

	gl.enableLogging(true);

	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Initial", "Initial");

		verifyStatePointer(result, gl, GL_DEBUG_CALLBACK_FUNCTION, 0, QUERY_POINTER);
	}

	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Set", "Set");

		gl.glDebugMessageCallback(dummyCallback, DE_NULL);
		verifyStatePointer(result, gl, GL_DEBUG_CALLBACK_FUNCTION, (const void*)dummyCallback, QUERY_POINTER);
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

class DebugCallbackUserParamCase : public TestCase
{
public:
					DebugCallbackUserParamCase	(Context& context, const char* name, const char* description);
	IterateResult	iterate						(void);
};

DebugCallbackUserParamCase::DebugCallbackUserParamCase (Context& context, const char* name, const char* description)
	: TestCase	(context, name, description)
{
}

DebugCallbackUserParamCase::IterateResult DebugCallbackUserParamCase::iterate (void)
{
	using namespace gls::StateQueryUtil;

	TCU_CHECK_AND_THROW(NotSupportedError, isKHRDebugSupported(m_context), "GL_KHR_debug is not supported");

	glu::CallLogWrapper		gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	tcu::ResultCollector	result	(m_testCtx.getLog(), " // ERROR: ");

	gl.enableLogging(true);

	{
		const tcu::ScopedLogSection	section(m_testCtx.getLog(), "Initial", "Initial");

		verifyStatePointer(result, gl, GL_DEBUG_CALLBACK_USER_PARAM, 0, QUERY_POINTER);
	}

	{
		const tcu::ScopedLogSection	section	(m_testCtx.getLog(), "Set", "Set");
		const void*					param	= (void*)(int*)0x123;

		gl.glDebugMessageCallback(dummyCallback, param);
		verifyStatePointer(result, gl, GL_DEBUG_CALLBACK_USER_PARAM, param, QUERY_POINTER);
	}

	result.setTestContextResult(m_testCtx);
	return STOP;
}

} // anonymous

DebugTests::DebugTests (Context& context)
	: TestCaseGroup(context, "debug", "Debug tests")
{
}

enum CaseType
{
	CASETYPE_CALLBACK = 0,
	CASETYPE_LOG,
	CASETYPE_GETERROR,

	CASETYPE_LAST
};

tcu::TestNode* createCase (CaseType type, Context& ctx, const char* name, const char* desc, TestFunctionWrapper function)
{
	switch(type)
	{
		case CASETYPE_CALLBACK: return new CallbackErrorCase(ctx, name, desc, function);
		case CASETYPE_LOG:		return new LogErrorCase(ctx, name, desc, function);
		case CASETYPE_GETERROR: return new GetErrorCase(ctx, name, desc, function);

		default:
			DE_FATAL("Invalid type");
	}

	return DE_NULL;
}

tcu::TestCaseGroup* createChildCases (CaseType type, Context& ctx, const char* name, const char* desc, const vector<FunctionContainer>& funcs)
{
	tcu::TestCaseGroup* host = new tcu::TestCaseGroup(ctx.getTestContext(), name, desc);

	for (size_t ndx = 0; ndx < funcs.size(); ndx++)
			host->addChild(createCase(type, ctx, funcs[ndx].name, funcs[ndx].desc, funcs[ndx].function));

	return host;
}

vector<FunctionContainer> wrapCoreFunctions (const vector<NegativeTestShared::FunctionContainer>& fns)
{
	vector<FunctionContainer> retVal;

	retVal.resize(fns.size());
	for (int ndx = 0; ndx < (int)fns.size(); ++ndx)
	{
		retVal[ndx].function = TestFunctionWrapper(fns[ndx].function);
		retVal[ndx].name = fns[ndx].name;
		retVal[ndx].desc = fns[ndx].desc;
	}

	return retVal;
}

void DebugTests::init (void)
{
	const vector<FunctionContainer> bufferFuncs					= wrapCoreFunctions(NegativeTestShared::getNegativeBufferApiTestFunctions());
	const vector<FunctionContainer> textureFuncs				= wrapCoreFunctions(NegativeTestShared::getNegativeTextureApiTestFunctions());
	const vector<FunctionContainer> shaderFuncs					= wrapCoreFunctions(NegativeTestShared::getNegativeShaderApiTestFunctions());
	const vector<FunctionContainer> fragmentFuncs				= wrapCoreFunctions(NegativeTestShared::getNegativeFragmentApiTestFunctions());
	const vector<FunctionContainer> vaFuncs						= wrapCoreFunctions(NegativeTestShared::getNegativeVertexArrayApiTestFunctions());
	const vector<FunctionContainer> stateFuncs					= wrapCoreFunctions(NegativeTestShared::getNegativeStateApiTestFunctions());
	const vector<FunctionContainer> atomicCounterFuncs			= wrapCoreFunctions(NegativeTestShared::getNegativeAtomicCounterTestFunctions());
	const vector<FunctionContainer> shaderImageLoadStoreFuncs	= wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageLoadStoreTestFunctions());
	const vector<FunctionContainer> shaderFunctionFuncs			= wrapCoreFunctions(NegativeTestShared::getNegativeShaderFunctionTestFunctions());
	const vector<FunctionContainer> shaderDirectiveFuncs		= wrapCoreFunctions(NegativeTestShared::getNegativeShaderDirectiveTestFunctions());
	const vector<FunctionContainer> preciseFuncs				= wrapCoreFunctions(NegativeTestShared::getNegativePreciseTestFunctions());
	const vector<FunctionContainer> advancedBlendFuncs			= wrapCoreFunctions(NegativeTestShared::getNegativeAdvancedBlendEquationTestFunctions());
	const vector<FunctionContainer> externalFuncs				= getUserMessageFuncs();

	{
		using namespace gls::StateQueryUtil;

		tcu::TestCaseGroup* const queries = new tcu::TestCaseGroup(m_testCtx, "state_query", "State query");

		static const struct
		{
			const char*	name;
			const char*	targetName;
			glw::GLenum	target;
			int			limit;
		} limits[] =
		{
			{ "max_debug_message_length",		"MAX_DEBUG_MESSAGE_LENGTH",		GL_MAX_DEBUG_MESSAGE_LENGTH,	1	},
			{ "max_debug_logged_messages",		"MAX_DEBUG_LOGGED_MESSAGES",	GL_MAX_DEBUG_LOGGED_MESSAGES,	1	},
			{ "max_debug_group_stack_depth",	"MAX_DEBUG_GROUP_STACK_DEPTH",	GL_MAX_DEBUG_GROUP_STACK_DEPTH,	64	},
			{ "max_label_length",				"MAX_LABEL_LENGTH",				GL_MAX_LABEL_LENGTH,			256	},
		};

		addChild(queries);

		#define FOR_ALL_TYPES(X) \
			do \
			{ \
				{ \
					const char* const	postfix = "_getboolean"; \
					const QueryType		queryType = QUERY_BOOLEAN; \
					X; \
				} \
				{ \
					const char* const	postfix = "_getinteger"; \
					const QueryType		queryType = QUERY_INTEGER; \
					X; \
				} \
				{ \
					const char* const	postfix = "_getinteger64"; \
					const QueryType		queryType = QUERY_INTEGER64; \
					X; \
				} \
				{ \
					const char* const	postfix = "_getfloat"; \
					const QueryType		queryType = QUERY_FLOAT; \
					X; \
				} \
			} \
			while (deGetFalse())
		#define FOR_ALL_ENABLE_TYPES(X) \
			do \
			{ \
				{ \
					const char* const	postfix = "_isenabled"; \
					const QueryType		queryType = QUERY_ISENABLED; \
					X; \
				} \
				FOR_ALL_TYPES(X); \
			} \
			while (deGetFalse())

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(limits); ++ndx)
		{
			FOR_ALL_TYPES(queries->addChild(new LimitQueryCase(m_context,
															   (std::string(limits[ndx].name) + postfix).c_str(),
															   (std::string("Test ") + limits[ndx].targetName).c_str(),
															   limits[ndx].target, limits[ndx].limit, queryType)));
		}

		FOR_ALL_ENABLE_TYPES(queries->addChild(new IsEnabledCase	(m_context, (std::string("debug_output") + postfix).c_str(),						"Test DEBUG_OUTPUT",						GL_DEBUG_OUTPUT,				IsEnabledCase::INITIAL_CTX_IS_DEBUG,	queryType)));
		FOR_ALL_ENABLE_TYPES(queries->addChild(new IsEnabledCase	(m_context, (std::string("debug_output_synchronous") + postfix).c_str(),			"Test DEBUG_OUTPUT_SYNCHRONOUS",			GL_DEBUG_OUTPUT_SYNCHRONOUS,	IsEnabledCase::INITIAL_FALSE,			queryType)));

		FOR_ALL_TYPES(queries->addChild(new PositiveIntegerCase		(m_context, (std::string("debug_logged_messages") + postfix).c_str(),				"Test DEBUG_LOGGED_MESSAGES",				GL_DEBUG_LOGGED_MESSAGES,				queryType)));
		FOR_ALL_TYPES(queries->addChild(new PositiveIntegerCase		(m_context, (std::string("debug_next_logged_message_length") + postfix).c_str(),	"Test DEBUG_NEXT_LOGGED_MESSAGE_LENGTH",	GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH,	queryType)));
		FOR_ALL_TYPES(queries->addChild(new GroupStackDepthQueryCase(m_context, (std::string("debug_group_stack_depth") + postfix).c_str(),				"Test DEBUG_GROUP_STACK_DEPTH",				queryType)));

		queries->addChild(new DebugCallbackFunctionCase	(m_context, "debug_callback_function_getpointer",	"Test DEBUG_CALLBACK_FUNCTION"));
		queries->addChild(new DebugCallbackUserParamCase(m_context, "debug_callback_user_param_getpointer", "Test DEBUG_CALLBACK_USER_PARAM"));

		#undef FOR_ALL_TYPES
		#undef FOR_ALL_ENABLE_TYPES
	}

	{
		tcu::TestCaseGroup* const	negative	= new tcu::TestCaseGroup(m_testCtx, "negative_coverage", "API error coverage with various reporting methods");

		addChild(negative);

		{
			tcu::TestCaseGroup* const	host	= new tcu::TestCaseGroup(m_testCtx, "callbacks", "Reporting of standard API errors via callback");

			negative->addChild(host);
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "buffer",						"Negative Buffer API Cases",						bufferFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "texture",					"Negative Texture API Cases",						textureFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader",						"Negative Shader API Cases",						shaderFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "fragment",					"Negative Fragment API Cases",						fragmentFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "vertex_array",				"Negative Vertex Array API Cases",					vaFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "state",						"Negative GL State API Cases",						stateFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "atomic_counter",				"Negative Atomic Counter API Cases",				atomicCounterFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_image_load_store",	"Negative Shader Image Load and Store API Cases",	shaderImageLoadStoreFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_function",			"Negative Shader Function Cases",					shaderFunctionFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_directive",			"Negative Shader Directive Cases",					shaderDirectiveFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "precise",					"Negative Precise Cases",							preciseFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "advanced_blend",				"Negative Advanced Blend Equation Cases",			advancedBlendFuncs));
		}

		{
			tcu::TestCaseGroup* const	host	= new tcu::TestCaseGroup(m_testCtx, "log", "Reporting of standard API errors via log");

			negative->addChild(host);

			host->addChild(createChildCases(CASETYPE_LOG, m_context, "buffer",					"Negative Buffer API Cases",						bufferFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "texture",					"Negative Texture API Cases",						textureFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader",					"Negative Shader API Cases",						shaderFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "fragment",				"Negative Fragment API Cases",						fragmentFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "vertex_array",			"Negative Vertex Array API Cases",					vaFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "state",					"Negative GL State API Cases",						stateFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "atomic_counter",			"Negative Atomic Counter API Cases",				atomicCounterFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_image_load_store",	"Negative Shader Image Load and Store API Cases",	shaderImageLoadStoreFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_function",			"Negative Shader Function Cases",					shaderFunctionFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_directive",		"Negative Shader Directive Cases",					shaderDirectiveFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "precise",					"Negative Precise Cases",							preciseFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "advanced_blend",			"Negative Advanced Blend Equation Cases",			advancedBlendFuncs));
		}

		{
			tcu::TestCaseGroup* const	host	= new tcu::TestCaseGroup(m_testCtx, "get_error", "Reporting of standard API errors via glGetError");

			negative->addChild(host);

			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "buffer",						"Negative Buffer API Cases",						bufferFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "texture",					"Negative Texture API Cases",						textureFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader",						"Negative Shader API Cases",						shaderFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "fragment",					"Negative Fragment API Cases",						fragmentFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "vertex_array",				"Negative Vertex Array API Cases",					vaFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "state",						"Negative GL State API Cases",						stateFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "atomic_counter",				"Negative Atomic Counter API Cases",				atomicCounterFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_image_load_store",	"Negative Shader Image Load and Store API Cases",	shaderImageLoadStoreFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_function",			"Negative Shader Function Cases",					shaderFunctionFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_directive",			"Negative Shader Directive Cases",					shaderDirectiveFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "precise",					"Negative Precise Cases",							preciseFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "advanced_blend",				"Negative Advanced Blend Equation Cases",			advancedBlendFuncs));
		}
	}

	{
		tcu::TestCaseGroup* const host = createChildCases(CASETYPE_CALLBACK, m_context, "externally_generated", "Externally Generated Messages", externalFuncs);

		host->addChild(new GroupCase(m_context, "push_pop_consistency", "Push/pop message generation with full message output checking"));

		addChild(host);
	}

	{
		vector<FunctionContainer>	containers;
		vector<TestFunctionWrapper>	allFuncs;

		de::Random					rng			(0x53941903 ^ m_context.getTestContext().getCommandLine().getBaseSeed());

		containers.insert(containers.end(), bufferFuncs.begin(), bufferFuncs.end());
		containers.insert(containers.end(), textureFuncs.begin(), textureFuncs.end());
		containers.insert(containers.end(), externalFuncs.begin(), externalFuncs.end());

		for (size_t ndx = 0; ndx < containers.size(); ndx++)
			allFuncs.push_back(containers[ndx].function);

		rng.shuffle(allFuncs.begin(), allFuncs.end());

		{
			tcu::TestCaseGroup* const	filtering				= new tcu::TestCaseGroup(m_testCtx, "error_filters", "Filtering of reported errors");
			const int					errorFuncsPerCase		= 4;
			const int					maxFilteringCaseCount	= 32;
			const int					caseCount				= (int(allFuncs.size()) + errorFuncsPerCase-1) / errorFuncsPerCase;

			addChild(filtering);

			for (int caseNdx = 0; caseNdx < de::min(caseCount, maxFilteringCaseCount); caseNdx++)
			{
				const int					start		= caseNdx*errorFuncsPerCase;
				const int					end			= de::min((caseNdx+1)*errorFuncsPerCase, int(allFuncs.size()));
				const string				name		= "case_" + de::toString(caseNdx);
				vector<TestFunctionWrapper>	funcs		(allFuncs.begin()+start, allFuncs.begin()+end);

				// These produce lots of different message types, thus always include at least one when testing filtering
				funcs.insert(funcs.end(), externalFuncs[caseNdx%externalFuncs.size()].function);

				filtering->addChild(new FilterCase(m_context, name.c_str(), "DebugMessageControl usage", funcs));
			}
		}

		{
			tcu::TestCaseGroup* const	groups					= new tcu::TestCaseGroup(m_testCtx, "error_groups", "Filtering of reported errors with use of Error Groups");
			const int					errorFuncsPerCase		= 4;
			const int					maxFilteringCaseCount	= 16;
			const int					caseCount				= (int(allFuncs.size()) + errorFuncsPerCase-1) / errorFuncsPerCase;

			addChild(groups);

			for (int caseNdx = 0; caseNdx < caseCount && caseNdx < maxFilteringCaseCount; caseNdx++)
			{
				const int					start		= caseNdx*errorFuncsPerCase;
				const int					end			= de::min((caseNdx+1)*errorFuncsPerCase, int(allFuncs.size()));
				const string				name		= ("case_" + de::toString(caseNdx)).c_str();
				vector<TestFunctionWrapper>	funcs		(&allFuncs[0]+start, &allFuncs[0]+end);

				// These produce lots of different message types, thus always include at least one when testing filtering
				funcs.insert(funcs.end(), externalFuncs[caseNdx%externalFuncs.size()].function);

				groups->addChild(new GroupFilterCase(m_context, name.c_str(), "Debug Group usage", funcs));
			}
		}

		{
			tcu::TestCaseGroup* const	async				= new tcu::TestCaseGroup(m_testCtx, "async", "Asynchronous message generation");
			const int					errorFuncsPerCase	= 2;
			const int					maxAsyncCaseCount	= 16;
			const int					caseCount			= (int(allFuncs.size()) + errorFuncsPerCase-1) / errorFuncsPerCase;

			addChild(async);

			for (int caseNdx = 0; caseNdx < caseCount && caseNdx < maxAsyncCaseCount; caseNdx++)
			{
				const int					start		= caseNdx*errorFuncsPerCase;
				const int					end			= de::min((caseNdx+1)*errorFuncsPerCase, int(allFuncs.size()));
				const string				name		= ("case_" + de::toString(caseNdx)).c_str();
				vector<TestFunctionWrapper>	funcs		(&allFuncs[0]+start, &allFuncs[0]+end);

				if (caseNdx&0x1)
					async->addChild(new AsyncCase(m_context, (name+"_callback").c_str(), "Async message generation", funcs, true));
				else
					async->addChild(new AsyncCase(m_context, (name+"_log").c_str(), "Async message generation", funcs, false));
			}
		}
	}

	{
		tcu::TestCaseGroup* const labels = new tcu::TestCaseGroup(m_testCtx, "object_labels", "Labeling objects");

		const struct
		{
			GLenum		identifier;
			const char*	name;
			const char* desc;
		} cases[] =
		{
			{ GL_BUFFER,				"buffer",				"Debug label on a buffer object"				},
			{ GL_SHADER,				"shader",				"Debug label on a shader object"				},
			{ GL_PROGRAM,				"program",				"Debug label on a program object"				},
			{ GL_QUERY,					"query",				"Debug label on a query object"					},
			{ GL_PROGRAM_PIPELINE,		"program_pipeline",		"Debug label on a program pipeline object"		},
			{ GL_TRANSFORM_FEEDBACK,	"transform_feedback",	"Debug label on a transform feedback object"	},
			{ GL_SAMPLER,				"sampler",				"Debug label on a sampler object"				},
			{ GL_TEXTURE,				"texture",				"Debug label on a texture object"				},
			{ GL_RENDERBUFFER,			"renderbuffer",			"Debug label on a renderbuffer object"			},
			{ GL_FRAMEBUFFER,			"framebuffer",			"Debug label on a framebuffer object"			},
		};

		addChild(labels);

		labels->addChild(new InitialLabelCase		(m_context, "initial",				"Debug label initial value"));
		labels->addChild(new ClearLabelCase			(m_context, "clearing",				"Debug label clearing"));
		labels->addChild(new SpecifyWithLengthCase	(m_context, "specify_with_length",	"Debug label specified with length"));
		labels->addChild(new BufferLimitedLabelCase	(m_context, "buffer_limited_query",	"Debug label query to too short buffer"));
		labels->addChild(new LabelMaxSizeCase		(m_context, "max_label_length",		"Max sized debug label"));
		labels->addChild(new LabelLengthCase		(m_context, "query_length_only",	"Query debug label length"));

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
			labels->addChild(new LabelCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].identifier));
		labels->addChild(new SyncLabelCase(m_context, "sync", "Debug label on a sync object"));
	}
}

} // Functional
} // gles31
} // deqp
