xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fIndexedStateQueryTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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