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