13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Debug output (KHR_debug) tests
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fDebugTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fNegativeTestShared.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fNegativeBufferApiTests.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fNegativeTextureApiTests.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fNegativeShaderApiTests.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fNegativeFragmentApiTests.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fNegativeVertexArrayApiTests.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fNegativeStateApiTests.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSTLUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMutex.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deThread.h"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluCallLogWrapper.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwDefs.hpp"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tes31Context.hpp"
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestContext.hpp"
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing NegativeTestShared::NegativeTestContext;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing NegativeTestShared::FunctionContainer;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLenum debugTypes[] =
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_TYPE_ERROR,
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR,
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR,
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_TYPE_PORTABILITY,
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_TYPE_PERFORMANCE,
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_TYPE_OTHER,
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_TYPE_MARKER,
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_TYPE_PUSH_GROUP,
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_TYPE_POP_GROUP,
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLenum debugSeverities[] =
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GL_DEBUG_SEVERITY_HIGH,
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    GL_DEBUG_SEVERITY_MEDIUM,
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    GL_DEBUG_SEVERITY_LOW,
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry    GL_DEBUG_SEVERITY_NOTIFICATION,
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid emitMessages(NegativeTestContext& ctx, GLenum source)
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(debugTypes); typeNdx++)
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int severityNdx = 0; severityNdx < DE_LENGTH_OF_ARRAY(debugSeverities); severityNdx++)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLenum type		= debugTypes[typeNdx];
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const GLenum severity	= debugSeverities[severityNdx];
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string msg		= string("Application generated message with type ") + glu::getDebugMessageTypeName(type)
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  + " and severity " + glu::getDebugMessageSeverityName(severity);
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Use severity as ID, guaranteed unique
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ctx.glDebugMessageInsert(source, type, severity, severity, -1, msg.c_str());
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ctx.expectMessage(source, type);
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid application_messages (NegativeTestContext& ctx)
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.beginSection("Messages with source of GL_DEBUG_SOURCE_APPLICATION");
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	emitMessages(ctx, GL_DEBUG_SOURCE_APPLICATION);
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.endSection();
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid thirdparty_messages (NegativeTestContext& ctx)
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.beginSection("Messages with source of GL_DEBUG_SOURCE_THIRD_PARTY");
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	emitMessages(ctx, GL_DEBUG_SOURCE_THIRD_PARTY);
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.endSection();
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid push_pop_messages (NegativeTestContext& ctx)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.beginSection("Push/Pop Debug Group");
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Application group 1");
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP);
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 2, -1, "Application group 1-1");
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP);
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 3, -1, "Application group 1-1-1");
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP);
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPopDebugGroup();
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP);
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPopDebugGroup();
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP);
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 4, -1, "Application group 1-2");
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP);
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPopDebugGroup();
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_THIRD_PARTY, 4, -1, "3rd Party group 1-3");
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_PUSH_GROUP);
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPopDebugGroup();
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_POP_GROUP);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPopDebugGroup();
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP);
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPushDebugGroup(GL_DEBUG_SOURCE_THIRD_PARTY, 4, -1, "3rd Party group 2");
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_PUSH_GROUP);
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.glPopDebugGroup();
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.expectMessage(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_POP_GROUP);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ctx.endSection();
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<FunctionContainer> getUserMessageFuncs (void)
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FunctionContainer funcs[] =
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ application_messages,	"application_messages", "Externally generated messages from the application"	},
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ thirdparty_messages,	"third_party_messages",	"Externally generated messages from a third party"		},
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ push_pop_messages,	"push_pop_stack",		"Messages from pushing/popping debug groups"			},
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Anonymous
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::set;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::MovePtr;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glw::GLenum;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glw::GLuint;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glw::GLsizei;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::ResultCollector;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::CallLogWrapper;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing NegativeTestShared::TestFunc;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing NegativeTestShared::FunctionContainer;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing NegativeTestShared::NegativeTestContext;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Data required to uniquely identify a debug message
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct MessageID
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum source;
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum type;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint id;
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageID (void) : source(GL_NONE), type(GL_NONE), id(0) {}
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageID (GLenum source_, GLenum type_, GLuint id_) : source(source_), type(type_), id(id_) {}
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool operator== (const MessageID& rhs) const { return source == rhs.source && type == rhs.type && id == rhs.id;}
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool operator!= (const MessageID& rhs) const { return source != rhs.source || type != rhs.type || id != rhs.id;}
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool operator<  (const MessageID& rhs) const
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return source < rhs.source || (source == rhs.source && (type < rhs.type || (type == rhs.type && id < rhs.id)));
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const MessageID &id)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return str << glu::getDebugMessageSourceStr(id.source) << ", "	<< glu::getDebugMessageTypeStr(id.type) << ", " << id.id;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// All info from a single debug message
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct MessageData
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageID	id;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum		severity;
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string		message;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageData (void) : id(MessageID()), severity(GL_NONE) {}
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageData (const MessageID& id_, GLenum severity_, const string& message_) : id(id_) , severity(severity_) , message(message_) {}
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryextern "C" typedef void GLW_APIENTRY DebugCallbackFunc(GLenum, GLenum, GLuint, GLenum, GLsizei, const char*, void*);
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Base class
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BaseCase : public NegativeTestShared::ErrorCase
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								BaseCase			(Context&					ctx,
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*				name,
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*				desc);
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual 					~BaseCase			(void) {}
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult		iterate				(void) = 0;
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				expectMessage		(GLenum source, GLenum type);
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				expectError			(GLenum error0, GLenum error1);
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct VerificationResult {
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const qpTestResult	result;
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string		resultMessage;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string		logMessage;
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VerificationResult (qpTestResult result_, const string& resultMessage_, const string& logMessage_)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: result(result_), resultMessage(resultMessage_), logMessage(logMessage_) {}
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static DebugCallbackFunc	callbackHandle;
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				callback			(GLenum source, GLenum type, GLuint id, GLenum severity, const std::string& message);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VerificationResult			verifyMessageCount	(const MessageID& id, GLenum severity, int refCount, int resCount, bool messageEnabled) const;
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Verify a single message instance against expected attributes
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						verifyMessage		(const MessageData& message, GLenum source, GLenum type, GLuint id, GLenum severity);
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						verifyMessage		(const MessageData& message, GLenum source, GLenum type);
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						verifyMessageExists	(const MessageData& message, GLenum source, GLenum type);
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						verifyMessageGroup	(const MessageData& message, GLenum source, GLenum type);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						verifyMessageString	(const MessageData& message);
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						isDebugContext		(void) const;
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::ResultCollector		m_results;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BaseCase::callbackHandle (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, void* userParam)
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static_cast<BaseCase*>(userParam)->callback(source, type, id, severity, string(message, &message[length]));
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBaseCase::BaseCase (Context& ctx, const char* name, const char* desc)
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ErrorCase(ctx, name, desc)
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BaseCase::expectMessage (GLenum source, GLenum type)
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(source);
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(type);
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BaseCase::expectError (GLenum error0, GLenum error1)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (error0 != GL_NO_ERROR || error1 != GL_NO_ERROR)
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		expectMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR);
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		expectMessage(GL_DONT_CARE, GL_DONT_CARE);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BaseCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(source);
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(type);
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(id);
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(severity);
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(message);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3043c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBaseCase::VerificationResult BaseCase::verifyMessageCount (const MessageID& id, GLenum severity, int refCount, int resCount, bool messageEnabled) const
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::stringstream log;
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// This message should not be filtered out
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (messageEnabled)
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (resCount != refCount)
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			/*
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * Technically nothing requires the implementation to be consistent in terms
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * of the messages it produces in most situations, allowing the set of messages
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * produced to vary between executions. This function splits messages
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * into deterministic and non-deterministic to facilitate handling of such messages.
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * Non-deterministic messages that are present in differing quantities in filtered and
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * unfiltered runs will not fail the test case unless in direct violation of a filter:
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * the implementation may produce an arbitrary number of such messages when they are
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * not filtered out and none when they are filtered.
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * A list of error source/type combinations with their assumed behaviour and
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * the rationale for expecting such behaviour follows
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * For API/shader messages we assume that the following types are deterministic:
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *   DEBUG_TYPE_ERROR                 Errors specified by spec and should always be produced
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * For API messages the following types are assumed to be non-deterministic
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * and treated as quality warnings since the underlying reported issue does not change between calls:
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *   DEBUG_TYPE_DEPRECATED_BEHAVIOR   Reasonable to only report first instance
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry             *   DEBUG_TYPE_UNDEFINED_BEHAVIOR    Reasonable to only report first instance
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry             *   DEBUG_TYPE_PORTABILITY           Reasonable to only report first instance
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * For API messages the following types are assumed to be non-deterministic
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * and do not affect test results.
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *   DEBUG_TYPE_PERFORMANCE           May be tied to arbitrary factors, reasonable to report only first instance
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry             *   DEBUG_TYPE_OTHER                 Definition allows arbitrary contents
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * For 3rd party and application messages the following types are deterministic:
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry             *   DEBUG_TYPE_MARKER                Only generated by test
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *   DEBUG_TYPE_PUSH_GROUP            Only generated by test
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *   DEBUG_TYPE_POP_GROUP             Only generated by test
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *   All others                       Only generated by test
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * All messages with category of window system or other are treated as non-deterministic
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * and do not effect test results since they can be assumed to be outside control of
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 * both the implementation and test case
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 *
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 */
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool isDeterministic	= id.source == GL_DEBUG_SOURCE_APPLICATION ||
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  id.source == GL_DEBUG_SOURCE_THIRD_PARTY ||
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										  ((id.source == GL_DEBUG_SOURCE_API || id.source == GL_DEBUG_SOURCE_SHADER_COMPILER) && id.type == GL_DEBUG_TYPE_ERROR);
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool canIgnore		= id.source == GL_DEBUG_SOURCE_WINDOW_SYSTEM || id.source == GL_DEBUG_SOURCE_OTHER;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDeterministic)
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (resCount > refCount)
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << "Extra instances of message were found: (" << id << ") with "
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< glu::getDebugMessageSeverityStr(severity)
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< " (got " << resCount << ", expected " << refCount << ")";
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return VerificationResult(QP_TEST_RESULT_FAIL, "Extra instances of a deterministic message were present", log.str());
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << "Instances of message were missing: (" << id << ") with "
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< glu::getDebugMessageSeverityStr(severity)
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< " (got " << resCount << ", expected " << refCount << ")";
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return VerificationResult(QP_TEST_RESULT_FAIL, "Message missing", log.str());
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if(!canIgnore)
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (resCount > refCount)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << "Extra instances of message were found but the message is non-deterministic(warning): (" << id << ") with "
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< glu::getDebugMessageSeverityStr(severity)
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< " (got " << resCount << ", expected " << refCount << ")";
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return VerificationResult(QP_TEST_RESULT_QUALITY_WARNING, "Extra instances of a message were present", log.str());
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << "Instances of message were missing but the message is non-deterministic(warning): (" << id << ") with "
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< glu::getDebugMessageSeverityStr(severity)
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< " (got " << resCount << ", expected " << refCount << ")";
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return VerificationResult(QP_TEST_RESULT_QUALITY_WARNING, "Message missing", log.str());
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (resCount > refCount)
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << "Extra instances of message were found but the message is non-deterministic(ignored): (" << id << ") with "
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< glu::getDebugMessageSeverityStr(severity)
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< " (got " << resCount << ", expected " << refCount << ")";
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return VerificationResult(QP_TEST_RESULT_PASS, "", log.str());
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					log << "Instances of message were missing but the message is non-deterministic(ignored): (" << id << ") with "
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< glu::getDebugMessageSeverityStr(severity)
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						<< " (got " << resCount << ", expected " << refCount << ")";
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return VerificationResult(QP_TEST_RESULT_PASS, "", log.str());
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else // Passed as appropriate
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << "Message was found when expected: ("<< id << ") with "
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getDebugMessageSeverityStr(severity);
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return VerificationResult(QP_TEST_RESULT_PASS, "", log.str());
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Message should be filtered out
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Filtered out
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (resCount == 0)
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << "Message was excluded correctly:  (" << id << ") with "
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getDebugMessageSeverityStr(severity);
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return VerificationResult(QP_TEST_RESULT_PASS, "", log.str());
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Only present in filtered run (ERROR)
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (resCount > 0 && refCount == 0)
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << "A message was not excluded as it should have been: (" << id << ") with "
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getDebugMessageSeverityStr(severity)
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< ". This message was not present in the reference run";
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return VerificationResult(QP_TEST_RESULT_FAIL, "A message was not filtered out", log.str());
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Present in both runs (ERROR)
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << "A message was not excluded as it should have been: (" << id << ") with "
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getDebugMessageSeverityStr(severity);
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return VerificationResult(QP_TEST_RESULT_FAIL, "A message was not filtered out", log.str());
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Return true if message needs further verification
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool BaseCase::verifyMessageExists (const MessageData& message, GLenum source, GLenum type)
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog& log = m_testCtx.getLog();
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (source == GL_DONT_CARE || type == GL_DONT_CARE)
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (message.id.source == GL_NONE || message.id.type == GL_NONE)
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isDebugContext())
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_FAIL, "Message was not reported as expected");
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "A message was expected but none was reported" << TestLog::EndMessage;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Verification accuracy is lacking without a debug context");
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "A message was expected but none was reported. Running without a debug context" << TestLog::EndMessage;
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BaseCase::verifyMessageGroup (const MessageData& message, GLenum source, GLenum type)
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog& log = m_testCtx.getLog();
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (message.id.source != source)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect message source");
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Message source was " << glu::getDebugMessageSourceStr(message.id.source)
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< " when it should have been "  << glu::getDebugMessageSourceStr(source) << TestLog::EndMessage;
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (message.id.type != type)
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect message type");
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Message type was " << glu::getDebugMessageTypeStr(message.id.type)
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< " when it should have been " << glu::getDebugMessageTypeStr(type) << TestLog::EndMessage;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BaseCase::verifyMessageString (const MessageData& message)
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog& log = m_testCtx.getLog();
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Driver says: \"" << message.message << "\"" << TestLog::EndMessage;
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (message.message.empty())
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Empty message");
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Message message was empty" << TestLog::EndMessage;
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BaseCase::verifyMessage (const MessageData& message, GLenum source, GLenum type)
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (verifyMessageExists(message, source, type))
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyMessageString(message);
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyMessageGroup(message, source, type);
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BaseCase::verifyMessage (const MessageData& message, GLenum source, GLenum type, GLuint id, GLenum severity)
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog& log = m_testCtx.getLog();
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (verifyMessageExists(message, source, type))
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyMessageString(message);
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verifyMessageGroup(message, source, type);
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (message.id.id != id)
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect message id");
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Message id was " << message.id.id
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< " when it should have been " << id << TestLog::EndMessage;
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (message.severity != severity)
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect message severity");
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Message severity was " << glu::getDebugMessageSeverityStr(message.severity)
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< " when it should have been " << glu::getDebugMessageSeverityStr(severity) << TestLog::EndMessage;
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool BaseCase::isDebugContext (void) const
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (m_context.getRenderContext().getType().getFlags() & glu::CONTEXT_DEBUG) != 0;
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Generate errors, verify that each error results in a callback call
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CallbackErrorCase : public BaseCase
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							CallbackErrorCase	(Context&				ctx,
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*			name,
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*			desc,
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 TestFunc				errorFunc);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual 				~CallbackErrorCase	(void) {}
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult	iterate				(void);
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			expectMessage		(GLenum source, GLenum type);
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			callback			(GLenum source, GLenum type, GLuint id, GLenum severity, const string& message);
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TestFunc			m_errorFunc;
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageData				m_lastMessage;
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCallbackErrorCase::CallbackErrorCase (Context&				ctx,
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  const char*			name,
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  const char*			desc,
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  TestFunc				errorFunc)
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: BaseCase		(ctx, name, desc)
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_errorFunc	(errorFunc)
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCallbackErrorCase::IterateResult CallbackErrorCase::iterate (void)
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_AND_THROW(NotSupportedError, m_context.getContextInfo().isExtensionSupported("GL_KHR_debug"), "GL_KHR_debug is not supported");
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&			log		= m_testCtx.getLog();
578271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry	NegativeTestContext		context	= NegativeTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, true);
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, false); // disable all
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, DE_NULL, true); // enable API errors
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DEBUG_SOURCE_APPLICATION, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); // enable application messages
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); // enable third party messages
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageCallback(callbackHandle, this);
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_errorFunc(context);
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageCallback(DE_NULL, DE_NULL);
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.disable(GL_DEBUG_OUTPUT);
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_results.setTestContextResult(m_testCtx);
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CallbackErrorCase::expectMessage (GLenum source, GLenum type)
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyMessage(m_lastMessage, source, type);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_lastMessage = MessageData();
60289a5d29adb4f831e3d22126a21e3b4f8ea74db22Pyry Haulos
60389a5d29adb4f831e3d22126a21e3b4f8ea74db22Pyry Haulos	// Reset error so that code afterwards doesn't break because of lingering error state
60489a5d29adb4f831e3d22126a21e3b4f8ea74db22Pyry Haulos	m_context.getRenderContext().getFunctions().getError();
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CallbackErrorCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_lastMessage = MessageData(MessageID(source, type, id), severity, message);
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Generate errors, verify that each error results in a log entry
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LogErrorCase : public BaseCase
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							LogErrorCase	(Context&				context,
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 const char*			name,
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 const char*			desc,
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 TestFunc				errorFunc);
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual 				~LogErrorCase	(void) {}
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult	iterate			(void);
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			expectMessage	(GLenum source, GLenum type);
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TestFunc			m_errorFunc;
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageData				m_lastMessage;
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLogErrorCase::LogErrorCase (Context&	ctx,
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const char*	name,
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const char*	desc,
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							TestFunc	errorFunc)
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: BaseCase		(ctx, name, desc)
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_errorFunc	(errorFunc)
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLogErrorCase::IterateResult LogErrorCase::iterate (void)
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_AND_THROW(NotSupportedError, m_context.getContextInfo().isExtensionSupported("GL_KHR_debug"), "GL_KHR_debug is not supported");
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&			log		= m_testCtx.getLog();
646271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry	NegativeTestContext		context	= NegativeTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, true);
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint					numMsg	= 0;
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT);
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, false); // disable all
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, DE_NULL, true); // enable API errors
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageCallback(DE_NULL, DE_NULL); // enable logging
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMsg);
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getDebugMessageLog(numMsg, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL); // clear log
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_errorFunc(context);
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.disable(GL_DEBUG_OUTPUT);
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_results.setTestContextResult(m_testCtx);
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LogErrorCase::expectMessage (GLenum source, GLenum type)
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						numMsg		= 0;
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log			= m_testCtx.getLog();
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageData				lastMsg;
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (source == GL_DONT_CARE || type == GL_DONT_CARE)
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMsg);
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numMsg == 0)
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isDebugContext())
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_FAIL, "Error was not reported as expected");
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "A message was expected but none was reported (empty message log)" << TestLog::EndMessage;
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Verification accuracy is lacking without a debug context");
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "A message was expected but none was reported (empty message log). Running without a debug context" << TestLog::EndMessage;
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// There may be messages other than the error we are looking for in the log.
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Strictly nothing prevents the implementation from producing more than the
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// required error from an API call with a defined error. however we assume that
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// since calls that produce an error should not change GL state the implementation
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// should have nothing else to report.
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numMsg > 1)
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getDebugMessageLog(numMsg-1, 0, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL, DE_NULL); // Clear all but last
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int  msgLen = 0;
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &msgLen);
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_MSG(msgLen >= 0, "Negative message length");
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_MSG(msgLen < 100000, "Excessively long message");
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		lastMsg.message.resize(msgLen);
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getDebugMessageLog(1, msgLen, &lastMsg.id.source, &lastMsg.id.type, &lastMsg.id.id, &lastMsg.severity, &msgLen, &lastMsg.message[0]);
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Message << "Driver says: \"" << lastMsg.message << "\"" << TestLog::EndMessage;
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyMessage(lastMsg, source, type);
71489a5d29adb4f831e3d22126a21e3b4f8ea74db22Pyry Haulos
71589a5d29adb4f831e3d22126a21e3b4f8ea74db22Pyry Haulos	// Reset error so that code afterwards doesn't break because of lingering error state
71689a5d29adb4f831e3d22126a21e3b4f8ea74db22Pyry Haulos	m_context.getRenderContext().getFunctions().getError();
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Generate errors, verify that calling glGetError afterwards produces desired result
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GetErrorCase : public BaseCase
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							GetErrorCase	(Context&				ctx,
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 const char*			name,
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 const char*			desc,
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 TestFunc				errorFunc);
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual 				~GetErrorCase	(void) {}
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult	iterate			(void);
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			expectMessage	(GLenum source, GLenum type);
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			expectError		(glw::GLenum error0, glw::GLenum error1);
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TestFunc			m_errorFunc;
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGetErrorCase::GetErrorCase (Context&	ctx,
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const char*	name,
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							const char*	desc,
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							TestFunc	errorFunc)
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: BaseCase		(ctx, name, desc)
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_errorFunc	(errorFunc)
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7473c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGetErrorCase::IterateResult GetErrorCase::iterate (void)
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&			log		= m_testCtx.getLog();
750271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry	NegativeTestContext		context	= NegativeTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, true);
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_errorFunc(context);
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_results.setTestContextResult(m_testCtx);
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GetErrorCase::expectMessage (GLenum source, GLenum type)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(source);
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(type);
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!"GetErrorCase cannot handle anything other than error codes");
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GetErrorCase::expectError (glw::GLenum error0, glw::GLenum error1)
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&				log		= m_testCtx.getLog();
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLenum			result	= gl.getError();
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (result != error0 && result != error1)
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_results.addResult(QP_TEST_RESULT_FAIL, "Incorrect error was reported");
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (error0 == error1)
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getErrorStr(error0) << " was expected but got "
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getErrorStr(result)
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::EndMessage;
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getErrorStr(error0) << " or "
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getErrorStr(error1) << " was expected but got "
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getErrorStr(result)
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::EndMessage;
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Generate errors, log the types, disable some, regenerate errors, verify correct errors (not)reported
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FilterCase : public BaseCase
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								FilterCase		(Context&				ctx,
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*			name,
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*			desc,
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const vector<TestFunc>	errorFuncs);
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual 					~FilterCase		(void) {}
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult		iterate			(void);
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				expectMessage	(GLenum source, GLenum type);
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct MessageFilter
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MessageFilter() : source(GL_DONT_CARE), type(GL_DONT_CARE), severity(GL_DONT_CARE), enabled(true) {} // Default to enable all
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MessageFilter(GLenum source_, GLenum type_, GLenum severity_, const vector<GLuint>& ids_, bool enabled_) : source(source_), type(type_), severity(severity_), ids(ids_), enabled(enabled_) {}
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum			source;
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum			type;
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum			severity;
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<GLuint>	ids;
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			enabled;
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				callback			(GLenum source, GLenum type, GLuint id, GLenum severity, const string& message);
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<MessageData>			genMessages			(bool uselog, const string& desc);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<MessageFilter>		genFilters			(const vector<MessageData>& messages, const vector<MessageFilter>& initial, deUint32 seed, int iterations) const;
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						applyFilters		(const vector<MessageFilter>& filters) const;
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						isEnabled			(const vector<MessageFilter>& filters, const MessageData& message) const;
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						verify				(const vector<MessageData>&		refMessages,
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const vector<MessageData>&		filteredMessages,
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const vector<MessageFilter>&	filters);
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<TestFunc>		m_errorFuncs;
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<MessageData>*		m_currentErrors;
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFilterCase::FilterCase (Context&				ctx,
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const char*				name,
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const char*				desc,
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const vector<TestFunc>	errorFuncs)
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: BaseCase			(ctx, name, desc)
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_errorFuncs		(errorFuncs)
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentErrors	(DE_NULL)
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8453c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFilterCase::IterateResult FilterCase::iterate (void)
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_AND_THROW(NotSupportedError, m_context.getContextInfo().isExtensionSupported("GL_KHR_debug"), "GL_KHR_debug is not supported");
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT);
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageCallback(callbackHandle, this);
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<MessageData>	refMessages		= genMessages(true, "Reference run");
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MessageFilter			baseFilter		(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, vector<GLuint>(), true);
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32				baseSeed		= deStringHash(getName()) ^ m_testCtx.getCommandLine().getBaseSeed();
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<MessageFilter>	filters			= genFilters(refMessages, vector<MessageFilter>(1, baseFilter), baseSeed, 4);
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<MessageData>			filteredMessages;
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		applyFilters(filters);
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Generate errors
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		filteredMessages = genMessages(false, "Filtered run");
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Verify
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verify(refMessages, filteredMessages, filters);
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isDebugContext() && refMessages.empty())
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Verification accuracy is lacking without a debug context");
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.disable(GL_DEBUG_OUTPUT);
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_results.setTestContextResult(m_testCtx);
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FilterCase::expectMessage (GLenum source, GLenum type)
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(source);
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(type);
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FilterCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentErrors)
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_currentErrors->push_back(MessageData(MessageID(source, type, id), severity, message));
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<MessageData> FilterCase::genMessages (bool uselog, const string& desc)
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&			log			= m_testCtx.getLog();
896271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry	NegativeTestContext		context		= NegativeTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, uselog);
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::ScopedLogSection	section		(log, "message gen", desc);
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<MessageData>		messages;
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentErrors = &messages;
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < int(m_errorFuncs.size()); ndx++)
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_errorFuncs[ndx](context);
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentErrors = DE_NULL;
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return messages;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<FilterCase::MessageFilter> FilterCase::genFilters (const vector<MessageData>& messages, const vector<MessageFilter>& initial, deUint32 seed, int iterations) const
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random				rng				(seed ^ deInt32Hash(deStringHash(getName())));
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	set<MessageID>			tempMessageIds;
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	set<GLenum>				tempSources;
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	set<GLenum>				tempTypes;
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	set<GLenum>				tempSeverities;
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (messages.empty())
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return initial;
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < int(messages.size()); ndx++)
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MessageData& msg = messages[ndx];
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tempMessageIds.insert(msg.id);
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tempSources.insert(msg.id.source);
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tempTypes.insert(msg.id.type);
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tempSeverities.insert(msg.severity);
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fetchable by index
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<MessageID> messageIds	(tempMessageIds.begin(), tempMessageIds.end());
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<GLenum>	sources		(tempSources.begin(), tempSources.end());
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<GLenum>	types		(tempTypes.begin(), tempTypes.end());
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<GLenum>	severities	(tempSeverities.begin(), tempSeverities.end());
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<MessageFilter>	filters		= initial;
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int iteration = 0; iteration < iterations; iteration++)
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch(rng.getInt(0, 8)) // Distribute so that per-message randomization (the default branch) is prevalent
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 0:
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const GLenum	source	= sources[rng.getInt(0, int(sources.size()-1))];
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const bool		enabled	= rng.getBool();
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					filters.push_back(MessageFilter(source, GL_DONT_CARE, GL_DONT_CARE, vector<GLuint>(), enabled));
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 1:
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const GLenum	type	= types[rng.getUint32()%types.size()];
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const bool		enabled	= rng.getBool();
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					filters.push_back(MessageFilter(GL_DONT_CARE, type, GL_DONT_CARE, vector<GLuint>(), enabled));
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case 2:
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const GLenum	severity	= severities[rng.getUint32()%severities.size()];
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const bool		enabled		= rng.getBool();
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					filters.push_back(MessageFilter(GL_DONT_CARE, GL_DONT_CARE, severity, vector<GLuint>(), enabled));
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					break;
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int start = rng.getInt(0, int(messageIds.size()));
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int itr = 0; itr < 4; itr++)
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const MessageID&	id		= messageIds[(start+itr)%messageIds.size()];
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const bool			enabled = rng.getBool();
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						filters.push_back(MessageFilter(id.source, id.type, GL_DONT_CARE, vector<GLuint>(1, id.id), enabled));
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return filters;
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FilterCase::applyFilters (const vector<MessageFilter>& filters) const
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log		= m_testCtx.getLog();
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ScopedLogSection	section	(log, "", "Setting message filters");
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl		= m_context.getRenderContext().getFunctions();
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t filterNdx = 0; filterNdx < filters.size(); filterNdx++)
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MessageFilter& filter = filters[filterNdx];
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (filter.ids.empty())
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Setting messages with"
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< " source " << glu::getDebugMessageSourceStr(filter.source)
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< ", type " << glu::getDebugMessageTypeStr(filter.type)
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< " and severity " << glu::getDebugMessageSeverityStr(filter.severity)
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< (filter.enabled ? " to enabled" : " to disabled")
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::EndMessage;
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (size_t ndx = 0; ndx < filter.ids.size(); ndx++)
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "Setting message (" << MessageID(filter.source, filter.type, filter.ids[ndx]) << ") to " << (filter.enabled ? "enabled" : "disabled") << TestLog::EndMessage;
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.debugMessageControl(filter.source, filter.type, filter.severity, GLsizei(filter.ids.size()), filter.ids.empty() ? DE_NULL : &filter.ids[0], filter.enabled);
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool FilterCase::isEnabled (const vector<MessageFilter>& filters, const MessageData& message) const
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool retval = true;
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t filterNdx = 0; filterNdx < filters.size(); filterNdx++)
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MessageFilter&	filter	= filters[filterNdx];
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (filter.ids.empty())
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (filter.source != GL_DONT_CARE && filter.source != message.id.source)
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (filter.type != GL_DONT_CARE && filter.type != message.id.type)
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (filter.severity != GL_DONT_CARE && filter.severity != message.severity)
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(filter.source != GL_DONT_CARE);
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(filter.type != GL_DONT_CARE);
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(filter.severity == GL_DONT_CARE);
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (filter.source != message.id.source || filter.type != message.id.type)
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::contains(filter.ids.begin(), filter.ids.end(), message.id.id))
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		retval = filter.enabled;
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retval;
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct MessageMeta
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		refCount;
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		resCount;
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum	severity;
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageMeta (void) : refCount(0), resCount(0), severity(GL_NONE) {}
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FilterCase::verify (const vector<MessageData>& refMessages, const vector<MessageData>& resMessages, const vector<MessageFilter>& filters)
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&						log		= m_testCtx.getLog();
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<MessageID, MessageMeta>		counts;
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Section("verification", "Verifying");
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Gather message counts & severities, report severity mismatches if found
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t refNdx = 0; refNdx < refMessages.size(); refNdx++)
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MessageData&	msg  = refMessages[refNdx];
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MessageMeta&		meta = counts[msg.id];
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (meta.severity != GL_NONE && meta.severity != msg.severity)
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "A message has variable severity between instances: (" << msg.id << ") with severity "
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getDebugMessageSeverityStr(meta.severity) << " and " << glu::getDebugMessageSeverityStr(msg.severity) << TestLog::EndMessage;
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_FAIL, "Message severity changed between instances of the same message");
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		meta.refCount++;
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		meta.severity = msg.severity;
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t resNdx = 0; resNdx < resMessages.size(); resNdx++)
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MessageData&	msg  = resMessages[resNdx];
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MessageMeta&		meta = counts[msg.id];
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (meta.severity != GL_NONE && meta.severity != msg.severity)
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "A message has variable severity between instances: (" << msg.id << ") with severity "
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< glu::getDebugMessageSeverityStr(meta.severity) << " and " << glu::getDebugMessageSeverityStr(msg.severity) << TestLog::EndMessage;
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_FAIL, "Message severity changed between instances of the same message");
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		meta.resCount++;
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		meta.severity = msg.severity;
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (map<MessageID, MessageMeta>::const_iterator itr = counts.begin(); itr != counts.end(); itr++)
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MessageID&	id			= itr->first;
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const GLenum		severity	= itr->second.severity;
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			refCount	= itr->second.refCount;
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			resCount	= itr->second.resCount;
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			enabled		= isEnabled(filters, MessageData(id, severity, ""));
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VerificationResult	result		= verifyMessageCount(id, severity, refCount, resCount, enabled);
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << result.logMessage << TestLog::EndMessage;
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (result.result != QP_TEST_RESULT_PASS)
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(result.result, result.resultMessage);
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::EndSection;
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Filter case that uses debug groups
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GroupFilterCase : public FilterCase
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							GroupFilterCase		(Context&				ctx,
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*			name,
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*			desc,
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const vector<TestFunc>	errorFuncs);
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual 				~GroupFilterCase	(void) {}
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult	iterate				(void);
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGroupFilterCase::GroupFilterCase (Context&					ctx,
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  const char*				name,
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  const char*				desc,
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  const vector<TestFunc>	errorFuncs)
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: FilterCase(ctx, name, desc, errorFuncs)
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T>
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<T> join(const vector<T>& a, const vector<T>&b)
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<T> retval;
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retval.reserve(a.size()+b.size());
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retval.insert(retval.end(), a.begin(), a.end());
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retval.insert(retval.end(), b.begin(), b.end());
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retval;
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGroupFilterCase::IterateResult GroupFilterCase::iterate (void)
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_AND_THROW(NotSupportedError, m_context.getContextInfo().isExtensionSupported("GL_KHR_debug"), "GL_KHR_debug is not supported");
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&			log			= m_testCtx.getLog();
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT);
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageCallback(callbackHandle, this);
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Generate reference (all errors)
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<MessageData>	refMessages	 = genMessages(true, "Reference run");
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32				baseSeed	 = deStringHash(getName()) ^ m_testCtx.getCommandLine().getBaseSeed();
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MessageFilter			baseFilter	 (GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, vector<GLuint>(), true);
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const vector<MessageFilter>	filter0		 = genFilters(refMessages, vector<MessageFilter>(1, baseFilter), baseSeed, 4);
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<MessageData>			resMessages0;
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		applyFilters(filter0);
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resMessages0 = genMessages(false, "Filtered run, default debug group");
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Initial verification
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verify(refMessages, resMessages0, filter0);
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generate reference (filters inherited from parent)
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const vector<MessageFilter> filter1base		= genFilters(refMessages, vector<MessageFilter>(), baseSeed ^ 0xDEADBEEF, 4);
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const vector<MessageFilter>	filter1full		= join(filter0, filter1base);
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::ScopedLogSection		section1		(log, "", "Pushing Debug Group");
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<MessageData>			resMessages1;
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Test Group");
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			applyFilters(filter1base);
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// First nested verification
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resMessages1 = genMessages(false, "Filtered run, pushed one debug group");
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			verify(refMessages, resMessages1, filter1full);
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Generate reference (filters iherited again)
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const vector<MessageFilter>	filter2base		= genFilters(refMessages, vector<MessageFilter>(), baseSeed ^ 0x43211234, 4);
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const vector<MessageFilter>	filter2full		= join(filter1full, filter2base);
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::ScopedLogSection		section2		(log, "", "Pushing Debug Group");
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<MessageData>			resMessages2;
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Nested Test Group");
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				applyFilters(filter2base);
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Second nested verification
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resMessages2 = genMessages(false, "Filtered run, pushed two debug groups");
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				verify(refMessages, resMessages2, filter2full);
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.popDebugGroup();
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// First restore verification
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resMessages1 = genMessages(false, "Filtered run, popped second debug group");
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			verify(refMessages, resMessages1, filter1full);
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.popDebugGroup();
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// restore verification
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resMessages0 = genMessages(false, "Filtered run, popped first debug group");
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		verify(refMessages, resMessages0, filter0);
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isDebugContext() && refMessages.empty())
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Verification accuracy is lacking without a debug context");
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.disable(GL_DEBUG_OUTPUT);
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_results.setTestContextResult(m_testCtx);
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Basic grouping functionality
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GroupCase : public BaseCase
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							GroupCase	(Context&				ctx,
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 const char*			name,
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 const char*			desc);
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual					~GroupCase	() {}
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult	iterate		(void);
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			callback	(GLenum source, GLenum type, GLuint id, GLenum severity, const string& message);
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageData				m_lastMessage;
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGroupCase::GroupCase (Context&				ctx,
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char*			name,
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char*			desc)
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: BaseCase(ctx, name, desc)
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGroupCase::IterateResult GroupCase::iterate (void)
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_AND_THROW(NotSupportedError, m_context.getContextInfo().isExtensionSupported("GL_KHR_debug"), "GL_KHR_debug is not supported");
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&			log		= m_testCtx.getLog();
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::CallLogWrapper		wrapper	(gl, log);
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT);
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, false); // disable all
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, DE_NULL, true); // enable API errors
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DEBUG_SOURCE_APPLICATION, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); // enable application messages
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); // enable third party messages
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageCallback(callbackHandle, this);
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	wrapper.enableLogging(true);
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	wrapper.glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1234, -1, "Pushed debug stack");
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyMessage(m_lastMessage, GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PUSH_GROUP, 1234, GL_DEBUG_SEVERITY_NOTIFICATION);
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	wrapper.glPopDebugGroup();
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyMessage(m_lastMessage, GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_POP_GROUP, 1234, GL_DEBUG_SEVERITY_NOTIFICATION);
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	wrapper.glPushDebugGroup(GL_DEBUG_SOURCE_THIRD_PARTY, 4231, -1, "Pushed debug stack");
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyMessage(m_lastMessage, GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_PUSH_GROUP, 4231, GL_DEBUG_SEVERITY_NOTIFICATION);
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	wrapper.glPopDebugGroup();
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	verifyMessage(m_lastMessage, GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_POP_GROUP, 4231, GL_DEBUG_SEVERITY_NOTIFICATION);
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageCallback(DE_NULL, DE_NULL);
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.disable(GL_DEBUG_OUTPUT);
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_results.setTestContextResult(m_testCtx);
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GroupCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_lastMessage = MessageData(MessageID(source, type, id), severity, message);
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Asynchronous debug output
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AsyncCase : public BaseCase
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							AsyncCase			(Context&				ctx,
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*			name,
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const char*			desc,
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const vector<TestFunc>	errorFuncs,
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 bool					useCallbacks);
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual					~AsyncCase			() {}
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult	iterate				(void);
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			expectMessage		(glw::GLenum source, glw::GLenum type);
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct MessageCount
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int received;
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int expected;
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MessageCount(void) : received(0), expected(0) {}
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef map<MessageID, MessageCount> MessageCounter;
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum VerifyState
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VERIFY_PASS = 0,
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VERIFY_MINIMUM,
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VERIFY_FAIL,
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VERIFY_LAST
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			callback			(glw::GLenum source, glw::GLenum type, glw::GLuint id, glw::GLenum severity, const std::string& message);
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VerifyState				verify				(bool uselog);
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					fetchLogMessages	(void);
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<TestFunc>	m_errorFuncs;
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool				m_useCallbacks;
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MessageCounter			m_counts;
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Mutex				m_mutex;
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAsyncCase::AsyncCase (Context&					ctx,
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char*				name,
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char*				desc,
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const vector<TestFunc>	errorFuncs,
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  bool						useCallbacks)
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: BaseCase			(ctx, name, desc)
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_errorFuncs		(errorFuncs)
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_useCallbacks	(useCallbacks)
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAsyncCase::IterateResult AsyncCase::iterate (void)
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_AND_THROW(NotSupportedError, m_context.getContextInfo().isExtensionSupported("GL_KHR_debug"), "GL_KHR_debug is not supported");
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestLog&		log			= m_testCtx.getLog();
1363271c2654cc44f23492888c7ef40c36c2fd810c77Jarkko Pöyry	NegativeTestContext	context		= NegativeTestContext(*this, m_context.getRenderContext(), m_context.getContextInfo(), log, m_results, true);
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			maxWait		= 10000; // ms
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int			warnWait	= 100;
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT);
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, false);
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Some messages could be dependent on the value of DEBUG_OUTPUT_SYNCHRONOUS so only use API errors which should be generated in all cases
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, DE_NULL, true);
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_useCallbacks) // will use log otherwise
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.debugMessageCallback(callbackHandle, this);
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.debugMessageCallback(DE_NULL, DE_NULL);
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Reference run (synchoronous)
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::ScopedLogSection section(log, "reference run", "Reference run (synchronous)");
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < int(m_errorFuncs.size()); ndx++)
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_errorFuncs[ndx](context);
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_counts.empty())
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isDebugContext())
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Need debug context to guarantee implementation behaviour (see command line options)");
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Reference run produced no messages, nothing to verify" << TestLog::EndMessage;
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.debugMessageCallback(DE_NULL, DE_NULL);
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.disable(GL_DEBUG_OUTPUT);
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_results.setTestContextResult(m_testCtx);
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (MessageCounter::iterator itr = m_counts.begin(); itr != m_counts.end(); itr++)
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		itr->second.expected = itr->second.received;
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		itr->second.received = 0;
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.disable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Result run (async)
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < int(m_errorFuncs.size()); ndx++)
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_errorFuncs[ndx](context);
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Repatedly try verification, new results may be added to m_receivedMessages at any time
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::ScopedLogSection	section			(log, "result run", "Result run (asynchronous)");
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VerifyState				lastTimelyState = VERIFY_FAIL;
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int waited = 0;;)
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const VerifyState	pass = verify(false);
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int			wait = de::max(50, waited>>2);
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Pass (possibly due to time limit)
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (pass == VERIFY_PASS || (pass == VERIFY_MINIMUM && waited >= maxWait))
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				verify(true); // log
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// State changed late
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (waited >= warnWait && lastTimelyState != pass)
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "Async messages were returned to application somewhat slowly");
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "Passed after ~" << waited << "ms of waiting" << TestLog::EndMessage;
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// fail
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (waited >= maxWait)
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				verify(true); // log
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "Waited for ~" << waited << "ms without getting all expected messages" << TestLog::EndMessage;
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_results.addResult(QP_TEST_RESULT_FAIL, "Async messages were not returned to application within a reasonable timeframe");
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (waited < warnWait)
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				lastTimelyState = pass;
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deSleep(wait);
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			waited += wait;
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!m_useCallbacks)
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				fetchLogMessages();
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.debugMessageCallback(DE_NULL, DE_NULL);
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.disable(GL_DEBUG_OUTPUT);
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_results.setTestContextResult(m_testCtx);
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AsyncCase::expectMessage (GLenum source, GLenum type)
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Good time to clean up the queue as this should be called after most messages are generated
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!m_useCallbacks)
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fetchLogMessages();
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(source);
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(type);
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AsyncCase::callback (GLenum source, GLenum type, GLuint id, GLenum severity, const string& message)
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_useCallbacks);
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(severity);
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(message);
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::ScopedLock lock(m_mutex);
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_counts[MessageID(source, type, id)].received++;
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// 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
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AsyncCase::fetchLogMessages (void)
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint					numMsg	= 0;
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMsg);
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for(int msgNdx = 0; msgNdx < numMsg; msgNdx++)
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			msgLen = 0;
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MessageData msg;
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &msgLen);
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_MSG(msgLen >= 0, "Negative message length");
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_MSG(msgLen < 100000, "Excessively long message");
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		msg.message.resize(msgLen);
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getDebugMessageLog(1, msgLen, &msg.id.source, &msg.id.type, &msg.id.id, &msg.severity, &msgLen, &msg.message[0]);
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const de::ScopedLock lock(m_mutex); // Don't block during API call
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_counts[MessageID(msg.id)].received++;
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAsyncCase::VerifyState AsyncCase::verify (bool uselog)
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	using std::map;
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VerifyState			retval		= VERIFY_PASS;
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&			log			= m_testCtx.getLog();
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const de::ScopedLock lock(m_mutex);
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (map<MessageID, MessageCount>::const_iterator itr = m_counts.begin(); itr != m_counts.end(); itr++)
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MessageID&	id			= itr->first;
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			refCount	= itr->second.expected;
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			resCount	= itr->second.received;
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool			enabled		= true;
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VerificationResult	result		= verifyMessageCount(id, GL_DONT_CARE, refCount, resCount, enabled);
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (uselog)
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << result.logMessage << TestLog::EndMessage;
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (result.result == QP_TEST_RESULT_FAIL)
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retval = VERIFY_FAIL;
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (result.result != QP_TEST_RESULT_PASS && retval == VERIFY_PASS)
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retval = VERIFY_MINIMUM;
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retval;
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Tests debug labels
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LabelCase : public TestCase
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							LabelCase	(Context&				ctx,
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 const char*			name,
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 const char*			desc,
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 GLenum					identifier);
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual					~LabelCase	(void) {}
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual IterateResult	iterate		(void);
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLenum					m_identifier;
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLabelCase::LabelCase (Context&		ctx,
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char*			name,
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  const char*			desc,
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  GLenum				identifier)
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase		(ctx, name, desc)
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_identifier	(identifier)
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLabelCase::IterateResult LabelCase::iterate (void)
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_AND_THROW(NotSupportedError, m_context.getContextInfo().isExtensionSupported("GL_KHR_debug"), "GL_KHR_debug is not supported");
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*	const		msg			= "This is a debug label";
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLuint					object		= 0;
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	char					buffer[64];
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						outlen		= 0;
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch(m_identifier)
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_BUFFER:
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genBuffers(1, &object);
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, object);
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SHADER:
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			object = gl.createShader(GL_FRAGMENT_SHADER);
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PROGRAM:
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			object = gl.createProgram();
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_QUERY:
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genQueries(1, &object);
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.beginQuery(GL_ANY_SAMPLES_PASSED, object); // Create
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.endQuery(GL_ANY_SAMPLES_PASSED); // Cleanup
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PROGRAM_PIPELINE:
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genProgramPipelines(1, &object);
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindProgramPipeline(object); // Create
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindProgramPipeline(0); // Cleanup
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TRANSFORM_FEEDBACK:
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genTransformFeedbacks(1, &object);
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, object);
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SAMPLER:
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genSamplers(1, &object);
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindSampler(0, object);
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindSampler(0, 0);
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE:
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genTextures(1, &object);
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(GL_TEXTURE_2D, object);
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindTexture(GL_TEXTURE_2D, 0);
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_RENDERBUFFER:
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genRenderbuffers(1, &object);
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindRenderbuffer(GL_RENDERBUFFER, object);
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_FRAMEBUFFER:
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.genFramebuffers(1, &object);
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, object);
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer());
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!"Invalid identifier");
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.objectLabel(m_identifier, object, -1, msg);
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getObjectLabel(m_identifier, object, sizeof(buffer), &outlen, buffer);
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (outlen == 0)
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to query debug label from object");
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (deStringEqual(msg, buffer))
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << "Query returned string: \"" << buffer << "\"" << TestLog::EndMessage;
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << TestLog::Message << "Query returned wrong string: expected \"" << msg << "\" but got \"" << buffer << "\"" << TestLog::EndMessage;
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query returned wrong label");
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch(m_identifier)
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_BUFFER:				gl.deleteBuffers(1, &object);				break;
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SHADER:				gl.deleteShader(object);					break;
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PROGRAM:			gl.deleteProgram(object);					break;
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_QUERY:				gl.deleteQueries(1, &object);				break;
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PROGRAM_PIPELINE:	gl.deleteProgramPipelines(1, &object);		break;
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TRANSFORM_FEEDBACK:	gl.deleteTransformFeedbacks(1, &object);	break;
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SAMPLER:			gl.deleteSamplers(1, &object);				break;
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE:			gl.deleteTextures(1, &object);				break;
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_RENDERBUFFER:		gl.deleteRenderbuffers(1, &object);			break;
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_FRAMEBUFFER:		gl.deleteFramebuffers(1, &object);			break;
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!"Invalid identifier");
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Anonymous
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDebugTests::DebugTests (Context& context)
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "debug", "Debug tests")
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum CaseType
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASETYPE_CALLBACK = 0,
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASETYPE_LOG,
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASETYPE_GETERROR,
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASETYPE_LAST
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TestNode* createCase (CaseType type, Context& ctx, const char* name, const char* desc, TestFunc function)
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch(type)
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASETYPE_CALLBACK: return new CallbackErrorCase(ctx, name, desc, function);
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASETYPE_LOG:		return new LogErrorCase(ctx, name, desc, function);
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASETYPE_GETERROR: return new GetErrorCase(ctx, name, desc, function);
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!"Invalid type");
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_NULL;
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TestCaseGroup* createChildCases (CaseType type, Context& ctx, const char* name, const char* desc, const vector<FunctionContainer>& funcs)
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TestCaseGroup* host = new tcu::TestCaseGroup(ctx.getTestContext(), name, desc);
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < funcs.size(); ndx++)
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createCase(type, ctx, funcs[ndx].name, funcs[ndx].desc, funcs[ndx].function));
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return host;
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid DebugTests::init (void)
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<FunctionContainer> bufferFuncs		= NegativeTestShared::getNegativeBufferApiTestFunctions();
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<FunctionContainer> textureFuncs	= NegativeTestShared::getNegativeTextureApiTestFunctions();
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<FunctionContainer> shaderFuncs		= NegativeTestShared::getNegativeShaderApiTestFunctions();
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<FunctionContainer> fragmentFuncs	= NegativeTestShared::getNegativeFragmentApiTestFunctions();
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<FunctionContainer> vaFuncs			= NegativeTestShared::getNegativeVertexArrayApiTestFunctions();
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<FunctionContainer> stateFuncs		= NegativeTestShared::getNegativeStateApiTestFunctions();
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const vector<FunctionContainer> externalFuncs	= getUserMessageFuncs();
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const	negative	= new tcu::TestCaseGroup(m_testCtx, "negative_coverage", "API error coverage with various reporting methods");
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(negative);
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const	host	= new tcu::TestCaseGroup(m_testCtx, "callbacks", "Reporting of standard API errors via callback");
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			negative->addChild(host);
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "buffer",			"Negative Buffer API Cases",		bufferFuncs));
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "texture",		"Negative Texture API Cases",		textureFuncs));
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader",			"Negative Shader API Cases",		shaderFuncs));
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "fragment",		"Negative Fragment API Cases",		fragmentFuncs));
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "vertex_array",	"Negative Vertex Array API Cases",	vaFuncs));
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "state",			"Negative GL State API Cases",		stateFuncs));
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const	host	= new tcu::TestCaseGroup(m_testCtx, "log", "Reporting of standard API errors via log");
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			negative->addChild(host);
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_LOG, m_context, "buffer",				"Negative Buffer API Cases",		bufferFuncs));
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_LOG, m_context, "texture",				"Negative Texture API Cases",		textureFuncs));
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader",				"Negative Shader API Cases",		shaderFuncs));
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_LOG, m_context, "fragment",			"Negative Fragment API Cases",		fragmentFuncs));
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_LOG, m_context, "vertex_array",		"Negative Vertex Array API Cases",	vaFuncs));
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_LOG, m_context, "state",				"Negative GL State API Cases",		stateFuncs));
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const	host	= new tcu::TestCaseGroup(m_testCtx, "get_error", "Reporting of standard API errors via glGetError");
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			negative->addChild(host);
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "buffer",			"Negative Buffer API Cases",		bufferFuncs));
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "texture",		"Negative Texture API Cases",		textureFuncs));
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader",			"Negative Shader API Cases",		shaderFuncs));
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "fragment",		"Negative Fragment API Cases",		fragmentFuncs));
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "vertex_array",	"Negative Vertex Array API Cases",	vaFuncs));
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "state",			"Negative GL State API Cases",		stateFuncs));
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup*			host	= createChildCases(CASETYPE_CALLBACK, m_context, "externally_generated", "Externally Generated Messages", externalFuncs);
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		host->addChild(new GroupCase(m_context, "push_pop_consistency", "Push/pop message generation with full message output checking"));
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(host);
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<FunctionContainer>	containers;
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<TestFunc>			allFuncs;
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::Random					rng			(0x53941903 ^ m_context.getTestContext().getCommandLine().getBaseSeed());
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		containers.insert(containers.end(), bufferFuncs.begin(), bufferFuncs.end());
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		containers.insert(containers.end(), textureFuncs.begin(), textureFuncs.end());
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		containers.insert(containers.end(), externalFuncs.begin(), externalFuncs.end());
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (size_t ndx = 0; ndx < containers.size(); ndx++)
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			allFuncs.push_back(containers[ndx].function);
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rng.shuffle(allFuncs.begin(), allFuncs.end());
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const	filtering				= new tcu::TestCaseGroup(m_testCtx, "error_filters", "Filtering of reported errors");
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					errorFuncsPerCase		= 4;
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					maxFilteringCaseCount	= 32;
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					caseCount				= (int(allFuncs.size()) + errorFuncsPerCase-1) / errorFuncsPerCase;
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addChild(filtering);
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int caseNdx = 0; caseNdx < de::min(caseCount, maxFilteringCaseCount); caseNdx++)
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			start		= caseNdx*errorFuncsPerCase;
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			end			= de::min((caseNdx+1)*errorFuncsPerCase, int(allFuncs.size()));
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name		= "case_" + de::toString(caseNdx);
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<TestFunc>	funcs		(allFuncs.begin()+start, allFuncs.begin()+end);
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// These produce lots of different message types, thus always include at least one when testing filtering
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				funcs.insert(funcs.end(), externalFuncs[caseNdx%externalFuncs.size()].function);
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				filtering->addChild(new FilterCase(m_context, name.c_str(), "DebugMessageControl usage", funcs));
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const	groups					= new tcu::TestCaseGroup(m_testCtx, "error_groups", "Filtering of reported errors with use of Error Groups");
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					errorFuncsPerCase		= 4;
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					maxFilteringCaseCount	= 16;
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					caseCount				= (int(allFuncs.size()) + errorFuncsPerCase-1) / errorFuncsPerCase;
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addChild(groups);
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int caseNdx = 0; caseNdx < caseCount && caseNdx < maxFilteringCaseCount; caseNdx++)
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			start		= caseNdx*errorFuncsPerCase;
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			end			= de::min((caseNdx+1)*errorFuncsPerCase, int(allFuncs.size()));
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name		= ("case_" + de::toString(caseNdx)).c_str();
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<TestFunc>	funcs		(&allFuncs[0]+start, &allFuncs[0]+end);
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// These produce lots of different message types, thus always include at least one when testing filtering
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				funcs.insert(funcs.end(), externalFuncs[caseNdx%externalFuncs.size()].function);
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				groups->addChild(new GroupFilterCase(m_context, name.c_str(), "Debug Group usage", funcs));
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* const	async				= new tcu::TestCaseGroup(m_testCtx, "async", "Asynchronous message generation");
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					errorFuncsPerCase	= 2;
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					maxAsyncCaseCount	= 16;
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int					caseCount			= (int(allFuncs.size()) + errorFuncsPerCase-1) / errorFuncsPerCase;
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			addChild(async);
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int caseNdx = 0; caseNdx < caseCount && caseNdx < maxAsyncCaseCount; caseNdx++)
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			start		= caseNdx*errorFuncsPerCase;
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int			end			= de::min((caseNdx+1)*errorFuncsPerCase, int(allFuncs.size()));
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string		name		= ("case_" + de::toString(caseNdx)).c_str();
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vector<TestFunc>	funcs		(&allFuncs[0]+start, &allFuncs[0]+end);
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (caseNdx&0x1)
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					async->addChild(new AsyncCase(m_context, (name+"_callback").c_str(), "Async message generation", funcs, true));
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					async->addChild(new AsyncCase(m_context, (name+"_log").c_str(), "Async message generation", funcs, false));
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup* const labels = new tcu::TestCaseGroup(m_testCtx, "object_labels", "Labeling objects");
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			GLenum		identifier;
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*	name;
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* desc;
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} cases[] =
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_BUFFER,				"buffer",				"Debug label on a buffer object"				},
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_SHADER,				"shader",				"Debug label on a shader object"				},
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_PROGRAM,				"program",				"Debug label on a program object"				},
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_QUERY,					"query",				"Debug label on a query object"					},
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_PROGRAM_PIPELINE,		"program_pipeline",		"Debug label on a program pipeline object"		},
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_TRANSFORM_FEEDBACK,	"transform_feedback",	"Debug label on a transform feedback object"	},
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_SAMPLER,				"sampler",				"Debug label on a sampler object"				},
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_TEXTURE,				"texture",				"Debug label on a texture object"				},
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_RENDERBUFFER,			"renderbuffer",			"Debug label on a renderbuffer object"			},
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ GL_FRAMEBUFFER,			"framebuffer",			"Debug label on a framebuffer object"			},
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(labels);
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			labels->addChild(new LabelCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].identifier));
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1896