Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Boolean State Query tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fBooleanStateQueryTests.hpp"
     25 #include "glsStateQueryUtil.hpp"
     26 #include "es3fApiCase.hpp"
     27 #include "gluRenderContext.hpp"
     28 #include "tcuRenderTarget.hpp"
     29 #include "glwEnums.hpp"
     30 
     31 using namespace glw; // GLint and other GL types
     32 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
     33 
     34 namespace deqp
     35 {
     36 namespace gles3
     37 {
     38 namespace Functional
     39 {
     40 namespace BooleanStateQueryVerifiers
     41 {
     42 
     43 // StateVerifier
     44 
     45 class StateVerifier : protected glu::CallLogWrapper
     46 {
     47 public:
     48 						StateVerifier					(const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix);
     49 	virtual				~StateVerifier					(); // make GCC happy
     50 
     51 	const char*			getTestNamePostfix				(void)																																													const;
     52 
     53 	virtual void		verifyBoolean					(tcu::TestContext& testCtx, GLenum name, bool reference)																																		= DE_NULL;
     54 	virtual void		verifyBoolean4					(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)																					= DE_NULL;
     55 private:
     56 	const char*	const	m_testNamePostfix;
     57 };
     58 
     59 StateVerifier::StateVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix)
     60 	: glu::CallLogWrapper	(gl, log)
     61 	, m_testNamePostfix		(testNamePostfix)
     62 {
     63 	enableLogging(true);
     64 }
     65 
     66 StateVerifier::~StateVerifier ()
     67 {
     68 }
     69 
     70 const char* StateVerifier::getTestNamePostfix (void) const
     71 {
     72 	return m_testNamePostfix;
     73 }
     74 
     75 // IsEnabledVerifier
     76 
     77 class IsEnabledVerifier : public StateVerifier
     78 {
     79 public:
     80 			IsEnabledVerifier			(const glw::Functions& gl, tcu::TestLog& log);
     81 	void	verifyBoolean					(tcu::TestContext& testCtx, GLenum name, bool reference);
     82 	void	verifyBoolean4					(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3);
     83 };
     84 
     85 IsEnabledVerifier::IsEnabledVerifier (const glw::Functions& gl, tcu::TestLog& log)
     86 	: StateVerifier(gl, log, "_isenabled")
     87 {
     88 }
     89 
     90 void IsEnabledVerifier::verifyBoolean (tcu::TestContext& testCtx, GLenum name, bool reference)
     91 {
     92 	using tcu::TestLog;
     93 
     94 	const GLboolean state = glIsEnabled(name);
     95 	const GLboolean expectedGLState = reference ? (GLboolean)GL_TRUE : (GLboolean)GL_FALSE;
     96 
     97 	if (state != expectedGLState)
     98 	{
     99 		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (reference ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage;
    100 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    101 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    102 	}
    103 }
    104 
    105 void IsEnabledVerifier::verifyBoolean4 (tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)
    106 {
    107 	DE_UNREF(testCtx);
    108 	DE_UNREF(name);
    109 	DE_UNREF(reference0);
    110 	DE_UNREF(reference1);
    111 	DE_UNREF(reference2);
    112 	DE_UNREF(reference3);
    113 	DE_ASSERT(false && "not supported");
    114 }
    115 
    116 // GetBooleanVerifier
    117 
    118 class GetBooleanVerifier : public StateVerifier
    119 {
    120 public:
    121 			GetBooleanVerifier		(const glw::Functions& gl, tcu::TestLog& log);
    122 	void	verifyBoolean					(tcu::TestContext& testCtx, GLenum name, bool reference);
    123 	void	verifyBoolean4					(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3);
    124 };
    125 
    126 GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log)
    127 	: StateVerifier(gl, log, "_getboolean")
    128 {
    129 }
    130 
    131 void GetBooleanVerifier::verifyBoolean (tcu::TestContext& testCtx, GLenum name, bool reference)
    132 {
    133 	using tcu::TestLog;
    134 
    135 	StateQueryMemoryWriteGuard<GLboolean> state;
    136 	glGetBooleanv(name, &state);
    137 
    138 	if (!state.verifyValidity(testCtx))
    139 		return;
    140 
    141 	const GLboolean expectedGLState = reference ? GL_TRUE : GL_FALSE;
    142 
    143 	if (state != expectedGLState)
    144 	{
    145 		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << (reference ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage;
    146 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    147 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    148 	}
    149 }
    150 
    151 void GetBooleanVerifier::verifyBoolean4 (tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)
    152 {
    153 	using tcu::TestLog;
    154 
    155 	StateQueryMemoryWriteGuard<GLboolean[4]> boolVector4;
    156 	glGetBooleanv(name, boolVector4);
    157 
    158 	if (!boolVector4.verifyValidity(testCtx))
    159 		return;
    160 
    161 	const GLboolean referenceAsGLBoolean[] =
    162 	{
    163 		reference0 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    164 		reference1 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    165 		reference2 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    166 		reference3 ? GLboolean(GL_TRUE) : GLboolean(GL_FALSE),
    167 	};
    168 
    169 	if (boolVector4[0] != referenceAsGLBoolean[0] ||
    170 		boolVector4[1] != referenceAsGLBoolean[1] ||
    171 		boolVector4[2] != referenceAsGLBoolean[2] ||
    172 		boolVector4[3] != referenceAsGLBoolean[3])
    173 	{
    174 		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
    175 			<< (referenceAsGLBoolean[0] ? "GL_TRUE" : "GL_FALSE") << " "
    176 			<< (referenceAsGLBoolean[1] ? "GL_TRUE" : "GL_FALSE") << " "
    177 			<< (referenceAsGLBoolean[2] ? "GL_TRUE" : "GL_FALSE") << " "
    178 			<< (referenceAsGLBoolean[3] ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage;
    179 
    180 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    181 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    182 	}
    183 }
    184 
    185 //GetIntegerVerifier
    186 
    187 class GetIntegerVerifier : public StateVerifier
    188 {
    189 public:
    190 			GetIntegerVerifier		(const glw::Functions& gl, tcu::TestLog& log);
    191 	void	verifyBoolean					(tcu::TestContext& testCtx, GLenum name, bool reference);
    192 	void	verifyBoolean4					(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3);
    193 
    194 };
    195 
    196 GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log)
    197 	: StateVerifier(gl, log, "_getinteger")
    198 {
    199 }
    200 
    201 void GetIntegerVerifier::verifyBoolean (tcu::TestContext& testCtx, GLenum name, bool reference)
    202 {
    203 	using tcu::TestLog;
    204 
    205 	StateQueryMemoryWriteGuard<GLint> state;
    206 	glGetIntegerv(name, &state);
    207 
    208 	if (!state.verifyValidity(testCtx))
    209 		return;
    210 
    211 	const GLint expectedGLState = reference ? 1 : 0;
    212 
    213 	if (state != expectedGLState)
    214 	{
    215 		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << expectedGLState << TestLog::EndMessage;
    216 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    217 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    218 	}
    219 }
    220 
    221 void GetIntegerVerifier::verifyBoolean4 (tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)
    222 {
    223 	using tcu::TestLog;
    224 
    225 	StateQueryMemoryWriteGuard<GLint[4]> boolVector4;
    226 	glGetIntegerv(name, boolVector4);
    227 
    228 	if (!boolVector4.verifyValidity(testCtx))
    229 		return;
    230 
    231 	const GLint referenceAsGLint[] =
    232 	{
    233 		reference0 ? 1 : 0,
    234 		reference1 ? 1 : 0,
    235 		reference2 ? 1 : 0,
    236 		reference3 ? 1 : 0,
    237 	};
    238 
    239 	if (boolVector4[0] != referenceAsGLint[0] ||
    240 		boolVector4[1] != referenceAsGLint[1] ||
    241 		boolVector4[2] != referenceAsGLint[2] ||
    242 		boolVector4[3] != referenceAsGLint[3])
    243 	{
    244 		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
    245 			<< referenceAsGLint[0] << " "
    246 			<< referenceAsGLint[1] << " "
    247 			<< referenceAsGLint[2] << " "
    248 			<< referenceAsGLint[3] << " " << TestLog::EndMessage;
    249 
    250 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    251 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    252 	}
    253 }
    254 
    255 //GetInteger64Verifier
    256 
    257 class GetInteger64Verifier : public StateVerifier
    258 {
    259 public:
    260 			GetInteger64Verifier		(const glw::Functions& gl, tcu::TestLog& log);
    261 	void	verifyBoolean					(tcu::TestContext& testCtx, GLenum name, bool reference);
    262 	void	verifyBoolean4					(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3);
    263 };
    264 
    265 GetInteger64Verifier::GetInteger64Verifier (const glw::Functions& gl, tcu::TestLog& log)
    266 	: StateVerifier(gl, log, "_getinteger64")
    267 {
    268 }
    269 
    270 void GetInteger64Verifier::verifyBoolean (tcu::TestContext& testCtx, GLenum name, bool reference)
    271 {
    272 	using tcu::TestLog;
    273 
    274 	StateQueryMemoryWriteGuard<GLint64> state;
    275 	glGetInteger64v(name, &state);
    276 
    277 	if (!state.verifyValidity(testCtx))
    278 		return;
    279 
    280 	const GLint64 expectedGLState = reference ? 1 : 0;
    281 
    282 	if (state != expectedGLState)
    283 	{
    284 		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << expectedGLState << TestLog::EndMessage;
    285 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    286 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    287 	}
    288 }
    289 
    290 void GetInteger64Verifier::verifyBoolean4 (tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)
    291 {
    292 	using tcu::TestLog;
    293 
    294 	StateQueryMemoryWriteGuard<GLint64[4]> boolVector4;
    295 	glGetInteger64v(name, boolVector4);
    296 
    297 	if (!boolVector4.verifyValidity(testCtx))
    298 		return;
    299 
    300 	const GLint64 referenceAsGLint64[] =
    301 	{
    302 		reference0 ? 1 : 0,
    303 		reference1 ? 1 : 0,
    304 		reference2 ? 1 : 0,
    305 		reference3 ? 1 : 0,
    306 	};
    307 
    308 	if (boolVector4[0] != referenceAsGLint64[0] ||
    309 		boolVector4[1] != referenceAsGLint64[1] ||
    310 		boolVector4[2] != referenceAsGLint64[2] ||
    311 		boolVector4[3] != referenceAsGLint64[3])
    312 	{
    313 		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
    314 			<< referenceAsGLint64[0] << " "
    315 			<< referenceAsGLint64[1] << " "
    316 			<< referenceAsGLint64[2] << " "
    317 			<< referenceAsGLint64[3] << " " << TestLog::EndMessage;
    318 
    319 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    320 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    321 	}
    322 }
    323 
    324 //GetFloatVerifier
    325 
    326 class GetFloatVerifier : public StateVerifier
    327 {
    328 public:
    329 			GetFloatVerifier			(const glw::Functions& gl, tcu::TestLog& log);
    330 	void	verifyBoolean					(tcu::TestContext& testCtx, GLenum name, bool reference);
    331 	void	verifyBoolean4					(tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3);
    332 };
    333 
    334 GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log)
    335 	: StateVerifier(gl, log, "_getfloat")
    336 {
    337 }
    338 
    339 void GetFloatVerifier::verifyBoolean (tcu::TestContext& testCtx, GLenum name, bool reference)
    340 {
    341 	using tcu::TestLog;
    342 
    343 	StateQueryMemoryWriteGuard<GLfloat> state;
    344 	glGetFloatv(name, &state);
    345 
    346 	if (!state.verifyValidity(testCtx))
    347 		return;
    348 
    349 	const GLfloat expectedGLState = reference ? 1.0f : 0.0f;
    350 
    351 	if (state != expectedGLState)
    352 	{
    353 		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << expectedGLState << "; got " << state << TestLog::EndMessage;
    354 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    355 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
    356 	}
    357 }
    358 
    359 void GetFloatVerifier::verifyBoolean4 (tcu::TestContext& testCtx, GLenum name, bool reference0, bool reference1, bool reference2, bool reference3)
    360 {
    361 	using tcu::TestLog;
    362 
    363 	StateQueryMemoryWriteGuard<GLfloat[4]> boolVector4;
    364 	glGetFloatv(name, boolVector4);
    365 
    366 	if (!boolVector4.verifyValidity(testCtx))
    367 		return;
    368 
    369 	const GLfloat referenceAsGLfloat[] =
    370 	{
    371 		reference0 ? 1.0f : 0.0f,
    372 		reference1 ? 1.0f : 0.0f,
    373 		reference2 ? 1.0f : 0.0f,
    374 		reference3 ? 1.0f : 0.0f,
    375 	};
    376 
    377 	if (boolVector4[0] != referenceAsGLfloat[0] ||
    378 		boolVector4[1] != referenceAsGLfloat[1] ||
    379 		boolVector4[2] != referenceAsGLfloat[2] ||
    380 		boolVector4[3] != referenceAsGLfloat[3])
    381 	{
    382 		testCtx.getLog() << TestLog::Message << "// ERROR: expected "
    383 			<< referenceAsGLfloat[0] << " "
    384 			<< referenceAsGLfloat[1] << " "
    385 			<< referenceAsGLfloat[2] << " "
    386 			<< referenceAsGLfloat[3] << " " << TestLog::EndMessage;
    387 
    388 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
    389 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
    390 	}
    391 }
    392 
    393 } // BooleanStateQueryVerifiers
    394 
    395 namespace
    396 {
    397 
    398 using namespace BooleanStateQueryVerifiers;
    399 
    400 static const char* transformFeedbackTestVertSource	=	"#version 300 es\n"
    401 														"void main (void)\n"
    402 														"{\n"
    403 														"	gl_Position = vec4(0.0);\n"
    404 														"}\n\0";
    405 static const char* transformFeedbackTestFragSource	=	"#version 300 es\n"
    406 														"layout(location = 0) out mediump vec4 fragColor;"
    407 														"void main (void)\n"
    408 														"{\n"
    409 														"	fragColor = vec4(0.0);\n"
    410 														"}\n\0";
    411 
    412 class IsEnabledStateTestCase : public ApiCase
    413 {
    414 public:
    415 	IsEnabledStateTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum targetName, bool initial)
    416 		: ApiCase		(context, name, description)
    417 		, m_targetName	(targetName)
    418 		, m_initial		(initial)
    419 		, m_verifier	(verifier)
    420 	{
    421 	}
    422 
    423 	void test (void)
    424 	{
    425 		// check inital value
    426 		m_verifier->verifyBoolean(m_testCtx, m_targetName, m_initial);
    427 		expectError(GL_NO_ERROR);
    428 
    429 		// check toggle
    430 
    431 		glEnable(m_targetName);
    432 		expectError(GL_NO_ERROR);
    433 
    434 		m_verifier->verifyBoolean(m_testCtx, m_targetName, true);
    435 		expectError(GL_NO_ERROR);
    436 
    437 		glDisable(m_targetName);
    438 		expectError(GL_NO_ERROR);
    439 
    440 		m_verifier->verifyBoolean(m_testCtx, m_targetName, false);
    441 		expectError(GL_NO_ERROR);
    442 	}
    443 
    444 private:
    445 	GLenum			m_targetName;
    446 	bool			m_initial;
    447 	StateVerifier*	m_verifier;
    448 };
    449 
    450 class DepthWriteMaskTestCase : public ApiCase
    451 {
    452 public:
    453 	DepthWriteMaskTestCase	(Context& context, StateVerifier* verifier, const char* name, const char* description)
    454 		: ApiCase		(context, name, description)
    455 		, m_verifier	(verifier)
    456 	{
    457 	}
    458 
    459 	void test (void)
    460 	{
    461 		m_verifier->verifyBoolean(m_testCtx, GL_DEPTH_WRITEMASK, true);
    462 		expectError(GL_NO_ERROR);
    463 
    464 		glDepthMask(GL_FALSE);
    465 		m_verifier->verifyBoolean(m_testCtx, GL_DEPTH_WRITEMASK, false);
    466 		expectError(GL_NO_ERROR);
    467 
    468 		glDepthMask(GL_TRUE);
    469 		m_verifier->verifyBoolean(m_testCtx, GL_DEPTH_WRITEMASK, true);
    470 		expectError(GL_NO_ERROR);
    471 	}
    472 private:
    473 	StateVerifier*	m_verifier;
    474 };
    475 
    476 class SampleCoverageInvertTestCase : public ApiCase
    477 {
    478 public:
    479 	SampleCoverageInvertTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
    480 		: ApiCase		(context, name, description)
    481 		, m_verifier	(verifier)
    482 	{
    483 	}
    484 
    485 	void test (void)
    486 	{
    487 		m_verifier->verifyBoolean(m_testCtx, GL_SAMPLE_COVERAGE_INVERT, false);
    488 		expectError(GL_NO_ERROR);
    489 
    490 		glSampleCoverage(1.0f, GL_TRUE);
    491 		m_verifier->verifyBoolean(m_testCtx, GL_SAMPLE_COVERAGE_INVERT, true);
    492 		expectError(GL_NO_ERROR);
    493 
    494 		glSampleCoverage(1.0f, GL_FALSE);
    495 		m_verifier->verifyBoolean(m_testCtx, GL_SAMPLE_COVERAGE_INVERT, false);
    496 		expectError(GL_NO_ERROR);
    497 	}
    498 private:
    499 	StateVerifier*	m_verifier;
    500 };
    501 
    502 class InitialBooleanTestCase : public ApiCase
    503 {
    504 public:
    505 	InitialBooleanTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description, GLenum target, bool reference)
    506 		: ApiCase		(context, name, description)
    507 		, m_target		(target)
    508 		, m_reference	(reference)
    509 		, m_verifier	(verifier)
    510 	{
    511 	}
    512 
    513 	void test (void)
    514 	{
    515 		m_verifier->verifyBoolean(m_testCtx, m_target, m_reference);
    516 		expectError(GL_NO_ERROR);
    517 	}
    518 
    519 private:
    520 	GLenum			m_target;
    521 	bool			m_reference;
    522 	StateVerifier*	m_verifier;
    523 };
    524 
    525 class ColorMaskTestCase : public ApiCase
    526 {
    527 public:
    528 	ColorMaskTestCase	(Context& context, StateVerifier* verifier, const char* name, const char* description)
    529 		: ApiCase(context, name, description)
    530 		, m_verifier	(verifier)
    531 	{
    532 	}
    533 	void test (void)
    534 	{
    535 		m_verifier->verifyBoolean4(m_testCtx, GL_COLOR_WRITEMASK, true, true, true, true);
    536 		expectError(GL_NO_ERROR);
    537 
    538 		const struct ColorMask
    539 		{
    540 			GLboolean r, g, b, a;
    541 		} testMasks[] =
    542 		{
    543 			{ GL_TRUE,	GL_TRUE,	GL_TRUE,	GL_TRUE  },
    544 			{ GL_TRUE,	GL_TRUE,	GL_TRUE,	GL_FALSE },
    545 			{ GL_TRUE,	GL_TRUE,	GL_FALSE,	GL_TRUE  },
    546 			{ GL_TRUE,	GL_TRUE,	GL_FALSE,	GL_FALSE },
    547 			{ GL_TRUE,	GL_FALSE,	GL_TRUE,	GL_TRUE  },
    548 			{ GL_TRUE,	GL_FALSE,	GL_TRUE,	GL_FALSE },
    549 			{ GL_TRUE,	GL_FALSE,	GL_FALSE,	GL_TRUE  },
    550 			{ GL_TRUE,	GL_FALSE,	GL_FALSE,	GL_FALSE },
    551 			{ GL_FALSE,	GL_TRUE,	GL_TRUE,	GL_TRUE  },
    552 			{ GL_FALSE,	GL_TRUE,	GL_TRUE,	GL_FALSE },
    553 			{ GL_FALSE,	GL_TRUE,	GL_FALSE,	GL_TRUE  },
    554 			{ GL_FALSE,	GL_TRUE,	GL_FALSE,	GL_FALSE },
    555 			{ GL_FALSE,	GL_FALSE,	GL_TRUE,	GL_TRUE  },
    556 			{ GL_FALSE,	GL_FALSE,	GL_TRUE,	GL_FALSE },
    557 			{ GL_FALSE,	GL_FALSE,	GL_FALSE,	GL_TRUE  },
    558 			{ GL_FALSE,	GL_FALSE,	GL_FALSE,	GL_FALSE },
    559 		};
    560 
    561 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testMasks); ndx++)
    562 		{
    563 			glColorMask(testMasks[ndx].r, testMasks[ndx].g, testMasks[ndx].b, testMasks[ndx].a);
    564 			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);
    565 			expectError(GL_NO_ERROR);
    566 		}
    567 	}
    568 private:
    569 	StateVerifier*	m_verifier;
    570 };
    571 
    572 
    573 class TransformFeedbackTestCase : public ApiCase
    574 {
    575 public:
    576 	TransformFeedbackTestCase (Context& context, StateVerifier* verifier, const char* name, const char* description)
    577 		: ApiCase				(context, name, description)
    578 		, m_verifier			(verifier)
    579 		, m_transformfeedback	(0)
    580 	{
    581 	}
    582 
    583 	void test (void)
    584 	{
    585 		glGenTransformFeedbacks(1, &m_transformfeedback);
    586 		expectError(GL_NO_ERROR);
    587 
    588 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
    589 		glShaderSource(shaderVert, 1, &transformFeedbackTestVertSource, DE_NULL);
    590 		glCompileShader(shaderVert);
    591 		expectError(GL_NO_ERROR);
    592 		GLint compileStatus;
    593 		glGetShaderiv(shaderVert, GL_COMPILE_STATUS, &compileStatus);
    594 		checkBooleans(compileStatus, GL_TRUE);
    595 
    596 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
    597 		glShaderSource(shaderFrag, 1, &transformFeedbackTestFragSource, DE_NULL);
    598 		glCompileShader(shaderFrag);
    599 		expectError(GL_NO_ERROR);
    600 		glGetShaderiv(shaderFrag, GL_COMPILE_STATUS, &compileStatus);
    601 		checkBooleans(compileStatus, GL_TRUE);
    602 
    603 		GLuint shaderProg = glCreateProgram();
    604 		glAttachShader(shaderProg, shaderVert);
    605 		glAttachShader(shaderProg, shaderFrag);
    606 		const char* transform_feedback_outputs = "gl_Position";
    607 		glTransformFeedbackVaryings(shaderProg, 1, &transform_feedback_outputs, GL_INTERLEAVED_ATTRIBS);
    608 		glLinkProgram(shaderProg);
    609 		expectError(GL_NO_ERROR);
    610 		GLint linkStatus;
    611 		glGetProgramiv(shaderProg, GL_LINK_STATUS, &linkStatus);
    612 		checkBooleans(linkStatus, GL_TRUE);
    613 
    614 		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_transformfeedback);
    615 		expectError(GL_NO_ERROR);
    616 
    617 		GLuint feedbackBufferId;
    618 		glGenBuffers(1, &feedbackBufferId);
    619 		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBufferId);
    620 		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ);
    621 		glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, feedbackBufferId);
    622 		expectError(GL_NO_ERROR);
    623 
    624 		glUseProgram(shaderProg);
    625 
    626 		testTransformFeedback();
    627 
    628 		glUseProgram(0);
    629 		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
    630 		glDeleteTransformFeedbacks(1, &m_transformfeedback);
    631 		glDeleteBuffers(1, &feedbackBufferId);
    632 		glDeleteShader(shaderVert);
    633 		glDeleteShader(shaderFrag);
    634 		glDeleteProgram(shaderProg);
    635 		expectError(GL_NO_ERROR);
    636 	}
    637 
    638 	virtual void testTransformFeedback (void) = DE_NULL;
    639 
    640 protected:
    641 	StateVerifier*	m_verifier;
    642 	GLuint			m_transformfeedback;
    643 };
    644 
    645 class TransformFeedbackBasicTestCase : public TransformFeedbackTestCase
    646 {
    647 public:
    648 	TransformFeedbackBasicTestCase (Context& context, StateVerifier* verifier, const char* name)
    649 		: TransformFeedbackTestCase	(context, verifier, name, "Test TRANSFORM_FEEDBACK_ACTIVE and TRANSFORM_FEEDBACK_PAUSED")
    650 	{
    651 	}
    652 
    653 	void testTransformFeedback (void)
    654 	{
    655 		glBeginTransformFeedback(GL_POINTS);
    656 		expectError(GL_NO_ERROR);
    657 
    658 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_ACTIVE, true);
    659 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_PAUSED, false);
    660 		expectError(GL_NO_ERROR);
    661 
    662 		glPauseTransformFeedback();
    663 		expectError(GL_NO_ERROR);
    664 
    665 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_ACTIVE, true);
    666 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_PAUSED, true);
    667 		expectError(GL_NO_ERROR);
    668 
    669 		glResumeTransformFeedback();
    670 		expectError(GL_NO_ERROR);
    671 
    672 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_ACTIVE, true);
    673 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_PAUSED, false);
    674 		expectError(GL_NO_ERROR);
    675 
    676 		glEndTransformFeedback();
    677 		expectError(GL_NO_ERROR);
    678 
    679 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_ACTIVE, false);
    680 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_PAUSED, false);
    681 		expectError(GL_NO_ERROR);
    682 	}
    683 };
    684 
    685 class TransformFeedbackImplicitResumeTestCase : public TransformFeedbackTestCase
    686 {
    687 public:
    688 	TransformFeedbackImplicitResumeTestCase (Context& context, StateVerifier* verifier, const char* name)
    689 		: TransformFeedbackTestCase(context, verifier, name, "EndTransformFeedback performs an implicit ResumeTransformFeedback.")
    690 	{
    691 	}
    692 
    693 	void testTransformFeedback (void)
    694 	{
    695 		glBeginTransformFeedback(GL_POINTS);
    696 		expectError(GL_NO_ERROR);
    697 
    698 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_ACTIVE, true);
    699 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_PAUSED, false);
    700 		expectError(GL_NO_ERROR);
    701 
    702 		glPauseTransformFeedback();
    703 		expectError(GL_NO_ERROR);
    704 
    705 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_ACTIVE, true);
    706 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_PAUSED, true);
    707 		expectError(GL_NO_ERROR);
    708 
    709 		glEndTransformFeedback();
    710 		expectError(GL_NO_ERROR);
    711 
    712 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_ACTIVE, false);
    713 		m_verifier->verifyBoolean(m_testCtx, GL_TRANSFORM_FEEDBACK_PAUSED, false);
    714 		expectError(GL_NO_ERROR);
    715 	}
    716 };
    717 
    718 #define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK)												\
    719 	for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++)	\
    720 	{																							\
    721 		StateVerifier* verifier = VERIFIERS[_verifierNdx];										\
    722 		CODE_BLOCK;																				\
    723 	}
    724 
    725 } // anonymous
    726 
    727 BooleanStateQueryTests::BooleanStateQueryTests (Context& context)
    728 	: TestCaseGroup				(context, "boolean", "Boolean State Query tests")
    729 	, m_verifierIsEnabled		(DE_NULL)
    730 	, m_verifierBoolean			(DE_NULL)
    731 	, m_verifierInteger			(DE_NULL)
    732 	, m_verifierInteger64		(DE_NULL)
    733 	, m_verifierFloat			(DE_NULL)
    734 {
    735 }
    736 
    737 BooleanStateQueryTests::~BooleanStateQueryTests (void)
    738 {
    739 	deinit();
    740 }
    741 
    742 void BooleanStateQueryTests::init (void)
    743 {
    744 	DE_ASSERT(m_verifierIsEnabled == DE_NULL);
    745 	DE_ASSERT(m_verifierBoolean == DE_NULL);
    746 	DE_ASSERT(m_verifierInteger == DE_NULL);
    747 	DE_ASSERT(m_verifierInteger64 == DE_NULL);
    748 	DE_ASSERT(m_verifierFloat == DE_NULL);
    749 
    750 	m_verifierIsEnabled		= new IsEnabledVerifier		(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
    751 	m_verifierBoolean		= new GetBooleanVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
    752 	m_verifierInteger		= new GetIntegerVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
    753 	m_verifierInteger64		= new GetInteger64Verifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
    754 	m_verifierFloat			= new GetFloatVerifier		(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
    755 
    756 	StateVerifier* isEnabledVerifiers[] = {m_verifierIsEnabled, m_verifierBoolean, m_verifierInteger, m_verifierInteger64, m_verifierFloat};
    757 	StateVerifier* normalVerifiers[] = {m_verifierBoolean, m_verifierInteger, m_verifierInteger64, m_verifierFloat};
    758 
    759 	struct StateBoolean
    760 	{
    761 		const char*		name;
    762 		const char*		description;
    763 		GLenum			targetName;
    764 		bool			value;
    765 	};
    766 	const StateBoolean isEnableds[] =
    767 	{
    768 		{ "primitive_restart_fixed_index",	"PRIMITIVE_RESTART_FIXED_INDEX",	GL_PRIMITIVE_RESTART_FIXED_INDEX,	false},
    769 		{ "rasterizer_discard",				"RASTERIZER_DISCARD",				GL_RASTERIZER_DISCARD,				false},
    770 		{ "cull_face",						"CULL_FACE",						GL_CULL_FACE,						false},
    771 		{ "polygon_offset_fill",			"POLYGON_OFFSET_FILL",				GL_POLYGON_OFFSET_FILL,				false},
    772 		{ "sample_alpha_to_coverage",		"SAMPLE_ALPHA_TO_COVERAGE",			GL_SAMPLE_ALPHA_TO_COVERAGE,		false},
    773 		{ "sample_coverage",				"SAMPLE_COVERAGE",					GL_SAMPLE_COVERAGE,					false},
    774 		{ "scissor_test",					"SCISSOR_TEST",						GL_SCISSOR_TEST,					false},
    775 		{ "stencil_test",					"STENCIL_TEST",						GL_STENCIL_TEST,					false},
    776 		{ "depth_test",						"DEPTH_TEST",						GL_DEPTH_TEST,						false},
    777 		{ "blend",							"BLEND",							GL_BLEND,							false},
    778 		{ "dither",							"DITHER",							GL_DITHER,							true },
    779 	};
    780 	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(isEnableds); testNdx++)
    781 	{
    782 		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)));
    783 	}
    784 
    785 	FOR_EACH_VERIFIER(normalVerifiers, addChild(new ColorMaskTestCase							(m_context, verifier, (std::string("color_writemask")						+ verifier->getTestNamePostfix()).c_str(), "COLOR_WRITEMASK")));
    786 	FOR_EACH_VERIFIER(normalVerifiers, addChild(new DepthWriteMaskTestCase						(m_context, verifier, (std::string("depth_writemask")						+ verifier->getTestNamePostfix()).c_str(), "DEPTH_WRITEMASK")));
    787 	FOR_EACH_VERIFIER(normalVerifiers, addChild(new SampleCoverageInvertTestCase				(m_context, verifier, (std::string("sample_coverage_invert")				+ verifier->getTestNamePostfix()).c_str(), "SAMPLE_COVERAGE_INVERT")));
    788 	FOR_EACH_VERIFIER(normalVerifiers, addChild(new InitialBooleanTestCase						(m_context, verifier, (std::string("shader_compiler")						+ verifier->getTestNamePostfix()).c_str(), "SHADER_COMPILER",						GL_SHADER_COMPILER, true)));
    789 	FOR_EACH_VERIFIER(normalVerifiers, addChild(new InitialBooleanTestCase						(m_context, verifier, (std::string("transform_feedback_active_initial")		+ verifier->getTestNamePostfix()).c_str(), "initial TRANSFORM_FEEDBACK_ACTIVE",		GL_TRANSFORM_FEEDBACK_ACTIVE, false)));
    790 	FOR_EACH_VERIFIER(normalVerifiers, addChild(new InitialBooleanTestCase						(m_context, verifier, (std::string("transform_feedback_paused_initial")		+ verifier->getTestNamePostfix()).c_str(), "initial TRANSFORM_FEEDBACK_PAUSED",		GL_TRANSFORM_FEEDBACK_PAUSED, false)));
    791 	FOR_EACH_VERIFIER(normalVerifiers, addChild(new TransformFeedbackBasicTestCase				(m_context, verifier, (std::string("transform_feedback")					+ verifier->getTestNamePostfix()).c_str())));
    792 	FOR_EACH_VERIFIER(normalVerifiers, addChild(new TransformFeedbackImplicitResumeTestCase		(m_context, verifier, (std::string("transform_feedback_implicit_resume")	+ verifier->getTestNamePostfix()).c_str())));
    793 }
    794 
    795 void BooleanStateQueryTests::deinit (void)
    796 {
    797 	if (m_verifierIsEnabled)
    798 	{
    799 		delete m_verifierIsEnabled;
    800 		m_verifierIsEnabled = DE_NULL;
    801 	}
    802 	if (m_verifierBoolean)
    803 	{
    804 		delete m_verifierBoolean;
    805 		m_verifierBoolean = DE_NULL;
    806 	}
    807 	if (m_verifierInteger)
    808 	{
    809 		delete m_verifierInteger;
    810 		m_verifierInteger = DE_NULL;
    811 	}
    812 	if (m_verifierInteger64)
    813 	{
    814 		delete m_verifierInteger64;
    815 		m_verifierInteger64 = DE_NULL;
    816 	}
    817 	if (m_verifierFloat)
    818 	{
    819 		delete m_verifierFloat;
    820 		m_verifierFloat = DE_NULL;
    821 	}
    822 
    823 	this->TestCaseGroup::deinit();
    824 }
    825 
    826 } // Functional
    827 } // gles3
    828 } // deqp
    829