• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Indexed State Query tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fIndexedStateQueryTests.hpp"
25 #include "es3fApiCase.hpp"
26 #include "glsStateQueryUtil.hpp"
27 #include "tcuRenderTarget.hpp"
28 #include "tcuTestLog.hpp"
29 #include "glwEnums.hpp"
30 #include "gluRenderContext.hpp"
31 #include "gluCallLogWrapper.hpp"
32 #include "gluContextInfo.hpp"
33 #include "deRandom.hpp"
34 
35 namespace deqp
36 {
37 namespace gles3
38 {
39 namespace Functional
40 {
41 namespace
42 {
43 
44 using namespace glw; // GLint and other GL types
45 using namespace gls::StateQueryUtil;
46 
checkIntEquals(tcu::TestContext & testCtx,GLint got,GLint expected)47 void checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected)
48 {
49 	using tcu::TestLog;
50 
51 	if (got != expected)
52 	{
53 		testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
54 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
55 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
56 	}
57 }
58 
checkIntEquals(tcu::TestContext & testCtx,GLint64 got,GLint64 expected)59 void checkIntEquals (tcu::TestContext& testCtx, GLint64 got, GLint64 expected)
60 {
61 	using tcu::TestLog;
62 
63 	if (got != expected)
64 	{
65 		testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
66 		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
67 			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
68 	}
69 }
70 
71 class TransformFeedbackCase : public ApiCase
72 {
73 public:
TransformFeedbackCase(Context & context,const char * name,const char * description)74 	TransformFeedbackCase (Context& context, const char* name, const char* description)
75 		: ApiCase(context, name, description)
76 	{
77 	}
78 
79 	virtual void testTransformFeedback (void) = DE_NULL;
80 
test(void)81 	void test (void)
82 	{
83 		static const char* transformFeedbackTestVertSource	=	"#version 300 es\n"
84 																"out highp vec4 anotherOutput;\n"
85 																"void main (void)\n"
86 																"{\n"
87 																"	gl_Position = vec4(0.0);\n"
88 																"	anotherOutput = vec4(0.0);\n"
89 																"}\n\0";
90 		static const char* transformFeedbackTestFragSource	=	"#version 300 es\n"
91 																"layout(location = 0) out mediump vec4 fragColor;"
92 																"void main (void)\n"
93 																"{\n"
94 																"	fragColor = vec4(0.0);\n"
95 																"}\n\0";
96 
97 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
98 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
99 
100 		glShaderSource(shaderVert, 1, &transformFeedbackTestVertSource, DE_NULL);
101 		glShaderSource(shaderFrag, 1, &transformFeedbackTestFragSource, DE_NULL);
102 
103 		glCompileShader(shaderVert);
104 		glCompileShader(shaderFrag);
105 		expectError(GL_NO_ERROR);
106 
107 		GLuint shaderProg = glCreateProgram();
108 		glAttachShader(shaderProg, shaderVert);
109 		glAttachShader(shaderProg, shaderFrag);
110 
111 		const char* transformFeedbackOutputs[] =
112 		{
113 			"gl_Position",
114 			"anotherOutput"
115 		};
116 
117 		glTransformFeedbackVaryings(shaderProg, 2, transformFeedbackOutputs, GL_INTERLEAVED_ATTRIBS);
118 		glLinkProgram(shaderProg);
119 		expectError(GL_NO_ERROR);
120 
121 		glGenTransformFeedbacks(2, transformFeedbacks);
122 		// Also store the default transform feedback in the array.
123 		transformFeedbacks[2] = 0;
124 		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[0]);
125 		expectError(GL_NO_ERROR);
126 
127 		testTransformFeedback();
128 
129 		// cleanup
130 
131 		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
132 
133 		glDeleteTransformFeedbacks(2, transformFeedbacks);
134 		glDeleteShader(shaderVert);
135 		glDeleteShader(shaderFrag);
136 		glDeleteProgram(shaderProg);
137 		expectError(GL_NO_ERROR);
138 	}
139 protected:
140 	GLuint transformFeedbacks[3];
141 };
142 
143 class TransformFeedbackBufferBindingCase : public TransformFeedbackCase
144 {
145 public:
TransformFeedbackBufferBindingCase(Context & context,const char * name,const char * description)146 	TransformFeedbackBufferBindingCase (Context& context, const char* name, const char* description)
147 		: TransformFeedbackCase(context, name, description)
148 	{
149 	}
150 
testTransformFeedback(void)151 	void testTransformFeedback (void)
152 	{
153 		const int feedbackPositionIndex = 0;
154 		const int feedbackOutputIndex = 1;
155 		const int feedbackIndex[2] = {feedbackPositionIndex, feedbackOutputIndex};
156 
157 		// bind bffers
158 
159 		GLuint feedbackBuffers[2];
160 		glGenBuffers(2, feedbackBuffers);
161 		expectError(GL_NO_ERROR);
162 
163 		for (int ndx = 0; ndx < 2; ++ndx)
164 		{
165 			glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[ndx]);
166 			glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ);
167 			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackIndex[ndx], feedbackBuffers[ndx]);
168 			expectError(GL_NO_ERROR);
169 		}
170 
171 		// test TRANSFORM_FEEDBACK_BUFFER_BINDING
172 
173 		for (int ndx = 0; ndx < 2; ++ndx)
174 		{
175 			StateQueryMemoryWriteGuard<GLint> boundBuffer;
176 			glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, feedbackIndex[ndx], &boundBuffer);
177 			boundBuffer.verifyValidity(m_testCtx);
178 			checkIntEquals(m_testCtx, boundBuffer, feedbackBuffers[ndx]);
179 		}
180 
181 
182 		// cleanup
183 
184 		glDeleteBuffers(2, feedbackBuffers);
185 	}
186 };
187 
188 class TransformFeedbackBufferBufferCase : public TransformFeedbackCase
189 {
190 public:
TransformFeedbackBufferBufferCase(Context & context,const char * name,const char * description)191 	TransformFeedbackBufferBufferCase (Context& context, const char* name, const char* description)
192 		: TransformFeedbackCase(context, name, description)
193 	{
194 	}
195 
testTransformFeedback(void)196 	void testTransformFeedback (void)
197 	{
198 		const int feedbackPositionIndex = 0;
199 		const int feedbackOutputIndex = 1;
200 
201 		const int rangeBufferOffset = 4;
202 		const int rangeBufferSize = 8;
203 
204 		// bind buffers
205 
206 		GLuint feedbackBuffers[2];
207 		glGenBuffers(2, feedbackBuffers);
208 		expectError(GL_NO_ERROR);
209 
210 		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[0]);
211 		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ);
212 		glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackPositionIndex, feedbackBuffers[0]);
213 		expectError(GL_NO_ERROR);
214 
215 		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[1]);
216 		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ);
217 		glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackOutputIndex, feedbackBuffers[1], rangeBufferOffset, rangeBufferSize);
218 		expectError(GL_NO_ERROR);
219 
220 		// test TRANSFORM_FEEDBACK_BUFFER_START and TRANSFORM_FEEDBACK_BUFFER_SIZE
221 
222 		const struct BufferRequirements
223 		{
224 			GLint	index;
225 			GLenum	pname;
226 			GLint64 value;
227 		} requirements[] =
228 		{
229 			{ feedbackPositionIndex,	GL_TRANSFORM_FEEDBACK_BUFFER_START, 0					},
230 			{ feedbackPositionIndex,	GL_TRANSFORM_FEEDBACK_BUFFER_SIZE,	0					},
231 			{ feedbackOutputIndex,		GL_TRANSFORM_FEEDBACK_BUFFER_START, rangeBufferOffset	},
232 			{ feedbackOutputIndex,		GL_TRANSFORM_FEEDBACK_BUFFER_SIZE,	rangeBufferSize		}
233 		};
234 
235 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requirements); ++ndx)
236 		{
237 			StateQueryMemoryWriteGuard<GLint64> state;
238 			glGetInteger64i_v(requirements[ndx].pname, requirements[ndx].index, &state);
239 
240 			if (state.verifyValidity(m_testCtx))
241 				checkIntEquals(m_testCtx, state, requirements[ndx].value);
242 		}
243 
244 		// cleanup
245 
246 		glDeleteBuffers(2, feedbackBuffers);
247 	}
248 };
249 
250 class TransformFeedbackSwitchingBufferCase : public TransformFeedbackCase
251 {
252 public:
TransformFeedbackSwitchingBufferCase(Context & context,const char * name,const char * description)253 	TransformFeedbackSwitchingBufferCase (Context& context, const char* name, const char* description)
254 		: TransformFeedbackCase(context, name, description)
255 	{
256 	}
257 
testTransformFeedback(void)258 	void testTransformFeedback (void)
259 	{
260 		GLuint feedbackBuffers[3];
261 		glGenBuffers(3, feedbackBuffers);
262 		expectError(GL_NO_ERROR);
263 
264 		for (int i = 0; i < 3; ++i)
265 		{
266 			glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[i]);
267 			expectError(GL_NO_ERROR);
268 			GLint value;
269 			glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &value);
270 			expectError(GL_NO_ERROR);
271 			checkIntEquals(m_testCtx, value, 0);
272 			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, feedbackBuffers[i]);
273 			expectError(GL_NO_ERROR);
274 			// glBindBufferBase should also set the generic binding point.
275 			glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &value);
276 			expectError(GL_NO_ERROR);
277 			checkIntEquals(m_testCtx, value, feedbackBuffers[i]);
278 		}
279 
280 		for (int i = 0; i < 3; ++i)
281 		{
282 			// glBindTransformFeedback should change the indexed binding points, but
283 			// not the generic one.
284 			glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[i]);
285 			expectError(GL_NO_ERROR);
286 			GLint value;
287 			glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &value);
288 			expectError(GL_NO_ERROR);
289 			checkIntEquals(m_testCtx, value, feedbackBuffers[i]);
290 			glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &value);
291 			expectError(GL_NO_ERROR);
292 			// Should be unchanged.
293 			checkIntEquals(m_testCtx, value, feedbackBuffers[2]);
294 		}
295 
296 		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[0]);
297 		expectError(GL_NO_ERROR);
298 		glDeleteBuffers(3, feedbackBuffers);
299 		expectError(GL_NO_ERROR);
300 
301 		// After deleting buffers the bound state should be changed but unbound
302 		// state should be unchanged.
303 
304 		GLint value;
305 		glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &value);
306 		expectError(GL_NO_ERROR);
307 		checkIntEquals(m_testCtx, value, 0);
308 		glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &value);
309 		expectError(GL_NO_ERROR);
310 		checkIntEquals(m_testCtx, value, 0);
311 
312 		for (int i = 1; i < 3; ++i)
313 		{
314 			glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[i]);
315 			expectError(GL_NO_ERROR);
316 			glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &value);
317 			expectError(GL_NO_ERROR);
318 			checkIntEquals(m_testCtx, value, feedbackBuffers[i]);
319 			glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &value);
320 			expectError(GL_NO_ERROR);
321 			checkIntEquals(m_testCtx, value, 0);
322 		}
323 	}
324 };
325 
326 class UniformBufferCase : public ApiCase
327 {
328 public:
UniformBufferCase(Context & context,const char * name,const char * description)329 	UniformBufferCase (Context& context, const char* name, const char* description)
330 		: ApiCase	(context, name, description)
331 		, m_program	(0)
332 	{
333 	}
334 
335 	virtual void testUniformBuffers (void) = DE_NULL;
336 
test(void)337 	void test (void)
338 	{
339 		static const char* testVertSource	=	"#version 300 es\n"
340 												"uniform highp vec4 input1;\n"
341 												"uniform highp vec4 input2;\n"
342 												"void main (void)\n"
343 												"{\n"
344 												"	gl_Position = input1 + input2;\n"
345 												"}\n\0";
346 		static const char* testFragSource	=	"#version 300 es\n"
347 												"layout(location = 0) out mediump vec4 fragColor;"
348 												"void main (void)\n"
349 												"{\n"
350 												"	fragColor = vec4(0.0);\n"
351 												"}\n\0";
352 
353 		GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
354 		GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
355 
356 		glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
357 		glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
358 
359 		glCompileShader(shaderVert);
360 		glCompileShader(shaderFrag);
361 		expectError(GL_NO_ERROR);
362 
363 		m_program = glCreateProgram();
364 		glAttachShader(m_program, shaderVert);
365 		glAttachShader(m_program, shaderFrag);
366 		glLinkProgram(m_program);
367 		glUseProgram(m_program);
368 		expectError(GL_NO_ERROR);
369 
370 		testUniformBuffers();
371 
372 		glUseProgram(0);
373 		glDeleteShader(shaderVert);
374 		glDeleteShader(shaderFrag);
375 		glDeleteProgram(m_program);
376 		expectError(GL_NO_ERROR);
377 	}
378 
379 protected:
380 	GLuint	m_program;
381 };
382 
383 class UniformBufferBindingCase : public UniformBufferCase
384 {
385 public:
UniformBufferBindingCase(Context & context,const char * name,const char * description)386 	UniformBufferBindingCase (Context& context, const char* name, const char* description)
387 		: UniformBufferCase(context, name, description)
388 	{
389 	}
390 
testUniformBuffers(void)391 	void testUniformBuffers (void)
392 	{
393 		const char* uniformNames[] =
394 		{
395 			"input1",
396 			"input2"
397 		};
398 		GLuint uniformIndices[2] = {0};
399 		glGetUniformIndices(m_program, 2, uniformNames, uniformIndices);
400 
401 		GLuint buffers[2];
402 		glGenBuffers(2, buffers);
403 
404 		for (int ndx = 0; ndx < 2; ++ndx)
405 		{
406 			glBindBuffer(GL_UNIFORM_BUFFER, buffers[ndx]);
407 			glBufferData(GL_UNIFORM_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
408 			glBindBufferBase(GL_UNIFORM_BUFFER, uniformIndices[ndx], buffers[ndx]);
409 			expectError(GL_NO_ERROR);
410 		}
411 
412 		for (int ndx = 0; ndx < 2; ++ndx)
413 		{
414 			StateQueryMemoryWriteGuard<GLint> boundBuffer;
415 			glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, uniformIndices[ndx], &boundBuffer);
416 
417 			if (boundBuffer.verifyValidity(m_testCtx))
418 				checkIntEquals(m_testCtx, boundBuffer, buffers[ndx]);
419 			expectError(GL_NO_ERROR);
420 		}
421 
422 		glDeleteBuffers(2, buffers);
423 	}
424 };
425 
426 class UniformBufferBufferCase : public UniformBufferCase
427 {
428 public:
UniformBufferBufferCase(Context & context,const char * name,const char * description)429 	UniformBufferBufferCase (Context& context, const char* name, const char* description)
430 		: UniformBufferCase(context, name, description)
431 	{
432 	}
433 
testUniformBuffers(void)434 	void testUniformBuffers (void)
435 	{
436 		const char* uniformNames[] =
437 		{
438 			"input1",
439 			"input2"
440 		};
441 		GLuint uniformIndices[2] = {0};
442 		glGetUniformIndices(m_program, 2, uniformNames, uniformIndices);
443 
444 		const GLint alignment = GetAlignment();
445 		if (alignment == -1) // cannot continue without this
446 			return;
447 
448 		m_testCtx.getLog() << tcu::TestLog::Message << "Alignment is " << alignment << tcu::TestLog::EndMessage;
449 
450 		int rangeBufferOffset		= alignment;
451 		int rangeBufferSize			= alignment * 2;
452 		int rangeBufferTotalSize	= rangeBufferOffset + rangeBufferSize + 8; // + 8 has no special meaning, just to make it != with the size of the range
453 
454 		GLuint buffers[2];
455 		glGenBuffers(2, buffers);
456 
457 		glBindBuffer(GL_UNIFORM_BUFFER, buffers[0]);
458 		glBufferData(GL_UNIFORM_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
459 		glBindBufferBase(GL_UNIFORM_BUFFER, uniformIndices[0], buffers[0]);
460 		expectError(GL_NO_ERROR);
461 
462 		glBindBuffer(GL_UNIFORM_BUFFER, buffers[1]);
463 		glBufferData(GL_UNIFORM_BUFFER, rangeBufferTotalSize, DE_NULL, GL_DYNAMIC_DRAW);
464 		glBindBufferRange(GL_UNIFORM_BUFFER, uniformIndices[1], buffers[1], rangeBufferOffset, rangeBufferSize);
465 		expectError(GL_NO_ERROR);
466 
467 		// test UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE
468 
469 		const struct BufferRequirements
470 		{
471 			GLuint	index;
472 			GLenum	pname;
473 			GLint64 value;
474 		} requirements[] =
475 		{
476 			{ uniformIndices[0], GL_UNIFORM_BUFFER_START,	0					},
477 			{ uniformIndices[0], GL_UNIFORM_BUFFER_SIZE,	0					},
478 			{ uniformIndices[1], GL_UNIFORM_BUFFER_START,	rangeBufferOffset	},
479 			{ uniformIndices[1], GL_UNIFORM_BUFFER_SIZE,	rangeBufferSize		}
480 		};
481 
482 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requirements); ++ndx)
483 		{
484 			StateQueryMemoryWriteGuard<GLint64> state;
485 			glGetInteger64i_v(requirements[ndx].pname, requirements[ndx].index, &state);
486 
487 			if (state.verifyValidity(m_testCtx))
488 				checkIntEquals(m_testCtx, state, requirements[ndx].value);
489 			expectError(GL_NO_ERROR);
490 		}
491 
492 		glDeleteBuffers(2, buffers);
493 	}
494 
GetAlignment()495 	int GetAlignment()
496 	{
497 		StateQueryMemoryWriteGuard<GLint> state;
498 		glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &state);
499 
500 		if (!state.verifyValidity(m_testCtx))
501 			return -1;
502 
503 		if (state <= 256)
504 			return state;
505 
506 		m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: UNIFORM_BUFFER_OFFSET_ALIGNMENT has a maximum value of 256." << tcu::TestLog::EndMessage;
507 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid UNIFORM_BUFFER_OFFSET_ALIGNMENT value");
508 
509 		return -1;
510 	}
511 };
512 
getVerifierSuffix(QueryType type)513 const char* getVerifierSuffix (QueryType type)
514 {
515 	switch (type)
516 	{
517 		case QUERY_INDEXED_INTEGER:			return "getintegeri_v";
518 		case QUERY_INDEXED_INTEGER64:		return "getinteger64i_v";
519 		case QUERY_INDEXED_INTEGER_VEC4:	return "getintegeri_v";
520 		case QUERY_INDEXED_INTEGER64_VEC4:	return "getinteger64i_v";
521 		case QUERY_INDEXED_ISENABLED:		return "isenabledi";
522 		default:
523 			DE_ASSERT(DE_FALSE);
524 			return DE_NULL;
525 	}
526 }
527 
isExtensionSupported(Context & context,std::string extensionName)528 void isExtensionSupported (Context& context, std::string extensionName)
529 {
530 	if (contextSupports(context.getRenderContext().getType(), glu::ApiType::core(4, 5)))
531 		return;
532 
533 	if (extensionName == "GL_EXT_draw_buffers_indexed" || extensionName == "GL_KHR_blend_equation_advanced")
534 	{
535 		if (!contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !context.getContextInfo().isExtensionSupported(extensionName.c_str()))
536 			TCU_THROW(NotSupportedError, (std::string("Extension ") + extensionName + std::string(" not supported.")).c_str());
537 	}
538 	else if (!context.getContextInfo().isExtensionSupported(extensionName.c_str()))
539 		TCU_THROW(NotSupportedError, (std::string("Extension ") + extensionName + std::string(" not supported.")).c_str());
540 }
541 
542 class EnableBlendCase : public TestCase
543 {
544 public:
545 	EnableBlendCase	(Context& context, const char* name, const char* desc, QueryType verifierType);
546 
547 	void				init			(void);
548 private:
549 	IterateResult		iterate			(void);
550 
551 	const QueryType		m_verifierType;
552 };
553 
EnableBlendCase(Context & context,const char * name,const char * desc,QueryType verifierType)554 EnableBlendCase::EnableBlendCase (Context& context, const char* name, const char* desc, QueryType verifierType)
555 		: TestCase			(context, name, desc)
556 		, m_verifierType	(verifierType)
557 {
558 }
559 
init(void)560 void EnableBlendCase::init (void)
561 {
562 	isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed");
563 }
564 
iterate(void)565 EnableBlendCase::IterateResult EnableBlendCase::iterate (void)
566 {
567 	glu::CallLogWrapper		gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
568 	tcu::ResultCollector	result			(m_testCtx.getLog(), " // ERROR: ");
569 	deInt32					maxDrawBuffers = 0;
570 
571 	gl.enableLogging(true);
572 
573 	gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
574 	GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv");
575 
576 	{
577 		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value");
578 
579 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
580 			verifyStateIndexedBoolean(result, gl, GL_BLEND, ndx, false, m_verifierType);
581 	}
582 	{
583 		const tcu::ScopedLogSection	superSection	(m_testCtx.getLog(), "AfterSettingCommon", "After setting common");
584 
585 		gl.glEnable(GL_BLEND);
586 
587 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
588 			verifyStateIndexedBoolean(result, gl, GL_BLEND, ndx, true, m_verifierType);
589 
590 	}
591 	{
592 		const tcu::ScopedLogSection	superSection	(m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed");
593 
594 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
595 		{
596 			if (ndx % 2 == 0)
597 				gl.glEnablei(GL_BLEND, ndx);
598 			else
599 				gl.glDisablei(GL_BLEND, ndx);
600 		}
601 
602 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
603 			verifyStateIndexedBoolean(result, gl, GL_BLEND, ndx, (ndx % 2 == 0), m_verifierType);
604 	}
605 	{
606 		const tcu::ScopedLogSection	superSection	(m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common");
607 
608 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
609 		{
610 			if (ndx % 2 == 0)
611 				gl.glEnablei(GL_BLEND, ndx);
612 			else
613 				gl.glDisablei(GL_BLEND, ndx);
614 		}
615 
616 		gl.glEnable(GL_BLEND);
617 
618 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
619 			verifyStateIndexedBoolean(result, gl, GL_BLEND, ndx, true, m_verifierType);
620 	}
621 
622 	result.setTestContextResult(m_testCtx);
623 	return STOP;
624 }
625 
626 class ColorMaskCase : public TestCase
627 {
628 public:
629 	ColorMaskCase	(Context& context, const char* name, const char* desc, QueryType verifierType);
630 
631 	void				init			(void);
632 private:
633 	IterateResult		iterate			(void);
634 
635 	const QueryType		m_verifierType;
636 };
637 
ColorMaskCase(Context & context,const char * name,const char * desc,QueryType verifierType)638 ColorMaskCase::ColorMaskCase (Context& context, const char* name, const char* desc, QueryType verifierType)
639 		: TestCase			(context, name, desc)
640 		, m_verifierType	(verifierType)
641 {
642 }
643 
init(void)644 void ColorMaskCase::init (void)
645 {
646 	isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed");
647 }
648 
iterate(void)649 ColorMaskCase::IterateResult ColorMaskCase::iterate (void)
650 {
651 	glu::CallLogWrapper		gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
652 	tcu::ResultCollector	result			(m_testCtx.getLog(), " // ERROR: ");
653 	deInt32					maxDrawBuffers = 0;
654 
655 	gl.enableLogging(true);
656 
657 	gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
658 	GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv");
659 
660 	{
661 		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value");
662 
663 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
664 			verifyStateIndexedBooleanVec4(result, gl, GL_COLOR_WRITEMASK, ndx, tcu::BVec4(true), m_verifierType);
665 	}
666 	{
667 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingCommon", "After setting common");
668 
669 		gl.glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
670 
671 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
672 			verifyStateIndexedBooleanVec4(result, gl, GL_COLOR_WRITEMASK, ndx, tcu::BVec4(false, true, true, false), m_verifierType);
673 	}
674 	{
675 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed");
676 
677 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
678 			gl.glColorMaski(ndx, (ndx % 2 == 0 ? GL_TRUE : GL_FALSE), (ndx % 2 == 1 ? GL_TRUE : GL_FALSE), (ndx % 2 == 0 ? GL_TRUE : GL_FALSE), (ndx % 2 == 1 ? GL_TRUE : GL_FALSE));
679 
680 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
681 			verifyStateIndexedBooleanVec4(result, gl, GL_COLOR_WRITEMASK, ndx, (ndx % 2 == 0 ? tcu::BVec4(true, false, true, false) : tcu::BVec4(false, true, false, true)), m_verifierType);
682 	}
683 	{
684 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common");
685 
686 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
687 			gl.glColorMaski(ndx, (ndx % 2 == 0 ? GL_TRUE : GL_FALSE), (ndx % 2 == 1 ? GL_TRUE : GL_FALSE), (ndx % 2 == 0 ? GL_TRUE : GL_FALSE), (ndx % 2 == 1 ? GL_TRUE : GL_FALSE));
688 
689 		gl.glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
690 
691 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
692 			verifyStateIndexedBooleanVec4(result, gl, GL_COLOR_WRITEMASK, ndx, tcu::BVec4(false, true, true, false), m_verifierType);
693 	}
694 
695 	result.setTestContextResult(m_testCtx);
696 	return STOP;
697 }
698 
699 class BlendFuncCase : public TestCase
700 {
701 public:
702 	BlendFuncCase	(Context& context, const char* name, const char* desc, QueryType verifierType);
703 
704 	void				init			(void);
705 private:
706 	IterateResult		iterate			(void);
707 
708 	const QueryType		m_verifierType;
709 };
710 
BlendFuncCase(Context & context,const char * name,const char * desc,QueryType verifierType)711 BlendFuncCase::BlendFuncCase (Context& context, const char* name, const char* desc, QueryType verifierType)
712 		: TestCase			(context, name, desc)
713 		, m_verifierType	(verifierType)
714 {
715 }
716 
init(void)717 void BlendFuncCase::init (void)
718 {
719 	isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed");
720 }
721 
iterate(void)722 BlendFuncCase::IterateResult BlendFuncCase::iterate (void)
723 {
724 	const deUint32 blendFuncs[] =
725 			{
726 					GL_ZERO,
727 					GL_ONE,
728 					GL_SRC_COLOR,
729 					GL_ONE_MINUS_SRC_COLOR,
730 					GL_DST_COLOR,
731 					GL_ONE_MINUS_DST_COLOR,
732 					GL_SRC_ALPHA,
733 					GL_ONE_MINUS_SRC_ALPHA,
734 					GL_DST_ALPHA,
735 					GL_ONE_MINUS_DST_ALPHA,
736 					GL_CONSTANT_COLOR,
737 					GL_ONE_MINUS_CONSTANT_COLOR,
738 					GL_CONSTANT_ALPHA,
739 					GL_ONE_MINUS_CONSTANT_ALPHA,
740 					GL_SRC_ALPHA_SATURATE
741 			};
742 
743 	glu::CallLogWrapper		gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
744 	tcu::ResultCollector	result			(m_testCtx.getLog(), " // ERROR: ");
745 	deInt32					maxDrawBuffers = 0;
746 
747 	gl.enableLogging(true);
748 
749 	gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
750 	GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv");
751 
752 	{
753 		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value");
754 
755 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
756 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_ONE, m_verifierType);
757 
758 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
759 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_ZERO, m_verifierType);
760 
761 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
762 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_ONE, m_verifierType);
763 
764 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
765 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_ZERO, m_verifierType);
766 	}
767 	{
768 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingCommon", "After setting common");
769 
770 		gl.glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
771 
772 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
773 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_SRC_ALPHA, m_verifierType);
774 
775 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
776 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_DST_ALPHA, m_verifierType);
777 
778 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
779 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_SRC_ALPHA, m_verifierType);
780 
781 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
782 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_DST_ALPHA, m_verifierType);
783 	}
784 	{
785 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingCommonSeparate", "After setting common separate");
786 
787 		gl.glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR, GL_ONE_MINUS_DST_ALPHA);
788 
789 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
790 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_SRC_COLOR, m_verifierType);
791 
792 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
793 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_ONE_MINUS_SRC_ALPHA, m_verifierType);
794 
795 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
796 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_DST_COLOR, m_verifierType);
797 
798 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
799 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_ONE_MINUS_DST_ALPHA, m_verifierType);
800 	}
801 	{
802 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed");
803 
804 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
805 			gl.glBlendFunci(ndx, blendFuncs[ndx % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)]);
806 
807 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
808 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, blendFuncs[ndx % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType);
809 
810 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
811 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType);
812 
813 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
814 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, blendFuncs[ndx % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType);
815 
816 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
817 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType);
818 	}
819 	{
820 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingIndexedSeparate", "After setting indexed separate");
821 
822 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
823 			gl.glBlendFuncSeparatei(ndx, blendFuncs[(ndx + 3) % DE_LENGTH_OF_ARRAY(blendFuncs)],
824 									blendFuncs[(ndx + 2) % DE_LENGTH_OF_ARRAY(blendFuncs)],
825 									blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)],
826 									blendFuncs[(ndx + 0) % DE_LENGTH_OF_ARRAY(blendFuncs)]);
827 
828 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
829 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, blendFuncs[(ndx + 3) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType);
830 
831 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
832 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, blendFuncs[(ndx + 2) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType);
833 
834 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
835 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType);
836 
837 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
838 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, blendFuncs[(ndx + 0) % DE_LENGTH_OF_ARRAY(blendFuncs)], m_verifierType);
839 
840 	}
841 	{
842 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common");
843 
844 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
845 			gl.glBlendFunci(ndx, blendFuncs[ndx % DE_LENGTH_OF_ARRAY(blendFuncs)], blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)]);
846 
847 		gl.glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
848 
849 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
850 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_SRC_ALPHA, m_verifierType);
851 
852 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
853 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_DST_ALPHA, m_verifierType);
854 
855 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
856 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_SRC_ALPHA, m_verifierType);
857 
858 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
859 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_DST_ALPHA, m_verifierType);
860 	}
861 	{
862 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterResettingIndexedWithCommonSeparate", "After resetting indexed with common separate");
863 
864 		gl.glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR, GL_ONE_MINUS_DST_ALPHA);
865 
866 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
867 			gl.glBlendFuncSeparatei(ndx, blendFuncs[(ndx + 3) % DE_LENGTH_OF_ARRAY(blendFuncs)],
868 									blendFuncs[(ndx + 2) % DE_LENGTH_OF_ARRAY(blendFuncs)],
869 									blendFuncs[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendFuncs)],
870 									blendFuncs[(ndx + 0) % DE_LENGTH_OF_ARRAY(blendFuncs)]);
871 
872 		gl.glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR, GL_ONE_MINUS_DST_ALPHA);
873 
874 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
875 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_RGB, ndx, GL_SRC_COLOR, m_verifierType);
876 
877 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
878 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_RGB, ndx, GL_ONE_MINUS_SRC_ALPHA, m_verifierType);
879 
880 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
881 			verifyStateIndexedInteger(result, gl, GL_BLEND_SRC_ALPHA, ndx, GL_DST_COLOR, m_verifierType);
882 
883 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
884 			verifyStateIndexedInteger(result, gl, GL_BLEND_DST_ALPHA, ndx, GL_ONE_MINUS_DST_ALPHA, m_verifierType);
885 	}
886 
887 	result.setTestContextResult(m_testCtx);
888 	return STOP;
889 }
890 
891 class BlendEquationCase : public TestCase
892 {
893 public:
894 	BlendEquationCase	(Context& context, const char* name, const char* desc, QueryType verifierType);
895 
896 	void				init				(void);
897 private:
898 	IterateResult		iterate				(void);
899 
900 	const QueryType		m_verifierType;
901 };
902 
BlendEquationCase(Context & context,const char * name,const char * desc,QueryType verifierType)903 BlendEquationCase::BlendEquationCase (Context& context, const char* name, const char* desc, QueryType verifierType)
904 		: TestCase			(context, name, desc)
905 		, m_verifierType	(verifierType)
906 {
907 }
908 
init(void)909 void BlendEquationCase::init (void)
910 {
911 	isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed");
912 }
913 
iterate(void)914 BlendEquationCase::IterateResult BlendEquationCase::iterate (void)
915 {
916 	const deUint32 blendEquations[] =
917 			{
918 					GL_FUNC_ADD,
919 					GL_FUNC_SUBTRACT,
920 					GL_FUNC_REVERSE_SUBTRACT,
921 					GL_MIN,
922 					GL_MAX
923 			};
924 
925 	glu::CallLogWrapper		gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
926 	tcu::ResultCollector	result			(m_testCtx.getLog(), " // ERROR: ");
927 	deInt32					maxDrawBuffers = 0;
928 
929 	gl.enableLogging(true);
930 
931 	gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
932 	GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv");
933 
934 	{
935 		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial value");
936 
937 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
938 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_ADD, m_verifierType);
939 
940 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
941 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_ADD, m_verifierType);
942 	}
943 	{
944 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingCommon", "After setting common");
945 
946 		gl.glBlendEquation(GL_FUNC_SUBTRACT);
947 
948 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
949 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_SUBTRACT, m_verifierType);
950 
951 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
952 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_SUBTRACT, m_verifierType);
953 	}
954 	{
955 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingCommonSeparate", "After setting common separate");
956 
957 		gl.glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_SUBTRACT);
958 
959 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
960 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_REVERSE_SUBTRACT, m_verifierType);
961 
962 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
963 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_SUBTRACT, m_verifierType);
964 	}
965 	{
966 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed");
967 
968 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
969 			gl.glBlendEquationi(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)]);
970 
971 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
972 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], m_verifierType);
973 
974 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
975 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], m_verifierType);
976 	}
977 	{
978 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingIndexedSeparate", "After setting indexed separate");
979 
980 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
981 			gl.glBlendEquationSeparatei(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], blendEquations[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendEquations)]);
982 
983 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
984 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], m_verifierType);
985 
986 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
987 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, blendEquations[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendEquations)], m_verifierType);
988 	}
989 	{
990 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common");
991 
992 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
993 			gl.glBlendEquationi(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)]);
994 
995 		gl.glBlendEquation(GL_FUNC_SUBTRACT);
996 
997 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
998 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_SUBTRACT, m_verifierType);
999 
1000 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1001 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_SUBTRACT, m_verifierType);
1002 	}
1003 	{
1004 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterResettingIndexedWithCommonSeparate", "After resetting indexed with common separate");
1005 
1006 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1007 			gl.glBlendEquationSeparatei(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], blendEquations[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendEquations)]);
1008 
1009 		gl.glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_SUBTRACT);
1010 
1011 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1012 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_FUNC_REVERSE_SUBTRACT, m_verifierType);
1013 
1014 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1015 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_FUNC_SUBTRACT, m_verifierType);
1016 	}
1017 
1018 	result.setTestContextResult(m_testCtx);
1019 	return STOP;
1020 }
1021 
1022 class BlendEquationAdvancedCase : public TestCase
1023 {
1024 public:
1025 	BlendEquationAdvancedCase	(Context& context, const char* name, const char* desc, QueryType verifierType);
1026 
1027 	void				init				(void);
1028 private:
1029 	IterateResult		iterate				(void);
1030 
1031 	const QueryType		m_verifierType;
1032 };
1033 
BlendEquationAdvancedCase(Context & context,const char * name,const char * desc,QueryType verifierType)1034 BlendEquationAdvancedCase::BlendEquationAdvancedCase (Context& context, const char* name, const char* desc, QueryType verifierType)
1035 		: TestCase			(context, name, desc)
1036 		, m_verifierType	(verifierType)
1037 {
1038 }
1039 
init(void)1040 void BlendEquationAdvancedCase::init (void)
1041 {
1042 	isExtensionSupported(m_context, "GL_EXT_draw_buffers_indexed");
1043 	isExtensionSupported(m_context, "GL_KHR_blend_equation_advanced");
1044 }
1045 
iterate(void)1046 BlendEquationAdvancedCase::IterateResult BlendEquationAdvancedCase::iterate (void)
1047 {
1048 	const deUint32 blendEquations[] =
1049 			{
1050 					GL_FUNC_ADD,
1051 					GL_FUNC_SUBTRACT,
1052 					GL_FUNC_REVERSE_SUBTRACT,
1053 					GL_MIN,
1054 					GL_MAX
1055 			};
1056 
1057 	const deUint32 blendEquationAdvanced[] =
1058 			{
1059 					GL_MULTIPLY,
1060 					GL_SCREEN,
1061 					GL_OVERLAY,
1062 					GL_DARKEN,
1063 					GL_LIGHTEN,
1064 					GL_COLORDODGE,
1065 					GL_COLORBURN,
1066 					GL_HARDLIGHT,
1067 					GL_SOFTLIGHT,
1068 					GL_DIFFERENCE,
1069 					GL_EXCLUSION,
1070 					GL_HSL_HUE,
1071 					GL_HSL_SATURATION,
1072 					GL_HSL_COLOR,
1073 					GL_HSL_LUMINOSITY
1074 			};
1075 
1076 	glu::CallLogWrapper		gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
1077 	tcu::ResultCollector	result			(m_testCtx.getLog(), " // ERROR: ");
1078 	deInt32					maxDrawBuffers = 0;
1079 
1080 	gl.enableLogging(true);
1081 
1082 	gl.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
1083 	GLU_EXPECT_NO_ERROR(gl.glGetError(), "glGetIntegerv");
1084 
1085 	{
1086 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingCommon", "After setting common");
1087 
1088 		gl.glBlendEquation(GL_SCREEN);
1089 
1090 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1091 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_SCREEN, m_verifierType);
1092 
1093 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1094 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_SCREEN, m_verifierType);
1095 	}
1096 	{
1097 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterSettingIndexed", "After setting indexed");
1098 
1099 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1100 			gl.glBlendEquationi(ndx, blendEquationAdvanced[ndx % DE_LENGTH_OF_ARRAY(blendEquationAdvanced)]);
1101 
1102 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1103 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, blendEquationAdvanced[ndx % DE_LENGTH_OF_ARRAY(blendEquationAdvanced)], m_verifierType);
1104 
1105 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1106 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, blendEquationAdvanced[ndx % DE_LENGTH_OF_ARRAY(blendEquationAdvanced)], m_verifierType);
1107 	}
1108 	{
1109 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterResettingIndexedWithCommon", "After resetting indexed with common");
1110 
1111 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1112 			gl.glBlendEquationi(ndx, blendEquationAdvanced[ndx % DE_LENGTH_OF_ARRAY(blendEquationAdvanced)]);
1113 
1114 		gl.glBlendEquation(GL_MULTIPLY);
1115 
1116 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1117 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_MULTIPLY, m_verifierType);
1118 
1119 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1120 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_MULTIPLY, m_verifierType);
1121 	}
1122 	{
1123 		const tcu::ScopedLogSection section (m_testCtx.getLog(), "AfterResettingIndexedSeparateWithCommon", "After resetting indexed separate with common");
1124 
1125 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1126 			gl.glBlendEquationSeparatei(ndx, blendEquations[ndx % DE_LENGTH_OF_ARRAY(blendEquations)], blendEquations[(ndx + 1) % DE_LENGTH_OF_ARRAY(blendEquations)]);
1127 
1128 		gl.glBlendEquation(GL_LIGHTEN);
1129 
1130 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1131 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_RGB, ndx, GL_LIGHTEN, m_verifierType);
1132 
1133 		for (int ndx = 0; ndx < maxDrawBuffers; ++ndx)
1134 			verifyStateIndexedInteger(result, gl, GL_BLEND_EQUATION_ALPHA, ndx, GL_LIGHTEN, m_verifierType);
1135 	}
1136 
1137 	result.setTestContextResult(m_testCtx);
1138 	return STOP;
1139 }
1140 
1141 } // anonymous
1142 
IndexedStateQueryTests(Context & context)1143 IndexedStateQueryTests::IndexedStateQueryTests (Context& context)
1144 	: TestCaseGroup(context, "indexed", "Indexed Integer Values")
1145 {
1146 }
1147 
init(void)1148 void IndexedStateQueryTests::init (void)
1149 {
1150 	// transform feedback
1151 	addChild(new TransformFeedbackBufferBindingCase(m_context, "transform_feedback_buffer_binding", "TRANSFORM_FEEDBACK_BUFFER_BINDING"));
1152 	addChild(new TransformFeedbackBufferBufferCase(m_context, "transform_feedback_buffer_start_size", "TRANSFORM_FEEDBACK_BUFFER_START and TRANSFORM_FEEDBACK_BUFFER_SIZE"));
1153 	addChild(new TransformFeedbackSwitchingBufferCase(m_context, "transform_feedback_switching_buffer", "TRANSFORM_FEEDBACK_BUFFER_BINDING while switching transform feedback objects"));
1154 
1155 	// uniform buffers
1156 	addChild(new UniformBufferBindingCase(m_context, "uniform_buffer_binding", "UNIFORM_BUFFER_BINDING"));
1157 	addChild(new UniformBufferBufferCase(m_context, "uniform_buffer_start_size", "UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE"));
1158 
1159 	static const QueryType verifiers[] = { QUERY_INDEXED_INTEGER, QUERY_INDEXED_INTEGER64 };
1160 	static const QueryType vec4Verifiers[] = { QUERY_INDEXED_INTEGER_VEC4, QUERY_INDEXED_INTEGER64_VEC4 };
1161 
1162 #define FOR_EACH_VERIFIER(X) \
1163 	for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)	\
1164 	{																						\
1165 		const QueryType verifier = verifiers[verifierNdx];									\
1166 		const char* verifierSuffix = getVerifierSuffix(verifier);							\
1167 		this->addChild(X);																	\
1168 	}
1169 
1170 #define FOR_EACH_VEC4_VERIFIER(X) \
1171 	for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(vec4Verifiers); ++verifierNdx)	\
1172 	{																							\
1173 		const QueryType verifier = vec4Verifiers[verifierNdx];									\
1174 		const char* verifierSuffix = getVerifierSuffix(verifier);								\
1175 		this->addChild(X);																		\
1176 	}
1177 
1178 	addChild(new EnableBlendCase(m_context, "blend_isenabledi", "BLEND", QUERY_INDEXED_ISENABLED));
1179 	FOR_EACH_VEC4_VERIFIER(new ColorMaskCase		(m_context, (std::string() + "color_mask_" + verifierSuffix).c_str(),						"COLOR_WRITEMASK",						verifier))
1180 	FOR_EACH_VERIFIER(new BlendFuncCase				(m_context, (std::string() + "blend_func_" + verifierSuffix).c_str(),						"BLEND_SRC and BLEND_DST",				verifier))
1181 	FOR_EACH_VERIFIER(new BlendEquationCase			(m_context, (std::string() + "blend_equation_" + verifierSuffix).c_str(),					"BLEND_EQUATION_RGB and BLEND_DST",		verifier))
1182 	FOR_EACH_VERIFIER(new BlendEquationAdvancedCase	(m_context, (std::string() + "blend_equation_advanced_" + verifierSuffix).c_str(),			"BLEND_EQUATION_RGB and BLEND_DST",		verifier))
1183 }
1184 
1185 } // Functional
1186 } // gles3
1187 } // deqp
1188