/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Boolean State Query tests.
 *//*--------------------------------------------------------------------*/

#include "es2fBooleanStateQueryTests.hpp"
#include "es2fApiCase.hpp"
#include "glsStateQueryUtil.hpp"
#include "gluRenderContext.hpp"
#include "tcuRenderTarget.hpp"
#include "glwEnums.hpp"

using namespace glw; // GLint and other GL types
using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;

namespace deqp
{
namespace gles2
{
namespace Functional
{
namespace BooleanStateQueryVerifiers
{

// StateVerifier

class StateVerifier : protected glu::CallLogWrapper
{
public:
						StateVerifier					(const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix);
	virtual				~StateVerifier					(); // make GCC happy

	const char*			getTestNamePostfix				(void) const;

	virtual void		verifyBoolean					(tcu::TestContext& testCtx, GLenum name, bool reference)														= DE_NULL;
	virtual void		verifyBoolean4					(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)	= DE_NULL;
	virtual void		verifyBooleanAnything			(tcu::TestContext& testCtx, GLenum name)																		= DE_NULL;
private:
	const char*	const	m_testNamePostfix;
};

StateVerifier::StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix)
	: glu::CallLogWrapper	(gl, log)
	, m_testNamePostfix		(testNamePostfix)
{
	enableLogging(true);
}

StateVerifier::~StateVerifier ()
{
}

const char* StateVerifier::getTestNamePostfix (void) const
{
	return m_testNamePostfix;
}

// IsEnabledVerifier

class IsEnabledVerifier : public StateVerifier
{
public:
			IsEnabledVerifier		(const glw::Functions& gl, tcu::TestLog& log);
	void	verifyBoolean			(tcu::TestContext& testCtx, GLenum name, bool reference);
	void	verifyBoolean4			(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3);
	void	verifyBooleanAnything	(tcu::TestContext& testCtx, GLenum name);
};

IsEnabledVerifier::IsEnabledVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: StateVerifier(gl, log, "_isenabled")
{
}

void IsEnabledVerifier::verifyBoolean (tcu::TestContext& testCtx, GLenum name, bool reference)
{
	using tcu::TestLog;

	const GLboolean state = glIsEnabled(name);
	const GLboolean expectedGLState = reference ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE;

	if (state != expectedGLState)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (reference ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
	}
}

void IsEnabledVerifier::verifyBoolean4 (tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)
{
	DE_UNREF(testCtx);
	DE_UNREF(name);
	DE_UNREF(reference0);
	DE_UNREF(reference1);
	DE_UNREF(reference2);
	DE_UNREF(reference3);
	DE_ASSERT(false && "not supported");
}

void IsEnabledVerifier::verifyBooleanAnything (tcu::TestContext& testCtx, GLenum name)
{
	DE_UNREF(testCtx);
	DE_UNREF(name);
	DE_ASSERT(false && "not supported");
}
// GetBooleanVerifier

class GetBooleanVerifier : public StateVerifier
{
public:
			GetBooleanVerifier		(const glw::Functions& gl, tcu::TestLog& log);
	void	verifyBoolean			(tcu::TestContext& testCtx, GLenum name, bool reference);
	void	verifyBoolean4			(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3);
	void	verifyBooleanAnything	(tcu::TestContext& testCtx, GLenum name);
};

GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: StateVerifier(gl, log, "_getboolean")
{
}

void GetBooleanVerifier::verifyBoolean (tcu::TestContext& testCtx, GLenum name, bool reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLboolean> state;
	glGetBooleanv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	const GLboolean expectedGLState = reference ? GL_TRUE : GL_FALSE;

	if (state != expectedGLState)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (reference ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
	}
}

void GetBooleanVerifier::verifyBoolean4 (tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLboolean[4]> boolVector4;
	glGetBooleanv(name, boolVector4);

	if (!boolVector4.verifyValidity(testCtx))
		return;

	const GLboolean referenceAsGLBoolean[] =
	{
		reference0 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
		reference1 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
		reference2 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
		reference3 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
	};

	if (boolVector4[0] != referenceAsGLBoolean[0] ||
		boolVector4[1] != referenceAsGLBoolean[1] ||
		boolVector4[2] != referenceAsGLBoolean[2] ||
		boolVector4[3] != referenceAsGLBoolean[3])
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
			<< (referenceAsGLBoolean[0] ? "GL_TRUE" : "GL_FALSE") << " "
			<< (referenceAsGLBoolean[1] ? "GL_TRUE" : "GL_FALSE") << " "
			<< (referenceAsGLBoolean[2] ? "GL_TRUE" : "GL_FALSE") << " "
			<< (referenceAsGLBoolean[3] ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
	}
}

void GetBooleanVerifier::verifyBooleanAnything (tcu::TestContext& testCtx, GLenum name)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLboolean> state;
	glGetBooleanv(name, &state);

	state.verifyValidity(testCtx);
}

//GetIntegerVerifier

class GetIntegerVerifier : public StateVerifier
{
public:
			GetIntegerVerifier		(const glw::Functions& gl, tcu::TestLog& log);
	void	verifyBoolean			(tcu::TestContext& testCtx, GLenum name, bool reference);
	void	verifyBoolean4			(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3);
	void	verifyBooleanAnything	(tcu::TestContext& testCtx, GLenum name);

};

GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: StateVerifier(gl, log, "_getinteger")
{
}

void GetIntegerVerifier::verifyBoolean (tcu::TestContext& testCtx, GLenum name, bool reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint> state;
	glGetIntegerv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	const GLint expectedGLState = reference ? 1 : 0;

	if (state != expectedGLState)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << expectedGLState << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetIntegerVerifier::verifyBoolean4 (tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint[4]> boolVector4;
	glGetIntegerv(name, boolVector4);

	if (!boolVector4.verifyValidity(testCtx))
		return;

	const GLint referenceAsGLint[] =
	{
		reference0 ? 1 : 0,
		reference1 ? 1 : 0,
		reference2 ? 1 : 0,
		reference3 ? 1 : 0,
	};

	if (boolVector4[0] != referenceAsGLint[0] ||
		boolVector4[1] != referenceAsGLint[1] ||
		boolVector4[2] != referenceAsGLint[2] ||
		boolVector4[3] != referenceAsGLint[3])
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
			<< referenceAsGLint[0] << " "
			<< referenceAsGLint[1] << " "
			<< referenceAsGLint[2] << " "
			<< referenceAsGLint[3] << " " << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
	}
}

void GetIntegerVerifier::verifyBooleanAnything (tcu::TestContext& testCtx, GLenum name)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint> state;
	glGetIntegerv(name, &state);

	state.verifyValidity(testCtx);
}

//GetFloatVerifier

class GetFloatVerifier : public StateVerifier
{
public:
			GetFloatVerifier		(const glw::Functions& gl, tcu::TestLog& log);
	void	verifyBoolean			(tcu::TestContext& testCtx, GLenum name, bool reference);
	void	verifyBoolean4			(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3);
	void	verifyBooleanAnything	(tcu::TestContext& testCtx, GLenum name);
};

GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: StateVerifier(gl, log, "_getfloat")
{
}

void GetFloatVerifier::verifyBoolean (tcu::TestContext& testCtx, GLenum name, bool reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat> state;
	glGetFloatv(name, &state);

	if (!state.verifyValidity(testCtx))
		return;

	const GLfloat expectedGLState = reference ? 1.0f : 0.0f;

	if (state != expectedGLState)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << expectedGLState << "; got " << state << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
	}
}

void GetFloatVerifier::verifyBoolean4 (tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat[4]> boolVector4;
	glGetFloatv(name, boolVector4);

	if (!boolVector4.verifyValidity(testCtx))
		return;

	const GLfloat referenceAsGLfloat[] =
	{
		reference0 ? 1.0f : 0.0f,
		reference1 ? 1.0f : 0.0f,
		reference2 ? 1.0f : 0.0f,
		reference3 ? 1.0f : 0.0f,
	};

	if (boolVector4[0] != referenceAsGLfloat[0] ||
		boolVector4[1] != referenceAsGLfloat[1] ||
		boolVector4[2] != referenceAsGLfloat[2] ||
		boolVector4[3] != referenceAsGLfloat[3])
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
			<< referenceAsGLfloat[0] << " "
			<< referenceAsGLfloat[1] << " "
			<< referenceAsGLfloat[2] << " "
			<< referenceAsGLfloat[3] << " " << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
	}
}

void GetFloatVerifier::verifyBooleanAnything (tcu::TestContext& testCtx, GLenum name)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLfloat> state;
	glGetFloatv(name, &state);

	state.verifyValidity(testCtx);
}

} // BooleanStateQueryVerifiers

namespace
{

using namespace BooleanStateQueryVerifiers;

class IsEnabledStateTestCase : public ApiCase
{
public:
	IsEnabledStateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName, bool initial)
		: ApiCase		(context, name, description)
		, m_targetName	(targetName)
		, m_initial		(initial)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		// check inital value
		m_verifier->verifyBoolean(m_testCtx, m_targetName, m_initial);
		expectError(GL_NO_ERROR);

		// check toggle

		glEnable(m_targetName);
		expectError(GL_NO_ERROR);

		m_verifier->verifyBoolean(m_testCtx, m_targetName, true);
		expectError(GL_NO_ERROR);

		glDisable(m_targetName);
		expectError(GL_NO_ERROR);

		m_verifier->verifyBoolean(m_testCtx, m_targetName, false);
		expectError(GL_NO_ERROR);
	}

private:
	GLenum			m_targetName;
	bool			m_initial;
	StateVerifier*	m_verifier;
};

class DepthWriteMaskTestCase : public ApiCase
{
public:
	DepthWriteMaskTestCase	(Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		m_verifier->verifyBoolean(m_testCtx, GL_DEPTH_WRITEMASK, true);
		expectError(GL_NO_ERROR);

		glDepthMask(GL_FALSE);
		m_verifier->verifyBoolean(m_testCtx, GL_DEPTH_WRITEMASK, false);
		expectError(GL_NO_ERROR);

		glDepthMask(GL_TRUE);
		m_verifier->verifyBoolean(m_testCtx, GL_DEPTH_WRITEMASK, true);
		expectError(GL_NO_ERROR);
	}
private:
	StateVerifier*	m_verifier;
};

class SampleCoverageInvertTestCase : public ApiCase
{
public:
	SampleCoverageInvertTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		m_verifier->verifyBoolean(m_testCtx, GL_SAMPLE_COVERAGE_INVERT, false);
		expectError(GL_NO_ERROR);

		glSampleCoverage(1.0f, GL_TRUE);
		m_verifier->verifyBoolean(m_testCtx, GL_SAMPLE_COVERAGE_INVERT, true);
		expectError(GL_NO_ERROR);

		glSampleCoverage(1.0f, GL_FALSE);
		m_verifier->verifyBoolean(m_testCtx, GL_SAMPLE_COVERAGE_INVERT, false);
		expectError(GL_NO_ERROR);
	}
private:
	StateVerifier*	m_verifier;
};

class ShaderCompilerTestCase : public ApiCase
{
public:
	ShaderCompilerTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase		(context, name, description)
		, m_verifier	(verifier)
	{
	}

	void test (void)
	{
		m_verifier->verifyBooleanAnything(m_testCtx, GL_SHADER_COMPILER);
		expectError(GL_NO_ERROR);
	}

private:
	StateVerifier*	m_verifier;
};

class ColorMaskTestCase : public ApiCase
{
public:
	ColorMaskTestCase	(Context& context, StateVerifier* verifier, const char* name, const char* description)
		: ApiCase(context, name, description)
		, m_verifier	(verifier)
	{
	}
	void test (void)
	{
		m_verifier->verifyBoolean4(m_testCtx, GL_COLOR_WRITEMASK, true, true, true, true);
		expectError(GL_NO_ERROR);

		const struct ColorMask
		{
			GLboolean r, g, b, a;
		} testMasks[] =
		{
			{ GL_TRUE,	GL_TRUE,	GL_TRUE,	GL_TRUE  },
			{ GL_TRUE,	GL_TRUE,	GL_TRUE,	GL_FALSE },
			{ GL_TRUE,	GL_TRUE,	GL_FALSE,	GL_TRUE  },
			{ GL_TRUE,	GL_TRUE,	GL_FALSE,	GL_FALSE },
			{ GL_TRUE,	GL_FALSE,	GL_TRUE,	GL_TRUE  },
			{ GL_TRUE,	GL_FALSE,	GL_TRUE,	GL_FALSE },
			{ GL_TRUE,	GL_FALSE,	GL_FALSE,	GL_TRUE  },
			{ GL_TRUE,	GL_FALSE,	GL_FALSE,	GL_FALSE },
			{ GL_FALSE,	GL_TRUE,	GL_TRUE,	GL_TRUE  },
			{ GL_FALSE,	GL_TRUE,	GL_TRUE,	GL_FALSE },
			{ GL_FALSE,	GL_TRUE,	GL_FALSE,	GL_TRUE  },
			{ GL_FALSE,	GL_TRUE,	GL_FALSE,	GL_FALSE },
			{ GL_FALSE,	GL_FALSE,	GL_TRUE,	GL_TRUE  },
			{ GL_FALSE,	GL_FALSE,	GL_TRUE,	GL_FALSE },
			{ GL_FALSE,	GL_FALSE,	GL_FALSE,	GL_TRUE  },
			{ GL_FALSE,	GL_FALSE,	GL_FALSE,	GL_FALSE },
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testMasks); ndx++)
		{
			glColorMask(testMasks[ndx].r, testMasks[ndx].g, testMasks[ndx].b, testMasks[ndx].a);
			m_verifier->verifyBoolean4(m_testCtx, GL_COLOR_WRITEMASK, testMasks[ndx].r==GL_TRUE, testMasks[ndx].g==GL_TRUE, testMasks[ndx].b==GL_TRUE, testMasks[ndx].a==GL_TRUE);
			expectError(GL_NO_ERROR);
		}
	}
private:
	StateVerifier*	m_verifier;
};

#define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK)												\
	for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++)	\
	{																							\
		StateVerifier* verifier = (VERIFIERS)[_verifierNdx];									\
		CODE_BLOCK;																				\
	}

} // anonymous

BooleanStateQueryTests::BooleanStateQueryTests (Context& context)
	: TestCaseGroup				(context, "boolean", "Boolean State Query tests")
	, m_verifierIsEnabled		(DE_NULL)
	, m_verifierBoolean			(DE_NULL)
	, m_verifierInteger			(DE_NULL)
	, m_verifierFloat			(DE_NULL)
{
}

BooleanStateQueryTests::~BooleanStateQueryTests (void)
{
	deinit();
}

void BooleanStateQueryTests::init (void)
{
	DE_ASSERT(m_verifierIsEnabled == DE_NULL);
	DE_ASSERT(m_verifierBoolean == DE_NULL);
	DE_ASSERT(m_verifierInteger == DE_NULL);
	DE_ASSERT(m_verifierFloat == DE_NULL);

	m_verifierIsEnabled		= new IsEnabledVerifier		(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	m_verifierBoolean		= new GetBooleanVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	m_verifierInteger		= new GetIntegerVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	m_verifierFloat			= new GetFloatVerifier		(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());

	StateVerifier* isEnabledVerifiers[] = {m_verifierIsEnabled, m_verifierBoolean, m_verifierInteger, m_verifierFloat};
	StateVerifier* normalVerifiers[]	= {						m_verifierBoolean, m_verifierInteger, m_verifierFloat};

	struct StateBoolean
	{
		const char*		name;
		const char*		description;
		GLenum			targetName;
		bool			value;
	};
	const StateBoolean isEnableds[] =
	{
		{ "cull_face",						"CULL_FACE",						GL_CULL_FACE,						false},
		{ "polygon_offset_fill",			"POLYGON_OFFSET_FILL",				GL_POLYGON_OFFSET_FILL,				false},
		{ "sample_alpha_to_coverage",		"SAMPLE_ALPHA_TO_COVERAGE",			GL_SAMPLE_ALPHA_TO_COVERAGE,		false},
		{ "sample_coverage",				"SAMPLE_COVERAGE",					GL_SAMPLE_COVERAGE,					false},
		{ "scissor_test",					"SCISSOR_TEST",						GL_SCISSOR_TEST,					false},
		{ "stencil_test",					"STENCIL_TEST",						GL_STENCIL_TEST,					false},
		{ "depth_test",						"DEPTH_TEST",						GL_DEPTH_TEST,						false},
		{ "blend",							"BLEND",							GL_BLEND,							false},
		{ "dither",							"DITHER",							GL_DITHER,							true },
	};
	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(isEnableds); testNdx++)
		FOR_EACH_VERIFIER(isEnabledVerifiers, addChild(new IsEnabledStateTestCase(m_context, verifier, (std::string(isEnableds[testNdx].name) + verifier->getTestNamePostfix()).c_str(), isEnableds[testNdx].description, isEnableds[testNdx].targetName, isEnableds[testNdx].value)));

	FOR_EACH_VERIFIER(normalVerifiers, addChild(new SampleCoverageInvertTestCase				(m_context, verifier, (std::string("sample_coverage_invert")				+ verifier->getTestNamePostfix()).c_str(), "SAMPLE_COVERAGE_INVERT")));
	FOR_EACH_VERIFIER(normalVerifiers, addChild(new ColorMaskTestCase							(m_context, verifier, (std::string("color_writemask")						+ verifier->getTestNamePostfix()).c_str(), "COLOR_WRITEMASK")));
	FOR_EACH_VERIFIER(normalVerifiers, addChild(new DepthWriteMaskTestCase						(m_context, verifier, (std::string("depth_writemask")						+ verifier->getTestNamePostfix()).c_str(), "DEPTH_WRITEMASK")));
	FOR_EACH_VERIFIER(normalVerifiers, addChild(new ShaderCompilerTestCase						(m_context, verifier, (std::string("shader_compiler")						+ verifier->getTestNamePostfix()).c_str(), "SHADER_COMPILER")));
}

void BooleanStateQueryTests::deinit (void)
{
	if (m_verifierIsEnabled)
	{
		delete m_verifierIsEnabled;
		m_verifierIsEnabled = DE_NULL;
	}
	if (m_verifierBoolean)
	{
		delete m_verifierBoolean;
		m_verifierBoolean = DE_NULL;
	}
	if (m_verifierInteger)
	{
		delete m_verifierInteger;
		m_verifierInteger = DE_NULL;
	}
	if (m_verifierFloat)
	{
		delete m_verifierFloat;
		m_verifierFloat = DE_NULL;
	}

	this->TestCaseGroup::deinit();
}

} // Functional
} // gles2
} // deqp
