Merge "Fix color change verification in dithering tests" into nougat-cts-dev am:...
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fIndexedStateQueryTests.cpp
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 "glwEnums.hpp"
29
30 using namespace glw; // GLint and other GL types
31 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
32
33 namespace deqp
34 {
35 namespace gles3
36 {
37 namespace Functional
38 {
39 namespace
40 {
41
42 void checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected)
43 {
44         using tcu::TestLog;
45
46         if (got != expected)
47         {
48                 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
49                 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
50                         testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
51         }
52 }
53
54 void checkIntEquals (tcu::TestContext& testCtx, GLint64 got, GLint64 expected)
55 {
56         using tcu::TestLog;
57
58         if (got != expected)
59         {
60                 testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
61                 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
62                         testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
63         }
64 }
65
66 class TransformFeedbackCase : public ApiCase
67 {
68 public:
69         TransformFeedbackCase (Context& context, const char* name, const char* description)
70                 : ApiCase(context, name, description)
71         {
72         }
73
74         virtual void testTransformFeedback (void) = DE_NULL;
75
76         void test (void)
77         {
78                 static const char* transformFeedbackTestVertSource      =       "#version 300 es\n"
79                                                                                                                                 "out highp vec4 anotherOutput;\n"
80                                                                                                                                 "void main (void)\n"
81                                                                                                                                 "{\n"
82                                                                                                                                 "       gl_Position = vec4(0.0);\n"
83                                                                                                                                 "       anotherOutput = vec4(0.0);\n"
84                                                                                                                                 "}\n\0";
85                 static const char* transformFeedbackTestFragSource      =       "#version 300 es\n"
86                                                                                                                                 "layout(location = 0) out mediump vec4 fragColor;"
87                                                                                                                                 "void main (void)\n"
88                                                                                                                                 "{\n"
89                                                                                                                                 "       fragColor = vec4(0.0);\n"
90                                                                                                                                 "}\n\0";
91
92                 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
93                 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
94
95                 glShaderSource(shaderVert, 1, &transformFeedbackTestVertSource, DE_NULL);
96                 glShaderSource(shaderFrag, 1, &transformFeedbackTestFragSource, DE_NULL);
97
98                 glCompileShader(shaderVert);
99                 glCompileShader(shaderFrag);
100                 expectError(GL_NO_ERROR);
101
102                 GLuint shaderProg = glCreateProgram();
103                 glAttachShader(shaderProg, shaderVert);
104                 glAttachShader(shaderProg, shaderFrag);
105
106                 const char* transformFeedbackOutputs[] =
107                 {
108                         "gl_Position",
109                         "anotherOutput"
110                 };
111
112                 glTransformFeedbackVaryings(shaderProg, 2, transformFeedbackOutputs, GL_INTERLEAVED_ATTRIBS);
113                 glLinkProgram(shaderProg);
114                 expectError(GL_NO_ERROR);
115
116                 GLuint transformFeedbackId = 0;
117                 glGenTransformFeedbacks(1, &transformFeedbackId);
118                 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackId);
119                 expectError(GL_NO_ERROR);
120
121                 testTransformFeedback();
122
123                 // cleanup
124
125                 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
126
127                 glDeleteTransformFeedbacks(1, &transformFeedbackId);
128                 glDeleteShader(shaderVert);
129                 glDeleteShader(shaderFrag);
130                 glDeleteProgram(shaderProg);
131                 expectError(GL_NO_ERROR);
132         }
133 };
134
135 class TransformFeedbackBufferBindingCase : public TransformFeedbackCase
136 {
137 public:
138         TransformFeedbackBufferBindingCase (Context& context, const char* name, const char* description)
139                 : TransformFeedbackCase(context, name, description)
140         {
141         }
142
143         void testTransformFeedback (void)
144         {
145                 const int feedbackPositionIndex = 0;
146                 const int feedbackOutputIndex = 1;
147                 const int feedbackIndex[2] = {feedbackPositionIndex, feedbackOutputIndex};
148
149                 // bind bffers
150
151                 GLuint feedbackBuffers[2];
152                 glGenBuffers(2, feedbackBuffers);
153                 expectError(GL_NO_ERROR);
154
155                 for (int ndx = 0; ndx < 2; ++ndx)
156                 {
157                         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[ndx]);
158                         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ);
159                         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackIndex[ndx], feedbackBuffers[ndx]);
160                         expectError(GL_NO_ERROR);
161                 }
162
163                 // test TRANSFORM_FEEDBACK_BUFFER_BINDING
164
165                 for (int ndx = 0; ndx < 2; ++ndx)
166                 {
167                         StateQueryMemoryWriteGuard<GLint> boundBuffer;
168                         glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, feedbackIndex[ndx], &boundBuffer);
169                         boundBuffer.verifyValidity(m_testCtx);
170                         checkIntEquals(m_testCtx, boundBuffer, feedbackBuffers[ndx]);
171                 }
172
173
174                 // cleanup
175
176                 glDeleteBuffers(2, feedbackBuffers);
177         }
178 };
179
180 class TransformFeedbackBufferBufferCase : public TransformFeedbackCase
181 {
182 public:
183         TransformFeedbackBufferBufferCase (Context& context, const char* name, const char* description)
184                 : TransformFeedbackCase(context, name, description)
185         {
186         }
187
188         void testTransformFeedback (void)
189         {
190                 const int feedbackPositionIndex = 0;
191                 const int feedbackOutputIndex = 1;
192
193                 const int rangeBufferOffset = 4;
194                 const int rangeBufferSize = 8;
195
196                 // bind buffers
197
198                 GLuint feedbackBuffers[2];
199                 glGenBuffers(2, feedbackBuffers);
200                 expectError(GL_NO_ERROR);
201
202                 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[0]);
203                 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ);
204                 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackPositionIndex, feedbackBuffers[0]);
205                 expectError(GL_NO_ERROR);
206
207                 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[1]);
208                 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_DYNAMIC_READ);
209                 glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, feedbackOutputIndex, feedbackBuffers[1], rangeBufferOffset, rangeBufferSize);
210                 expectError(GL_NO_ERROR);
211
212                 // test TRANSFORM_FEEDBACK_BUFFER_START and TRANSFORM_FEEDBACK_BUFFER_SIZE
213
214                 const struct BufferRequirements
215                 {
216                         GLint   index;
217                         GLenum  pname;
218                         GLint64 value;
219                 } requirements[] =
220                 {
221                         { feedbackPositionIndex,        GL_TRANSFORM_FEEDBACK_BUFFER_START, 0                                   },
222                         { feedbackPositionIndex,        GL_TRANSFORM_FEEDBACK_BUFFER_SIZE,      0                                       },
223                         { feedbackOutputIndex,          GL_TRANSFORM_FEEDBACK_BUFFER_START, rangeBufferOffset   },
224                         { feedbackOutputIndex,          GL_TRANSFORM_FEEDBACK_BUFFER_SIZE,      rangeBufferSize         }
225                 };
226
227                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requirements); ++ndx)
228                 {
229                         StateQueryMemoryWriteGuard<GLint64> state;
230                         glGetInteger64i_v(requirements[ndx].pname, requirements[ndx].index, &state);
231
232                         if (state.verifyValidity(m_testCtx))
233                                 checkIntEquals(m_testCtx, state, requirements[ndx].value);
234                 }
235
236                 // cleanup
237
238                 glDeleteBuffers(2, feedbackBuffers);
239         }
240 };
241
242 class UniformBufferCase : public ApiCase
243 {
244 public:
245         UniformBufferCase (Context& context, const char* name, const char* description)
246                 : ApiCase       (context, name, description)
247                 , m_program     (0)
248         {
249         }
250
251         virtual void testUniformBuffers (void) = DE_NULL;
252
253         void test (void)
254         {
255                 static const char* testVertSource       =       "#version 300 es\n"
256                                                                                                 "uniform highp vec4 input1;\n"
257                                                                                                 "uniform highp vec4 input2;\n"
258                                                                                                 "void main (void)\n"
259                                                                                                 "{\n"
260                                                                                                 "       gl_Position = input1 + input2;\n"
261                                                                                                 "}\n\0";
262                 static const char* testFragSource       =       "#version 300 es\n"
263                                                                                                 "layout(location = 0) out mediump vec4 fragColor;"
264                                                                                                 "void main (void)\n"
265                                                                                                 "{\n"
266                                                                                                 "       fragColor = vec4(0.0);\n"
267                                                                                                 "}\n\0";
268
269                 GLuint shaderVert = glCreateShader(GL_VERTEX_SHADER);
270                 GLuint shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
271
272                 glShaderSource(shaderVert, 1, &testVertSource, DE_NULL);
273                 glShaderSource(shaderFrag, 1, &testFragSource, DE_NULL);
274
275                 glCompileShader(shaderVert);
276                 glCompileShader(shaderFrag);
277                 expectError(GL_NO_ERROR);
278
279                 m_program = glCreateProgram();
280                 glAttachShader(m_program, shaderVert);
281                 glAttachShader(m_program, shaderFrag);
282                 glLinkProgram(m_program);
283                 glUseProgram(m_program);
284                 expectError(GL_NO_ERROR);
285
286                 testUniformBuffers();
287
288                 glUseProgram(0);
289                 glDeleteShader(shaderVert);
290                 glDeleteShader(shaderFrag);
291                 glDeleteProgram(m_program);
292                 expectError(GL_NO_ERROR);
293         }
294
295 protected:
296         GLuint  m_program;
297 };
298
299 class UniformBufferBindingCase : public UniformBufferCase
300 {
301 public:
302         UniformBufferBindingCase (Context& context, const char* name, const char* description)
303                 : UniformBufferCase(context, name, description)
304         {
305         }
306
307         void testUniformBuffers (void)
308         {
309                 const char* uniformNames[] =
310                 {
311                         "input1",
312                         "input2"
313                 };
314                 GLuint uniformIndices[2] = {0};
315                 glGetUniformIndices(m_program, 2, uniformNames, uniformIndices);
316
317                 GLuint buffers[2];
318                 glGenBuffers(2, buffers);
319
320                 for (int ndx = 0; ndx < 2; ++ndx)
321                 {
322                         glBindBuffer(GL_UNIFORM_BUFFER, buffers[ndx]);
323                         glBufferData(GL_UNIFORM_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
324                         glBindBufferBase(GL_UNIFORM_BUFFER, uniformIndices[ndx], buffers[ndx]);
325                         expectError(GL_NO_ERROR);
326                 }
327
328                 for (int ndx = 0; ndx < 2; ++ndx)
329                 {
330                         StateQueryMemoryWriteGuard<GLint> boundBuffer;
331                         glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, uniformIndices[ndx], &boundBuffer);
332
333                         if (boundBuffer.verifyValidity(m_testCtx))
334                                 checkIntEquals(m_testCtx, boundBuffer, buffers[ndx]);
335                         expectError(GL_NO_ERROR);
336                 }
337
338                 glDeleteBuffers(2, buffers);
339         }
340 };
341
342 class UniformBufferBufferCase : public UniformBufferCase
343 {
344 public:
345         UniformBufferBufferCase (Context& context, const char* name, const char* description)
346                 : UniformBufferCase(context, name, description)
347         {
348         }
349
350         void testUniformBuffers (void)
351         {
352                 const char* uniformNames[] =
353                 {
354                         "input1",
355                         "input2"
356                 };
357                 GLuint uniformIndices[2] = {0};
358                 glGetUniformIndices(m_program, 2, uniformNames, uniformIndices);
359
360                 const GLint alignment = GetAlignment();
361                 if (alignment == -1) // cannot continue without this
362                         return;
363
364                 m_testCtx.getLog() << tcu::TestLog::Message << "Alignment is " << alignment << tcu::TestLog::EndMessage;
365
366                 int rangeBufferOffset           = alignment;
367                 int rangeBufferSize                     = alignment * 2;
368                 int rangeBufferTotalSize        = rangeBufferOffset + rangeBufferSize + 8; // + 8 has no special meaning, just to make it != with the size of the range
369
370                 GLuint buffers[2];
371                 glGenBuffers(2, buffers);
372
373                 glBindBuffer(GL_UNIFORM_BUFFER, buffers[0]);
374                 glBufferData(GL_UNIFORM_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
375                 glBindBufferBase(GL_UNIFORM_BUFFER, uniformIndices[0], buffers[0]);
376                 expectError(GL_NO_ERROR);
377
378                 glBindBuffer(GL_UNIFORM_BUFFER, buffers[1]);
379                 glBufferData(GL_UNIFORM_BUFFER, rangeBufferTotalSize, DE_NULL, GL_DYNAMIC_DRAW);
380                 glBindBufferRange(GL_UNIFORM_BUFFER, uniformIndices[1], buffers[1], rangeBufferOffset, rangeBufferSize);
381                 expectError(GL_NO_ERROR);
382
383                 // test UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE
384
385                 const struct BufferRequirements
386                 {
387                         GLuint  index;
388                         GLenum  pname;
389                         GLint64 value;
390                 } requirements[] =
391                 {
392                         { uniformIndices[0], GL_UNIFORM_BUFFER_START,   0                                       },
393                         { uniformIndices[0], GL_UNIFORM_BUFFER_SIZE,    0                                       },
394                         { uniformIndices[1], GL_UNIFORM_BUFFER_START,   rangeBufferOffset       },
395                         { uniformIndices[1], GL_UNIFORM_BUFFER_SIZE,    rangeBufferSize         }
396                 };
397
398                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(requirements); ++ndx)
399                 {
400                         StateQueryMemoryWriteGuard<GLint64> state;
401                         glGetInteger64i_v(requirements[ndx].pname, requirements[ndx].index, &state);
402
403                         if (state.verifyValidity(m_testCtx))
404                                 checkIntEquals(m_testCtx, state, requirements[ndx].value);
405                         expectError(GL_NO_ERROR);
406                 }
407
408                 glDeleteBuffers(2, buffers);
409         }
410
411         int GetAlignment()
412         {
413                 StateQueryMemoryWriteGuard<GLint> state;
414                 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &state);
415
416                 if (!state.verifyValidity(m_testCtx))
417                         return -1;
418
419                 if (state <= 256)
420                         return state;
421
422                 m_testCtx.getLog() << tcu::TestLog::Message << "// ERROR: UNIFORM_BUFFER_OFFSET_ALIGNMENT has a maximum value of 256." << tcu::TestLog::EndMessage;
423                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid UNIFORM_BUFFER_OFFSET_ALIGNMENT value");
424
425                 return -1;
426         }
427 };
428
429 } // anonymous
430
431 IndexedStateQueryTests::IndexedStateQueryTests (Context& context)
432         : TestCaseGroup(context, "indexed", "Indexed Integer Values")
433 {
434 }
435
436 void IndexedStateQueryTests::init (void)
437 {
438         // transform feedback
439         addChild(new TransformFeedbackBufferBindingCase(m_context, "transform_feedback_buffer_binding", "TRANSFORM_FEEDBACK_BUFFER_BINDING"));
440         addChild(new TransformFeedbackBufferBufferCase(m_context, "transform_feedback_buffer_start_size", "TRANSFORM_FEEDBACK_BUFFER_START and TRANSFORM_FEEDBACK_BUFFER_SIZE"));
441
442         // uniform buffers
443         addChild(new UniformBufferBindingCase(m_context, "uniform_buffer_binding", "UNIFORM_BUFFER_BINDING"));
444         addChild(new UniformBufferBufferCase(m_context, "uniform_buffer_start_size", "UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE"));
445 }
446
447 } // Functional
448 } // gles3
449 } // deqp