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
31using namespace glw; // GLint and other GL types
32using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
33
34namespace deqp
35{
36namespace gles3
37{
38namespace Functional
39{
40namespace BooleanStateQueryVerifiers
41{
42
43// StateVerifier
44
45class StateVerifier : protected glu::CallLogWrapper
46{
47public:
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;
55private:
56	const char*	const	m_testNamePostfix;
57};
58
59StateVerifier::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
66StateVerifier::~StateVerifier ()
67{
68}
69
70const char* StateVerifier::getTestNamePostfix (void) const
71{
72	return m_testNamePostfix;
73}
74
75// IsEnabledVerifier
76
77class IsEnabledVerifier : public StateVerifier
78{
79public:
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
85IsEnabledVerifier::IsEnabledVerifier (const glw::Functions& gl, tcu::TestLog& log)
86	: StateVerifier(gl, log, "_isenabled")
87{
88}
89
90void 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
105void 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
118class GetBooleanVerifier : public StateVerifier
119{
120public:
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
126GetBooleanVerifier::GetBooleanVerifier (const glw::Functions& gl, tcu::TestLog& log)
127	: StateVerifier(gl, log, "_getboolean")
128{
129}
130
131void 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
151void 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
187class GetIntegerVerifier : public StateVerifier
188{
189public:
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
196GetIntegerVerifier::GetIntegerVerifier (const glw::Functions& gl, tcu::TestLog& log)
197	: StateVerifier(gl, log, "_getinteger")
198{
199}
200
201void 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
221void 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
257class GetInteger64Verifier : public StateVerifier
258{
259public:
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
265GetInteger64Verifier::GetInteger64Verifier (const glw::Functions& gl, tcu::TestLog& log)
266	: StateVerifier(gl, log, "_getinteger64")
267{
268}
269
270void 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
290void 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
326class GetFloatVerifier : public StateVerifier
327{
328public:
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
334GetFloatVerifier::GetFloatVerifier (const glw::Functions& gl, tcu::TestLog& log)
335	: StateVerifier(gl, log, "_getfloat")
336{
337}
338
339void 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
359void 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
395namespace
396{
397
398using namespace BooleanStateQueryVerifiers;
399
400static const char* transformFeedbackTestVertSource	=	"#version 300 es\n"
401														"void main (void)\n"
402														"{\n"
403														"	gl_Position = vec4(0.0);\n"
404														"}\n\0";
405static 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
412class IsEnabledStateTestCase : public ApiCase
413{
414public:
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
444private:
445	GLenum			m_targetName;
446	bool			m_initial;
447	StateVerifier*	m_verifier;
448};
449
450class DepthWriteMaskTestCase : public ApiCase
451{
452public:
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	}
472private:
473	StateVerifier*	m_verifier;
474};
475
476class SampleCoverageInvertTestCase : public ApiCase
477{
478public:
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	}
498private:
499	StateVerifier*	m_verifier;
500};
501
502class InitialBooleanTestCase : public ApiCase
503{
504public:
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
519private:
520	GLenum			m_target;
521	bool			m_reference;
522	StateVerifier*	m_verifier;
523};
524
525class ColorMaskTestCase : public ApiCase
526{
527public:
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	}
568private:
569	StateVerifier*	m_verifier;
570};
571
572
573class TransformFeedbackTestCase : public ApiCase
574{
575public:
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
640protected:
641	StateVerifier*	m_verifier;
642	GLuint			m_transformfeedback;
643};
644
645class TransformFeedbackBasicTestCase : public TransformFeedbackTestCase
646{
647public:
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
685class TransformFeedbackImplicitResumeTestCase : public TransformFeedbackTestCase
686{
687public:
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
727BooleanStateQueryTests::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
737BooleanStateQueryTests::~BooleanStateQueryTests (void)
738{
739	deinit();
740}
741
742void 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
795void 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