/*-------------------------------------------------------------------------
 * 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 "es31fNegativeSSBOBlockTests.hpp"
#include "es31fNegativePreciseTests.hpp"
#include "es31fNegativeAdvancedBlendEquationTests.hpp"
#include "es31fNegativeShaderStorageTests.hpp"
#include "es31fNegativeTessellationTests.hpp"
#include "es31fNegativeComputeTests.hpp"
#include "es31fNegativeSampleVariablesTests.hpp"
#include "es31fNegativeShaderFramebufferFetchTests.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 supportsES32 = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	return supportsES32 || 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)
{
	m_func.coreFn = 0;
}

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*, const 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, const void* userParam)
{
	static_cast<BaseCase*>(const_cast<void*>(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 emptyCallback(GLenum, GLenum, GLuint, GLenum, GLsizei, const char*, const void*)
{
	// empty
}

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(emptyCallback, DE_NULL);
		verifyStatePointer(result, gl, GL_DEBUG_CALLBACK_FUNCTION, (const void*)emptyCallback, 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(emptyCallback, 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> tessellationFuncs		 = wrapCoreFunctions(NegativeTestShared::getNegativeTessellationTestFunctions());
	const vector<FunctionContainer> atomicCounterFuncs		 = wrapCoreFunctions(NegativeTestShared::getNegativeAtomicCounterTestFunctions());
	const vector<FunctionContainer> imageLoadFuncs			 = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageLoadTestFunctions());
	const vector<FunctionContainer> imageStoreFuncs			 = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageStoreTestFunctions());
	const vector<FunctionContainer> imageAtomicFuncs		 = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageAtomicTestFunctions());
	const vector<FunctionContainer> imageAtomicExchangeFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageAtomicExchangeTestFunctions());
	const vector<FunctionContainer> shaderFunctionFuncs		 = wrapCoreFunctions(NegativeTestShared::getNegativeShaderFunctionTestFunctions());
	const vector<FunctionContainer> shaderDirectiveFuncs	 = wrapCoreFunctions(NegativeTestShared::getNegativeShaderDirectiveTestFunctions());
	const vector<FunctionContainer> ssboBlockFuncs			 = wrapCoreFunctions(NegativeTestShared::getNegativeSSBOBlockTestFunctions());
	const vector<FunctionContainer> preciseFuncs			 = wrapCoreFunctions(NegativeTestShared::getNegativePreciseTestFunctions());
	const vector<FunctionContainer> advancedBlendFuncs		 = wrapCoreFunctions(NegativeTestShared::getNegativeAdvancedBlendEquationTestFunctions());
	const vector<FunctionContainer> shaderStorageFuncs		 = wrapCoreFunctions(NegativeTestShared::getNegativeShaderStorageTestFunctions());
	const vector<FunctionContainer> sampleVariablesFuncs	 = wrapCoreFunctions(NegativeTestShared::getNegativeSampleVariablesTestFunctions());
	const vector<FunctionContainer> computeFuncs			 = wrapCoreFunctions(NegativeTestShared::getNegativeComputeTestFunctions());
	const vector<FunctionContainer> framebufferFetchFuncs    = wrapCoreFunctions(NegativeTestShared::getNegativeShaderFramebufferFetchTestFunctions());
	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",			"Negative Shader Image Load API Cases",				imageLoadFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_image_store",			"Negative Shader Image Store API Cases",			imageStoreFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_image_atomic",		"Negative Shader Image Atomic API Cases",			imageAtomicFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_image_exchange",		"Negative Shader Image Atomic Exchange API Cases",	imageAtomicExchangeFuncs));
			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, "ssbo_block",					"Negative SSBO Block Cases",						ssboBlockFuncs));
			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));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_storage",				"Negative Shader Storage Cases",					shaderStorageFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "tessellation",				"Negative Tessellation Cases",						tessellationFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "oes_sample_variables",		"Negative Sample Variables Cases",					sampleVariablesFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "compute",					"Negative Compute Cases",							computeFuncs));
			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "framebuffer_fetch",			"Negative Framebuffer Fetch Cases",					framebufferFetchFuncs));
		}

		{
			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",		"Negative Shader Image Load API Cases",				imageLoadFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_image_store",		"Negative Shader Image Store API Cases",			imageStoreFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_image_atomic",		"Negative Shader Image Atomic API Cases",			imageAtomicFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_image_exchange",	"Negative Shader Image Atomic Exchange API Cases",	imageAtomicExchangeFuncs));
			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, "ssbo_block",				"Negative SSBO Block Cases",						ssboBlockFuncs));
			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));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_storage",			"Negative Shader Storage Cases",					shaderStorageFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "tessellation",			"Negative Tessellation Cases",						tessellationFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "oes_sample_variables",	"Negative Sample Variables Cases",					sampleVariablesFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "compute",					"Negative Compute Cases",							computeFuncs));
			host->addChild(createChildCases(CASETYPE_LOG, m_context, "framebuffer_fetch",		"Negative Framebuffer Fetch Cases",					framebufferFetchFuncs));
		}

		{
			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",			"Negative Shader Image Load API Cases",				imageLoadFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_image_store",			"Negative Shader Image Store API Cases",			imageStoreFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_image_atomic",		"Negative Shader Image Atomic API Cases",			imageAtomicFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_image_exchange",		"Negative Shader Image Atomic Exchange API Cases",	imageAtomicExchangeFuncs));
			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, "ssbo_block",					"Negative SSBO Block Cases",						ssboBlockFuncs));
			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));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_storage",				"Negative Shader Storage Cases",					shaderStorageFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "tessellation",				"Negative Tessellation Cases",						tessellationFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "oes_sample_variables",		"Negative Sample Variables Cases",					sampleVariablesFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "compute",					"Negative Compute Cases",							computeFuncs));
			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "framebuffer_fetch",			"Negative Framebuffer Fetch Cases",					framebufferFetchFuncs));
		}
	}

	{
		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
